epan/dissectors/pidl/ C99 drsuapi
[wireshark-sm.git] / epan / dissectors / packet-dec-dnart.c
blob186c92c33de7153a332b58bae957762a0dbf41c9
1 /* packet-dec-dnart.c
3 * Routines for DECnet NSP/RT disassembly
5 * Copyright 2003-2005 Philips Medical Systems
6 * Copyright 2003-2005 Fred Hoekstra, Philips Medical Systems.
7 * (fred.hoekstra@philips.com)
9 * Use was made of the following documentation:
11 * DECnet DIGITAL Network Architecture
12 * Routing Layer Functional Specification
13 * Version 2.0.0 May, 1983
15 * DECnet DIGITAL Network Architecture
16 * NSP Functional Specification
17 * Phase IV, Version 4.0.1, July 1984
19 * DNA FS SESSION CONTROL
20 * SECON.RNO [31,1]
21 * EDITED 10/17/80
23 * See
25 * http://h71000.www7.hp.com/wizard/decnet/
27 * for some DECnet specifications.
29 * Wireshark - Network traffic analyzer
30 * By Gerald Combs <gerald@wireshark.org>
31 * Copyright 1998 Gerald Combs
33 * SPDX-License-Identifier: GPL-2.0-or-later
36 #include "config.h"
38 #include <epan/packet.h>
39 #include <epan/etypes.h>
40 #include <epan/expert.h>
41 #include <epan/ppptypes.h>
42 #include <epan/tfs.h>
44 typedef enum {
45 RT_CTL_INITIALIZATION,
46 RT_CTL_VERIFICATION,
47 RT_CTL_HELLO_TEST,
48 RT_CTL_LVL1_ROUTING,
49 RT_CTL_LVL2_ROUTING,
50 RT_CTL_ETH_ROUTER_HELLO_MSG,
51 RT_CTL_ETH_ENDNODE_HELLO_MSG
52 } ctl_msg_types;
54 #define DEC_RT_SIZE 27
56 #define DATA_SEGMENT_MSG 0x00 /* "Data segment" */
57 #define LINK_SERVICE_MSG 0x10 /* "Link service message" */
58 #define BOM_MSG 0x20 /* "Beginning of segment (BOM)message" */
59 #define EOM_MSG 0x40 /* "End of segment (EOM)message" */
60 #define BOM_EOM_MSG 0x60 /* "BOM / EOM message" */
61 #define INTERRUPT_MSG 0x30 /* "Interrupt message" */
62 #define DATA_ACK_MSG 0x04 /* "Data acknowledgement message" */
63 #define OTHER_DATA_ACK_MSG 0x14 /* "Other data acknowledgement message" */
64 #define CONN_ACK_MSG 0x24 /* "Connect acknowledgement message" */
65 #define NOP_MSG 0x08 /* "NOP" */
66 #define CONN_INITIATE_MSG 0x18 /* "Connect initiate" */
67 #define CONN_CONFIRM_MSG 0x28 /* "Connect confirm" */
68 #define DISCONN_INITIATE_MSG 0x38 /* "Disconnect initiate" */
69 #define DISCONN_CONFIRM_MSG 0x48 /* "Disconnect confirm" */
70 #define RE_XMT_CONN_INIT_MSG 0x68 /* "Retransmitted connect initiate" */
72 /* Flag bits */
74 #define RT_FLAGS_CTRL_MSG 0x01
75 #define RT_FLAGS_LONG_MSG 0x04 /* Actually: 0x06->long, 0x02->short*/
76 #define RT_FLAGS_RQR 0x08
77 #define RT_FLAGS_RTS 0x10
78 #define RT_FLAGS_INTRA_ETHER 0x20
79 #define RT_FLAGS_DISCARD 0x40
80 #define RT_FLAGS_PAD 0x80
82 void proto_register_dec_rt(void);
83 void proto_reg_handoff_dec_rt(void);
85 static dissector_handle_t dec_rt_handle;
87 static int proto_dec_rt;
89 static int hf_dec_routing_flags;
90 static int hf_dec_rt_ctrl_msg;
91 static int hf_dec_rt_long_msg;
92 static int hf_dec_rt_short_msg;
93 static int hf_dec_rt_rqr;
94 static int hf_dec_rt_rts;
95 static int hf_dec_rt_inter_eth;
96 static int hf_dec_rt_discard;
97 static int hf_dec_rt_dst_addr;
98 static int hf_dec_rt_src_addr;
99 static int hf_dec_rt_nl2;
100 static int hf_dec_rt_service_class;
101 static int hf_dec_rt_protocol_type;
102 static int hf_dec_rt_visit_count;
103 static int hf_dec_rt_dst_node;
104 static int hf_dec_rt_src_node;
105 /* Routing control messages */
106 static int hf_dec_rt_visited_nodes;
107 static int hf_dec_ctl_msgs;
108 static int hf_dec_ctl_msg_hdr;
109 static int hf_dec_nsp_msgs;
110 static int hf_dec_rt_tiinfo;
111 static int hf_dec_rt_blk_size;
112 static int hf_dec_rt_version;
113 static int hf_dec_rt_timer;
114 static int hf_dec_rt_reserved;
115 static int hf_dec_rt_fcnval;
116 static int hf_dec_rt_test_data;
117 static int hf_dec_rt_segment;
118 static int hf_dec_rt_checksum;
119 static int hf_dec_rt_checksum_status;
120 static int hf_dec_rt_id;
121 static int hf_dec_rt_iinfo;
122 static int hf_dec_rt_iinfo_node_type;
123 static int hf_dec_rt_iinfo_vrf;
124 static int hf_dec_rt_iinfo_rej;
125 static int hf_dec_rt_iinfo_verf;
126 static int hf_dec_rt_iinfo_mta;
127 static int hf_dec_rt_iinfo_blkreq;
128 static int hf_dec_rt_iprio;
129 static int hf_dec_rt_neighbor;
130 static int hf_dec_rt_seed;
131 static int hf_dec_rt_elist;
132 static int hf_dec_rt_ename;
133 static int hf_dec_rt_router_id;
134 static int hf_dec_rt_router_state;
135 static int hf_dec_rt_router_prio;
136 static int hf_dec_rt_seg_size;
137 static int hf_dec_rt_acknum;
138 static int hf_dec_rt_segnum;
139 static int hf_dec_rt_delay;
140 static int hf_dec_flow_control;
141 static int hf_dec_rt_fc_val;
142 static int hf_dec_rt_services;
143 static int hf_dec_rt_info;
144 static int hf_dec_disc_reason;
145 static int hf_dec_conn_contents;
146 static int hf_dec_sess_obj_type;
147 static int hf_dec_sess_grp_code;
148 static int hf_dec_sess_usr_code;
149 static int hf_dec_sess_dst_name;
150 static int hf_dec_sess_src_name;
151 static int hf_dec_sess_menu_ver;
152 static int hf_dec_sess_rqstr_id;
154 static int ett_dec_rt;
155 static int ett_dec_routing_flags;
156 static int ett_dec_msg_flags;
157 static int ett_dec_rt_ctl_msg;
158 static int ett_dec_rt_nsp_msg;
159 static int ett_dec_rt_info_flags;
160 static int ett_dec_rt_list;
161 static int ett_dec_rt_rlist;
162 static int ett_dec_rt_state;
163 static int ett_dec_flow_control;
164 static int ett_dec_sess_contents;
166 static expert_field ei_dec_rt_checksum;
168 static int dec_dna_total_bytes_this_segment;
169 static int dec_dna_previous_total;
171 static const value_string rt_msg_type_vals[] = {
172 { 0x0 , "Initialization message" },
173 { 0x1 , "Verification message" },
174 { 0x2 , "Hello and test message" },
175 { 0x3 , "Level 1 routing message" },
176 { 0x4 , "Level 2 routing message" },
177 { 0x5 , "Ethernet router hello message" },
178 { 0x6 , "Ethernet endnode hello message" },
179 { 0, NULL }
182 static const value_string nsp_msg_type_vals[] = {
183 { 0x00 , "Data segment continuation" },
184 { 0x04 , "Data acknowledgement message" },
185 { 0x08 , "NOP" },
186 { 0x10 , "Link service message" },
187 { 0x14 , "Other data acknowledgement message" },
188 { 0x18 , "Connect initiate" },
189 { 0x20 , "Beginning of segment message" },
190 { 0x24 , "Connect acknowledgement message" },
191 { 0x28 , "Connect confirm" },
192 { 0x30 , "Interrupt message" },
193 { 0x38 , "Disconnect initiate" },
194 { 0x40 , "End of segment message" },
195 { 0x48 , "Disconnect confirm" },
196 { 0x60 , "Begin of segment / End of segment" },
197 { 0x68 , "Retransmitted connect initiate" },
198 { 0, NULL }
201 static const value_string rt_tiinfo_vals[] = {
202 {0x01, "Level 2 router"},
203 {0x02, "Level 1 router"},
204 {0x03, "End node"},
205 {0x04, "Routing layer verification required"},
206 {0x08, "Blocking requested"},
207 {0x0, NULL}
210 static const value_string rt_iinfo_node_type_vals[] = {
211 {0x01, "Level 2 router"},
212 {0x02, "Level 1 router"},
213 {0x03, "End node"},
214 {0x0, NULL}
217 static const value_string rt_flow_control_vals[] = {
218 {0x00, "no change"},
219 {0x01, "do not send data"},
220 {0x02, "send data"},
221 {0x03, "reserved"},
222 {0x0, NULL}
225 static const value_string rt_services_vals[] = {
226 {0x00, "none"},
227 {0x01, "segment request count"},
228 {0x02, "Session control message request count"},
229 {0x03, "reserved"},
230 {0x0, NULL}
233 static const value_string rt_info_version_vals[] = {
234 {0x00, "version 3.2"},
235 {0x01, "version 3.1"},
236 {0x02, "version 4.0"},
237 {0x03, "reserved"},
238 {0x0, NULL}
241 static const value_string rt_disc_reason_vals[] = {
242 { 0, "no error"},
243 { 3, "The node is shutting down"},
244 { 4, "The destination end user does not exist"},
245 { 5, "A connect message contains an invalid end user name"},
246 { 6, "Destination end user has insufficient resources"},
247 { 7, "Unspecified error"},
248 { 8, "A third party has disconnected the link"},
249 { 9, "An end user has aborted the logical link"},
250 { 32, "The node has insufficient resources"},
251 { 33, "Destination end user has insufficient resources"},
252 { 34, "Connect request rejected because incorrect RQSTRID or PASSWORD"},
253 { 36, "Connect request rejected because of unacceptable ACCOUNT info"},
254 { 38, "End user has timed out, aborted or cancelled a connect request"},
255 { 43, "Connect request RQSTRID, PASSWORD, ACCOUNT or USRDATA too long"},
256 { 0, NULL}
259 #define RT_TYPE_TOPOLOGY_CHANGE 2
260 #define RT_TYPE_HELLO 25
262 #if ! defined true
263 #define true 1
264 #endif
265 #if ! defined false
266 #define false 0
267 #endif
269 static int
270 handle_nsp_msg(
271 tvbuff_t *tvb,
272 packet_info *pinfo,
273 proto_tree *tree,
274 unsigned offset,
275 uint8_t nsp_msg_type);
278 static int
279 do_initialization_msg(
280 tvbuff_t *tvb,
281 packet_info *pinfo,
282 proto_tree *ctl_msg_tree,
283 unsigned offset);
285 static int
286 do_verification_msg(
287 tvbuff_t *tvb,
288 packet_info *pinfo,
289 proto_tree *ctl_msg_tree,
290 unsigned offset);
292 static int
293 do_hello_test_msg(
294 tvbuff_t *tvb,
295 packet_info *pinfo,
296 proto_tree *ctl_msg_tree,
297 unsigned offset);
299 static int
300 do_routing_msg(
301 tvbuff_t *tvb,
302 packet_info *pinfo,
303 proto_tree *ctl_msg_tree,
304 unsigned offset,
305 unsigned msg);
307 static int
308 do_hello_msg(
309 tvbuff_t *tvb,
310 packet_info *pinfo,
311 proto_tree *ctl_msg_tree,
312 unsigned offset,
313 unsigned msg);
315 static int
316 handle_connect_contents(
317 tvbuff_t *tvb,
318 proto_tree *tree,
319 unsigned offset);
321 static int
322 handle_disc_init_contents(
323 unsigned offset);
325 static char *
326 dnet_ntoa(wmem_allocator_t *pool, const uint8_t *data)
328 if (data[0] == 0xAA && data[1] == 0x00 && data[2] == 0x04 && data[3] == 0x00) {
329 uint16_t dnet_addr = data[4] | (data[5] << 8);
330 return wmem_strdup_printf(pool, "%d.%d", dnet_addr >> 10, dnet_addr & 0x03FF);
332 return NULL;
335 static void
336 set_dnet_address(packet_info *pinfo, address *paddr_src, address *paddr_tgt)
338 if (paddr_tgt->type != AT_STRINGZ && paddr_src->type == AT_ETHER) {
339 char *addr = dnet_ntoa(pinfo->pool, (const uint8_t *)paddr_src->data);
340 if (addr != NULL)
341 set_address(paddr_tgt, AT_STRINGZ, 1,
342 wmem_strdup(pinfo->pool, addr));
346 static int
347 dissect_dec_rt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
349 uint8_t padding_length;
350 uint8_t forward;
351 uint8_t msg_flags;
352 unsigned rt_visit_count, rt_zero = 0;
353 int offset;
354 proto_tree *rt_tree;
355 proto_tree *flags_tree;
356 proto_item *ti;
357 char *addr;
359 offset = 0;
360 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DEC DNA");
361 col_clear(pinfo->cinfo, COL_INFO);
363 set_dnet_address(pinfo, &pinfo->dl_src, &pinfo->net_src);
364 set_dnet_address(pinfo, &pinfo->dl_src, &pinfo->src);
365 set_dnet_address(pinfo, &pinfo->dl_dst, &pinfo->net_dst);
366 set_dnet_address(pinfo, &pinfo->dl_dst, &pinfo->dst);
368 offset += 2;
369 msg_flags = tvb_get_uint8(tvb, offset);
370 ti = proto_tree_add_item(tree, proto_dec_rt, tvb, 0, -1, ENC_NA);
371 rt_tree = proto_item_add_subtree(ti, ett_dec_rt);
372 /* When padding, the first byte after the padding has
373 the real routing flags */
374 if (msg_flags & 0x80) {
375 /* There is padding present, skip it */
376 padding_length = msg_flags & 0x7f;
377 offset += padding_length;
380 /* The real routing flag */
381 msg_flags = tvb_get_uint8(tvb, offset);
382 ti = proto_tree_add_uint(rt_tree, hf_dec_routing_flags, tvb,
383 offset, 1, msg_flags);
384 flags_tree = proto_item_add_subtree(ti, ett_dec_routing_flags);
386 if (msg_flags & RT_FLAGS_CTRL_MSG) {
387 uint8_t ctl_msg_type;
388 proto_tree *ctl_msg_tree;
390 ctl_msg_type = (msg_flags >> 1) & 0x7;
391 proto_tree_add_boolean(flags_tree, hf_dec_rt_ctrl_msg, tvb, offset, 1,
392 msg_flags);
393 proto_tree_add_uint(flags_tree, hf_dec_ctl_msgs, tvb, offset, 1,
394 msg_flags);
396 ti = proto_tree_add_uint(rt_tree, hf_dec_ctl_msg_hdr, tvb, offset, 1,
397 ctl_msg_type);
398 ctl_msg_tree = proto_item_add_subtree(ti, ett_dec_rt_ctl_msg);
400 /* Get past the msg_flags */
401 offset++;
402 switch (ctl_msg_type) {
403 case RT_CTL_INITIALIZATION:
404 do_initialization_msg(
405 tvb, pinfo, ctl_msg_tree, offset);
406 break;
407 case RT_CTL_VERIFICATION:
408 do_verification_msg(
409 tvb, pinfo, ctl_msg_tree, offset);
410 break;
411 case RT_CTL_HELLO_TEST:
412 do_hello_test_msg(
413 tvb, pinfo, ctl_msg_tree, offset);
414 break;
415 case RT_CTL_LVL1_ROUTING:
416 case RT_CTL_LVL2_ROUTING:
417 do_routing_msg(
418 tvb, pinfo, ctl_msg_tree, offset, msg_flags >> 1);
419 break;
420 case RT_CTL_ETH_ROUTER_HELLO_MSG:
421 case RT_CTL_ETH_ENDNODE_HELLO_MSG:
422 do_hello_msg(
423 tvb, pinfo, ctl_msg_tree, offset, msg_flags >> 1);
424 break;
425 default:
426 break;
428 } else if (msg_flags & RT_FLAGS_LONG_MSG){
429 static int * const msg_bit_flags[] = {
430 &hf_dec_rt_long_msg,
431 &hf_dec_rt_rqr,
432 &hf_dec_rt_rts,
433 &hf_dec_rt_inter_eth,
434 &hf_dec_rt_discard,
435 NULL
438 proto_tree_add_bitmask_list_value(flags_tree, tvb, offset, 1, msg_bit_flags, msg_flags);
440 /* Increment offset by three:
441 1 to get past the flags field
442 2 to skip the DEC area/subarea field
444 offset += 3;
445 ti = proto_tree_add_item(rt_tree, hf_dec_rt_dst_addr, tvb,
446 offset, 6, ENC_NA);
447 addr = dnet_ntoa(pinfo->pool, (const uint8_t *)tvb_memdup(pinfo->pool, tvb, offset, 6));
448 if (addr != NULL) {
449 proto_item_append_text(ti, " (%s)", addr);
452 /* Skip 6 bytes for the MAC and
453 2 bytes for DEC area/subarea
455 offset += 8;
456 ti = proto_tree_add_item(rt_tree, hf_dec_rt_src_addr, tvb,
457 offset, 6, ENC_NA);
458 addr = dnet_ntoa(pinfo->pool, (const uint8_t *)tvb_memdup(pinfo->pool, tvb, offset, 6));
459 if (addr != NULL) {
460 proto_item_append_text(ti, " (%s)", addr);
463 /* Proceed to the NL2 byte */
464 offset += 6;
465 proto_tree_add_uint(rt_tree, hf_dec_rt_nl2, tvb,
466 offset, 1, rt_zero);
467 offset++;
468 rt_visit_count = tvb_get_uint8(tvb, offset);
469 proto_tree_add_uint(rt_tree, hf_dec_rt_visit_count, tvb,
470 offset, 1, rt_visit_count);
471 offset++;
472 proto_tree_add_uint(rt_tree, hf_dec_rt_service_class, tvb,
473 offset, 1, rt_zero);
474 offset++;
475 proto_tree_add_uint(rt_tree, hf_dec_rt_protocol_type, tvb,
476 offset, 1, rt_zero);
477 offset++;
478 } else {
479 proto_tree_add_uint(flags_tree, hf_dec_rt_short_msg,
480 tvb, offset, 1, msg_flags);
481 proto_tree_add_boolean(flags_tree, hf_dec_rt_rqr, tvb,
482 offset, 1, msg_flags);
483 proto_tree_add_boolean(flags_tree, hf_dec_rt_rts, tvb,
484 offset, 1, msg_flags);
486 /* Increment offset to get past the flags field
488 offset++;
489 proto_tree_add_item(rt_tree, hf_dec_rt_dst_node, tvb, offset, 2, ENC_LITTLE_ENDIAN);
490 offset += 2;
491 proto_tree_add_item(rt_tree, hf_dec_rt_src_node, tvb, offset, 2, ENC_LITTLE_ENDIAN);
492 offset += 2;
493 forward = tvb_get_uint8(tvb, offset);
494 proto_tree_add_uint(rt_tree, hf_dec_rt_visited_nodes, tvb,
495 offset, 1, forward);
496 offset++;
499 if (!(msg_flags & RT_FLAGS_CTRL_MSG)) {
500 /* It is not a routing control message */
501 proto_tree *nsp_msg_tree;
502 proto_item *ti_local;
503 uint8_t nsp_msg_type;
505 nsp_msg_type = tvb_get_uint8(tvb, offset);
506 ti_local = proto_tree_add_uint(
507 tree, hf_dec_nsp_msgs, tvb, offset, 1, nsp_msg_type);
508 if (nsp_msg_type == NOP_MSG) {
509 /* Only test data in this msg */
510 return offset;
512 nsp_msg_tree = proto_item_add_subtree(ti_local, ett_dec_rt_nsp_msg);
513 /* Get past the nsp_msg_type */
514 offset++;
515 proto_tree_add_item(nsp_msg_tree, hf_dec_rt_dst_node, tvb, offset, 2, ENC_LITTLE_ENDIAN);
516 offset += 2;
517 if (nsp_msg_type == CONN_ACK_MSG) {
518 col_set_str(pinfo->cinfo, COL_INFO, "NSP connect acknowledgement");
519 /* Done with this msg type */
520 return offset;
522 /* All other messages have a source node */
523 proto_tree_add_item(nsp_msg_tree, hf_dec_rt_src_node, tvb, offset, 2, ENC_LITTLE_ENDIAN);
524 offset += 2;
526 handle_nsp_msg(tvb,
527 pinfo,
528 nsp_msg_tree,
529 offset,
530 nsp_msg_type);
532 return tvb_captured_length(tvb);
535 static int
536 do_initialization_msg(
537 tvbuff_t *tvb,
538 packet_info *pinfo,
539 proto_tree *tree,
540 unsigned offset)
542 unsigned my_offset = offset;
543 uint8_t version, eco_nr, user_eco;
544 uint8_t remainder_count;
546 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, initialization message");
547 proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
548 my_offset, 2, ENC_LITTLE_ENDIAN);
549 my_offset += 2;
550 proto_tree_add_item(tree, hf_dec_rt_tiinfo, tvb,
551 my_offset, 2, ENC_LITTLE_ENDIAN);
552 my_offset += 2;
553 proto_tree_add_item(tree, hf_dec_rt_blk_size, tvb,
554 my_offset, 2, ENC_LITTLE_ENDIAN);
555 my_offset += 2;
556 version = tvb_get_uint8(tvb, my_offset);
557 eco_nr = tvb_get_uint8(tvb, my_offset + 1);
558 user_eco = tvb_get_uint8(tvb, my_offset + 2);
559 proto_tree_add_none_format(tree, hf_dec_rt_version, tvb,
560 my_offset, 3, "Routing Layer version: %d.%d.%d.",
561 version, eco_nr, user_eco);
562 my_offset +=3;
563 proto_tree_add_item(tree, hf_dec_rt_timer, tvb,
564 my_offset, 2, ENC_LITTLE_ENDIAN);
565 my_offset += 2;
566 remainder_count = tvb_get_uint8(tvb, my_offset);
567 if (remainder_count != 0) {
568 proto_tree_add_item(tree, hf_dec_rt_reserved, tvb,
569 my_offset, remainder_count, ENC_NA);
570 my_offset += remainder_count;
572 return (my_offset);
575 static int
576 do_verification_msg(
577 tvbuff_t *tvb,
578 packet_info *pinfo,
579 proto_tree *tree,
580 unsigned offset)
582 unsigned my_offset = offset;
583 uint8_t remainder_count;
585 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, verification message");
586 proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
587 my_offset, 2, ENC_LITTLE_ENDIAN);
588 my_offset += 2;
589 remainder_count = tvb_get_uint8(tvb, my_offset);
590 if (remainder_count != 0) {
591 proto_tree_add_item(tree, hf_dec_rt_fcnval, tvb,
592 my_offset, remainder_count, ENC_NA);
593 my_offset += remainder_count;
595 return (my_offset);
598 static int
599 do_hello_test_msg(
600 tvbuff_t *tvb,
601 packet_info *pinfo,
602 proto_tree *tree,
603 unsigned offset)
605 unsigned my_offset = offset;
606 unsigned remainder_count;
608 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, hello/test message");
609 proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
610 my_offset, 2, ENC_LITTLE_ENDIAN);
611 my_offset += 2;
612 remainder_count = tvb_reported_length_remaining(tvb, my_offset);
613 if (remainder_count != 0) {
614 proto_tree_add_item(tree, hf_dec_rt_test_data, tvb,
615 my_offset, remainder_count, ENC_NA);
616 my_offset += remainder_count;
618 return (my_offset);
621 static int
622 do_routing_msg(
623 tvbuff_t *tvb,
624 packet_info *pinfo,
625 proto_tree *tree,
626 unsigned offset,
627 unsigned msg)
629 unsigned my_offset = offset;
630 uint32_t my_checksum = 1;
631 uint16_t count, startid, rtginfo;
632 unsigned remainder_count;
634 proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
635 my_offset, 2, ENC_LITTLE_ENDIAN);
636 /* Skip the 1-byte reserved field */
637 my_offset += 3;
638 remainder_count = tvb_reported_length_remaining(tvb, my_offset);
639 do {
640 /* if the remainder_count == 1, only the checksum remains */
641 count = tvb_get_letohs(tvb, my_offset);
642 startid = tvb_get_letohs(tvb, my_offset + 2);
643 rtginfo = tvb_get_letohs(tvb, my_offset + 4);
644 if (msg == 3) {
645 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, Level 1 routing message");
646 proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
647 my_offset, 6,
648 "Segment: count:%d, start Id: %d, hops:%d, cost: %d",
649 count, startid, (rtginfo & 0x7c00) >> 10, rtginfo & 0x3ff);
650 } else {
651 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, Level 2 routing message");
652 proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
653 my_offset, 6,
654 "Segment: count:%d, start area: %d, hops:%d, cost: %d",
655 count, startid, (rtginfo & 0x7c00) >> 10, rtginfo & 0x3ff);
657 my_checksum += (count + startid + rtginfo);
658 my_offset += 6;
659 remainder_count -= 6;
660 } while (remainder_count > 6);
661 my_offset += remainder_count - 2;
662 /* fold 32 bit sum into 16 bits */
663 while (my_checksum>>16)
664 my_checksum = (my_checksum & 0xffff) + (my_checksum >> 16);
666 proto_tree_add_checksum(tree, tvb, my_offset, hf_dec_rt_checksum, hf_dec_rt_checksum_status, &ei_dec_rt_checksum, pinfo, my_checksum, ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
667 my_offset += 2;
668 return (my_offset);
671 static int
672 do_hello_msg(
673 tvbuff_t *tvb,
674 packet_info *pinfo,
675 proto_tree *tree,
676 unsigned offset,
677 unsigned msg)
679 unsigned my_offset = offset;
680 uint8_t priority;
681 uint16_t version, eco_nr, user_eco;
682 proto_item *ti;
683 char *addr;
684 static int * const info_flags[] = {
685 &hf_dec_rt_iinfo_node_type,
686 &hf_dec_rt_iinfo_vrf,
687 &hf_dec_rt_iinfo_rej,
688 &hf_dec_rt_iinfo_verf,
689 &hf_dec_rt_iinfo_mta,
690 &hf_dec_rt_iinfo_blkreq,
691 NULL
694 version = tvb_get_uint8(tvb, my_offset);
695 eco_nr = tvb_get_uint8(tvb, my_offset + 1);
696 user_eco = tvb_get_uint8(tvb, my_offset + 2);
697 proto_tree_add_none_format(tree, hf_dec_rt_version, tvb,
698 my_offset, 3, "Routing Layer Version: %d.%d.%d",
699 version, eco_nr, user_eco);
700 my_offset +=3;
701 ti = proto_tree_add_item(tree, hf_dec_rt_id, tvb,
702 my_offset, 6, ENC_NA);
703 addr = dnet_ntoa(pinfo->pool, (const uint8_t *)tvb_memdup(pinfo->pool, tvb, my_offset, 6));
704 if (addr != NULL) {
705 proto_item_append_text(ti, " (%s)", addr);
707 my_offset += 6;
708 proto_tree_add_bitmask(tree, tvb, my_offset, hf_dec_rt_iinfo, ett_dec_rt_info_flags, info_flags, ENC_NA);
709 my_offset++;
711 proto_tree_add_item(tree, hf_dec_rt_blk_size, tvb,
712 my_offset, 2, ENC_LITTLE_ENDIAN);
713 my_offset += 2;
714 if (msg == 5) {
715 /* Ethernet router hello message
716 Has a 'priority' field in this position */
717 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, Ethernet Router Hello message");
718 priority = tvb_get_uint8(tvb, my_offset);
719 proto_tree_add_uint(
720 tree, hf_dec_rt_iprio, tvb, my_offset, 1, priority);
721 my_offset++;
723 /* Skip the 'area' field common to both hello messages */
724 my_offset += 1;
725 if (msg == 6) {
726 /* The endnode hello message has 'seed' and 'neighbor' fields */
727 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, Endnode Hello message");
728 proto_tree_add_item(tree, hf_dec_rt_seed, tvb,
729 my_offset, 8, ENC_NA);
730 my_offset += 8;
731 ti = proto_tree_add_item(tree, hf_dec_rt_neighbor, tvb,
732 my_offset, 6, ENC_NA);
733 addr = dnet_ntoa(pinfo->pool, (const uint8_t *)tvb_memdup(pinfo->pool, tvb, my_offset, 6));
734 if (addr != NULL) {
735 proto_item_append_text(ti, " (%s)", addr);
737 my_offset += 6;
739 /*'Timer' and 'mpd' fields are common
740 'mpd' field is reserved */
741 proto_tree_add_item(tree, hf_dec_rt_timer, tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
742 my_offset += 3;
743 if (msg == 5) {
744 /* The Ethernet router hello message contains
745 a list of router states
746 The Ethernet Endnode Hello Message contains
747 up to 128 bytes of test data at the end.
748 These data are left to be dissected as 'data'.
750 proto_item *ti_locala, *ti_ether;
751 proto_tree *list_tree, *list_ether;
752 uint8_t image_len;
753 uint8_t item_len;
755 /* image field is preceded by count of remainder of field */
756 image_len = tvb_get_uint8(tvb, my_offset);
757 my_offset++;
759 ti_locala = proto_tree_add_item(tree, hf_dec_rt_elist, tvb,
760 my_offset, image_len, ENC_NA);
761 list_tree = proto_item_add_subtree(ti_locala, ett_dec_rt_list);
763 while (image_len > 0) {
764 ti_ether = proto_tree_add_item(list_tree, hf_dec_rt_ename, tvb,
765 my_offset, 7, ENC_NA);
766 list_ether = proto_item_add_subtree(ti_ether, ett_dec_rt_rlist);
767 my_offset += 7;
768 image_len -= 7;
770 /* image field is preceded by count of remainder of field */
771 item_len = tvb_get_uint8(tvb, my_offset);
772 my_offset++;
773 image_len -= 1;
774 while (item_len > 0)
776 uint8_t pristate;
777 proto_item *ti_localb;
778 proto_tree *pstate_tree;
780 ti_localb = proto_tree_add_item(list_ether, hf_dec_rt_router_id,
781 tvb, my_offset, 6, ENC_NA);
782 addr = dnet_ntoa(pinfo->pool, (const uint8_t *)tvb_memdup(pinfo->pool, tvb, my_offset, 6));
783 if (addr != NULL) {
784 proto_item_append_text(ti_localb, " (%s)", addr);
786 my_offset += 6;
787 pstate_tree = proto_item_add_subtree(ti_localb, ett_dec_rt_state);
788 pristate = tvb_get_uint8(tvb, my_offset);
789 proto_tree_add_string(pstate_tree, hf_dec_rt_router_state,
790 tvb, my_offset, 1,
791 ((pristate & 0x80) ? "known 2-way": "unknown"));
792 proto_tree_add_uint(pstate_tree, hf_dec_rt_router_prio,
793 tvb, my_offset, 1, pristate);
794 my_offset++;
795 item_len -= 7;
796 image_len -= 7;
800 return (my_offset);
803 static int
804 handle_nsp_msg(
805 tvbuff_t *tvb,
806 packet_info *pinfo,
807 proto_tree *tree,
808 unsigned offset,
809 uint8_t nsp_msg_type)
811 /* Offset in tvb now points at the first byte still to be handled */
812 unsigned my_offset = offset;
813 int data_length;
814 uint16_t ack_num, ack_dat, ack_oth, seg_num;
815 uint8_t ls_flags, fc_val, services;
816 proto_item *ti;
817 proto_tree *flow_control_tree;
819 /* 'tree' is now the subtree for the NSP message */
820 switch (nsp_msg_type) {
821 case DATA_SEGMENT_MSG: /* "Data segment" */
822 case BOM_MSG: /* "Beginning of segment message" */
823 case EOM_MSG: /* "End of segment message" */
824 case BOM_EOM_MSG: /* "BOM / EOM message" */
825 ack_num = tvb_get_letohs(tvb, my_offset);
826 if (ack_num & 0x8000) {
827 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
828 tvb, my_offset, 2,
829 "Last data segment %s acknowledged: %d",
830 (ack_num & 0x1000) ? "negatively" : "positively",
831 ack_num & 0xfff);
832 my_offset += 2;
833 /* There may still be an ackoth field */
834 ack_oth = tvb_get_letohs(tvb, my_offset);
835 if (ack_oth & 0x8000) {
836 /* There is an ack_oth field */
837 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
838 tvb, my_offset, 2,
839 "Cross sub-channel %s of other data msg %d",
840 ((ack_oth & 0x3000) == 0x2000) ? "ACK" : "NAK",
841 ack_oth & 0xfff);
842 my_offset += 2;
846 * The optional ACKNUM and ACKOTH fields are not present
847 * There is still the segnum field
849 seg_num = tvb_get_letohs(tvb, my_offset);
850 if (nsp_msg_type == BOM_MSG) {
851 dec_dna_total_bytes_this_segment = 0;
852 col_append_fstr(pinfo->cinfo, COL_INFO,
853 "msg nr. %d: start of segment",
854 seg_num & 0xfff);
855 } else if (nsp_msg_type == DATA_SEGMENT_MSG) {
856 col_append_fstr(pinfo->cinfo, COL_INFO,
857 "msg nr. %d: continuation segment ",
858 seg_num & 0xfff);
859 } else if (nsp_msg_type == EOM_MSG) {
860 col_append_fstr(pinfo->cinfo, COL_INFO,
861 "msg nr. %d: end of segment",
862 seg_num & 0xfff);
863 } else if (nsp_msg_type == BOM_EOM_MSG) {
864 dec_dna_total_bytes_this_segment = 0;
865 col_append_fstr(pinfo->cinfo, COL_INFO,
866 "msg nr. %d single segment",
867 seg_num & 0xfff);
869 /* This is the last field, the rest are data */
870 proto_tree_add_item(tree, hf_dec_rt_segnum,
871 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
872 proto_tree_add_item(tree, hf_dec_rt_delay,
873 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
874 my_offset += 2;
875 /* Compute the number of bytes in this data segment */
876 data_length =
877 tvb_reported_length_remaining(tvb, my_offset);
878 dec_dna_previous_total = dec_dna_total_bytes_this_segment;
879 dec_dna_total_bytes_this_segment += data_length;
880 col_append_fstr(pinfo->cinfo, COL_INFO,
881 ", bytes this segment: %d, total so far:%d",
882 data_length, dec_dna_total_bytes_this_segment);
883 /* We are done, return my_offset */
884 break;
885 case INTERRUPT_MSG: /* "Interrupt message" */
886 col_set_str(pinfo->cinfo, COL_INFO, "NSP interrupt message");
887 ack_num = tvb_get_letohs(tvb, my_offset);
888 if (ack_num & 0x8000) {
889 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
890 tvb, my_offset, 2,
891 "Last interrupt/link service msg %s acknowledged: %d",
892 (ack_num & 0x1000) ? "negatively" : "positively",
893 ack_num & 0xfff);
894 my_offset += 2;
895 /* There may still be an ack_dat field */
896 } else {
897 /* There are no ack/nak fields */
898 proto_tree_add_item(tree, hf_dec_rt_segnum,
899 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
900 proto_tree_add_item(tree, hf_dec_rt_delay,
901 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
902 my_offset += 2;
903 /* We are done, return my_offset */
904 break;
906 ack_dat = tvb_get_letohs(tvb, my_offset);
907 if (ack_dat & 0x8000) {
908 /* There is an ack_dat field */
909 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
910 tvb, my_offset, 2,
911 "Cross sub-channel %s of data segment msg: %d",
912 ((ack_dat & 0x3000) == 0x2000) ? "ACK" : "NAK",
913 ack_dat & 0xfff);
914 my_offset += 2;
916 /* This is the last field, the rest are data */
917 proto_tree_add_item(tree, hf_dec_rt_segnum,
918 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
919 proto_tree_add_item(tree, hf_dec_rt_delay,
920 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
921 my_offset += 2;
922 /* We are done, return my_offset */
923 break;
924 case LINK_SERVICE_MSG: /* "Link service message" */
925 col_set_str(pinfo->cinfo, COL_INFO, "NSP link control message");
926 ack_num = tvb_get_letohs(tvb, my_offset);
927 if (ack_num & 0x8000) {
928 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
929 tvb, my_offset, 2,
930 "Last interrupt/link service msg %s acknowledged: %d",
931 (ack_num & 0x1000) ? "negatively" : "positively",
932 ack_num & 0xfff);
933 my_offset += 2;
934 /* There may still be an ack_dat field */
935 } else {
936 /* There are no ack/nak fields */
937 proto_tree_add_item(tree, hf_dec_rt_segnum,
938 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
939 proto_tree_add_item(tree, hf_dec_rt_delay,
940 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
941 my_offset += 2;
942 /* We are done, return my_offset */
943 break;
945 ack_dat = tvb_get_letohs(tvb, my_offset);
946 if (ack_dat & 0x8000) {
947 /* There is an ack_dat field */
948 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
949 tvb, my_offset, 2,
950 "Cross sub-channel %s of data segment msg: %d",
951 ((ack_dat & 0x3000) == 0x2000) ? "ACK" : "NAK",
952 ack_dat & 0xfff);
953 my_offset += 2;
955 proto_tree_add_item(tree, hf_dec_rt_segnum,
956 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
957 proto_tree_add_item(tree, hf_dec_rt_delay,
958 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
959 my_offset += 2;
960 /* Now follows the ls_flags field */
961 ls_flags = tvb_get_uint8(tvb, my_offset);
962 switch(ls_flags) {
963 case 0: /* no change */
964 col_append_str(pinfo->cinfo, COL_INFO,
965 "(no change)");
966 break;
967 case 1: /* stop sending data */
968 col_append_str(pinfo->cinfo, COL_INFO,
969 "(stop)");
970 break;
971 case 2: /* send data */
972 col_append_str(pinfo->cinfo, COL_INFO,
973 "(go)");
974 break;
975 default:
976 break;
978 fc_val = tvb_get_uint8(tvb, my_offset + 1);
979 ti = proto_tree_add_uint(tree, hf_dec_flow_control, tvb,
980 my_offset, 1, ls_flags);
981 flow_control_tree =
982 proto_item_add_subtree(ti, ett_dec_flow_control);
983 proto_tree_add_none_format(flow_control_tree, hf_dec_rt_fc_val,
984 tvb, my_offset, 2,
985 "Request for additional %d %s msgs",
986 fc_val, ((ls_flags & 0x04) ? "interrupt" : "data"));
987 my_offset += 2;
988 break;
989 case DATA_ACK_MSG: /* "Data acknowledgement message" */
990 ack_num = tvb_get_letohs(tvb, my_offset);
991 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
992 tvb, my_offset, 2,
993 "Last data segment %s acknowledged: %d",
994 (ack_num & 0x1000) ? "negatively" : "positively",
995 ack_num & 0xfff);
996 my_offset += 2;
997 /* There may be an optional ack_oth field */
998 col_append_fstr(pinfo->cinfo, COL_INFO,
999 "NSP data %s message(%d)",
1000 (ack_num & 0x1000) ? "NAK" : "ACK",
1001 ack_num & 0xfff);
1003 if (tvb_reported_length_remaining(tvb, my_offset) > 0) {
1004 ack_oth = tvb_get_letohs(tvb, my_offset);
1005 if (ack_oth & 0x8000) {
1006 /* There is an ack_oth field */
1007 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1008 tvb, my_offset, 2,
1009 "Cross sub-channel %s of other data msg %d",
1010 ((ack_oth & 0x3000) == 0x2000) ? "ACK" : "NAK",
1011 ack_oth & 0xfff);
1012 my_offset += 2;
1015 /* We are done, return my_offset */
1016 break;
1017 case OTHER_DATA_ACK_MSG: /* "Other data acknowledgement message" */
1018 col_set_str(pinfo->cinfo, COL_INFO, "NSP other data ACK message");
1019 ack_num = tvb_get_letohs(tvb, my_offset);
1020 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1021 tvb, my_offset, 2,
1022 "Last interrupt/link service msg %s acknowledged: %d",
1023 (ack_num & 0x1000) ? "negatively" : "positively",
1024 ack_num & 0xfff);
1025 my_offset += 2;
1026 /* There may be an optional ack_dat field */
1027 if (tvb_reported_length_remaining(tvb, my_offset) > 0) {
1028 ack_dat = tvb_get_letohs(tvb, my_offset);
1029 if (ack_dat & 0x8000) {
1030 /* There is an ack_dat field */
1031 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1032 tvb, my_offset, 2,
1033 "Cross sub-channel %s of data msg %d",
1034 ((ack_dat & 0x3000) == 0x2000) ? "ACK" : "NAK",
1035 ack_dat & 0xfff);
1036 my_offset += 2;
1039 /* We are done, return my_offset */
1040 break;
1041 case CONN_CONFIRM_MSG: /* "Connect confirm" */
1042 case CONN_INITIATE_MSG: /* "Connect initiate" */
1043 col_set_str(pinfo->cinfo, COL_INFO, "NSP connect confirm/initiate message");
1044 services = tvb_get_uint8(tvb, my_offset);
1045 proto_tree_add_uint(tree, hf_dec_rt_services, tvb,
1046 my_offset, 1, services);
1047 my_offset++;
1048 proto_tree_add_item(tree, hf_dec_rt_info, tvb, my_offset, 1, ENC_LITTLE_ENDIAN);
1049 my_offset++;
1050 proto_tree_add_item(tree, hf_dec_rt_seg_size, tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
1051 my_offset += 2;
1052 my_offset = handle_connect_contents(tvb, tree, my_offset);
1053 break;
1054 case DISCONN_INITIATE_MSG: /* "Disconnect initiate" */
1055 case DISCONN_CONFIRM_MSG: /* "Disconnect confirm" */
1056 col_set_str(pinfo->cinfo, COL_INFO, "NSP disconnect initiate/confirm message");
1057 proto_tree_add_item(tree, hf_dec_disc_reason, tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
1058 my_offset += 2;
1059 if (nsp_msg_type == DISCONN_INITIATE_MSG) {
1060 my_offset =
1061 handle_disc_init_contents( my_offset);
1063 break;
1064 default:
1065 break;
1067 return (my_offset);
1070 static int
1071 handle_connect_contents(
1072 tvbuff_t *tvb,
1073 proto_tree *tree,
1074 unsigned offset)
1076 unsigned my_offset = offset;
1077 proto_item *ti;
1078 proto_tree *contents_tree;
1079 uint8_t dst_format, src_format, obj_type, image_len, menu_ver;
1081 ti = proto_tree_add_item(tree, hf_dec_conn_contents,
1082 tvb, my_offset, -1, ENC_NA);
1083 contents_tree = proto_item_add_subtree(ti, ett_dec_sess_contents);
1084 /* The destination end user */
1085 dst_format = tvb_get_uint8(tvb, my_offset);
1086 my_offset++;
1087 obj_type = tvb_get_uint8(tvb, my_offset);
1088 proto_tree_add_uint(contents_tree, hf_dec_sess_obj_type, tvb, my_offset, 1, obj_type);
1089 my_offset++;
1090 if (dst_format == 2) {
1091 proto_tree_add_item(contents_tree, hf_dec_sess_grp_code, tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
1092 my_offset += 2;
1093 proto_tree_add_item(contents_tree, hf_dec_sess_usr_code, tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
1094 my_offset += 2;
1096 if (dst_format != 0) {
1097 /* The name field for formats 1 and 2 */
1098 image_len = tvb_get_uint8(tvb, my_offset);
1099 my_offset++;
1100 proto_tree_add_item(contents_tree, hf_dec_sess_dst_name, tvb, my_offset, image_len, ENC_ASCII);
1101 my_offset += image_len;
1103 /* The source end user */
1104 src_format = tvb_get_uint8(tvb, my_offset);
1105 my_offset++;
1106 obj_type = tvb_get_uint8(tvb, my_offset);
1107 proto_tree_add_uint(contents_tree, hf_dec_sess_obj_type,
1108 tvb, my_offset, 1, obj_type);
1109 my_offset++;
1110 if (src_format == 2) {
1111 proto_tree_add_item(contents_tree, hf_dec_sess_grp_code, tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
1112 my_offset += 2;
1113 proto_tree_add_item(contents_tree, hf_dec_sess_usr_code, tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
1114 my_offset += 2;
1116 if (dst_format != 0) {
1117 /* The name field for formats 1 and 2 */
1118 image_len = tvb_get_uint8(tvb, my_offset);
1119 my_offset++;
1120 proto_tree_add_item(contents_tree, hf_dec_sess_src_name,
1121 tvb, my_offset, image_len, ENC_ASCII);
1122 my_offset += image_len;
1124 /* Now the MENUVER field */
1125 menu_ver = tvb_get_uint8(tvb, my_offset);
1126 switch (menu_ver) {
1127 case 1:
1128 case 3:
1129 proto_tree_add_string(contents_tree, hf_dec_sess_menu_ver,
1130 tvb, my_offset, 1,
1131 "Version 1.0: RQSTRID, PASSWRD and ACCOUNT fields included");
1132 my_offset++;
1133 image_len = tvb_get_uint8(tvb, my_offset);
1134 my_offset++;
1135 proto_tree_add_item(contents_tree, hf_dec_sess_rqstr_id,
1136 tvb, my_offset, image_len, ENC_ASCII);
1137 my_offset += image_len;
1138 image_len = tvb_get_uint8(tvb, my_offset);
1139 my_offset++;
1140 proto_tree_add_item(contents_tree, hf_dec_sess_rqstr_id,
1141 tvb, my_offset, image_len, ENC_ASCII);
1142 my_offset += image_len;
1143 image_len = tvb_get_uint8(tvb, my_offset);
1144 my_offset++;
1145 proto_tree_add_item(contents_tree, hf_dec_sess_rqstr_id,
1146 tvb, my_offset, image_len, ENC_ASCII);
1147 my_offset += image_len;
1150 break;
1151 case 2:
1152 /* A USRDATA field is handled by dissect_data */
1153 proto_tree_add_string(contents_tree, hf_dec_sess_menu_ver,
1154 tvb, my_offset, 1,
1155 "Version 1.0: USRDATA field included");
1156 break;
1157 default:
1158 proto_tree_add_string(contents_tree, hf_dec_sess_menu_ver,
1159 tvb, my_offset, 1,
1160 "Session control version 1.0");
1161 break;
1163 return (my_offset);
1166 static int
1167 handle_disc_init_contents(
1168 unsigned offset)
1170 unsigned my_offset = offset;
1172 return (my_offset);
1176 void
1177 proto_register_dec_rt(void)
1180 static hf_register_info hf[] = {
1181 /* Message header items */
1182 { &hf_dec_routing_flags,
1183 { "Routing flags", "dec_dna.flags",
1184 FT_UINT8, BASE_HEX, NULL, 0x0,
1185 "DNA routing flag", HFILL }},
1186 { &hf_dec_rt_ctrl_msg,
1187 { "Control packet", "dec_dna.flags.control",
1188 FT_BOOLEAN, 8, TFS(&tfs_yes_no), RT_FLAGS_CTRL_MSG,
1189 NULL, HFILL }},
1190 { &hf_dec_rt_long_msg,
1191 { "Long data packet format", "dec_dna.flags.msglen",
1192 FT_UINT8, BASE_HEX, NULL, 0x06,
1193 "Long message indicator", HFILL }},
1194 { &hf_dec_rt_short_msg,
1195 { "Short data packet format", "dec_dna.flags.msglen",
1196 FT_UINT8, BASE_HEX, NULL, 0x06,
1197 "Short message indicator", HFILL }},
1198 { &hf_dec_rt_rqr,
1199 { "Return to Sender Request", "dec_dna.flags.RQR",
1200 FT_BOOLEAN, 8, TFS(&tfs_yes_no), RT_FLAGS_RQR,
1201 NULL, HFILL }},
1202 { &hf_dec_rt_rts,
1203 { "Packet on return trip", "dec_dna.flags.RTS",
1204 FT_BOOLEAN, 8, TFS(&tfs_yes_no), RT_FLAGS_RTS,
1205 NULL, HFILL }},
1206 { &hf_dec_rt_inter_eth,
1207 { "Intra-ethernet packet", "dec_dna.flags.intra_eth",
1208 FT_BOOLEAN, 8, TFS(&tfs_yes_no), RT_FLAGS_INTRA_ETHER,
1209 NULL, HFILL }},
1210 { &hf_dec_rt_discard,
1211 { "Discarded packet", "dec_dna.flags.discard",
1212 FT_BOOLEAN, 8, TFS(&tfs_yes_no), RT_FLAGS_DISCARD,
1213 NULL, HFILL }},
1214 { &hf_dec_rt_dst_addr,
1215 { "Destination Address", "dec_dna.dst.address",
1216 FT_ETHER, BASE_NONE, NULL, 0x0,
1217 NULL, HFILL }},
1218 { &hf_dec_rt_src_addr,
1219 { "Source Address", "dec_dna.src.addr",
1220 FT_ETHER, BASE_NONE, NULL, 0x0,
1221 NULL, HFILL }},
1222 { &hf_dec_rt_nl2,
1223 { "Next level 2 router", "dec_dna.nl2",
1224 FT_UINT8, BASE_HEX, NULL, 0x0,
1225 "reserved", HFILL }},
1226 { &hf_dec_rt_service_class,
1227 { "Service class", "dec_dna.svc_cls",
1228 FT_UINT8, BASE_HEX, NULL, 0x0,
1229 "reserved", HFILL }},
1230 { &hf_dec_rt_protocol_type,
1231 { "Protocol type", "dec_dna.proto_type",
1232 FT_UINT8, BASE_HEX, NULL, 0x0,
1233 "reserved", HFILL }},
1234 { &hf_dec_rt_visit_count,
1235 { "Visit count", "dec_dna.visit_cnt",
1236 FT_UINT8, BASE_HEX, NULL, 0x0,
1237 NULL, HFILL }},
1238 { &hf_dec_flow_control,
1239 { "Flow control", "dec_dna.nsp.flow_control",
1240 FT_UINT8, BASE_HEX, VALS(rt_flow_control_vals), 0x3,
1241 "Flow control(stop, go)", HFILL }},
1242 { &hf_dec_rt_services,
1243 { "Requested services", "dec_dna.nsp.services",
1244 FT_UINT8, BASE_HEX, VALS(rt_services_vals), 0x0c,
1245 NULL, HFILL }},
1246 { &hf_dec_rt_info,
1247 { "Version info", "dec_dna.nsp.info",
1248 FT_UINT8, BASE_HEX, VALS(rt_info_version_vals), 0x03,
1249 NULL, HFILL }},
1250 { &hf_dec_rt_dst_node,
1251 { "Destination node", "dec_dna.dst_node",
1252 FT_UINT16, BASE_HEX, NULL, 0x0,
1253 NULL, HFILL }},
1254 { &hf_dec_rt_seg_size,
1255 { "Maximum data segment size", "dec_dna.nsp.segsize",
1256 FT_UINT16, BASE_DEC, NULL, 0x0,
1257 "Max. segment size", HFILL }},
1258 { &hf_dec_rt_src_node,
1259 { "Source node", "dec_dna.src_node",
1260 FT_UINT16, BASE_HEX, NULL, 0x0,
1261 NULL, HFILL }},
1262 { &hf_dec_rt_segnum,
1263 { "Message number", "dec_dna.nsp.segnum",
1264 FT_UINT16, BASE_DEC, NULL, 0x0fff,
1265 "Segment number", HFILL }},
1266 { &hf_dec_rt_delay,
1267 { "Delayed ACK allowed", "dec_dna.nsp.delay",
1268 FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x1000,
1269 "Delayed ACK allowed?", HFILL }},
1270 { &hf_dec_rt_visited_nodes,
1271 { "Nodes visited by this package", "dec_dna.vst_node",
1272 FT_UINT8, BASE_DEC, NULL, 0x0,
1273 NULL, HFILL }},
1274 /* Control message items */
1275 { &hf_dec_ctl_msgs,
1276 { "Routing control message", "dec_dna.rt.msg_type",
1277 FT_UINT8, BASE_HEX, VALS(rt_msg_type_vals), 0xe,
1278 NULL, HFILL }},
1279 { &hf_dec_ctl_msg_hdr,
1280 { "Routing control message", "dec_dna.rt.msg_type",
1281 FT_UINT8, BASE_HEX, VALS(rt_msg_type_vals), 0xe,
1282 NULL, HFILL }},
1283 { &hf_dec_nsp_msgs,
1284 { "DNA NSP message", "dec_dna.nsp.msg_type",
1285 FT_UINT8, BASE_HEX, VALS(nsp_msg_type_vals), 0x0,
1286 NULL, HFILL }},
1287 { &hf_dec_rt_acknum,
1288 { "Ack/Nak", "dec_dna.ctl.acknum",
1289 FT_NONE, BASE_NONE, NULL, 0x0,
1290 "ack/nak number", HFILL }},
1291 { &hf_dec_rt_fc_val,
1292 { "Flow control", "dec_dna.nsp.fc_val",
1293 FT_NONE, BASE_NONE, NULL, 0x0,
1294 NULL, HFILL }},
1295 { &hf_dec_rt_tiinfo,
1296 { "Routing information", "dec_dna.ctl.tiinfo",
1297 FT_UINT16, BASE_HEX, VALS(rt_tiinfo_vals), 0x0,
1298 NULL, HFILL }},
1299 { &hf_dec_rt_blk_size,
1300 { "Block size", "dec_dna.ctl.blk_size",
1301 FT_UINT16, BASE_DEC, NULL, 0x0,
1302 NULL, HFILL }},
1303 { &hf_dec_disc_reason,
1304 { "Reason for disconnect", "dec_dna.nsp.disc_reason",
1305 FT_UINT16, BASE_HEX, VALS(rt_disc_reason_vals), 0x0,
1306 NULL, HFILL }},
1307 { &hf_dec_rt_version,
1308 { "Version", "dec_dna.ctl.version",
1309 FT_NONE, BASE_NONE, NULL, 0x0,
1310 "Control protocol version", HFILL }},
1311 { &hf_dec_rt_timer,
1312 { "Hello timer(seconds)", "dec_dna.ctl.timer",
1313 FT_UINT16, BASE_DEC, NULL, 0x0,
1314 "Hello timer in seconds", HFILL }},
1315 { &hf_dec_rt_reserved,
1316 { "Reserved", "dec_dna.ctl.reserved",
1317 FT_BYTES, BASE_NONE, NULL, 0x0,
1318 NULL, HFILL }},
1319 { &hf_dec_rt_fcnval,
1320 { "Verification message function value", "dec_dna.ctl.fcnval",
1321 FT_BYTES, BASE_NONE, NULL, 0x0,
1322 "Routing Verification function", HFILL }},
1323 { &hf_dec_rt_test_data,
1324 { "Test message data", "dec_dna.ctl.test_data",
1325 FT_BYTES, BASE_NONE, NULL, 0x0,
1326 "Routing Test message data", HFILL }},
1327 { &hf_dec_rt_segment,
1328 { "Segment", "dec_dna.ctl.segment",
1329 FT_NONE, BASE_NONE, NULL, 0x0,
1330 "Routing Segment", HFILL }},
1331 { &hf_dec_rt_checksum,
1332 { "Checksum", "dec_dna.ctl.checksum",
1333 FT_UINT16, BASE_HEX, NULL, 0x0,
1334 NULL, HFILL }},
1335 { &hf_dec_rt_checksum_status,
1336 { "Checksum Status", "dec_dna.ctl.checksum.status",
1337 FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0x0,
1338 NULL, HFILL }},
1339 { &hf_dec_rt_id,
1340 { "Transmitting system ID", "dec_dna.ctl.id",
1341 FT_ETHER, BASE_NONE, NULL, 0x0,
1342 NULL, HFILL }},
1343 { &hf_dec_rt_iinfo,
1344 { "Routing information", "dec_dna.ctl.tiinfo",
1345 FT_UINT8, BASE_HEX, NULL, 0x0,
1346 NULL, HFILL }},
1347 { &hf_dec_rt_iinfo_node_type,
1348 { "Node type", "dec_dna.ctl.iinfo.node_type",
1349 FT_UINT8, BASE_HEX, VALS(rt_iinfo_node_type_vals), 0x03,
1350 NULL, HFILL }},
1351 { &hf_dec_rt_iinfo_vrf,
1352 { "Verification required", "dec_dna.ctl.iinfo.vrf",
1353 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x4,
1354 "Verification required?", HFILL }},
1355 { &hf_dec_rt_iinfo_rej,
1356 { "Rejected", "dec_dna.ctl.iinfo.rej",
1357 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x8,
1358 "Rejected message", HFILL }},
1359 { &hf_dec_rt_iinfo_verf,
1360 { "Verification failed", "dec_dna.ctl.iinfo.verf",
1361 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
1362 "Verification failed?", HFILL }},
1363 { &hf_dec_rt_iinfo_mta,
1364 { "Accepts multicast traffic", "dec_dna.ctl.iinfo.mta",
1365 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
1366 "Accepts multicast traffic?", HFILL }},
1367 { &hf_dec_rt_iinfo_blkreq,
1368 { "Blocking requested", "dec_dna.ctl.iinfo.blkreq",
1369 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
1370 "Blocking requested?", HFILL }},
1371 { &hf_dec_rt_iprio,
1372 { "Routing priority", "dec_dna.ctl.prio",
1373 FT_UINT8, BASE_HEX, NULL, 0x0,
1374 NULL, HFILL }},
1375 { &hf_dec_rt_neighbor,
1376 { "Neighbor", "dec_dna.ctl_neighbor",
1377 FT_ETHER, BASE_NONE, NULL, 0x0,
1378 "Neighbour ID", HFILL }},
1379 { &hf_dec_rt_seed,
1380 { "Verification seed", "dec_dna.ctl.seed",
1381 FT_BYTES, BASE_NONE, NULL, 0x0,
1382 NULL, HFILL }},
1383 { &hf_dec_rt_elist,
1384 { "List of router states", "dec_dna.ctl.elist",
1385 FT_NONE, BASE_NONE, NULL, 0x0,
1386 NULL, HFILL }},
1387 { &hf_dec_rt_ename,
1388 { "Ethernet name", "dec_dna.ctl.ename",
1389 FT_BYTES, BASE_NONE, NULL, 0x0,
1390 NULL, HFILL }},
1391 { &hf_dec_rt_router_id,
1392 { "Router ID", "dec_dna.ctl.router_id",
1393 FT_ETHER, BASE_NONE, NULL, 0x0,
1394 NULL, HFILL }},
1395 { &hf_dec_rt_router_state,
1396 { "Router state", "dec_dna.ctl.router_state",
1397 FT_STRING, BASE_NONE, NULL, 0x0,
1398 NULL, HFILL }},
1399 { &hf_dec_conn_contents,
1400 { "Session connect data", "dec_dna.sess.conn",
1401 FT_NONE, BASE_NONE, NULL, 0x0,
1402 NULL, HFILL }},
1403 { &hf_dec_rt_router_prio,
1404 { "Router priority", "dec_dna.ctl.router_prio",
1405 FT_UINT8, BASE_HEX, NULL, 0x7f,
1406 NULL, HFILL }},
1407 { &hf_dec_sess_grp_code,
1408 { "Session Group code", "dec_dna.sess.grp_code",
1409 FT_UINT16, BASE_HEX, NULL, 0x0,
1410 NULL, HFILL }},
1411 { &hf_dec_sess_usr_code,
1412 { "Session User code", "dec_dna.sess.usr_code",
1413 FT_UINT16, BASE_HEX, NULL, 0x0,
1414 NULL, HFILL }},
1415 { &hf_dec_sess_dst_name,
1416 { "Session Destination end user", "dec_dna.sess.dst_name",
1417 FT_STRING, BASE_NONE, NULL, 0x0,
1418 NULL, HFILL }},
1419 { &hf_dec_sess_src_name,
1420 { "Session Source end user", "dec_dna.sess.src_name",
1421 FT_STRING, BASE_NONE, NULL, 0x0,
1422 NULL, HFILL }},
1423 { &hf_dec_sess_obj_type,
1424 { "Session Object type", "dec_dna.sess.obj_type",
1425 FT_UINT8, BASE_HEX, NULL, 0x0,
1426 NULL, HFILL }},
1427 { &hf_dec_sess_menu_ver,
1428 { "Session Menu version", "dec_dna.sess.menu_ver",
1429 FT_STRING, BASE_NONE, NULL, 0x0,
1430 NULL, HFILL }},
1431 { &hf_dec_sess_rqstr_id,
1432 { "Session Requestor ID", "dec_dna.sess.rqstr_id",
1433 FT_STRING, BASE_NONE, NULL, 0x0,
1434 NULL, HFILL }},
1438 static int *ett[] = {
1439 &ett_dec_rt,
1440 &ett_dec_routing_flags,
1441 &ett_dec_msg_flags,
1442 &ett_dec_rt_ctl_msg,
1443 &ett_dec_rt_nsp_msg,
1444 &ett_dec_rt_info_flags,
1445 &ett_dec_rt_list,
1446 &ett_dec_rt_rlist,
1447 &ett_dec_rt_state,
1448 &ett_dec_flow_control,
1449 &ett_dec_sess_contents,
1452 static ei_register_info ei[] = {
1453 { &ei_dec_rt_checksum, { "dec_dna.bad_checksum", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
1456 expert_module_t* expert_dec_rt;
1458 proto_dec_rt = proto_register_protocol("DEC DNA Routing Protocol", "DEC_DNA", "dec_dna");
1459 proto_register_field_array(proto_dec_rt, hf, array_length(hf));
1460 proto_register_subtree_array(ett, array_length(ett));
1461 expert_dec_rt = expert_register_protocol(proto_dec_rt);
1462 expert_register_field_array(expert_dec_rt, ei, array_length(ei));
1464 dec_rt_handle = register_dissector("dec_dna", dissect_dec_rt,
1465 proto_dec_rt);
1468 void
1469 proto_reg_handoff_dec_rt(void)
1471 dissector_add_uint("ethertype", ETHERTYPE_DNA_RT, dec_rt_handle);
1472 dissector_add_uint("chdlc.protocol", ETHERTYPE_DNA_RT, dec_rt_handle);
1473 dissector_add_uint("ppp.protocol", PPP_DEC4, dec_rt_handle);
1474 /* dissector_add_uint("ppp.protocol", PPP_DECNETCP, dec_rt_handle);*/
1478 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1480 * Local variables:
1481 * c-basic-offset: 4
1482 * tab-width: 8
1483 * indent-tabs-mode: nil
1484 * End:
1486 * vi: set shiftwidth=4 tabstop=8 expandtab:
1487 * :indentSize=4:tabSize=8:noTabs=true: