Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-tipc.c
blob203700fe002af0baf810ddbf33585f9781310312
1 /* packet-tipc.c
2 * Routines for Transparent Inter Process Communication packet dissection
4 * Copyright 2005-2006, Anders Broman <anders.broman@ericsson.com>
6 * TIPCv2 protocol updates
7 * Copyright 2006-2008, Martin Peylo <wireshark@izac.de>
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * SPDX-License-Identifier: GPL-2.0-or-later
14 * Protocol ref:
15 * https://tipc.sourceforge.net/
16 * https://tipc.sourceforge.net/protocol.html
20 #include "config.h"
22 #include <epan/packet.h>
23 #include <epan/prefs.h>
24 #include <epan/proto_data.h>
25 #include <epan/expert.h>
26 #include <epan/etypes.h>
27 #include <epan/address_types.h>
28 #include <epan/reassemble.h>
30 #include "packet-tcp.h"
32 void proto_register_tipc(void);
34 static int proto_tipc;
36 static int hf_tipc_msg_fragments;
37 static int hf_tipc_msg_fragment;
38 static int hf_tipc_msg_fragment_overlap;
39 static int hf_tipc_msg_fragment_overlap_conflicts;
40 static int hf_tipc_msg_fragment_multiple_tails;
41 static int hf_tipc_msg_fragment_too_long_fragment;
42 static int hf_tipc_msg_fragment_error;
43 static int hf_tipc_msg_fragment_count;
44 static int hf_tipc_msg_reassembled_in;
45 static int hf_tipc_msg_reassembled_length;
47 static int hf_tipc_ver;
48 static int hf_tipc_usr;
49 static int hf_tipcv2_usr;
50 static int hf_tipc_hdr_size;
51 static int hf_tipc_nonsequenced;
52 static int hf_tipc_destdrop;
53 static int hf_tipc_unused;
54 static int hf_tipc_msg_size;
55 static int hf_tipc_ack_link_lev_seq;
56 static int hf_tipc_link_lev_seq;
57 static int hf_tipc_prev_proc;
58 static int hf_tipc_org_port;
59 static int hf_tipc_dst_port;
60 static int hf_tipc_data_msg_type;
61 static int hf_tipc_err_code;
62 static int hf_tipc_reroute_cnt;
63 static int hf_tipc_act_id;
64 static int hf_tipc_org_proc;
65 static int hf_tipc_dst_proc;
66 static int hf_tipc_unused2;
67 static int hf_tipc_importance;
68 static int hf_tipc_link_selector;
69 static int hf_tipc_msg_cnt;
70 static int hf_tipc_probe;
71 static int hf_tipc_bearer_id;
72 static int hf_tipc_link_selector2;
73 static int hf_tipc_remote_addr;
74 static int hf_tipc_rm_msg_type;
75 static int hf_tipc_nd_msg_type;
76 static int hf_tipc_cm_msg_type;
77 static int hf_tipc_lp_msg_type;
78 static int hf_tipc_cng_prot_msg_type;
79 static int hf_tipc_sm_msg_type;
80 static int hf_tipc_unknown_msg_type;
81 static int hf_tipc_seq_gap;
82 static int hf_tipc_nxt_snt_pkg;
83 static int hf_tipc_unused_word;
84 static int hf_tipc_bearer_name;
85 static int hf_tipc_data;
86 static int hf_tipc_msg_no_bundle;
87 static int hf_tipc_changeover_protocol;
88 static int hf_tipc_named_msg_hdr;
89 static int hf_tipc_port_name_type;
90 static int hf_tipc_port_name_instance;
91 static int hf_tipc_data_fragment;
92 static int hf_tipc_message_bundle;
95 static int hf_tipc_name_dist_type;
96 static int hf_tipc_name_dist_lower;
97 static int hf_tipc_name_dist_upper;
98 static int hf_tipc_name_dist_port;
99 static int hf_tipc_name_dist_key;
101 static int hf_tipcv2_srcdrop;
102 static int hf_tipcv2_data_msg_type;
103 static int hf_tipcv2_bcast_mtype;
104 static int hf_tipcv2_bundler_mtype;
105 static int hf_tipcv2_link_mtype;
106 static int hf_tipcv2_connmgr_mtype;
107 static int hf_tipcv2_route_mtype_1_6;
108 static int hf_tipcv2_route_mtype_1_7;
109 static int hf_tipcv2_changeover_mtype;
110 static int hf_tipcv2_naming_mtype;
111 static int hf_tipcv2_fragmenter_mtype;
112 static int hf_tipcv2_neighbour_mtype;
113 static int hf_tipcv2_errorcode;
114 static int hf_tipcv2_rer_cnt;
115 static int hf_tipcv2_lookup_scope;
116 static int hf_tipcv2_opt_p;
117 static int hf_tipcv2_broadcast_ack_no;
118 static int hf_tipcv2_link_level_ack_no;
119 static int hf_tipcv2_link_level_seq_no;
120 /* static int hf_tipcv2_bcast_seq_no; */
121 static int hf_tipcv2_prev_node;
122 static int hf_tipcv2_orig_node;
123 static int hf_tipcv2_dest_node;
124 static int hf_tipcv2_port_name_type;
125 static int hf_tipcv2_port_name_instance;
126 static int hf_tipcv2_multicast_lower;
127 static int hf_tipcv2_multicast_upper;
129 static int hf_tipcv2_sequence_gap;
130 static int hf_tipcv2_next_sent_broadcast;
131 static int hf_tipcv2_fragment_number;
132 static int hf_tipcv2_fragment_msg_number;
133 static int hf_tipcv2_next_sent_packet;
134 static int hf_tipcv2_session_no;
135 static int hf_tipcv2_link_prio;
136 static int hf_tipcv2_network_plane;
137 static int hf_tipcv2_probe;
138 static int hf_tipcv2_link_tolerance;
139 static int hf_tipcv2_bearer_instance;
140 static int hf_tipcv2_padding;
141 static int hf_tipcv2_bearer_level_orig_addr;
142 static int hf_tipcv2_cluster_address;
143 static int hf_tipcv2_bitmap;
144 static int hf_tipcv2_node_address;
145 static int hf_tipcv2_destination_domain;
146 static int hf_tipcv2_network_id;
148 static int hf_tipcv2_bcast_tag;
149 static int hf_tipcv2_msg_count;
150 static int hf_tipcv2_max_packet;
151 static int hf_tipcv2_transport_seq_no;
152 static int hf_tipcv2_redundant_link;
153 static int hf_tipcv2_bearer_id;
154 static int hf_tipcv2_conn_mgr_msg_ack;
155 static int hf_tipcv2_minor_pv;
156 static int hf_tipcv2_node_sig;
157 static int hf_tipcv2_filler_mtu_discovery;
158 static int hf_tipcv2_vendor_specific_data;
159 static int hf_tipcv2_options;
161 /* added for TIPC v1.7 */
162 static int hf_tipcv2_timestamp;
163 static int hf_tipcv2_item_size;
164 static int hf_tipcv2_network_region;
165 static int hf_tipcv2_local_router;
166 static int hf_tipcv2_remote_router;
167 static int hf_tipcv2_dist_dist;
168 static int hf_tipcv2_dist_scope;
169 static int hf_tipcv2_name_dist_port_id_node;
170 static int hf_tipcv2_media_id;
172 /* added in minor PV 1 */
173 static int hf_tipcv2_syn;
176 static int ett_tipc_msg_fragment;
177 static int ett_tipc_msg_fragments;
180 /* Initialize the subtree pointer */
181 static int ett_tipc;
182 static int ett_tipc_data;
184 static expert_field ei_tipc_field_not_specified;
185 static expert_field ei_tipc_invalid_bundle_size;
186 static expert_field ei_tipc_max_recursion_depth_reached;
188 static int tipc_address_type = -1;
190 /* protocol preferences */
191 static bool tipc_defragment = true;
192 static bool dissect_tipc_data = true;
193 static bool try_heuristic_first;
194 #define V2_AS_ALL 0x1
195 #define V2_AS_1_6 0x2
196 #define V2_AS_1_7 0x4
197 static int handle_v2_as = V2_AS_ALL;
198 static bool tipc_tcp_desegment = true;
200 static dissector_handle_t tipc_handle;
201 static dissector_handle_t tipc_tcp_handle;
203 /* IANA have assigned port 6118 port for TIPC UDP transport. */
204 #define DEFAULT_TIPC_PORT_RANGE "6118"
206 /* this is used to find encapsulated protocols */
207 static dissector_table_t tipc_user_dissector;
208 static dissector_table_t tipc_type_dissector;
210 static heur_dissector_list_t tipc_heur_subdissector_list;
212 static proto_tree *top_tree;
214 static const fragment_items tipc_msg_frag_items = {
215 /* Fragment subtrees */
216 &ett_tipc_msg_fragment,
217 &ett_tipc_msg_fragments,
218 /* Fragment fields */
219 &hf_tipc_msg_fragments,
220 &hf_tipc_msg_fragment,
221 &hf_tipc_msg_fragment_overlap,
222 &hf_tipc_msg_fragment_overlap_conflicts,
223 &hf_tipc_msg_fragment_multiple_tails,
224 &hf_tipc_msg_fragment_too_long_fragment,
225 &hf_tipc_msg_fragment_error,
226 &hf_tipc_msg_fragment_count,
227 /* Reassembled in field */
228 &hf_tipc_msg_reassembled_in,
229 /* Reassembled length field */
230 &hf_tipc_msg_reassembled_length,
231 /* Reassembled data field */
232 NULL,
233 /* Tag */
234 "TIPC Message fragments"
238 #define MAX_TIPC_ADDRESS_STR_LEN 15
239 #define TIPCv1 1
240 #define TIPCv2 2
241 /* Users */
242 #define TIPC_DATA_PRIO_0 0
243 #define TIPC_DATA_PRIO_1 1
244 #define TIPC_DATA_PRIO_2 2
245 #define TIPC_DATA_NON_REJECTABLE 3
247 #define TIPC_ROUTING_MANAGER 8
248 #define TIPC_NAME_DISTRIBUTOR 9
249 #define TIPC_CONNECTION_MANAGER 10
250 #define TIPC_LINK_PROTOCOL 11
251 #define TIPC_CHANGEOVER_PROTOCOL 13
252 #define TIPC_SEGMENTATION_MANAGER 14
253 #define TIPC_MSG_BUNDLER 15
255 #define TIPC_LINK_PROTOCO_STATE_MSG 0
257 static const value_string tipc_user_values[] = {
258 { TIPC_DATA_PRIO_0, "DATA_PRIO_0"},
259 { TIPC_DATA_PRIO_1, "DATA_PRIO_1"},
260 { TIPC_DATA_PRIO_2, "DATA_PRIO_2"},
261 { TIPC_DATA_NON_REJECTABLE, "DATA_NON_REJECTABLE"},
262 { TIPC_ROUTING_MANAGER, "ROUTING_MANAGER"},
263 { TIPC_NAME_DISTRIBUTOR, "NAME_DISTRIBUTOR"},
264 { TIPC_CONNECTION_MANAGER, "CONNECTION_MANAGER"},
265 { TIPC_LINK_PROTOCOL, "LINK_PROTOCOL"},
266 { TIPC_CHANGEOVER_PROTOCOL, "CHANGEOVER_PROTOCOL"},
267 { TIPC_SEGMENTATION_MANAGER, "SEGMENTATION_MANAGER"},
268 { TIPC_MSG_BUNDLER, "MSG_BUNDLER"},
269 { 0, NULL}
272 #define TIPCv2_DATA_LOW 0
273 #define TIPCv2_DATA_NORMAL 1
274 #define TIPCv2_DATA_HIGH 2
275 #define TIPCv2_DATA_NON_REJECTABLE 3
277 #define TIPCv2_BCAST_PROTOCOL 5
278 #define TIPCv2_MSG_BUNDLER 6
279 #define TIPCv2_LINK_PROTOCOL 7
280 #define TIPCv2_CONN_MANAGER 8
281 #define TIPCv2_ROUTE_DISTRIBUTOR 9
282 #define TIPCv2_CHANGEOVER_PROTOCOL 10
283 #define TIPCv2_NAME_DISTRIBUTOR 11
284 #define TIPCv2_MSG_FRAGMENTER 12
285 #define TIPCv2_NEIGHBOUR_DISCOVERY 13
287 #define TIPCv2_USER_FIRST_FRAGMENT 0
288 #define TIPCv2_USER_FRAGMENT 1
289 #define TIPCv2_USER_LAST_FRAGMENT 2
291 static const value_string tipcv2_user_values[] = {
292 { TIPCv2_DATA_LOW, "Low Priority Payload Data"},
293 { TIPCv2_DATA_NORMAL, "Normal Priority Payload Data"},
294 { TIPCv2_DATA_HIGH, "High Priority Payload Data"},
295 { TIPCv2_DATA_NON_REJECTABLE, "Non-Rejectable Payload Data"},
296 { TIPCv2_BCAST_PROTOCOL, "Broadcast Maintenance Protocol"},
297 { TIPCv2_MSG_BUNDLER, "Message Bundler Protocol"},
298 { TIPCv2_LINK_PROTOCOL, "Link State Maintenance Protocol"},
299 { TIPCv2_CONN_MANAGER, "Connection Manager"},
300 { TIPCv2_ROUTE_DISTRIBUTOR, "Routing Table Update Protocol"},
301 { TIPCv2_CHANGEOVER_PROTOCOL, "Link Changeover Protocol"},
302 { TIPCv2_NAME_DISTRIBUTOR, "Name Table Update Protocol"},
303 { TIPCv2_MSG_FRAGMENTER, "Message Fragmentation Protocol"},
304 { TIPCv2_NEIGHBOUR_DISCOVERY, "Neighbour Discovery Protocol"},
305 { 0, NULL}
308 static const value_string tipcv2_user_short_str_vals[] = {
309 { TIPCv2_DATA_LOW, "Payld:Low"},
310 { TIPCv2_DATA_NORMAL, "Payld:Normal"},
311 { TIPCv2_DATA_HIGH, "Payld:High"},
312 { TIPCv2_DATA_NON_REJECTABLE, "Payld:NoRej"},
313 { TIPCv2_BCAST_PROTOCOL, "Broadcast"},
314 { TIPCv2_MSG_BUNDLER, "Bundler"},
315 { TIPCv2_LINK_PROTOCOL, "Link State"},
316 { TIPCv2_CONN_MANAGER, "Conn Mgr"},
317 { TIPCv2_ROUTE_DISTRIBUTOR, "Route Dist"},
318 { TIPCv2_CHANGEOVER_PROTOCOL, "Changeover"},
319 { TIPCv2_NAME_DISTRIBUTOR, "Name Dist"},
320 { TIPCv2_MSG_FRAGMENTER, "Fragmenter"},
321 { TIPCv2_NEIGHBOUR_DISCOVERY, "Ngbr Disc"},
322 { 0, NULL}
325 #define TIPC_CONNECTED_MSG 0
326 #define TIPC_NAMED_MSG 2
327 #define TIPC_DIRECT_MSG 3
328 #define TIPC_OVERLOAD_W_MSG 4
330 static const value_string tipc_data_msg_type_values[] = {
331 { 0, "CONN_MSG"},
332 { 2, "NAMED_MSG"},
333 { 3, "DIRECT_MSG"},
334 { 4, "OVERLOAD_W_MSG"},
335 { 0, NULL}
338 static const value_string tipcv2_data_msg_type_defines[] = {
339 { 0, "ConnMsg"},
340 { 1, "McastMsg"},
341 { 2, "NamedMsg"},
342 { 3, "DirectMsg"},
343 { 0, NULL}
346 static const value_string tipcv2_data_msg_type_values[] _U_ = {
347 { 0, "Sent on connection (CONN_MSG)"},
348 { 1, "Logical multicast (MCAST_MSG)"},
349 { 2, "Port name destination address (NAMED_MSG)"},
350 { 3, "Port identity destination address (DIRECT_MSG)"},
351 { 0, NULL}
354 static const value_string tipc_error_code_values[] = {
355 { 0, "MSG_OK"},
356 { 1, "NO_PORT_NAME"},
357 { 2, "NO_REMOTE_PORT"},
358 { 3, "NO_REMOTE_PROCESSOR"},
359 { 4, "DEST_OVERLOADED"},
360 { 5, "CONN_SHUTDOWN"},
361 { 6, "NO_CONNECTION"},
362 { 7, "COMMUNICATION_ERROR"},
363 { 0, NULL}
366 static const value_string tipcv2_error_code_strings[] = {
367 { 0, "No error (TIPC_OK)"},
368 { 1, "Destination port name unknown (TIPC_ERR_NO_NAME)"},
369 { 2, "Destination port does not exist (TIPC_ERR_NO_PORT)"},
370 { 3, "Destination node unavailable (TIPC_ERR_NO_NODE)"},
371 { 4, "Destination node overloaded (TIPC_ERR_OVERLOAD)"},
372 { 5, "Connection Shutdown (No error) (TIPC_CONN_SHUTDOWN)"},
373 { 6, "Communication Error (TIPC_CONN_ERROR)"},
374 { 0, NULL}
377 static const value_string tipcv2_error_code_short_strings[] = {
378 { 0, "OK"},
379 { 1, "ErrNoName"},
380 { 2, "ErrNoPort"},
381 { 3, "ErrNoNode"},
382 { 4, "ErrOverload"},
383 { 5, "ConnShutdown"},
384 { 6, "ConnError"},
385 { 0, NULL}
388 static const value_string tipcv2_lookup_scope_strings[] = {
389 { 0, "Zone Scope"},
390 { 1, "Cluster Scope"},
391 { 2, "Node Scope"},
392 { 0, NULL}
395 static const value_string tipc_routing_mgr_msg_type_values[] = {
396 { 0, "EXT_ROUTING_TABLE"},
397 { 1, "LOCAL_ROUTING_TABLE"},
398 { 2, "DP_ROUTING_TABLE"},
399 { 3, "ROUTE_ADDITION"},
400 { 4, "ROUTE_REMOVAL"},
401 { 0, NULL}
404 static const value_string tipc_name_dist_msg_type_values[] = {
405 { 0, "PUBLICATION"},
406 { 1, "WITHDRAWAL"},
407 { 0, NULL}
410 /* CONNECTION_MANAGER */
411 static const value_string tipc_cm_msg_type_values[] = {
412 { 0, "CONNECTION_PROBE"},
413 { 1, "CONNECTION_PROBE_REPLY"},
414 { 0, NULL}
417 static const value_string tipc_link_prot_msg_type_values[] = {
418 { 10, "RESET_MSG"},
419 { 11, "ACTIVATE_MSG"},
420 { 12, "STATE_MSG"},
421 { 0, NULL}
424 /* CHANGEOVER_PROTOCOL */
425 static const value_string tipc_cng_prot_msg_type_values[] = {
426 { 0, "DUPLICATE_MSG"},
427 { 1, "ORIGINAL_MSG"},
428 { 2, "INFO_MSG"},
429 { 0, NULL}
432 /* SEGMENTATION_MANAGER */
433 #define TIPC_FIRST_SEGMENT 1
434 #define TIPC_SEGMENT 2
435 static const value_string tipc_sm_msg_type_values[] = {
436 { 1, "FIRST_SEGMENT"},
437 { 2, "SEGMENT"},
438 { 0, NULL}
441 /* TIPCv2_BCAST_PROTOCOL - Broadcast Maintenance Protocol */
442 static const value_string tipcv2_bcast_mtype_strings[] = {
443 { 0, "Bcast"},
444 { 0, NULL}
447 /* TIPCv2_MSG_BUNDLER - Message Bundler Protocol */
448 static const value_string tipcv2_bundler_mtype_strings[] = {
449 { 1, "Bundler"},
450 { 0, NULL}
453 /* TIPCv2_LINK_PROTOCOL - Link State Maintenance Protocol */
454 #define TIPCv2_STATE_MSG 0
455 #define TIPCv2_RESET_MSG 1
456 #define TIPCv2_ACTIV_MSG 2
458 static const value_string tipcv2_link_mtype_strings[] = {
459 { TIPCv2_STATE_MSG, "State"},
460 { TIPCv2_RESET_MSG, "Reset"},
461 { TIPCv2_ACTIV_MSG, "Activate"},
462 { 0, NULL}
465 /* TIPCv2_CONN_MANAGER - Connection Manager */
466 #define TIPCv2_CONMGR_CONN_PROBE 0
467 #define TIPCv2_CONMGR_CONN_PROBE_REPLY 1
468 #define TIPCv2_CONMGR_MSG_ACK 2
469 static const value_string tipcv2_connmgr_mtype_strings[] = {
470 { TIPCv2_CONMGR_CONN_PROBE , "Probe"},
471 { TIPCv2_CONMGR_CONN_PROBE_REPLY , "ProbeReply"},
472 { TIPCv2_CONMGR_MSG_ACK , "Ack"},
473 { 0, NULL}
476 /* TIPCv2_ROUTE_DISTRIBUTOR - Routing Table Update Protocol */
477 /* for TIPC 1.6 */
478 #define TIPCv2_EXT_ROUTING_TABLE 0
479 #define TIPCv2_LOCAL_ROUTING_TABLE 1
480 #define TIPCv2_SEC_ROUTING_TABLE 2
481 #define TIPCv2_ROUTE_ADDITION 3
482 #define TIPCv2_ROUTE_REMOVAL 4
483 /* for TIPC 1.7 */
484 #define TIPCv2_DIST_PUBLISH 0
485 #define TIPCv2_DIST_WITHDRAW 1
486 #define TIPCv2_DIST_PURGE 2
488 static const value_string tipcv2_route_mtype_strings_1_6[] = {
489 { 0, "ExtRoutingTab"},
490 { 1, "LocalRoutingTab"},
491 { 2, "SecRoutingTab"},
492 { 3, "RouteAddition"},
493 { 4, "RouteRemoval"},
494 { 0, NULL}
497 static const value_string tipcv2_route_mtype_strings_1_7[] = {
498 { 0, "Dist Publish"},
499 { 1, "Dist Withdraw"},
500 { 2, "Dist Purge"},
501 { 0, NULL}
504 static const value_string tipcv2_dist_dist_strings[] = {
505 { 0, "Nowhere"},
506 { 1, "To Cluster"},
507 { 2, "To Zone"},
508 { 3, "To Cluster and Zone"},
509 { 4, "To Network"},
510 { 5, "To Cluster and Network"},
511 { 6, "To Zone and Network"},
512 { 7, "To Cluster, Zone and Network"},
513 { 0, NULL}
516 static const value_string tipcv2_dist_scope_strings[] = {
517 { 0, "Zone Scope"},
518 { 1, "Cluster Scope"},
519 { 2, "Node Scope"},
520 { 0, NULL}
523 /* TIPCv2_CHANGEOVER_PROTOCOL - Link Changeover Protocol */
524 static const value_string tipcv2_changeover_mtype_strings[] = {
525 { 0, "Duplicate"},
526 { 1, "Original"},
527 { 0, NULL}
530 /* TIPCv2_NAME_DISTRIBUTOR - Name Table Update Protocol */
531 static const value_string tipcv2_naming_mtype_strings[] = {
532 { 0, "Publication"},
533 { 1, "Withdrawal"},
534 { 0, NULL}
537 /* TIPCv2_MSG_FRAGMENTER - Message Fragmentation Protocol" */
538 static const value_string tipcv2_fragmenter_mtype_strings[] = {
539 { 0, "First"},
540 { 1, "Fragment"},
541 { 2, "Last"},
542 { 0, NULL}
545 /* TIPCv2_NEIGHBOUR_DISCOVERY
546 * 4.3.9 Neighbour Detection Protocol
549 static const value_string tipcv2_neighbour_mtype_strings[] = {
550 { 0, "Request"},
551 { 1, "Response"},
552 { 0, NULL}
555 static const value_string tipcv2_networkplane_strings[] = {
556 { 0, "A"},
557 { 1, "B"},
558 { 2, "C"},
559 { 3, "D"},
560 { 4, "E"},
561 { 5, "F"},
562 { 0, NULL}
565 /* functions forward declarations */
566 static int dissect_tipc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_);
567 void proto_reg_handoff_tipc(void);
569 static reassembly_table tipc_msg_reassembly_table;
571 static char*
572 tipc_addr_value_to_buf(unsigned tipc_address, char *buf, int buf_len)
574 uint8_t zone;
575 uint16_t subnetwork;
576 uint16_t processor;
578 processor = tipc_address & 0x0fff;
580 tipc_address = tipc_address >> 12;
581 subnetwork = tipc_address & 0x0fff;
583 tipc_address = tipc_address >> 12;
584 zone = tipc_address & 0xff;
586 snprintf(buf, buf_len, "%u.%u.%u", zone, subnetwork, processor);
587 return buf;
590 static char *
591 tipc_addr_to_str(unsigned tipc_address)
593 char *buf;
595 buf = (char *)wmem_alloc(wmem_packet_scope(), MAX_TIPC_ADDRESS_STR_LEN);
596 return tipc_addr_value_to_buf(tipc_address, buf, MAX_TIPC_ADDRESS_STR_LEN);
599 static int
600 tipc_addr_to_str_buf(const address* addr, char *buf, int buf_len)
602 const uint8_t *data = (const uint8_t *)addr->data;
603 uint32_t tipc_address;
605 tipc_address = data[0];
606 tipc_address = (tipc_address << 8) ^ data[1];
607 tipc_address = (tipc_address << 8) ^ data[2];
608 tipc_address = (tipc_address << 8) ^ data[3];
610 tipc_addr_value_to_buf(tipc_address, buf, buf_len);
611 return (int)(strlen(buf)+1);
614 static int
615 tipc_addr_str_len(const address* addr _U_)
617 return MAX_TIPC_ADDRESS_STR_LEN;
622 All name distributor messages have a data part containing one or more table elements with
623 the following five-word structure:
624 struct DistributionItem {
625 unsigned int type; / Published port name type /
626 unsigned int lower; / Lower bound of published sequence /
627 unsigned int upper; / Upper bound of published sequence /
628 unsigned int port; / Random number part of port identity /
629 unsigned int key; / Use for verification at withdrawal /
632 static void
633 dissect_tipc_name_dist_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint8_t item_size)
635 int offset = 0;
636 uint32_t dword;
637 char *addr_str_ptr;
639 if ((handle_v2_as & V2_AS_1_6) || ((handle_v2_as & (V2_AS_ALL) && item_size == 0))) {
640 /* TIPC 1.6 */
641 while (tvb_reported_length_remaining(tvb, offset) > 0) {
642 proto_tree_add_item(tree, hf_tipc_name_dist_type, tvb, offset, 4, ENC_BIG_ENDIAN);
643 offset = offset+4;
644 proto_tree_add_item(tree, hf_tipc_name_dist_lower, tvb, offset, 4, ENC_BIG_ENDIAN);
645 offset = offset+4;
646 proto_tree_add_item(tree, hf_tipc_name_dist_upper, tvb, offset, 4, ENC_BIG_ENDIAN);
647 offset = offset+4;
648 proto_tree_add_item(tree, hf_tipc_name_dist_port, tvb, offset, 4, ENC_BIG_ENDIAN);
649 offset = offset+4;
650 proto_tree_add_item(tree, hf_tipc_name_dist_key, tvb, offset, 4, ENC_BIG_ENDIAN);
651 offset = offset+4;
653 } else {
654 /* TIPC 1.7 */
655 while (tvb_reported_length_remaining(tvb, offset) > 0) {
656 proto_tree_add_item(tree, hf_tipc_name_dist_type, tvb, offset, 4, ENC_BIG_ENDIAN);
657 offset = offset+4;
658 proto_tree_add_item(tree, hf_tipc_name_dist_lower, tvb, offset, 4, ENC_BIG_ENDIAN);
659 offset = offset+4;
660 proto_tree_add_item(tree, hf_tipc_name_dist_upper, tvb, offset, 4, ENC_BIG_ENDIAN);
661 offset = offset+4;
662 proto_tree_add_item(tree, hf_tipc_name_dist_port, tvb, offset, 4, ENC_BIG_ENDIAN);
663 offset = offset+4;
664 proto_tree_add_item(tree, hf_tipc_name_dist_key, tvb, offset, 4, ENC_BIG_ENDIAN);
665 offset = offset+4;
666 dword = tvb_get_ntohl(tvb, offset);
667 addr_str_ptr = tipc_addr_to_str(dword);
668 proto_tree_add_string(tree, hf_tipcv2_name_dist_port_id_node, tvb, offset, 4, addr_str_ptr);
669 offset = offset+4;
670 proto_tree_add_item(tree, hf_tipcv2_dist_dist, tvb, offset, 4, ENC_BIG_ENDIAN);
671 proto_tree_add_item(tree, hf_tipcv2_dist_scope, tvb, offset, 4, ENC_BIG_ENDIAN);
672 offset = offset + 4;
673 if (item_size == 7) continue;
674 /* if item_size is >7, the following fields are ignored
675 * so far */
676 proto_tree_add_expert(tree, pinfo, &ei_tipc_field_not_specified, tvb, offset, ((item_size-7)*4));
677 offset += (item_size-7)*4;
682 /* Set message type in COL INFO and return type of message (data or Internal message type */
683 static void
684 tipc_v2_set_info_col(tvbuff_t *tvb, packet_info *pinfo, uint8_t user, uint8_t msg_type, uint8_t hdr_size)
686 uint32_t portNameInst, dword;
687 uint32_t portNameType, portNameInstLow, portNameInstHigh;
688 uint8_t error;
689 /*uint8_t item_size = 0;*/
691 switch (user) {
692 case TIPCv2_DATA_LOW:
693 case TIPCv2_DATA_NORMAL:
694 case TIPCv2_DATA_HIGH:
695 case TIPCv2_DATA_NON_REJECTABLE:
696 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val_to_str_const(msg_type, tipcv2_data_msg_type_defines, "unknown"));
698 /* Display Error != 0 in Info Column */
699 dword = tvb_get_ntohl(tvb, 4);
700 error = (dword>>25) & 0xf;
701 if (error > 0)
702 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val_to_str_const(error, tipcv2_error_code_short_strings, "unknown"));
703 if (hdr_size > 8) {
704 /* Port Name Type: 32 bits */
705 portNameType = tvb_get_ntohl(tvb, 32);
706 col_append_fstr(pinfo->cinfo, COL_INFO, " type:%d", portNameType);
707 if (hdr_size > 9) {
708 /* W9 name instance/multicast lower bound */
709 portNameInst = tvb_get_ntohl(tvb, 36);
710 col_append_fstr(pinfo->cinfo, COL_INFO, " inst:%d", portNameInst);
711 /* Port Name Sequence Lower: 32 bits */
712 if (hdr_size > 10) {
713 portNameInst = tvb_get_ntohl(tvb, 40);
714 col_append_fstr(pinfo->cinfo, COL_INFO, "-%d", portNameInst);
718 break;
719 case TIPCv2_BCAST_PROTOCOL:
720 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val_to_str_const(msg_type, tipcv2_bcast_mtype_strings, "unknown"));
721 break;
722 case TIPCv2_MSG_BUNDLER:
723 /* No message types */
724 break;
725 case TIPCv2_LINK_PROTOCOL:
726 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val_to_str_const(msg_type, tipcv2_link_mtype_strings, "unknown"));
727 break;
728 case TIPCv2_CONN_MANAGER:
729 dword = tvb_get_ntohl(tvb, 4);
730 /* Display Error != 0 in Info Column */
731 error = (dword>>25) & 0xf;
732 if (error > 0)
733 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val_to_str_const(error, tipcv2_error_code_short_strings, "unknown"));
734 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val_to_str_const(msg_type, tipcv2_connmgr_mtype_strings, "unknown"));
735 break;
736 case TIPCv2_ROUTE_DISTRIBUTOR:
737 /* determine if it is TIPC v1.6 or v1.7 */
738 /*dword = tvb_get_ntohl(tvb, 36); */
739 /*item_size = (dword >> 24) & 0xff;*/
740 if ((handle_v2_as & V2_AS_1_6) || ((handle_v2_as & V2_AS_ALL) == 0)) {
741 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val_to_str_const(msg_type, tipcv2_route_mtype_strings_1_6, "unknown"));
742 } else {
743 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val_to_str_const(msg_type, tipcv2_route_mtype_strings_1_7, "unknown"));
745 break;
746 case TIPCv2_CHANGEOVER_PROTOCOL:
747 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val_to_str_const(msg_type, tipcv2_changeover_mtype_strings, "unknown"));
748 break;
749 case TIPCv2_NAME_DISTRIBUTOR:
750 portNameType = tvb_get_ntohl(tvb, 40);
751 portNameInstLow = tvb_get_ntohl(tvb, 44);
752 portNameInstHigh = tvb_get_ntohl(tvb, 48);
754 if (portNameInstLow == portNameInstHigh) {
755 col_append_fstr(pinfo->cinfo, COL_INFO, " %s type:%d inst:%d",
756 val_to_str_const(msg_type, tipcv2_naming_mtype_strings, "unknown"), portNameType, portNameInstLow);
757 } else {
758 /* sequence */
759 col_append_fstr(pinfo->cinfo, COL_INFO, " %s type:%d seq:%d-%d",
760 val_to_str_const(msg_type, tipcv2_naming_mtype_strings, "unknown"), portNameType, portNameInstLow, portNameInstHigh);
762 break;
763 case TIPCv2_MSG_FRAGMENTER:
764 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val_to_str_const(msg_type, tipcv2_fragmenter_mtype_strings, "unknown"));
765 break;
766 case TIPCv2_NEIGHBOUR_DISCOVERY:
767 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val_to_str_const(msg_type, tipcv2_neighbour_mtype_strings, "unknown"));
768 break;
769 default:
770 break;
774 /* Set message type in COL INFO and return type of message (data or Internal message type */
775 static bool
776 tipc_v1_set_col_msgtype(packet_info *pinfo, uint8_t user, uint8_t msg_type)
778 bool datatype_hdr = false;
780 switch (user) {
781 case TIPC_DATA_PRIO_0:
782 case TIPC_DATA_PRIO_1:
783 case TIPC_DATA_PRIO_2:
784 case TIPC_DATA_NON_REJECTABLE:
786 * src and dest address will be found at different location depending on User as hdr_size
788 datatype_hdr = true;
789 col_append_fstr(pinfo->cinfo, COL_INFO, "%s(%u) ", val_to_str_const(msg_type, tipc_data_msg_type_values, "unknown"), msg_type);
790 break;
791 case TIPC_NAME_DISTRIBUTOR:
792 col_append_fstr(pinfo->cinfo, COL_INFO, "%s(%u) ", val_to_str_const(msg_type, tipc_name_dist_msg_type_values, "unknown"), msg_type);
793 break;
794 case TIPC_CONNECTION_MANAGER:
795 col_append_fstr(pinfo->cinfo, COL_INFO, "%s(%u) ", val_to_str_const(msg_type, tipc_cm_msg_type_values, "unknown"), msg_type);
796 break;
797 case TIPC_ROUTING_MANAGER:
798 col_append_fstr(pinfo->cinfo, COL_INFO, "%s(%u) ", val_to_str_const(msg_type, tipc_routing_mgr_msg_type_values, "unknown"), msg_type);
799 break;
800 case TIPC_LINK_PROTOCOL:
801 col_append_fstr(pinfo->cinfo, COL_INFO, "%s(%u) ", val_to_str_const(msg_type, tipc_link_prot_msg_type_values, "unknown"), msg_type);
802 break;
803 case TIPC_CHANGEOVER_PROTOCOL:
804 col_append_fstr(pinfo->cinfo, COL_INFO, "%s(%u) ", val_to_str_const(msg_type, tipc_cng_prot_msg_type_values, "unknown"), msg_type);
805 break;
806 case TIPC_SEGMENTATION_MANAGER:
807 col_append_fstr(pinfo->cinfo, COL_INFO, "%s(%u) ", val_to_str_const(msg_type, tipc_sm_msg_type_values, "unknown"), msg_type);
808 break;
809 case TIPC_MSG_BUNDLER:
810 break;
811 default:
812 break;
814 return datatype_hdr;
818 Version 2(draft-maloy-tipc-01.txt):
819 4.2.1 Internal Message Header Format
821 0 1 2 3
822 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
823 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
824 w0:|vers |msg usr|hdr sz |n|resrv| packet size |
825 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
826 w1:|m typ| sequence gap | broadcast ack no |
827 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
828 w2:| link level ack no | broadcast/link level seq no |
829 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
830 w3:| previous node |
831 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
832 w4:| next sent broadcast/fragm no | next sent pkt/ fragm msg no |
833 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
834 w5:| session no | res |r|berid|link prio|netpl|p|
835 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
836 w6:| originating node |
837 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
838 w7:| destination node |
839 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
840 w8:| transport sequence number |
841 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
842 w9:| msg count | link tolerance |
843 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
845 / User Specific Data /
847 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
850 static int
851 // NOLINTNEXTLINE(misc-no-recursion)
852 dissect_tipc_v2_internal_msg(tvbuff_t *tipc_tvb, proto_tree *tipc_tree, packet_info *pinfo, int offset, uint8_t user, uint32_t msg_size, uint8_t orig_hdr_size)
854 uint32_t dword;
855 char *addr_str_ptr;
856 tvbuff_t *data_tvb;
857 uint8_t message_type;
858 uint8_t item_size = 0;
859 uint16_t message_count;
860 unsigned msg_no = 0;
861 uint32_t msg_in_bundle_size;
862 uint8_t msg_in_bundle_user;
863 uint32_t b_inst_strlen;
864 int padlen;
866 /* for fragmented messages */
867 int len, reported_len;
868 bool save_fragmented;
869 uint32_t frag_no, frag_msg_no;
870 tvbuff_t* new_tvb = NULL;
871 fragment_head *frag_msg = NULL;
872 proto_item *ti;
874 message_type = (tvb_get_uint8(tipc_tvb, offset) >>5) & 0x7;
876 switch (user) {
877 case TIPCv2_BCAST_PROTOCOL:
878 /* W1 */
879 proto_tree_add_item(tipc_tree, hf_tipcv2_bcast_mtype, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
880 /* NO sequence gap */
881 proto_tree_add_item(tipc_tree, hf_tipcv2_broadcast_ack_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
882 offset = offset + 4;
883 /* W2 */
884 proto_tree_add_item(tipc_tree, hf_tipcv2_link_level_ack_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
885 proto_tree_add_item(tipc_tree, hf_tipcv2_link_level_seq_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
886 offset = offset + 4;
887 /* W3 */
888 dword = tvb_get_ntohl(tipc_tvb, offset);
889 addr_str_ptr = tipc_addr_to_str(dword);
890 proto_tree_add_string(tipc_tree, hf_tipcv2_prev_node, tipc_tvb, offset, 4, addr_str_ptr);
891 offset = offset + 4;
892 if (handle_v2_as & (V2_AS_1_6)) {
893 /* W4 Unused */
894 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 4 unused for this user");
895 offset = offset + 4;
896 /* W5 Unused */
897 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 5 unused for this user");
898 offset = offset + 4;
899 /* W6 Unused */
900 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 6 unused for this user");
901 offset = offset + 4;
902 /* W7 Unused */
903 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 7 unused for this user");
904 offset = offset + 4;
905 /* W8 Unused */
906 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 8 unused for this user");
907 offset = offset + 4;
908 } else {
909 /* W4 Unused */
910 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 4 unused for this user");
911 offset = offset + 4;
912 /* W5 */
913 proto_tree_add_item(tipc_tree, hf_tipcv2_network_id, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
914 offset = offset + 4;
915 /* W6 */
916 dword = tvb_get_ntohl(tipc_tvb, offset);
917 addr_str_ptr = tipc_addr_to_str(dword);
918 proto_tree_add_string(tipc_tree, hf_tipcv2_orig_node, tipc_tvb, offset, 4, addr_str_ptr);
919 offset = offset + 4;
920 /* W7 */
921 dword = tvb_get_ntohl(tipc_tvb, offset);
922 addr_str_ptr = tipc_addr_to_str(dword);
923 proto_tree_add_string(tipc_tree, hf_tipcv2_dest_node, tipc_tvb, offset, 4, addr_str_ptr);
924 offset = offset + 4;
925 /* W8 Unused */
926 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 8 unused for this user");
927 offset = offset + 4;
929 /* W9 */
930 proto_tree_add_item(tipc_tree, hf_tipcv2_bcast_tag, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
931 /* NO link tolerance */
932 offset = offset + 4;
933 break;
934 case TIPCv2_MSG_BUNDLER:
935 if (handle_v2_as & (V2_AS_1_6)) {
936 /* W1 Unused */
937 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 1 unused for this user");
938 offset = offset + 4;
939 /* W2 Unused */
940 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 2 unused for this user");
941 offset = offset + 4;
942 } else {
943 /* W1 */
944 proto_tree_add_item(tipc_tree, hf_tipcv2_bundler_mtype, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
945 proto_tree_add_item(tipc_tree, hf_tipcv2_broadcast_ack_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
946 offset = offset + 4;
947 /* W2 */
948 proto_tree_add_item(tipc_tree, hf_tipcv2_link_level_ack_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
949 proto_tree_add_item(tipc_tree, hf_tipcv2_link_level_seq_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
950 offset = offset + 4;
952 /* W3 */
953 dword = tvb_get_ntohl(tipc_tvb, offset);
954 addr_str_ptr = tipc_addr_to_str(dword);
955 proto_tree_add_string(tipc_tree, hf_tipcv2_prev_node, tipc_tvb, offset, 4, addr_str_ptr);
956 offset = offset + 4;
957 if (handle_v2_as & (V2_AS_1_6)) {
958 /* W4 Unused */
959 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 4 unused for this user");
960 offset = offset + 4;
961 /* W5 Unused */
962 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 5 unused for this user");
963 offset = offset + 4;
964 /* W6 Unused */
965 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 6 unused for this user");
966 offset = offset + 4;
967 /* W7 Unused */
968 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 7 unused for this user");
969 offset = offset + 4;
970 /* W8 Unused */
971 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 8 unused for this user");
972 offset = offset + 4;
973 } else {
974 /* W4 Unused */
975 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 4 unused for this user");
976 offset = offset + 4;
977 /* W5 Unused */
978 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 5 unused for this user");
979 offset = offset + 4;
980 /* W6 */
981 dword = tvb_get_ntohl(tipc_tvb, offset);
982 addr_str_ptr = tipc_addr_to_str(dword);
983 proto_tree_add_string(tipc_tree, hf_tipcv2_orig_node, tipc_tvb, offset, 4, addr_str_ptr);
984 offset = offset + 4;
985 /* W7 */
986 dword = tvb_get_ntohl(tipc_tvb, offset);
987 addr_str_ptr = tipc_addr_to_str(dword);
988 proto_tree_add_string(tipc_tree, hf_tipcv2_dest_node, tipc_tvb, offset, 4, addr_str_ptr);
989 offset = offset + 4;
990 /* W8 Unused */
991 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 8 unused for this user");
992 offset = offset + 4;
994 /* W9 */
995 /* Message Count: 16 bits. */
996 proto_tree_add_item(tipc_tree, hf_tipcv2_msg_count, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
997 message_count = tvb_get_ntohs(tipc_tvb, offset);
998 /* According to the spec this should not be set here,
999 * while there is data != 0 in this field when capturing
1001 proto_tree_add_item(tipc_tree, hf_tipcv2_link_tolerance, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1003 offset = offset + 4;
1004 /* This should give equal results like
1005 * while (message_count-- > 0) */
1006 while ((uint32_t)offset < msg_size) {
1007 msg_no++;
1009 dword = tvb_get_ntohl(tipc_tvb, offset);
1010 msg_in_bundle_size = dword & 0x1ffff;
1011 msg_in_bundle_user = (dword >> 25) & 0xf;
1013 ti = proto_tree_add_uint_format(top_tree, hf_tipc_msg_no_bundle, tipc_tvb, offset, 1, msg_no, "Message %u of %u in Bundle (%s)",
1014 msg_no, message_count, val_to_str_const(msg_in_bundle_user, tipcv2_user_short_str_vals, "unknown"));
1015 proto_item_set_len(ti, msg_in_bundle_size);
1016 data_tvb = tvb_new_subset_length(tipc_tvb, offset, msg_in_bundle_size);
1018 /* the info column shall not be deleted by the
1019 * encapsulated messages */
1020 col_append_str(pinfo->cinfo, COL_INFO, " | ");
1021 col_set_fence(pinfo->cinfo, COL_INFO);
1023 dissect_tipc(data_tvb, pinfo, top_tree, NULL);
1025 /* the modulo is used to align the messages to 4 Bytes */
1026 offset += msg_in_bundle_size + ((msg_in_bundle_size%4)?(4-(msg_in_bundle_size%4)):0);
1028 break;
1029 case TIPCv2_LINK_PROTOCOL:
1030 /* W1 */
1031 proto_tree_add_item(tipc_tree, hf_tipcv2_link_mtype, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1032 /* Sequence Gap: 13 bits. */
1033 proto_tree_add_item(tipc_tree, hf_tipcv2_sequence_gap, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1034 proto_tree_add_item(tipc_tree, hf_tipcv2_broadcast_ack_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1035 offset = offset + 4;
1036 /* W2 */
1037 proto_tree_add_item(tipc_tree, hf_tipcv2_link_level_ack_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1038 proto_tree_add_item(tipc_tree, hf_tipcv2_link_level_seq_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1039 offset = offset + 4;
1040 /* W3 */
1041 dword = tvb_get_ntohl(tipc_tvb, offset);
1042 addr_str_ptr = tipc_addr_to_str(dword);
1043 proto_tree_add_string(tipc_tree, hf_tipcv2_prev_node, tipc_tvb, offset, 4, addr_str_ptr);
1044 offset = offset + 4;
1045 /* W4 */
1046 /* Next Sent Broadcast: 16 bits */
1047 proto_tree_add_item(tipc_tree, hf_tipcv2_next_sent_broadcast, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1048 /* Next Sent Packet: 16 bits. */
1049 proto_tree_add_item(tipc_tree, hf_tipcv2_next_sent_packet, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1050 offset = offset + 4;
1051 /* W5 */
1052 /* Session Number: 16 bits. */
1053 proto_tree_add_item(tipc_tree, hf_tipcv2_session_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1054 /* Reserved: 3 bits Must be set to zero. */
1055 /* the following two fields appear in this user according to */
1056 /* Jon Maloy on the tipc-discussion mailing list */
1057 /* Redundant Link: 1 bit */
1058 proto_tree_add_item(tipc_tree, hf_tipcv2_redundant_link, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1059 /* Bearer Identity: 3 bits */
1060 proto_tree_add_item(tipc_tree, hf_tipcv2_bearer_id, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1061 /* Link Priority: 5 bits. */
1062 proto_tree_add_item(tipc_tree, hf_tipcv2_link_prio, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1063 /* Network Plane: 3 bits. */
1064 proto_tree_add_item(tipc_tree, hf_tipcv2_network_plane, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1065 /* Probe: 1 bit. */
1066 proto_tree_add_item(tipc_tree, hf_tipcv2_probe, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1067 offset = offset + 4;
1068 if (handle_v2_as & (V2_AS_1_6)) {
1069 /* W6 Unused */
1070 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 6 unused for this user");
1071 offset = offset + 4;
1072 /* W7 Unused */
1073 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 7 unused for this user");
1074 offset = offset + 4;
1075 /* W8 Unused */
1076 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 8 unused for this user");
1077 offset = offset + 4;
1078 } else {
1079 /* W6 */
1080 dword = tvb_get_ntohl(tipc_tvb, offset);
1081 addr_str_ptr = tipc_addr_to_str(dword);
1082 proto_tree_add_string(tipc_tree, hf_tipcv2_orig_node, tipc_tvb, offset, 4, addr_str_ptr);
1083 offset = offset + 4;
1084 /* W7 */
1085 dword = tvb_get_ntohl(tipc_tvb, offset);
1086 addr_str_ptr = tipc_addr_to_str(dword);
1087 proto_tree_add_string(tipc_tree, hf_tipcv2_dest_node, tipc_tvb, offset, 4, addr_str_ptr);
1088 offset = offset + 4;
1089 /* W8 */
1090 proto_tree_add_item(tipc_tree, hf_tipcv2_timestamp, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1091 offset = offset + 4;
1093 /* W9 */
1094 proto_tree_add_item(tipc_tree, hf_tipcv2_max_packet, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1095 /* Link Tolerance: 16 bits */
1096 proto_tree_add_item(tipc_tree, hf_tipcv2_link_tolerance, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1097 offset = offset + 4;
1099 if ((message_type == TIPCv2_RESET_MSG)
1100 || ((message_type == TIPCv2_STATE_MSG) && ((msg_size-(orig_hdr_size*4)) != 0))){ /* is allowed */
1101 proto_tree_add_item_ret_length(tipc_tree, hf_tipcv2_bearer_instance, tipc_tvb, offset, -1, ENC_ASCII, &b_inst_strlen);
1102 offset += b_inst_strlen;
1103 /* the bearer instance string is padded with \0 to the next word boundary */
1104 if ((padlen = ((b_inst_strlen%4)?(4-(b_inst_strlen%4)):0)) > 0) {
1105 proto_tree_add_bytes_format_value(tipc_tree, hf_tipcv2_padding, tipc_tvb, offset, padlen, NULL, "%d byte%c", padlen, (padlen!=1?'s':0));
1106 offset += padlen;
1109 * If there's any data left, show it as
1110 * padding for MTU discovery.
1112 if ((uint32_t)offset < msg_size) {
1113 uint32_t filler_len;
1115 filler_len = msg_size - (uint32_t)offset;
1116 proto_tree_add_bytes_format_value(tipc_tree, hf_tipcv2_filler_mtu_discovery, tipc_tvb, offset, filler_len, NULL,
1117 "%d byte%c", filler_len, (filler_len!=1?'s':0));
1120 break;
1121 case TIPCv2_CONN_MANAGER:
1122 /* CONN_MANAGER uses the 36-byte header format of CONN_MSG payload messages */
1123 /* W1 */
1124 proto_tree_add_item(tipc_tree, hf_tipcv2_connmgr_mtype, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1125 proto_tree_add_item(tipc_tree, hf_tipcv2_errorcode, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1126 proto_tree_add_item(tipc_tree, hf_tipcv2_rer_cnt, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1127 proto_tree_add_item(tipc_tree, hf_tipcv2_lookup_scope, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1129 /* Options Position: 3 bits */
1130 /* this is not used by this user according to Jon Maloy in tipc-discussion mailing list
1131 opt_p = tvb_get_uint8(tipc_tvb, offset+1) & 0x7;
1132 proto_tree_add_item(tipc_tree, hf_tipcv2_opt_p , tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1133 if (opt_p != 0) {
1134 hdr_size = hdr_size - (opt_p << 2);
1137 proto_tree_add_item(tipc_tree, hf_tipcv2_broadcast_ack_no , tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1138 offset = offset + 4;
1140 /* W2 */
1141 proto_tree_add_item(tipc_tree, hf_tipcv2_link_level_ack_no , tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1142 proto_tree_add_item(tipc_tree, hf_tipcv2_link_level_seq_no , tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1143 offset = offset + 4;
1145 /* W3 */
1146 dword = tvb_get_ntohl(tipc_tvb, offset);
1147 addr_str_ptr = tipc_addr_to_str(dword);
1148 proto_tree_add_string(tipc_tree, hf_tipcv2_prev_node, tipc_tvb, offset, 4, addr_str_ptr);
1149 offset = offset + 4;
1151 /* W4 */
1152 proto_tree_add_item(tipc_tree, hf_tipc_org_port , tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1153 offset = offset + 4;
1155 /* W5 */
1156 proto_tree_add_item(tipc_tree, hf_tipc_dst_port , tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1157 offset = offset + 4;
1159 /* W6 */
1160 dword = tvb_get_ntohl(tipc_tvb, offset);
1161 addr_str_ptr = tipc_addr_to_str(dword);
1162 proto_tree_add_string(tipc_tree, hf_tipcv2_orig_node, tipc_tvb, offset, 4, addr_str_ptr);
1163 offset = offset + 4;
1165 /* W7 */
1166 dword = tvb_get_ntohl(tipc_tvb, offset);
1167 addr_str_ptr = tipc_addr_to_str(dword);
1168 proto_tree_add_string(tipc_tree, hf_tipcv2_dest_node, tipc_tvb, offset, 4, addr_str_ptr);
1169 offset = offset + 4;
1171 /* W8 Unused */
1172 /* might be set prior to 1.7.3 but according to Allan Stephens this was never verfied by the receiver
1173 proto_tree_add_item(tipc_tree, hf_tipcv2_transport_seq_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1175 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 8 unused for this user");
1176 offset = offset + 4;
1179 /* this is not used here according to Jon Maloy in tipc-discussion mailing list
1180 * Options
1182 if (opt_p != 0) {
1183 proto_tree_add_subtree(tipc_tree, tipc_tvb, offset, (opt_p >> 2), "Options");
1184 offset = offset + (opt_p << 2);
1188 if (message_type == TIPCv2_CONMGR_MSG_ACK || (handle_v2_as & (V2_AS_ALL + V2_AS_1_7)))
1190 /* W9 */
1191 proto_tree_add_item(tipc_tree, hf_tipcv2_conn_mgr_msg_ack, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1192 offset += 4;
1194 break;
1195 case TIPCv2_ROUTE_DISTRIBUTOR:
1196 /* W1 */
1197 /* determine if it is TIPC v1.6 or v1.7 */
1198 dword = tvb_get_ntohl(tipc_tvb, offset+28);
1199 item_size = (dword >> 24) & 0xff;
1200 if ((handle_v2_as & V2_AS_1_6) || ((handle_v2_as & V2_AS_ALL) == 0)) {
1201 proto_tree_add_item(tipc_tree, hf_tipcv2_route_mtype_1_6, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1202 } else {
1203 proto_tree_add_item(tipc_tree, hf_tipcv2_route_mtype_1_7, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1205 proto_tree_add_item(tipc_tree, hf_tipcv2_broadcast_ack_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1206 offset = offset + 4;
1207 /* W2 */
1208 proto_tree_add_item(tipc_tree, hf_tipcv2_link_level_ack_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1209 proto_tree_add_item(tipc_tree, hf_tipcv2_link_level_seq_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1210 offset = offset + 4;
1211 /* W3 */
1212 dword = tvb_get_ntohl(tipc_tvb, offset);
1213 addr_str_ptr = tipc_addr_to_str(dword);
1214 proto_tree_add_string(tipc_tree, hf_tipcv2_prev_node, tipc_tvb, offset, 4, addr_str_ptr);
1215 offset = offset + 4;
1216 /* W4 */
1218 if (handle_v2_as & V2_AS_1_6) {
1219 /* W4 Unused */
1220 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 4 unused for this user");
1221 offset = offset + 4;
1222 /* W5 Unused */
1223 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 5 unused for this user");
1224 offset = offset + 4;
1225 /* W6 Unused */
1226 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 6 unused for this user");
1227 offset = offset + 4;
1228 /* W7 Unused */
1229 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 7 unused for this user");
1230 offset = offset + 4;
1231 /* W8 Unused */
1232 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 8 unused for this user");
1233 offset = offset + 4;
1234 /* W9 Unused */
1235 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 9 unused for this user");
1236 offset = offset + 4;
1237 } else {
1238 /* W4 Unused */
1239 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 4 unused for this user");
1240 offset = offset + 4;
1241 /* W5 */
1242 proto_tree_add_item(tipc_tree, hf_tipc_dst_port, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1243 offset = offset + 4;
1244 /* W6 */
1245 dword = tvb_get_ntohl(tipc_tvb, offset);
1246 addr_str_ptr = tipc_addr_to_str(dword);
1247 proto_tree_add_string(tipc_tree, hf_tipcv2_orig_node, tipc_tvb, offset, 4, addr_str_ptr);
1248 offset = offset + 4;
1249 /* W7 */
1250 dword = tvb_get_ntohl(tipc_tvb, offset);
1251 addr_str_ptr = tipc_addr_to_str(dword);
1252 proto_tree_add_string(tipc_tree, hf_tipcv2_dest_node, tipc_tvb, offset, 4, addr_str_ptr);
1253 offset = offset + 4;
1254 /* W8 Unused */
1255 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 8 unused for this user");
1256 offset = offset + 4;
1257 /* W9 */
1258 dword = tvb_get_ntohl(tipc_tvb, offset);
1259 item_size = (dword >> 24) & 0xff;
1260 proto_tree_add_item(tipc_tree, hf_tipcv2_item_size, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1261 offset = offset + 4;
1264 /* item_size == 0 indicates that it's TIPC v1.6 style */
1265 if ((handle_v2_as & V2_AS_1_6) || ((handle_v2_as & V2_AS_ALL) && (item_size == 0))) {
1266 /* W10 */
1267 switch (message_type) {
1268 case TIPCv2_EXT_ROUTING_TABLE: /* 0 */
1269 case TIPCv2_LOCAL_ROUTING_TABLE: /* 1 */
1270 case TIPCv2_SEC_ROUTING_TABLE: /* 2 */
1271 /* Cluster Address */
1272 dword = tvb_get_ntohl(tipc_tvb, offset);
1273 addr_str_ptr = tipc_addr_to_str(dword);
1274 proto_tree_add_string(tipc_tree, hf_tipcv2_cluster_address, tipc_tvb, offset, 4, addr_str_ptr);
1275 offset = offset + 4;
1276 /* bitmap */
1277 proto_tree_add_item(tipc_tree, hf_tipcv2_bitmap, tipc_tvb, offset, -1, ENC_NA);
1278 break;
1279 case TIPCv2_ROUTE_ADDITION: /* 3 */
1280 case TIPCv2_ROUTE_REMOVAL: /* 4 */
1281 /* Node Address */
1282 dword = tvb_get_ntohl(tipc_tvb, offset);
1283 addr_str_ptr = tipc_addr_to_str(dword);
1284 proto_tree_add_string(tipc_tree, hf_tipcv2_node_address, tipc_tvb, offset, 4, addr_str_ptr);
1285 offset = offset + 4;
1286 default:
1287 break;
1289 } else {
1290 /* what if item_size is set to a value fitting to TIPC v1.6 ? */
1291 dword = tvb_get_ntohl(tipc_tvb, offset);
1292 addr_str_ptr = tipc_addr_to_str(dword);
1293 proto_tree_add_string(tipc_tree, hf_tipcv2_network_region, tipc_tvb, offset, 4, addr_str_ptr);
1294 offset += 4;
1295 dword = tvb_get_ntohl(tipc_tvb, offset);
1296 addr_str_ptr = tipc_addr_to_str(dword);
1297 proto_tree_add_string(tipc_tree, hf_tipcv2_local_router, tipc_tvb, offset, 4, addr_str_ptr);
1298 offset += 4;
1299 dword = tvb_get_ntohl(tipc_tvb, offset);
1300 addr_str_ptr = tipc_addr_to_str(dword);
1301 proto_tree_add_string(tipc_tree, hf_tipcv2_remote_router, tipc_tvb, offset, 4, addr_str_ptr);
1302 offset += 4;
1303 proto_tree_add_item(tipc_tree, hf_tipcv2_dist_dist, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1304 proto_tree_add_item(tipc_tree, hf_tipcv2_dist_scope, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1305 offset = offset + 4;
1307 break;
1309 case TIPCv2_CHANGEOVER_PROTOCOL:
1310 /* W1 */
1311 proto_tree_add_item(tipc_tree, hf_tipcv2_changeover_mtype, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1312 proto_tree_add_item(tipc_tree, hf_tipcv2_broadcast_ack_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1313 offset = offset + 4;
1314 /* W2 */
1315 proto_tree_add_item(tipc_tree, hf_tipcv2_link_level_ack_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1316 proto_tree_add_item(tipc_tree, hf_tipcv2_link_level_seq_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1317 offset = offset + 4;
1318 /* W3 */
1319 dword = tvb_get_ntohl(tipc_tvb, offset);
1320 addr_str_ptr = tipc_addr_to_str(dword);
1321 proto_tree_add_string(tipc_tree, hf_tipcv2_prev_node, tipc_tvb, offset, 4, addr_str_ptr);
1322 offset = offset + 4;
1323 /* W4 Unused */
1324 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 4 unused for this user");
1325 offset = offset + 4;
1326 /* W5 */
1327 /* the following two fields appear in this user according to */
1328 /* Jon Maloy on the tipc-discussion mailing list */
1329 /* Redundant Link: 1 bit */
1330 if (handle_v2_as & (V2_AS_1_6)) {
1331 proto_tree_add_item(tipc_tree, hf_tipcv2_redundant_link, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1333 /* Bearer Identity: 3 bits */
1334 proto_tree_add_item(tipc_tree, hf_tipcv2_bearer_id, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1335 offset = offset + 4;
1336 /* W6-W8 */
1337 if (handle_v2_as & (V2_AS_1_6)) {
1338 /* W6 Unused */
1339 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 6 unused for this user");
1340 offset = offset + 4;
1341 /* W7 Unused */
1342 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 7 unused for this user");
1343 offset = offset + 4;
1344 /* W8 Unused */
1345 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 8 unused for this user");
1346 offset = offset + 4;
1347 } else {
1348 /* W6 */
1349 dword = tvb_get_ntohl(tipc_tvb, offset);
1350 addr_str_ptr = tipc_addr_to_str(dword);
1351 proto_tree_add_string(tipc_tree, hf_tipcv2_orig_node, tipc_tvb, offset, 4, addr_str_ptr);
1352 offset = offset + 4;
1353 /* W7 */
1354 dword = tvb_get_ntohl(tipc_tvb, offset);
1355 addr_str_ptr = tipc_addr_to_str(dword);
1356 proto_tree_add_string(tipc_tree, hf_tipcv2_dest_node, tipc_tvb, offset, 4, addr_str_ptr);
1357 offset = offset + 4;
1358 /* W8 Unused */
1359 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 8 unused for this user");
1360 offset = offset + 4;
1362 /* W9 */
1363 switch (message_type)
1365 case 0:
1366 /* DUPLICATE_MSG */
1367 /* W9 Unused */
1368 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 9 unused for this user");
1369 break;
1370 case 1:
1371 /* ORIGINAL_MSG */
1372 /* Message Count: 16 bits. */
1373 proto_tree_add_item(tipc_tree, hf_tipcv2_msg_count, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1374 break;
1375 default:
1376 break;
1378 offset = offset + 4;
1379 break;
1380 case TIPCv2_NAME_DISTRIBUTOR:
1381 /* W1 */
1382 proto_tree_add_item(tipc_tree, hf_tipcv2_naming_mtype, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1383 proto_tree_add_item(tipc_tree, hf_tipcv2_broadcast_ack_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1384 offset = offset + 4;
1385 /* W2 */
1386 proto_tree_add_item(tipc_tree, hf_tipcv2_link_level_ack_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1387 proto_tree_add_item(tipc_tree, hf_tipcv2_link_level_seq_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1388 offset = offset + 4;
1389 /* W3 */
1390 dword = tvb_get_ntohl(tipc_tvb, offset);
1391 addr_str_ptr = tipc_addr_to_str(dword);
1392 proto_tree_add_string(tipc_tree, hf_tipcv2_prev_node, tipc_tvb, offset, 4, addr_str_ptr);
1393 offset = offset + 4;
1394 /* W4 Unused */
1395 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 4 unused for this user");
1396 offset = offset + 4;
1397 /* W5 Unused */
1398 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 5 unused for this user");
1399 offset = offset + 4;
1400 /* W6 */
1401 /* Originating Node: 32 bits. */
1402 dword = tvb_get_ntohl(tipc_tvb, offset);
1403 addr_str_ptr = tipc_addr_to_str(dword);
1404 proto_tree_add_string(tipc_tree, hf_tipcv2_orig_node, tipc_tvb, offset, 4, addr_str_ptr);
1405 offset = offset + 4;
1406 /* W7 */
1407 /* Destination Node: 32 bits. */
1408 dword = tvb_get_ntohl(tipc_tvb, offset);
1409 addr_str_ptr = tipc_addr_to_str(dword);
1410 proto_tree_add_string(tipc_tree, hf_tipcv2_dest_node, tipc_tvb, offset, 4, addr_str_ptr);
1411 offset = offset + 4;
1412 if (handle_v2_as & (V2_AS_1_6 + V2_AS_ALL)) {
1413 /* W8 */
1414 /* Transport Level Sequence Number: 32 bits */
1415 proto_tree_add_item(tipc_tree, hf_tipcv2_transport_seq_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1416 offset = offset + 4;
1417 } else {
1418 /* W8 Unused */
1419 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 8 unused for this user");
1420 offset = offset + 4;
1422 /* W9 */
1423 if (handle_v2_as & V2_AS_1_6) {
1424 /* W9 Unused */
1425 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 9 unused for this user");
1426 offset = offset + 4;
1427 } else {
1428 dword = tvb_get_ntohl(tipc_tvb, offset);
1429 item_size = (dword >> 24) & 0xff;
1430 proto_tree_add_item(tipc_tree, hf_tipcv2_item_size, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1431 offset = offset + 4;
1433 /* W10 */
1434 /* dissect the (one or more) Publications */
1435 data_tvb = tvb_new_subset_remaining(tipc_tvb, offset);
1436 dissect_tipc_name_dist_data(data_tvb, pinfo, tipc_tree, item_size);
1437 break;
1438 case TIPCv2_MSG_FRAGMENTER:
1439 /* W1 */
1440 proto_tree_add_item(tipc_tree, hf_tipcv2_fragmenter_mtype, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1441 proto_tree_add_item(tipc_tree, hf_tipcv2_broadcast_ack_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1442 offset = offset + 4;
1443 /* W2 */
1444 proto_tree_add_item(tipc_tree, hf_tipcv2_link_level_ack_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1445 proto_tree_add_item(tipc_tree, hf_tipcv2_link_level_seq_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1446 offset = offset + 4;
1447 /* W3 */
1448 dword = tvb_get_ntohl(tipc_tvb, offset);
1449 addr_str_ptr = tipc_addr_to_str(dword);
1450 proto_tree_add_string(tipc_tree, hf_tipcv2_prev_node, tipc_tvb, offset, 4, addr_str_ptr);
1451 offset = offset + 4;
1452 /* W4 */
1453 dword = tvb_get_ntohl(tipc_tvb, offset);
1454 /* Fragment Number: 16 Bits. */
1455 proto_tree_add_item(tipc_tree, hf_tipcv2_fragment_number, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1456 frag_no = (dword >> 16) & 0x0000ffff;
1457 /* Fragment msg Number: 16 bits */
1458 proto_tree_add_item(tipc_tree, hf_tipcv2_fragment_msg_number, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1459 frag_msg_no = dword & 0x0000ffff;
1460 offset = offset + 4;
1461 if (handle_v2_as & (V2_AS_1_6)) {
1462 /* W5 Unused */
1463 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 5 unused for this user");
1464 offset = offset + 4;
1465 /* W6 Unused */
1466 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 6 unused for this user");
1467 offset = offset + 4;
1468 /* W7 Unused */
1469 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 7 unused for this user");
1470 offset = offset + 4;
1471 /* W8 Unused */
1472 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 8 unused for this user");
1473 offset = offset + 4;
1474 /* W9 Unused */
1475 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 9 unused for this user");
1476 offset = offset + 4;
1477 } else {
1478 /* W5 Unused */
1479 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 5 unused for this user");
1480 offset = offset + 4;
1481 /* W6 */
1482 dword = tvb_get_ntohl(tipc_tvb, offset);
1483 addr_str_ptr = tipc_addr_to_str(dword);
1484 proto_tree_add_string(tipc_tree, hf_tipcv2_orig_node, tipc_tvb, offset, 4, addr_str_ptr);
1485 offset = offset + 4;
1486 /* W7 */
1487 dword = tvb_get_ntohl(tipc_tvb, offset);
1488 addr_str_ptr = tipc_addr_to_str(dword);
1489 proto_tree_add_string(tipc_tree, hf_tipcv2_dest_node, tipc_tvb, offset, 4, addr_str_ptr);
1490 offset = offset + 4;
1491 /* W8 Unused */
1492 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 8 unused for this user");
1493 offset = offset + 4;
1494 /* W9 Unused */
1495 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tipc_tvb, offset, 4, "word 9 unused for this user");
1496 offset = offset + 4;
1499 len = (msg_size - (orig_hdr_size<<2));
1500 reported_len = tvb_reported_length_remaining(tipc_tvb, offset);
1502 if (tipc_defragment) {
1503 /* reassemble fragmented packages */
1504 save_fragmented = pinfo->fragmented;
1505 pinfo->fragmented = true;
1507 frag_msg = fragment_add_seq_check(&tipc_msg_reassembly_table,
1508 tipc_tvb, offset,
1509 pinfo,
1510 frag_msg_no, /* ID for fragments belonging together */
1511 NULL,
1512 /* TODO: make sure that fragments are on the same LINK */
1513 /* TIPC starts with "1" but we * need "0" */
1514 (frag_no-1), /* number of the fragment */
1515 len, /* fragment length - to the end of the data */
1516 (message_type != TIPCv2_USER_LAST_FRAGMENT)); /* More fragments? */
1518 new_tvb = process_reassembled_data(tipc_tvb, offset, pinfo,
1519 "Reassembled TIPC", frag_msg, &tipc_msg_frag_items,
1520 NULL, tipc_tree);
1522 if (frag_msg) { /* Reassembled */
1523 col_append_str(pinfo->cinfo, COL_INFO,
1524 " (Message Reassembled)");
1525 } else { /* Not last packet of reassembled Short Message */
1526 col_append_fstr(pinfo->cinfo, COL_INFO,
1527 " (Message fragment %u)", frag_no);
1529 if (new_tvb) { /* take it all */
1531 /* the info column shall not be deleted by the
1532 * encapsulated messages */
1533 col_append_str(pinfo->cinfo, COL_INFO, " | ");
1534 col_set_fence(pinfo->cinfo, COL_INFO);
1535 dissect_tipc(new_tvb, pinfo, top_tree, NULL);
1536 } else { /* make a new subset */
1537 data_tvb = tvb_new_subset_length_caplen(tipc_tvb, offset, len, reported_len);
1538 call_data_dissector(data_tvb, pinfo, top_tree);
1541 pinfo->fragmented = save_fragmented;
1542 } else {
1543 /* don't reassemble is set in the "preferences" */
1544 data_tvb = tvb_new_subset_length_caplen(tipc_tvb, offset, len, reported_len);
1545 call_data_dissector(data_tvb, pinfo, top_tree);
1548 break;
1549 case TIPCv2_NEIGHBOUR_DISCOVERY:
1551 The protocol for neighbour detection
1552 uses a special message format, with the following generic structure:
1554 0 1 2 3
1555 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1556 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1557 w0:|vers |msg usr|hdr sz |n|resrv| packet size |
1558 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1559 w1:|m typ|00000| minor_pv | node signature |
1560 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1561 w2:| destination domain |
1562 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1563 w3:| previous node |
1564 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1565 w4:| network identity |
1566 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1567 w5:| |
1568 +-+-+-+-+-+-+- +-+-+-+-+-+-+-+
1569 w6:| |
1570 +-+-+-+-+-+-+- bearer level originating address +-+-+-+-+-+-+-+
1571 w7:| |
1572 +-+-+-+-+-+-+- +-+-+-+-+-+-+-+
1573 w8:| |
1574 +-+-+-+-+-+-+- +-+-+-+-+-+-+-+
1575 w9:| |
1576 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1578 / vendor specific data (optional) /
1580 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1582 /* W1 */
1583 proto_tree_add_item(tipc_tree, hf_tipcv2_neighbour_mtype, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1584 /* Reserved 5 bits */
1585 /* Minor pv 8 bits */
1586 proto_tree_add_item(tipc_tree, hf_tipcv2_minor_pv, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1587 proto_tree_add_item(tipc_tree, hf_tipcv2_node_sig, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1588 offset = offset + 4;
1589 /* W2 */
1590 /* Destination Domain */
1591 dword = tvb_get_ntohl(tipc_tvb, offset);
1592 addr_str_ptr = tipc_addr_to_str(dword);
1593 proto_tree_add_string(tipc_tree, hf_tipcv2_destination_domain, tipc_tvb, offset, 4, addr_str_ptr);
1594 offset = offset + 4;
1595 /* W3 */
1596 dword = tvb_get_ntohl(tipc_tvb, offset);
1597 addr_str_ptr = tipc_addr_to_str(dword);
1598 proto_tree_add_string(tipc_tree, hf_tipcv2_prev_node, tipc_tvb, offset, 4, addr_str_ptr);
1599 offset = offset + 4;
1600 /* W4 */
1601 /* Network Identity: */
1602 proto_tree_add_item(tipc_tree, hf_tipcv2_network_id, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1603 offset = offset + 4;
1604 if (handle_v2_as & (V2_AS_1_6)) {
1605 /* W5 - W9 Bearer Level Originating Address: */
1606 proto_tree_add_item(tipc_tree, hf_tipcv2_bearer_level_orig_addr, tipc_tvb, offset, 20, ENC_NA);
1607 offset = offset + 20;
1608 } else {
1609 /* W5 */
1610 proto_tree_add_item(tipc_tree, hf_tipcv2_media_id, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1611 offset = offset + 4;
1612 /* W6 - W9 Bearer Level Originating Address: */
1613 proto_tree_add_item(tipc_tree, hf_tipcv2_bearer_level_orig_addr, tipc_tvb, offset, 16, ENC_NA);
1614 offset = offset + 16;
1616 if (msg_size-(orig_hdr_size*4) != 0) {
1617 proto_tree_add_item(tipc_tree, hf_tipcv2_vendor_specific_data, tipc_tvb, offset, -1, ENC_NA);
1619 break;
1620 default:
1621 break;
1624 return offset;
1628 /* Version 2 Header
1629 http://tipc.sourceforge.net/doc/draft-spec-tipc-02.html#sec:TIPC_Pkt_Format
1630 3.1.1. Payload Message Header Format
1632 0 1 2 3
1633 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1634 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1635 w0:|vers | user |hdr sz |n|d|s|r| message size |
1636 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1637 w1:|mstyp| error |rer cnt|lsc|opt p| broadcast ack no |
1638 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1639 w2:| link level ack no | broadcast/link level seq no |
1640 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1641 w3:| previous node |
1642 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1643 w4:| originating port |
1644 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1645 w5:| destination port |
1646 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1647 w6:| originating node |
1648 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1649 w7:| destination node |
1650 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1651 w8:| name type / transport sequence number |
1652 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1653 w9:| name instance/multicast lower bound |
1654 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1655 wA:| multicast upper bound |
1656 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1658 \ options \
1660 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1663 /* this function tries to call subdissectors for encapsulated data
1664 * @name_type pointer to the used port name type, NULL if not available
1665 * @user uint8_t holding the used TIPC user, is allways available
1667 static void
1668 call_tipc_v2_data_subdissectors(tvbuff_t *data_tvb, packet_info *pinfo, uint32_t *name_type_p, uint8_t user)
1670 if (dissect_tipc_data) {
1671 heur_dtbl_entry_t *hdtbl_entry;
1672 /* dissection of TIPC data is set in preferences */
1674 /* check for heuristic dissectors if specified in the
1675 * preferences to try them first */
1676 if (try_heuristic_first) {
1677 if (dissector_try_heuristic(tipc_heur_subdissector_list, data_tvb, pinfo, top_tree, &hdtbl_entry, NULL))
1678 return;
1680 /* This triggers if a dissectors if
1681 * tipc.user is just set to a TIPC user holding data */
1682 if (dissector_try_uint(tipc_user_dissector, user, data_tvb, pinfo, top_tree))
1683 return;
1684 /* The Name Type is not always explicitly set in a TIPC Data
1685 * Message.
1687 * On the tipc-discussion mailing list, Allan Stephens described
1688 * where the Port Name is not set with the following words:
1690 * <cite>
1691 * The "named" and "mcast" message types have info in the TIPC header to
1692 * specify the message's destination (a port name and port name sequence,
1693 * respectively); these message types typically occur when an application
1694 * sends connectionless traffic. The "conn" type is used to carry
1695 * connection-oriented traffic over an already established connection;
1696 * since the sending socket/port already knows the port ID of the other end
1697 * of the connection, there is no need for any port name information to be
1698 * present in the TIPC header.
1700 * The "direct" type is used to carry connectionless traffic to a
1701 * destination that was specified using a port ID, rather than a port name;
1702 * again, no port name info is present in the TIPC header because it is not
1703 * required. Situations where this sort of message might be generated
1704 * include: a) an application obtains a port ID as part of a subscription
1705 * event generated by TIPC's topology server and then sends a message to
1706 * that port ID (using sendto() or sendmsg()), and b) a server obtains a
1707 * client's port ID when it receives a message from the client (using
1708 * recvfrom() or recvmsg()) and then sends a reply back to that client port
1709 * ID (using sendto() or sendmsg()).
1710 * </cite>
1712 * TODO: it should be determined by
1713 * some kind of static function which port name type a message
1714 * is going to, if it is not specified explicitly in a message */
1715 if (name_type_p)
1716 if (dissector_try_uint(tipc_type_dissector, *name_type_p, data_tvb, pinfo, top_tree))
1717 return;
1718 /* check for heuristic dissectors if specified in the
1719 * preferences not to try them first */
1720 if (!try_heuristic_first) {
1721 if (dissector_try_heuristic(tipc_heur_subdissector_list, data_tvb, pinfo, top_tree, &hdtbl_entry, NULL))
1722 return;
1726 /* dissection of TIPC data is not set in preferences or no subdissector found */
1728 call_data_dissector(data_tvb, pinfo, top_tree);
1732 static void
1733 // NOLINTNEXTLINE(misc-no-recursion)
1734 dissect_tipc_v2(tvbuff_t *tipc_tvb, proto_tree *tipc_tree, packet_info *pinfo, int offset, uint8_t user, uint32_t msg_size, uint8_t hdr_size, bool datatype_hdr)
1736 uint32_t dword;
1737 char *addr_str_ptr;
1738 uint8_t opt_p = 0;
1739 proto_item *item;
1740 /* The unit used is 32 bit words */
1741 uint8_t orig_hdr_size;
1743 uint32_t name_type = 0;
1744 uint32_t *name_type_p = NULL;
1745 tvbuff_t *data_tvb;
1746 int len, reported_len;
1748 orig_hdr_size = hdr_size;
1750 /* Word 0 */
1751 /* Version: 3 bits */
1752 proto_tree_add_item(tipc_tree, hf_tipc_ver, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1753 /* User: 4 bits */
1754 proto_tree_add_item(tipc_tree, hf_tipcv2_usr, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1755 /* Header Size: 4 bits */
1756 item = proto_tree_add_item(tipc_tree, hf_tipc_hdr_size, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1757 proto_item_append_text(item, " = %u bytes", (hdr_size * 4));
1758 /* Non-sequenced: 1 bit */
1759 proto_tree_add_item(tipc_tree, hf_tipc_nonsequenced, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1760 if (datatype_hdr) {
1761 /* Destination Droppable: 1 bit */
1762 proto_tree_add_item(tipc_tree, hf_tipc_destdrop, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1763 /* Source Droppable: 1 bit */
1764 proto_tree_add_item(tipc_tree, hf_tipcv2_srcdrop, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1765 /* SYN: 1 bit */
1766 proto_tree_add_item(tipc_tree, hf_tipcv2_syn, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1768 /* Reserved: 1 bits */
1770 /* Message Size: 17 bits */
1771 proto_tree_add_item(tipc_tree, hf_tipc_msg_size, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1772 offset = offset + 4;
1774 if (!datatype_hdr) {
1775 dissect_tipc_v2_internal_msg(tipc_tvb, tipc_tree, pinfo, offset, user, msg_size, orig_hdr_size);
1776 return;
1779 /* Word 1 */
1780 /* Message Type: 3 bits */
1781 proto_tree_add_item(tipc_tree, hf_tipcv2_data_msg_type, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1782 /* Error Code: 4 bits */
1783 proto_tree_add_item(tipc_tree, hf_tipcv2_errorcode, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1785 /* Reroute Counter: 4 bits */
1786 proto_tree_add_item(tipc_tree, hf_tipcv2_rer_cnt, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1787 /* Lookup Scope: 2 bits */
1788 proto_tree_add_item(tipc_tree, hf_tipcv2_lookup_scope, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1790 /* Options Position: 3 bits */
1791 if (handle_v2_as & (V2_AS_ALL + V2_AS_1_6)) {
1792 opt_p = tvb_get_uint8(tipc_tvb, offset+1) & 0x7;
1793 proto_tree_add_item(tipc_tree, hf_tipcv2_opt_p, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1794 if (opt_p != 0) {
1795 hdr_size = hdr_size - (opt_p << 2);
1798 /* Broadcast Acknowledge Number: 16 bits */
1799 proto_tree_add_item(tipc_tree, hf_tipcv2_broadcast_ack_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1800 offset = offset + 4;
1802 /* W2 */
1803 /* Link Level Acknowledge Number: 16 bits */
1804 proto_tree_add_item(tipc_tree, hf_tipcv2_link_level_ack_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1805 /* broadcast/link level seq no */
1806 proto_tree_add_item(tipc_tree, hf_tipcv2_link_level_seq_no, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1807 offset = offset + 4;
1808 /* W3 previous node */
1809 dword = tvb_get_ntohl(tipc_tvb, offset);
1810 addr_str_ptr = tipc_addr_to_str(dword);
1811 proto_tree_add_string(tipc_tree, hf_tipcv2_prev_node, tipc_tvb, offset, 4, addr_str_ptr);
1812 offset = offset + 4;
1814 /* W4 Originating Port: 32 bits */
1815 proto_tree_add_item(tipc_tree, hf_tipc_org_port, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1816 offset = offset + 4;
1818 /* W5 Destination Port: 32 bits */
1819 proto_tree_add_item(tipc_tree, hf_tipc_dst_port, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1820 offset = offset + 4;
1821 if (hdr_size > 6) {
1823 /* W6 Originating Node: 32 bits */
1824 dword = tvb_get_ntohl(tipc_tvb, offset);
1825 addr_str_ptr = tipc_addr_to_str(dword);
1826 proto_tree_add_string(tipc_tree, hf_tipcv2_orig_node, tipc_tvb, offset, 4, addr_str_ptr);
1827 offset = offset + 4;
1828 /* W7 Destination Node: 32 bits */
1829 dword = tvb_get_ntohl(tipc_tvb, offset);
1830 addr_str_ptr = tipc_addr_to_str(dword);
1831 proto_tree_add_string(tipc_tree, hf_tipcv2_dest_node, tipc_tvb, offset, 4, addr_str_ptr);
1832 offset = offset + 4;
1833 if (hdr_size > 8) {
1834 /* W8 name type / transport sequence number */
1835 /* Transport Level Sequence Number: 32 bits */
1836 /* Port Name Type: 32 bits */
1837 proto_tree_add_item(tipc_tree, hf_tipcv2_port_name_type, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1838 name_type = tvb_get_ntohl(tipc_tvb, offset);
1839 name_type_p = &name_type;
1840 offset = offset + 4;
1842 if (hdr_size > 9) {
1843 /* W9 name instance/multicast lower bound */
1844 if (hdr_size < 11)
1845 /* no multicast */
1846 /* Port Name Instance: 32 bits */
1847 proto_tree_add_item(tipc_tree, hf_tipcv2_port_name_instance, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1848 else
1849 /* multicast */
1850 /* Port Name Sequence Lower: 32 bits */
1851 proto_tree_add_item(tipc_tree, hf_tipcv2_multicast_lower, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1852 offset = offset + 4;
1853 if (hdr_size > 10) {
1855 /* W10 multicast upper bound */
1856 /* Port Name Sequence Upper: 32 bits */
1857 proto_tree_add_item(tipc_tree, hf_tipcv2_multicast_upper, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
1858 offset = offset + 4;
1863 /* Options */
1864 if (handle_v2_as & (V2_AS_ALL + V2_AS_1_6)) {
1865 if (opt_p != 0) {
1866 proto_tree_add_bytes_format(tipc_tree, hf_tipcv2_options, tipc_tvb, offset, (opt_p >> 2), NULL, "Options");
1867 offset = offset + (opt_p << 2);
1870 /* TIPCv2 data */
1871 len = (msg_size - (orig_hdr_size<<2));
1872 reported_len = tvb_reported_length_remaining(tipc_tvb, offset);
1873 data_tvb = tvb_new_subset_length_caplen(tipc_tvb, offset, len, reported_len);
1875 call_tipc_v2_data_subdissectors(data_tvb, pinfo, name_type_p, user);
1878 /* From message.h (http://cvs.sourceforge.net/viewcvs.py/tipc/source/stable_ericsson/TIPC_SCC/src/Message.h?rev=1.2&view=markup)
1879 ////////////////////////////////////////////////////////////////////
1880 TIPC internal header format, version 1:
1883 | Word 0-2: common to all users |
1885 +-------+-------+-------+-------+-------+-------+-------+-------+
1886 |netw-|imp|link | | |p|bea- |link |
1887 w3:|ork |ort|sel- | message count | |r|rer |sel- |
1888 |id |anc|ector| | |b|id |ector|
1889 +-------+-------+-------+-------+-------+-------+-------+-------+
1891 w4:| remote address |
1893 +-------+-------+-------+-------+-------+-------+-------+-------+
1894 | msg | | |
1895 w5:| type | gap | next sent |
1896 | | | |
1897 +-------+-------+-------+-------+-------+-------+-------+-------+
1898 | | link | |
1899 w6:| reserve | prio- | link tolerance |
1900 | | ity | |
1901 +-------+-------+-------+-------+-------+-------+-------+-------+
1903 w7:| |
1905 +-------+-------+ +-------+-------+
1907 w8:| |
1909 +-------+-------+ bearer name +-------+-------+
1911 w9:| |
1913 +-------+-------+ +-------+-------+
1915 wa:| |
1917 +-------+-------+-------+-------+-------+-------+-------+-------+
1919 NB: Connection Manager and Name Distributor use data message format.
1922 static void
1923 // NOLINTNEXTLINE(misc-no-recursion)
1924 dissect_tipc_int_prot_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tipc_tree, int offset, uint8_t user, uint32_t msg_size)
1926 uint8_t msg_type;
1927 tvbuff_t *data_tvb;
1928 uint32_t msg_in_bundle_size;
1929 uint32_t dword;
1930 unsigned msg_no = 0;
1931 uint8_t link_sel;
1932 uint16_t link_lev_seq_no;
1933 uint32_t reassembled_msg_length = 0;
1934 uint32_t no_of_segments = 0;
1936 bool save_fragmented;
1937 tvbuff_t* new_tvb = NULL;
1938 tvbuff_t* next_tvb = NULL;
1939 fragment_head *frag_msg = NULL;
1940 proto_item *item;
1942 link_lev_seq_no = tvb_get_ntohl(tvb, 4) & 0xffff;
1943 /* Internal Protocol Header */
1944 /* Unused */
1946 msg_type = tvb_get_uint8(tvb, 20)>>4;
1947 /* W3 */
1948 dword = tvb_get_ntohl(tvb, offset);
1949 link_sel = dword & 0x7;
1950 proto_tree_add_item(tipc_tree, hf_tipc_unused2, tvb, offset, 4, ENC_BIG_ENDIAN);
1951 /* Importance */
1952 if (user == TIPC_SEGMENTATION_MANAGER)
1953 proto_tree_add_item(tipc_tree, hf_tipc_importance, tvb, offset, 4, ENC_BIG_ENDIAN);
1954 /* Link selector */
1955 if (user == TIPC_SEGMENTATION_MANAGER || user == TIPC_NAME_DISTRIBUTOR || user == TIPC_CHANGEOVER_PROTOCOL)
1956 proto_tree_add_item(tipc_tree, hf_tipc_link_selector, tvb, offset, 4, ENC_BIG_ENDIAN);
1957 /* Message count */
1958 if (user == TIPC_MSG_BUNDLER || user == TIPC_CHANGEOVER_PROTOCOL) {
1959 proto_tree_add_item(tipc_tree, hf_tipc_msg_cnt, tvb, offset, 4, ENC_BIG_ENDIAN);
1961 /* Unused */
1962 /* Probe */
1963 if (user == TIPC_LINK_PROTOCOL)
1964 proto_tree_add_item(tipc_tree, hf_tipc_probe, tvb, offset, 4, ENC_BIG_ENDIAN);
1965 /* Bearer identity */
1966 if (user == TIPC_LINK_PROTOCOL || user == TIPC_CHANGEOVER_PROTOCOL)
1967 proto_tree_add_item(tipc_tree, hf_tipc_bearer_id, tvb, offset, 4, ENC_BIG_ENDIAN);
1968 /* Link selector */
1969 if (user == TIPC_SEGMENTATION_MANAGER || user == TIPC_NAME_DISTRIBUTOR || user == TIPC_CHANGEOVER_PROTOCOL)
1970 proto_tree_add_item(tipc_tree, hf_tipc_link_selector2, tvb, offset, 4, ENC_BIG_ENDIAN);
1972 offset = offset + 4;
1974 /* W4 */
1975 /* Remote address */
1976 if (user == TIPC_ROUTING_MANAGER)
1977 proto_tree_add_item(tipc_tree, hf_tipc_remote_addr, tvb, offset, 4, ENC_BIG_ENDIAN);
1978 offset = offset + 4;
1980 /* W5 */
1981 /* Message type */
1982 switch (user) {
1983 case TIPC_ROUTING_MANAGER:
1984 proto_tree_add_item(tipc_tree, hf_tipc_rm_msg_type, tvb, offset, 4, ENC_BIG_ENDIAN);
1985 break;
1986 case TIPC_NAME_DISTRIBUTOR:
1987 proto_tree_add_item(tipc_tree, hf_tipc_nd_msg_type, tvb, offset, 4, ENC_BIG_ENDIAN);
1988 break;
1989 case TIPC_CONNECTION_MANAGER:
1990 break;
1991 case TIPC_LINK_PROTOCOL:
1992 proto_tree_add_item(tipc_tree, hf_tipc_lp_msg_type, tvb, offset, 4, ENC_BIG_ENDIAN);
1993 break;
1994 case TIPC_CHANGEOVER_PROTOCOL:
1995 proto_tree_add_item(tipc_tree, hf_tipc_cng_prot_msg_type, tvb, offset, 4, ENC_BIG_ENDIAN);
1996 break;
1997 case TIPC_SEGMENTATION_MANAGER:
1998 proto_tree_add_item(tipc_tree, hf_tipc_sm_msg_type, tvb, offset, 4, ENC_BIG_ENDIAN);
1999 break;
2000 default:
2001 proto_tree_add_item(tipc_tree, hf_tipc_unknown_msg_type, tvb, offset, 4, ENC_BIG_ENDIAN);
2002 break;
2004 /* Sequence gap */
2005 if (user == TIPC_LINK_PROTOCOL && msg_type == TIPC_LINK_PROTOCO_STATE_MSG)
2006 proto_tree_add_item(tipc_tree, hf_tipc_seq_gap, tvb, offset, 4, ENC_BIG_ENDIAN);
2007 /* Next sent packet */
2008 proto_tree_add_item(tipc_tree, hf_tipc_nxt_snt_pkg, tvb, offset, 4, ENC_BIG_ENDIAN);
2010 offset = offset + 4;
2011 /* W6 Unused */
2012 proto_tree_add_none_format(tipc_tree, hf_tipc_unused_word, tvb, offset, 4, "word 6 unused for this user");
2013 offset = offset + 4;
2014 /* W7 */
2015 if (msg_size == 28) /* No data */
2016 return;
2018 switch (user) {
2019 case TIPC_LINK_PROTOCOL:
2020 proto_tree_add_item(tipc_tree, hf_tipc_bearer_name, tvb, offset, -1, ENC_ASCII);
2021 break;
2022 case TIPC_CHANGEOVER_PROTOCOL:
2023 switch (msg_type) {
2024 case 0: /* DUPLICATE_MSG */
2025 case 1: /* ORIGINAL_MSG */
2026 item = proto_tree_add_uint_format(tipc_tree, hf_tipc_changeover_protocol, tvb, offset, 1,
2027 msg_type, "TIPC_CHANGEOVER_PROTOCOL %s (%u)",
2028 val_to_str_const(msg_type, tipc_cng_prot_msg_type_values, "unknown"), msg_type);
2029 proto_item_set_len(item, tvb_reported_length_remaining(tvb, offset));
2030 data_tvb = tvb_new_subset_remaining(tvb, offset);
2031 col_set_fence(pinfo->cinfo, COL_INFO);
2032 dissect_tipc(data_tvb, pinfo, tipc_tree, NULL);
2033 break;
2034 default:
2035 /* INFO_MSG: Even when there are no packets in the send queue of a removed link, the other
2036 * endpoint must be informed about this fact, so it can be unblocked when it has terminated its
2037 * part of the changeover procedure. This message type may be regarded as an empty
2038 * ORIGINAL_MSG, where message count is zero, and no packet is wrapped inside.
2040 item = proto_tree_add_uint_format(tipc_tree, hf_tipc_changeover_protocol, tvb, offset, 1, msg_type,
2041 "TIPC_CHANGEOVER_PROTOCOL Protocol/dissection Error");
2042 proto_item_set_len(item, tvb_reported_length_remaining(tvb, offset));
2043 break;
2045 break;
2046 case TIPC_SEGMENTATION_MANAGER:
2047 save_fragmented = pinfo->fragmented;
2048 if (tipc_defragment) {
2049 pinfo->fragmented = true;
2051 frag_msg = fragment_add_seq_next(&tipc_msg_reassembly_table,
2052 tvb, offset,
2053 pinfo,
2054 link_sel, /* ID for fragments belonging together - NEEDS IMPROVING? */
2055 NULL,
2056 tvb_captured_length_remaining(tvb, offset), /* fragment length - to the end */
2057 true); /* More fragments? */
2058 if (msg_type == TIPC_FIRST_SEGMENT) {
2059 reassembled_msg_length = tvb_get_ntohl(tvb, offset) & 0x1ffff;
2060 /* The number of segments needed for he complete message (Including header) will be
2061 * The size of the data section of the first message, divided by the complete message size
2062 * + one segment for the remainder (if any).
2064 no_of_segments = reassembled_msg_length/(msg_size - 28);
2065 if (reassembled_msg_length > (no_of_segments * (msg_size - 28)))
2066 no_of_segments++;
2067 fragment_set_tot_len(&tipc_msg_reassembly_table,
2068 pinfo, link_sel, NULL,
2069 no_of_segments-1);
2070 item = proto_tree_add_bytes_format(tipc_tree, hf_tipc_data_fragment, tvb, offset, -1, NULL, "Segmented message size %u bytes -> No segments = %i",
2071 reassembled_msg_length, no_of_segments);
2072 proto_item_set_generated(item);
2075 new_tvb = process_reassembled_data(tvb, offset, pinfo,
2076 "Reassembled TIPC", frag_msg, &tipc_msg_frag_items,
2077 NULL, tipc_tree);
2079 if (frag_msg) { /* Reassembled */
2080 col_append_str(pinfo->cinfo, COL_INFO,
2081 " (Message Reassembled)");
2082 } else { /* Not last packet of reassembled Short Message */
2083 col_append_fstr(pinfo->cinfo, COL_INFO,
2084 " (Message fragment %u)", link_lev_seq_no);
2088 if (new_tvb) { /* take it all */
2089 next_tvb = new_tvb;
2090 } else { /* make a new subset */
2091 next_tvb = tvb_new_subset_remaining(tvb, offset);
2093 pinfo->fragmented = save_fragmented;
2094 if (new_tvb) {
2095 col_set_fence(pinfo->cinfo, COL_INFO);
2096 dissect_tipc(next_tvb, pinfo, tipc_tree, NULL);
2097 return;
2100 proto_tree_add_bytes_format(tipc_tree, hf_tipc_data_fragment, next_tvb, 0, -1, NULL, "%u bytes Data Fragment", (msg_size - 28));
2101 break;
2102 case TIPC_MSG_BUNDLER:
2103 proto_tree_add_item(tipc_tree, hf_tipc_message_bundle, tvb, offset, -1, ENC_NA);
2104 while ((uint32_t)offset < msg_size) {
2105 msg_no++;
2106 msg_in_bundle_size = tvb_get_ntohl(tvb, offset) & 0x1FFFF;
2107 item = proto_tree_add_uint_format(tipc_tree, hf_tipc_msg_no_bundle, tvb, offset, 1, msg_no, "%u Message in Bundle", msg_no);
2108 int remaining = tvb_reported_length_remaining(tvb, offset);
2109 if (remaining > 0 && msg_in_bundle_size <= (unsigned)remaining) {
2110 proto_item_set_len(item, msg_in_bundle_size);
2111 data_tvb = tvb_new_subset_length(tvb, offset, msg_in_bundle_size);
2112 col_set_fence(pinfo->cinfo, COL_INFO);
2113 dissect_tipc(data_tvb, pinfo, tipc_tree, NULL);
2114 offset += msg_in_bundle_size;
2115 } else {
2116 proto_tree_add_expert(tipc_tree, pinfo, &ei_tipc_invalid_bundle_size, tvb, offset, 4);
2117 break;
2120 break;
2121 default:
2122 proto_tree_add_item(tipc_tree, hf_tipc_data, tvb, offset, -1, ENC_NA);
2123 break;
2128 /* determines the length of a TIPC package */
2129 static unsigned
2130 get_tipc_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
2132 return tvb_get_ntohl(tvb, offset) & 0x0001FFFF;
2136 /* triggers the dissection of TIPC-over-TCP */
2137 static int
2138 dissect_tipc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data)
2140 tcp_dissect_pdus(tvb, pinfo, parent_tree, tipc_tcp_desegment, 4, get_tipc_pdu_len,
2141 dissect_tipc, data);
2142 return tvb_captured_length(tvb);
2145 #define TIPC_MAX_RECURSION_DEPTH 10 // Arbitrary
2146 static int
2147 // NOLINTNEXTLINE(misc-no-recursion)
2148 dissect_tipc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2150 proto_item *ti, *item;
2151 proto_tree *tipc_tree, *tipc_data_tree;
2152 int offset = 0;
2153 uint32_t srcport, destport = 0, dword;
2154 uint8_t version;
2155 uint32_t msg_size;
2156 uint8_t hdr_size;
2157 uint8_t user;
2158 char *addr_str_ptr;
2159 tvbuff_t *data_tvb, *tipc_tvb;
2160 bool datatype_hdr = false;
2161 uint8_t msg_type = 0;
2163 /* Make entry in Protocol column on summary display */
2164 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TIPC");
2166 col_clear(pinfo->cinfo, COL_INFO);
2168 top_tree = tree;
2169 dword = tvb_get_ntohl(tvb, offset);
2170 version = (dword >>29) & 0xf;
2171 hdr_size = (dword >>21) & 0xf;
2172 user = (dword>>25) & 0xf;
2173 msg_size = dword & 0x1ffff;
2175 unsigned recursion_depth = p_get_proto_depth(pinfo, proto_tipc);
2176 if (++recursion_depth >= TIPC_MAX_RECURSION_DEPTH) {
2177 proto_tree_add_expert(tree, pinfo, &ei_tipc_max_recursion_depth_reached, tvb, 0, 0);
2178 return tvb_captured_length(tvb);
2180 p_set_proto_depth(pinfo, proto_tipc, recursion_depth);
2182 if ((uint32_t)tvb_reported_length_remaining(tvb, offset) < msg_size) {
2183 tipc_tvb = tvb;
2184 } else {
2185 tipc_tvb = tvb_new_subset_length(tvb, offset, msg_size);
2187 /* user == 7 only works for v2, this will decode the legacy TIPC configuration protocol */
2188 if (user == TIPCv2_LINK_PROTOCOL) version = TIPCv2;
2189 /* Set User values in COL INFO different in V1 and V2 */
2190 switch (version) {
2191 case 0:
2192 case TIPCv1:
2193 msg_type = tvb_get_uint8(tipc_tvb, offset + 20)>>4;
2194 col_append_fstr(pinfo->cinfo, COL_INFO, " %s(%u) ", val_to_str_const(user, tipc_user_values, "unknown"), user);
2195 /* Set msg type in info col and find out if it's a data hdr or not */
2196 datatype_hdr = tipc_v1_set_col_msgtype(pinfo, user, msg_type);
2197 if (datatype_hdr) {
2198 /* Data type header */
2199 if (hdr_size > 5 && user <4) {
2200 /* W6 Originating Processor */
2201 set_address_tvb(&pinfo->src, tipc_address_type, 4, tipc_tvb, offset + 24);
2203 /* W7 Destination Processor */
2204 set_address_tvb(&pinfo->dst, tipc_address_type, 4, tipc_tvb, offset + 28);
2205 } else {
2206 /* Short data hdr */
2207 /* W2 Previous Processor */
2208 set_address_tvb(&pinfo->src, tipc_address_type, 4, tipc_tvb, offset + 8);
2210 } else {
2211 /* W2 Previous Processor */
2212 set_address_tvb(&pinfo->src, tipc_address_type, 4, tipc_tvb, offset + 8);
2214 break;
2215 case TIPCv2:
2216 msg_type = tvb_get_uint8(tipc_tvb, offset + 4)>>5;
2217 col_append_fstr(pinfo->cinfo, COL_INFO, "%-12s", val_to_str_const(user, tipcv2_user_short_str_vals, "unknown"));
2218 /* Set msg type in info col */
2219 tipc_v2_set_info_col(tvb, pinfo, user, msg_type, hdr_size);
2221 /* find out if it's a data hdr or not */
2222 switch (user) {
2223 case TIPCv2_DATA_LOW:
2224 case TIPCv2_DATA_NORMAL:
2225 case TIPCv2_DATA_HIGH:
2226 case TIPCv2_DATA_NON_REJECTABLE:
2227 datatype_hdr = true;
2228 break;
2229 default:
2230 datatype_hdr = false;
2231 break;
2234 if (datatype_hdr) {
2235 if (hdr_size > 6) {
2236 /* W6 Originating Processor */
2237 set_address_tvb(&pinfo->src, tipc_address_type, 4, tipc_tvb, offset + 24);
2239 /* W7 Destination Processor */
2240 set_address_tvb(&pinfo->dst, tipc_address_type, 4, tipc_tvb, offset + 28);
2241 } else {
2242 /* W3 Previous Processor */
2243 set_address_tvb(&pinfo->src, tipc_address_type, 4, tipc_tvb, offset + 12);
2246 } else {
2247 if (user != TIPCv2_NEIGHBOUR_DISCOVERY) {
2248 /* W6 Originating Processor */
2249 set_address_tvb(&pinfo->src, tipc_address_type, 4, tipc_tvb, offset + 24);
2251 /* W7 Destination Processor */
2252 set_address_tvb(&pinfo->dst, tipc_address_type, 4, tipc_tvb, offset + 28);
2253 } else {
2254 /* W2 Destination Domain */
2255 set_address_tvb(&pinfo->dst, tipc_address_type, 4, tipc_tvb, offset + 8);
2257 /* W3 Previous Node */
2258 set_address_tvb(&pinfo->src, tipc_address_type, 4, tipc_tvb, offset + 12);
2261 break;
2262 default:
2263 break;
2266 ti = proto_tree_add_item(tree, proto_tipc, tipc_tvb, offset, -1, ENC_NA);
2267 tipc_tree = proto_item_add_subtree(ti, ett_tipc);
2268 if (version == TIPCv2) {
2269 dissect_tipc_v2(tipc_tvb, tipc_tree, pinfo, offset, user, msg_size, hdr_size, datatype_hdr);
2270 p_set_proto_depth(pinfo, proto_tipc, recursion_depth - 1);
2271 return tvb_captured_length(tvb);
2274 /* Word 0-2 common for all messages */
2275 /* Word 0 */
2276 proto_tree_add_item(tipc_tree, hf_tipc_ver, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
2277 proto_tree_add_item(tipc_tree, hf_tipc_usr, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
2278 item = proto_tree_add_item(tipc_tree, hf_tipc_hdr_size, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
2279 proto_item_append_text(item, " = %u bytes", (hdr_size * 4));
2280 proto_tree_add_item(tipc_tree, hf_tipc_nonsequenced, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
2281 proto_tree_add_item(tipc_tree, hf_tipc_unused, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
2282 if (datatype_hdr) {
2283 proto_tree_add_item(tipc_tree, hf_tipc_destdrop, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
2284 proto_tree_add_item(tipc_tree, hf_tipcv2_srcdrop, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
2287 proto_tree_add_item(tipc_tree, hf_tipc_msg_size, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
2288 offset = offset + 4;
2290 /* Word 1 */
2291 proto_tree_add_item(tipc_tree, hf_tipc_ack_link_lev_seq, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
2292 proto_tree_add_item(tipc_tree, hf_tipc_link_lev_seq, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
2293 offset = offset + 4;
2295 /* Word 2 */
2296 dword = tvb_get_ntohl(tipc_tvb, offset);
2297 addr_str_ptr = tipc_addr_to_str(dword);
2298 proto_tree_add_string(tipc_tree, hf_tipc_prev_proc, tipc_tvb, offset, 4, addr_str_ptr);
2300 offset = offset + 4;
2301 switch (user) {
2302 case TIPC_ROUTING_MANAGER:
2303 case TIPC_LINK_PROTOCOL:
2304 case TIPC_CHANGEOVER_PROTOCOL:
2305 case TIPC_SEGMENTATION_MANAGER:
2306 case TIPC_MSG_BUNDLER:
2307 dissect_tipc_int_prot_msg(tipc_tvb, pinfo, tipc_tree, offset, user, msg_size);
2308 p_set_proto_depth(pinfo, proto_tipc, recursion_depth - 1);
2309 return tvb_captured_length(tvb);
2310 default:
2311 break;
2314 proto_tree_add_item_ret_uint(tipc_tree, hf_tipc_org_port, tipc_tvb, offset, 4, ENC_BIG_ENDIAN, &srcport);
2315 offset = offset + 4;
2316 if (user != TIPC_NAME_DISTRIBUTOR) {
2317 proto_tree_add_item_ret_uint(tipc_tree, hf_tipc_dst_port, tipc_tvb, offset, 4, ENC_BIG_ENDIAN, &destport);
2320 conversation_set_conv_addr_port_endpoints(pinfo, &pinfo->src, &pinfo->dst, CONVERSATION_TIPC, srcport, destport);
2322 offset = offset + 4;
2323 /* 20 - 24 Bytes
2324 20 bytes: Used in subnetwork local, connection oriented messages, where error code, reroute
2325 counter and activity identity are zero. A recipient finding that the header size field is 20 does
2326 by default know both user (DATA), message type (CONNECTED_MSG), error code
2327 (MSG_OK), reroute counter (0), and activity identity (undefined). Since no more testing for
2328 this is needed these fields can be left out in the header. Furthermore, since such messages
2329 only will do zero or one inter-processor hop, we know that previous processor is the real
2330 origin of the message. Hence the field originating processor can be omitted. For the same
2331 reason, the recipient processor will know that it is identical to destination processor, so even
2332 this field can be skipped. Finally, because the link layer guarantees delivery and sequence
2333 order for this single hop, even the connection sequence number is redundant. So the message
2334 can just be passed directly on to the destination port. Since this type of message statistically
2335 should be by far the most frequent one this small optimization pays off.
2337 if (hdr_size <= 6) {
2338 proto_tree_add_item(tipc_tree, hf_tipc_data, tipc_tvb, offset, -1, ENC_NA);
2339 } else {
2340 switch (user) {
2341 case TIPC_NAME_DISTRIBUTOR:
2342 proto_tree_add_item(tipc_tree, hf_tipc_nd_msg_type, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
2343 break;
2344 case TIPC_CONNECTION_MANAGER:
2345 proto_tree_add_item(tipc_tree, hf_tipc_cm_msg_type, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
2346 break;
2347 default:
2348 proto_tree_add_item(tipc_tree, hf_tipc_data_msg_type, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
2349 break;
2351 proto_tree_add_item(tipc_tree, hf_tipc_err_code, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
2352 proto_tree_add_item(tipc_tree, hf_tipc_reroute_cnt, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
2353 proto_tree_add_item(tipc_tree, hf_tipc_act_id, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
2354 offset = offset + 4;
2356 dword = tvb_get_ntohl(tipc_tvb, offset);
2357 addr_str_ptr = tipc_addr_to_str(dword);
2359 proto_tree_add_string(tipc_tree, hf_tipc_org_proc, tipc_tvb, offset, 4, addr_str_ptr);
2360 offset = offset + 4;
2362 dword = tvb_get_ntohl(tipc_tvb, offset);
2363 addr_str_ptr = tipc_addr_to_str(dword);
2365 proto_tree_add_string(tipc_tree, hf_tipc_dst_proc, tipc_tvb, offset, 4, addr_str_ptr);
2366 offset = offset + 4;
2367 /* 32 bytes
2368 32 bytes: The size of all data messages containing an explicit port identity as destination
2369 address.
2371 if (hdr_size > 8) {
2372 if (user == TIPC_NAME_DISTRIBUTOR) {
2374 Although an internal service, the name distributor uses the full 40-byte "external" data header
2375 format when updating the naming table instances. This is because its messages may need
2376 routing, - all system processor must contain the publications from all device processors and
2377 vice versa, whether they are directly linked or not. The fields name type, name instance, and
2378 destination port of that header have no meaning for such messages
2380 offset = offset + 8;
2381 tipc_data_tree = proto_tree_add_subtree_format(tipc_tree, tvb, offset, -1, ett_tipc_data, NULL,
2382 "TIPC_NAME_DISTRIBUTOR %u bytes User Data", (msg_size - hdr_size*4));
2383 data_tvb = tvb_new_subset_remaining(tipc_tvb, offset);
2384 dissect_tipc_name_dist_data(data_tvb, pinfo, tipc_data_tree, 0);
2385 p_set_proto_depth(pinfo, proto_tipc, recursion_depth - 1);
2386 return tvb_captured_length(tvb);
2387 } else {
2388 /* Port name type / Connection level sequence number */
2389 proto_tree_add_item(tipc_tree, hf_tipc_port_name_type, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
2390 offset = offset + 4;
2391 /* Port name instance */
2392 proto_tree_add_item(tipc_tree, hf_tipc_port_name_instance, tipc_tvb, offset, 4, ENC_BIG_ENDIAN);
2393 offset = offset + 4;
2397 if (user < 4 && dissect_tipc_data) { /* DATA type user */
2398 tvbuff_t *next_tvb;
2399 uint32_t msg_type32 = msg_type;
2400 uint32_t *name_type_p = &msg_type32;
2401 switch (msg_type) {
2402 case TIPC_CONNECTED_MSG:
2403 proto_tree_add_item(tipc_tree, hf_tipc_data, tipc_tvb, offset, -1, ENC_NA);
2404 break;
2405 case TIPC_NAMED_MSG:
2406 proto_tree_add_item(tipc_tree, hf_tipc_named_msg_hdr, tipc_tvb, offset, 14, ENC_NA);
2407 proto_tree_add_item(tipc_tree, hf_tipc_data, tipc_tvb, offset+14, -1, ENC_NA);
2408 break;
2409 case TIPC_DIRECT_MSG:
2410 proto_tree_add_item(tipc_tree, hf_tipc_data, tipc_tvb, offset, -1, ENC_NA);
2411 break;
2412 default:
2413 proto_tree_add_item(tipc_tree, hf_tipc_data, tipc_tvb, offset, -1, ENC_NA);
2414 break;
2416 /* tipc data type user doesn't change format, reuse v2 function */
2417 next_tvb = tvb_new_subset_remaining(tvb, offset);
2418 call_tipc_v2_data_subdissectors(next_tvb, pinfo, name_type_p, user);
2420 } /*if (hdr_size <= 5) */
2422 p_set_proto_depth(pinfo, proto_tipc, recursion_depth - 1);
2423 return tvb_captured_length(tvb);
2426 /* Register TIPC with Wireshark */
2427 void
2428 proto_register_tipc(void)
2430 static hf_register_info hf[] = {
2431 { &hf_tipc_msg_fragments,
2432 { "Message fragments", "tipc.msg.fragments",
2433 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL }
2435 { &hf_tipc_msg_fragment,
2436 { "Message fragment", "tipc.msg.fragment",
2437 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
2439 { &hf_tipc_msg_fragment_overlap,
2440 { "Message fragment overlap", "tipc.msg.fragment.overlap",
2441 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }
2443 { &hf_tipc_msg_fragment_overlap_conflicts,
2444 { "Message fragment overlapping with conflicting data", "tipc.msg.fragment.overlap.conflicts",
2445 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }
2447 { &hf_tipc_msg_fragment_multiple_tails,
2448 { "Message has multiple tail fragments", "tipc.msg.fragment.multiple_tails",
2449 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }
2451 { &hf_tipc_msg_fragment_too_long_fragment,
2452 { "Message fragment too long", "tipc.msg.fragment.too_long_fragment",
2453 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }
2455 { &hf_tipc_msg_fragment_error,
2456 { "Message defragmentation error", "tipc.msg.fragment.error",
2457 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
2459 { &hf_tipc_msg_fragment_count,
2460 { "Message fragment count", "tipc.msg.fragment.count",
2461 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
2463 { &hf_tipc_msg_reassembled_in,
2464 { "Reassembled in", "tipc.msg.reassembled.in",
2465 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
2467 { &hf_tipc_msg_reassembled_length,
2468 { "Reassembled TIPC length", "tipc.msg.reassembled.length",
2469 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
2471 { &hf_tipc_ver,
2472 { "Version", "tipc.ver",
2473 FT_UINT32, BASE_DEC, NULL, 0xe0000000,
2474 "TIPC protocol version", HFILL }
2476 { &hf_tipc_usr,
2477 { "User", "tipc.usr",
2478 FT_UINT32, BASE_DEC, VALS(tipc_user_values), 0x1e000000,
2479 "TIPC User", HFILL }
2481 { &hf_tipcv2_usr,
2482 { "User", "tipc.usr",
2483 FT_UINT32, BASE_DEC, VALS(tipcv2_user_values), 0x1e000000,
2484 "TIPC User", HFILL }
2486 { &hf_tipc_hdr_size,
2487 { "Header size", "tipc.hdr_size",
2488 FT_UINT32, BASE_DEC, NULL, 0x01e00000,
2489 "TIPC Header size", HFILL }
2491 { &hf_tipc_nonsequenced,
2492 { "Non-sequenced", "tipc.non_sequenced",
2493 FT_UINT32, BASE_DEC, NULL, 0x00100000,
2494 "Non-sequenced Bit", HFILL }
2496 { &hf_tipc_destdrop,
2497 { "Destination Droppable", "tipc.destdrop",
2498 FT_UINT32, BASE_DEC, NULL, 0x00080000,
2499 "Destination Droppable Bit", HFILL }
2501 { &hf_tipc_unused,
2502 { "Unused", "tipc.hdr_unused",
2503 FT_UINT32, BASE_DEC, NULL, 0x000e0000,
2504 "TIPC Unused", HFILL }
2506 { &hf_tipc_msg_size,
2507 { "Message size", "tipc.msg_size",
2508 FT_UINT32, BASE_DEC, NULL, 0x0001ffff,
2509 "TIPC Message size", HFILL }
2511 { &hf_tipc_ack_link_lev_seq,
2512 { "Acknowledged link level sequence number", "tipc.ack_link_lev_seq",
2513 FT_UINT32, BASE_DEC, NULL, 0xffff0000,
2514 "TIPC Acknowledged link level sequence number", HFILL }
2516 { &hf_tipc_link_lev_seq,
2517 { "Link level sequence number", "tipc.link_lev_seq",
2518 FT_UINT32, BASE_DEC, NULL, 0x0000ffff,
2519 "TIPC Link level sequence number", HFILL }
2521 { &hf_tipc_prev_proc,
2522 { "Previous processor", "tipc.prev_proc",
2523 FT_STRING, BASE_NONE, NULL, 0x0,
2524 "TIPC Previous processor", HFILL }
2526 { &hf_tipc_org_port,
2527 { "Originating port", "tipc.org_port",
2528 FT_UINT32, BASE_DEC, NULL, 0x0,
2529 "TIPC Originating port", HFILL }
2531 { &hf_tipc_dst_port,
2532 { "Destination port", "tipc.dst_port",
2533 FT_UINT32, BASE_DEC, NULL, 0x0,
2534 "TIPC Destination port", HFILL }
2536 { &hf_tipc_data_msg_type,
2537 { "Message type", "tipc.msg_type",
2538 FT_UINT32, BASE_DEC, VALS(tipc_data_msg_type_values), 0xf0000000,
2539 "TIPC Message type", HFILL }
2541 { &hf_tipc_err_code,
2542 { "Error code", "tipc.err_code",
2543 FT_UINT32, BASE_DEC, VALS(tipc_error_code_values), 0x0f000000,
2544 "TIPC Error code", HFILL }
2546 { &hf_tipc_reroute_cnt,
2547 { "Reroute counter", "tipc.route_cnt",
2548 FT_UINT32, BASE_DEC, NULL, 0x00f00000,
2549 "TIPC Reroute counter", HFILL }
2551 { &hf_tipc_act_id,
2552 { "Activity identity", "tipc.act_id",
2553 FT_UINT32, BASE_DEC, NULL, 0x000fffff,
2554 "TIPC Activity identity", HFILL }
2556 { &hf_tipc_org_proc,
2557 { "Originating processor", "tipc.org_proc",
2558 FT_STRING, BASE_NONE, NULL, 0x0,
2559 "TIPC Originating processor", HFILL }
2561 { &hf_tipc_dst_proc,
2562 { "Destination processor", "tipc.dst_proc",
2563 FT_STRING, BASE_NONE, NULL, 0x0,
2564 "TIPC Destination processor", HFILL }
2566 { &hf_tipc_unused2,
2567 { "Unused", "tipc.unused2",
2568 FT_UINT32, BASE_DEC, NULL, 0xe0000000,
2569 "TIPC Unused", HFILL }
2571 { &hf_tipc_importance,
2572 { "Importance", "tipc.importance",
2573 FT_UINT32, BASE_DEC, NULL, 0x18000000,
2574 "TIPC Importance", HFILL }
2576 { &hf_tipc_link_selector,
2577 { "Link selector", "tipc.link_selector",
2578 FT_UINT32, BASE_DEC, NULL, 0x07000000,
2579 "TIPC Link selector", HFILL }
2581 { &hf_tipc_msg_cnt,
2582 { "Message count", "tipc.imsg_cnt",
2583 FT_UINT32, BASE_DEC, NULL, 0x00ffff00,
2584 "TIPC Message count", HFILL }
2586 { &hf_tipc_probe,
2587 { "Probe", "tipc.probe",
2588 FT_UINT32, BASE_DEC, NULL, 0x00000040,
2589 "TIPC Probe", HFILL }
2591 { &hf_tipc_bearer_id,
2592 { "Bearer identity", "tipc.bearer_id",
2593 FT_UINT32, BASE_DEC, NULL, 0x00000038,
2594 "TIPC Bearer identity", HFILL }
2596 { &hf_tipc_link_selector2,
2597 { "Link selector", "tipc.link_selector",
2598 FT_UINT32, BASE_DEC, NULL, 0x00000007,
2599 "TIPC Link selector", HFILL }
2601 { &hf_tipc_remote_addr,
2602 { "Remote address", "tipc.remote_addr",
2603 FT_UINT32, BASE_DEC, NULL, 0x0,
2604 "TIPC Remote address", HFILL }
2606 { &hf_tipc_rm_msg_type,
2607 { "Message type", "tipc.rm_msg_type",
2608 FT_UINT32, BASE_DEC, VALS(tipc_routing_mgr_msg_type_values), 0xf0000000,
2609 "TIPC Message type", HFILL }
2611 { &hf_tipc_nd_msg_type,
2612 { "Message type", "tipc.nd_msg_type",
2613 FT_UINT32, BASE_DEC, VALS(tipc_name_dist_msg_type_values), 0xf0000000,
2614 "TIPC Message type", HFILL }
2616 { &hf_tipc_cm_msg_type,
2617 { "Message type", "tipc.nd_msg_type",
2618 FT_UINT32, BASE_DEC, VALS(tipc_cm_msg_type_values), 0xf0000000,
2619 "TIPC Message type", HFILL }
2621 { &hf_tipc_lp_msg_type,
2622 { "Message type", "tipc.lp_msg_type",
2623 FT_UINT32, BASE_DEC, VALS(tipc_link_prot_msg_type_values), 0xf0000000,
2624 "TIPC Message type", HFILL }
2626 { &hf_tipc_cng_prot_msg_type,
2627 { "Message type", "tipc.cng_prot_msg_type",
2628 FT_UINT32, BASE_DEC, VALS(tipc_cng_prot_msg_type_values), 0xf0000000,
2629 "TIPC Message type", HFILL }
2631 { &hf_tipc_sm_msg_type,
2632 { "Message type", "tipc.sm_msg_type",
2633 FT_UINT32, BASE_DEC, VALS(tipc_sm_msg_type_values), 0xf0000000,
2634 "TIPC Message type", HFILL }
2636 { &hf_tipc_unknown_msg_type,
2637 { "Message type", "tipc.unknown_msg_type",
2638 FT_UINT32, BASE_DEC, NULL, 0xf0000000,
2639 "TIPC Message type", HFILL }
2641 { &hf_tipc_seq_gap,
2642 { "Sequence gap", "tipc.seq_gap",
2643 FT_UINT32, BASE_DEC, NULL, 0x1fff0000,
2644 "TIPC Sequence gap", HFILL }
2646 { &hf_tipc_nxt_snt_pkg,
2647 { "Next sent packet", "tipc.nxt_snt_pkg",
2648 FT_UINT32, BASE_DEC, NULL, 0x0000ffff,
2649 "TIPC Next sent packet", HFILL }
2651 { &hf_tipc_unused_word,
2652 { "Word Unused", "tipc.unused_word",
2653 FT_NONE, BASE_NONE, NULL, 0x0,
2654 NULL, HFILL }
2656 { &hf_tipc_bearer_name,
2657 { "Bearer name", "tipc.bearer_name",
2658 FT_STRINGZ, BASE_NONE, NULL, 0x0,
2659 "TIPC Bearer name", HFILL }
2661 { &hf_tipc_data,
2662 { "Data", "tipc.data",
2663 FT_BYTES, BASE_NONE, NULL, 0x0,
2664 NULL, HFILL }
2666 { &hf_tipc_msg_no_bundle,
2667 { "Message no. in bundle", "tipc.msg_no_bundle",
2668 FT_UINT32, BASE_DEC, NULL, 0x0,
2669 NULL, HFILL }
2671 { &hf_tipc_changeover_protocol,
2672 { "TIPC_CHANGEOVER_PROTOCOL", "tipc.changeover_protocol",
2673 FT_UINT32, BASE_DEC, NULL, 0x0,
2674 NULL, HFILL }
2676 { &hf_tipc_name_dist_type,
2677 { "Published port name type", "tipc.name_dist_type",
2678 FT_UINT32, BASE_DEC, NULL, 0x0,
2679 "TIPC Published port name type", HFILL }
2681 { &hf_tipc_name_dist_lower,
2682 { "Lower bound of published sequence", "tipc.name_dist_lower",
2683 FT_UINT32, BASE_DEC, NULL, 0x0,
2684 "TIPC Lower bound of published sequence", HFILL }
2686 { &hf_tipc_name_dist_upper,
2687 { "Upper bound of published sequence", "tipc.name_dist_upper",
2688 FT_UINT32, BASE_DEC, NULL, 0x0,
2689 "TIPC Upper bound of published sequence", HFILL }
2691 { &hf_tipc_name_dist_port,
2692 { "Random number part of port identity", "tipc.dist_port",
2693 FT_UINT32, BASE_DEC, NULL, 0x0,
2694 "TIPC Random number part of port identity", HFILL }
2696 { &hf_tipc_name_dist_key,
2697 { "Key (Use for verification at withdrawal)", "tipc.dist_key",
2698 FT_UINT32, BASE_DEC, NULL, 0x0,
2699 "TIPC key", HFILL }
2701 { &hf_tipcv2_srcdrop,
2702 { "Source Droppable", "tipc.srcdrop",
2703 FT_UINT32, BASE_DEC, NULL, 0x00040000,
2704 "Destination Droppable Bit", HFILL }
2706 { &hf_tipcv2_syn,
2707 { "Connection request (SYN)", "tipc.syn",
2708 FT_UINT32, BASE_DEC, NULL, 0x00020000,
2709 "Destination Droppable Bit", HFILL }
2711 { &hf_tipcv2_data_msg_type,
2712 { "Message type", "tipc.data_type",
2713 FT_UINT32, BASE_DEC, VALS(tipc_data_msg_type_values), 0xe0000000,
2714 "TIPC Message type", HFILL }
2716 { &hf_tipcv2_bcast_mtype,
2717 { "Message type", "tipcv2.bcast_msg_type",
2718 FT_UINT32, BASE_DEC, VALS(tipcv2_bcast_mtype_strings), 0xe0000000,
2719 "TIPC Message type", HFILL }
2721 { &hf_tipcv2_bundler_mtype,
2722 { "Message type", "tipcv2.bundler_msg_type",
2723 FT_UINT32, BASE_DEC, VALS(tipcv2_bundler_mtype_strings), 0xe0000000,
2724 "TIPC Message type", HFILL }
2726 { &hf_tipcv2_link_mtype,
2727 { "Message type", "tipcv2.link_msg_type",
2728 FT_UINT32, BASE_DEC, VALS(tipcv2_link_mtype_strings), 0xe0000000,
2729 "TIPC Message type", HFILL }
2731 { &hf_tipcv2_connmgr_mtype,
2732 { "Message type", "tipcv2.connmgr_msg_type",
2733 FT_UINT32, BASE_DEC, VALS(tipcv2_connmgr_mtype_strings), 0xe0000000,
2734 "TIPC Message type", HFILL }
2736 { &hf_tipcv2_route_mtype_1_6,
2737 { "Message type", "tipcv2.route_msg_type",
2738 FT_UINT32, BASE_DEC, VALS(tipcv2_route_mtype_strings_1_6), 0xe0000000,
2739 "TIPC Message type", HFILL }
2741 { &hf_tipcv2_route_mtype_1_7,
2742 { "Message type", "tipcv2.route_msg_type",
2743 FT_UINT32, BASE_DEC, VALS(tipcv2_route_mtype_strings_1_7), 0xe0000000,
2744 "TIPC Message type", HFILL }
2746 { &hf_tipcv2_changeover_mtype,
2747 { "Message type", "tipcv2.changeover_msg_type",
2748 FT_UINT32, BASE_DEC, VALS(tipcv2_changeover_mtype_strings), 0xe0000000,
2749 "TIPC Message type", HFILL }
2751 { &hf_tipcv2_naming_mtype,
2752 { "Message type", "tipcv2.naming_msg_type",
2753 FT_UINT32, BASE_DEC, VALS(tipcv2_naming_mtype_strings), 0xe0000000,
2754 "TIPC Message type", HFILL }
2756 { &hf_tipcv2_fragmenter_mtype,
2757 { "Message type", "tipcv2.fragmenter_msg_type",
2758 FT_UINT32, BASE_DEC, VALS(tipcv2_fragmenter_mtype_strings), 0xe0000000,
2759 "TIPC Message type", HFILL }
2761 { &hf_tipcv2_neighbour_mtype,
2762 { "Message type", "tipcv2.data_msg_type",
2763 FT_UINT32, BASE_DEC, VALS(tipcv2_neighbour_mtype_strings), 0xe0000000,
2764 "TIPC Message type", HFILL }
2766 { &hf_tipcv2_errorcode,
2767 { "Error code", "tipcv2.errorcode",
2768 FT_UINT32, BASE_DEC, VALS(tipcv2_error_code_strings), 0x1e000000,
2769 NULL, HFILL }
2771 { &hf_tipcv2_rer_cnt,
2772 { "Reroute Counter", "tipcv2.rer_cnt",
2773 FT_UINT32, BASE_DEC, NULL, 0x01e00000,
2774 NULL, HFILL }
2776 { &hf_tipcv2_lookup_scope,
2777 { "Lookup Scope", "tipcv2.lookup_scope",
2778 FT_UINT32, BASE_DEC, VALS(tipcv2_lookup_scope_strings), 0x00180000,
2779 NULL, HFILL }
2781 { &hf_tipcv2_opt_p,
2782 { "Options Position", "tipcv2.opt_p",
2783 FT_UINT32, BASE_DEC, NULL, 0x00070000,
2784 NULL, HFILL }
2786 { &hf_tipcv2_broadcast_ack_no,
2787 { "Broadcast Acknowledge Number", "tipcv2.broadcast_ack_no",
2788 FT_UINT32, BASE_DEC, NULL, 0x0000FFFF,
2789 NULL, HFILL }
2791 { &hf_tipcv2_link_level_ack_no,
2792 { "Link Level Acknowledge Number", "tipcv2.link_level_ack_no",
2793 FT_UINT32, BASE_DEC, NULL, 0xFFFF0000,
2794 NULL, HFILL }
2796 { &hf_tipcv2_link_level_seq_no,
2797 { "Link Level Sequence Number", "tipcv2.link_level_seq_no",
2798 FT_UINT32, BASE_DEC, NULL, 0x0000FFFF,
2799 NULL, HFILL }
2801 #if 0
2802 { &hf_tipcv2_bcast_seq_no,
2803 { "Broadcast Sequence Number", "tipcv2.bcast_seq_no",
2804 FT_UINT32, BASE_DEC, NULL, 0x0000FFFF,
2805 NULL, HFILL }
2807 #endif
2808 { &hf_tipcv2_prev_node,
2809 { "Previous Node", "tipcv2.prev_node",
2810 FT_STRING, BASE_NONE, NULL, 0x0,
2811 "TIPC Previous Node", HFILL }
2813 { &hf_tipcv2_orig_node,
2814 { "Originating Node", "tipcv2.orig_node",
2815 FT_STRING, BASE_NONE, NULL, 0x0,
2816 "TIPC Originating Node", HFILL }
2818 { &hf_tipcv2_dest_node,
2819 { "Destination Node", "tipcv2.dest_node",
2820 FT_STRING, BASE_NONE, NULL, 0x0,
2821 "TIPC Destination Node", HFILL }
2823 { &hf_tipcv2_port_name_type,
2824 { "Port name type", "tipcv2.port_name_type",
2825 FT_UINT32, BASE_DEC, NULL, 0x0,
2826 NULL, HFILL }
2828 { &hf_tipcv2_port_name_instance,
2829 { "Port name instance", "tipcv2.port_name_instance",
2830 FT_UINT32, BASE_DEC, NULL, 0x0,
2831 NULL, HFILL }
2833 { &hf_tipcv2_multicast_lower,
2834 { "Multicast lower bound", "tipcv2.multicast_lower",
2835 FT_UINT32, BASE_DEC, NULL, 0x0,
2836 "Multicast port name instance lower bound", HFILL }
2838 { &hf_tipcv2_multicast_upper,
2839 { "Multicast upper bound", "tipcv2.multicast_upper",
2840 FT_UINT32, BASE_DEC, NULL, 0x0,
2841 "Multicast port name instance upper bound", HFILL }
2843 { &hf_tipcv2_sequence_gap,
2844 { "Sequence Gap", "tipcv2.seq_gap",
2845 FT_UINT32, BASE_DEC, NULL, 0x1FFF0000,
2846 NULL, HFILL }
2848 { &hf_tipcv2_next_sent_broadcast,
2849 { "Next Sent Broadcast", "tipcv2.next_sent_broadcast",
2850 FT_UINT32, BASE_DEC, NULL, 0xFFFF0000,
2851 NULL, HFILL }
2853 { &hf_tipcv2_fragment_number,
2854 { "Fragment Number", "tipcv2.fragment_number",
2855 FT_UINT32, BASE_DEC, NULL, 0xFFFF0000,
2856 NULL, HFILL }
2858 { &hf_tipcv2_fragment_msg_number,
2859 { "Fragment Message Number", "tipcv2.fragment_msg_number",
2860 FT_UINT32, BASE_DEC, NULL, 0x0000FFFF,
2861 NULL, HFILL }
2863 { &hf_tipcv2_next_sent_packet,
2864 { "Next Sent Packet", "tipcv2.next_sent_packet",
2865 FT_UINT32, BASE_DEC, NULL, 0x0000FFFF,
2866 NULL, HFILL }
2868 { &hf_tipcv2_session_no,
2869 { "Session Number", "tipcv2.session_no",
2870 FT_UINT32, BASE_DEC, NULL, 0xFFFF0000,
2871 NULL, HFILL }
2873 { &hf_tipcv2_link_prio,
2874 { "Link Priority", "tipcv2.link_prio",
2875 FT_UINT32, BASE_DEC, NULL, 0x000001F0,
2876 NULL, HFILL }
2878 { &hf_tipcv2_network_plane,
2879 { "Network Plane", "tipcv2.network_plane",
2880 FT_UINT32, BASE_DEC, VALS(tipcv2_networkplane_strings), 0x0000000E,
2881 NULL, HFILL }
2883 { &hf_tipcv2_probe,
2884 { "Probe", "tipcv2.probe",
2885 FT_UINT32, BASE_DEC, NULL, 0x00000001,
2886 NULL, HFILL }
2888 { &hf_tipcv2_link_tolerance,
2889 { "Link Tolerance (ms)", "tipcv2.link_tolerance",
2890 FT_UINT32, BASE_DEC, NULL, 0x0000FFFF,
2891 "Link Tolerance in ms", HFILL }
2893 { &hf_tipcv2_bearer_instance,
2894 { "Bearer Instance", "tipcv2.bearer_instance",
2895 FT_STRINGZ, BASE_NONE, NULL, 0,
2896 "Bearer instance used by the sender node for this link", HFILL }
2898 { &hf_tipcv2_padding,
2899 { "Padding", "tipcv2.padding",
2900 FT_BYTES, BASE_NONE, NULL, 0,
2901 NULL, HFILL }
2903 { &hf_tipcv2_bearer_level_orig_addr,
2904 { "Bearer Level Originating Address", "tipcv2.bearer_level_orig_addr",
2905 FT_BYTES, BASE_NONE, NULL, 0,
2906 NULL, HFILL }
2908 { &hf_tipcv2_cluster_address,
2909 { "Cluster Address", "tipcv2.cluster_address",
2910 FT_STRING, BASE_NONE, NULL, 0x0,
2911 "The remote cluster concerned by the table", HFILL }
2913 { &hf_tipcv2_bitmap,
2914 { "Bitmap", "tipcv2.bitmap",
2915 FT_BYTES, BASE_NONE, NULL, 0,
2916 "Bitmap, indicating to which nodes within that cluster the sending node has direct links", HFILL }
2918 { &hf_tipcv2_node_address,
2919 { "Node Address", "tipcv2.node_address",
2920 FT_STRING, BASE_NONE, NULL, 0x0,
2921 "Which node the route addition/loss concern", HFILL }
2923 { &hf_tipcv2_destination_domain,
2924 { "Destination Domain", "tipcv2.destination_domain",
2925 FT_STRING, BASE_NONE, NULL, 0x0,
2926 "The domain to which the link request is directed", HFILL }
2928 { &hf_tipcv2_network_id,
2929 { "Network Identity", "tipcv2.network_id",
2930 FT_UINT32, BASE_DEC, NULL, 0x0,
2931 "The sender node's network identity", HFILL }
2933 { &hf_tipcv2_bcast_tag,
2934 { "Broadcast Tag", "tipcv2.bcast_tag",
2935 FT_UINT32, BASE_DEC, NULL, 0xFFFF0000,
2936 NULL, HFILL }
2938 { &hf_tipcv2_msg_count,
2939 { "Message Count", "tipcv2.msg_count",
2940 FT_UINT32, BASE_DEC, NULL, 0xFFFF0000,
2941 NULL, HFILL }
2943 { &hf_tipcv2_max_packet,
2944 { "Max Packet", "tipcv2.max_packet",
2945 FT_UINT32, BASE_DEC, NULL, 0xFFFF0000,
2946 NULL, HFILL }
2948 { &hf_tipcv2_transport_seq_no,
2949 { "Transport Sequence No", "tipcv2.tseq_no",
2950 FT_UINT32, BASE_DEC, NULL, 0x0,
2951 "Transport Level Sequence Number", HFILL }
2953 { &hf_tipcv2_redundant_link,
2954 { "Redundant Link", "tipcv2.redundant_link",
2955 FT_UINT32, BASE_DEC, NULL, 0x00001000,
2956 NULL, HFILL }
2958 { &hf_tipcv2_bearer_id,
2959 { "Bearer identity", "tipcv2.bearer_id",
2960 FT_UINT32, BASE_DEC, NULL, 0x00000e00,
2961 NULL, HFILL }
2963 { &hf_tipcv2_conn_mgr_msg_ack, /* special CONN_MANAGER payload */
2964 { "Number of Messages Acknowledged", "tipcv2.conn_mgr_msg_ack",
2965 FT_UINT32, BASE_DEC, NULL, 0xffff0000,
2966 NULL, HFILL }
2968 { &hf_tipcv2_minor_pv,
2969 { "Minor protocol version", "tipcv2.minor_pv",
2970 FT_UINT32, BASE_DEC, NULL, 0x00ff0000,
2971 NULL, HFILL }
2973 { &hf_tipcv2_node_sig,
2974 { "Node signature", "tipcv2.node_sig",
2975 FT_UINT32, BASE_DEC, NULL, 0x0000FFFF,
2976 NULL, HFILL }
2978 { &hf_tipcv2_filler_mtu_discovery,
2979 { "Filler for MTU discovery", "tipcv2.filler_mtu_discovery",
2980 FT_BYTES, BASE_NONE, NULL, 0,
2981 NULL, HFILL }
2983 { &hf_tipcv2_vendor_specific_data,
2984 { "Vendor specific data", "tipcv2.vendor_specific_data",
2985 FT_BYTES, BASE_NONE, NULL, 0,
2986 NULL, HFILL }
2988 { &hf_tipcv2_options,
2989 { "Options", "tipcv2.options",
2990 FT_BYTES, BASE_NONE, NULL, 0,
2991 NULL, HFILL }
2993 { &hf_tipc_named_msg_hdr,
2994 { "TIPC_NAMED_MSG Hdr", "tipc.named_msg_hdr",
2995 FT_BYTES, BASE_NONE, NULL, 0,
2996 NULL, HFILL }
2998 { &hf_tipc_port_name_type,
2999 { "Port name type / Connection level sequence number", "tipc.port_name_type",
3000 FT_UINT32, BASE_DEC, NULL, 0x0,
3001 NULL, HFILL }
3003 { &hf_tipc_port_name_instance,
3004 { "Port name instance", "tipc.port_name_instance",
3005 FT_UINT32, BASE_DEC, NULL, 0x0,
3006 NULL, HFILL }
3008 { &hf_tipc_data_fragment,
3009 { "Data fragment", "tipc.data_fragment",
3010 FT_BYTES, BASE_NONE, NULL, 0,
3011 NULL, HFILL }
3013 { &hf_tipc_message_bundle,
3014 { "Message Bundle", "tipc.message_bundle",
3015 FT_NONE, BASE_NONE, NULL, 0,
3016 NULL, HFILL }
3018 { &hf_tipcv2_timestamp,
3019 { "Timestamp", "tipcv2.timestamp",
3020 FT_UINT32, BASE_DEC, NULL, 0x0,
3021 "OS-dependent Timestamp", HFILL }
3023 { &hf_tipcv2_item_size,
3024 { "Item Size", "tipcv2.item_size",
3025 FT_UINT32, BASE_DEC, NULL, 0xFF000000,
3026 NULL, HFILL }
3028 { &hf_tipcv2_network_region,
3029 { "Network Region", "tipcv2.network_region",
3030 FT_STRING, BASE_NONE, NULL, 0x0,
3031 NULL, HFILL }
3033 { &hf_tipcv2_local_router,
3034 { "Local Router", "tipcv2.local_router",
3035 FT_STRING, BASE_NONE, NULL, 0x0,
3036 NULL, HFILL }
3038 { &hf_tipcv2_remote_router,
3039 { "Remote Router", "tipcv2.remote_router",
3040 FT_STRING, BASE_NONE, NULL, 0x0,
3041 NULL, HFILL }
3043 { &hf_tipcv2_dist_dist,
3044 { "Route Distributor Dist", "tipcv2.dist_dist",
3045 FT_UINT32, BASE_DEC, VALS(tipcv2_dist_dist_strings), 0x000000f0,
3046 NULL, HFILL }
3048 { &hf_tipcv2_dist_scope,
3049 { "Route Distributor Scope", "tipcv2.dist_scope",
3050 FT_UINT32, BASE_DEC, VALS(tipcv2_dist_scope_strings), 0x0000000f,
3051 NULL, HFILL }
3053 { &hf_tipcv2_name_dist_port_id_node,
3054 { "Port Id Node", "tipcv2.port_id_node",
3055 FT_STRING, BASE_NONE, NULL, 0x0,
3056 NULL, HFILL }
3058 { &hf_tipcv2_media_id,
3059 { "Media Id", "tipcv2.media_id",
3060 FT_UINT32, BASE_DEC, NULL, 0x000000ff,
3061 NULL, HFILL }
3065 /* Setup protocol subtree array */
3066 static int *ett[] = {
3067 &ett_tipc,
3068 &ett_tipc_data,
3069 &ett_tipc_msg_fragment,
3070 &ett_tipc_msg_fragments
3073 static ei_register_info ei[] = {
3074 { &ei_tipc_field_not_specified, { "tipc.field_not_specified", PI_PROTOCOL, PI_WARN, "This field is not specified in TIPC v7", EXPFILL }},
3075 { &ei_tipc_invalid_bundle_size, { "tipc.invalid_bundle_size", PI_PROTOCOL, PI_WARN, "Invalid message bundle size", EXPFILL }},
3076 { &ei_tipc_max_recursion_depth_reached, { "tipc.max_recursion_depth_reached", PI_PROTOCOL, PI_WARN, "Maximum allowed recursion depth reached. Dissection stopped.", EXPFILL }},
3079 module_t *tipc_module;
3080 expert_module_t* expert_tipc;
3082 /* options for the enum in the protocol preferences */
3083 static const enum_val_t handle_v2_as_options[] = {
3084 { "all", "ALL", V2_AS_ALL },
3085 { "1.5_1.6", "TIPC 1.5/1.6", V2_AS_1_6 },
3086 { "1.7", "TIPC 1.7", V2_AS_1_7 },
3087 { NULL, NULL, 0 }
3090 /* Register the protocol name and description */
3091 proto_tipc = proto_register_protocol("Transparent Inter Process Communication(TIPC)", "TIPC", "tipc");
3093 /* Required function calls to register the header fields and subtrees used */
3094 proto_register_field_array(proto_tipc, hf, array_length(hf));
3095 proto_register_subtree_array(ett, array_length(ett));
3096 expert_tipc = expert_register_protocol(proto_tipc);
3097 expert_register_field_array(expert_tipc, ei, array_length(ei));
3099 /* allow other protocols to be called according to specific values in order to
3100 * dissect the protocols sent by TIPC */
3102 /* this allows e.g. to dissect everything which is TIPC Data */
3103 tipc_user_dissector = register_dissector_table("tipc.usr",
3104 "TIPC user", proto_tipc, FT_UINT8, BASE_DEC);
3105 /* this allows to dissect everything which is TIPC Data and uses a specific
3106 * port name type it actually does not really work because the type is not
3107 * necessarily set in every data message */
3108 tipc_type_dissector = register_dissector_table("tipcv2.port_name_type",
3109 "TIPC port name type", proto_tipc, FT_UINT32, BASE_DEC);
3111 /* make heuristic dissectors possible */
3112 tipc_heur_subdissector_list = register_heur_dissector_list_with_description("tipc", "TIPC v2 data", proto_tipc);
3114 /* Register by name */
3115 tipc_handle = register_dissector("tipc", dissect_tipc, proto_tipc);
3116 tipc_tcp_handle = register_dissector("tipc.tcp", dissect_tipc_tcp, proto_tipc);
3118 reassembly_table_register(&tipc_msg_reassembly_table,
3119 &addresses_reassembly_table_functions);
3121 /* Register configuration options */
3122 tipc_module = prefs_register_protocol(proto_tipc, NULL);
3124 tipc_address_type = address_type_dissector_register("AT_TIPC", "TIPC Address Zone,Subnetwork,Processor",
3125 tipc_addr_to_str_buf, tipc_addr_str_len, NULL, NULL, NULL, NULL, NULL);
3127 prefs_register_bool_preference(tipc_module, "defragment",
3128 "Reassemble TIPCv1 SEGMENTATION_MANAGER datagrams",
3129 "Whether TIPCv1 SEGMENTATION_MANAGER datagrams should be reassembled",
3130 &tipc_defragment);
3132 prefs_register_bool_preference(tipc_module, "dissect_tipc_data",
3133 "Dissect TIPC data",
3134 "Whether to try to dissect TIPC data or not",
3135 &dissect_tipc_data);
3137 prefs_register_bool_preference(tipc_module, "try_heuristic_first",
3138 "Try heuristic sub-dissectors first",
3139 "Try to decode a TIPCv2 packet using an heuristic sub-dissector before using a registered sub-dissector",
3140 &try_heuristic_first);
3142 prefs_register_enum_preference(tipc_module, "handle_v2_as",
3143 "Handle version 2 as",
3144 "TIPC 1.7 removes/adds fields (not) available in TIPC 1.5/1.6 while keeping the version number 2 in the packages. \"ALL\" shows all fields that were ever used in both versions.",
3145 &handle_v2_as,
3146 handle_v2_as_options,
3147 true);
3149 prefs_register_bool_preference(tipc_module, "desegment",
3150 "Reassemble TIPC-over-TCP messages spanning multiple TCP segments",
3151 "Whether the TIPC-over-TCP dissector should reassemble messages spanning multiple TCP segments. "
3152 "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
3153 &tipc_tcp_desegment);
3156 void
3157 proto_reg_handoff_tipc(void)
3159 dissector_add_uint("ethertype", ETHERTYPE_TIPC, tipc_handle);
3160 dissector_add_for_decode_as_with_preference("tcp.port", tipc_tcp_handle);
3161 dissector_add_uint_range_with_preference("udp.port", DEFAULT_TIPC_PORT_RANGE, tipc_handle);
3165 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3167 * Local variables:
3168 * c-basic-offset: 8
3169 * tab-width: 8
3170 * indent-tabs-mode: t
3171 * End:
3173 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3174 * :indentSize=8:tabSize=8:noTabs=false: