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
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
38 #include <epan/packet.h>
39 #include <epan/etypes.h>
40 #include <epan/expert.h>
41 #include <epan/ppptypes.h>
45 RT_CTL_INITIALIZATION
,
50 RT_CTL_ETH_ROUTER_HELLO_MSG
,
51 RT_CTL_ETH_ENDNODE_HELLO_MSG
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" */
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" },
182 static const value_string nsp_msg_type_vals
[] = {
183 { 0x00 , "Data segment continuation" },
184 { 0x04 , "Data acknowledgement message" },
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" },
201 static const value_string rt_tiinfo_vals
[] = {
202 {0x01, "Level 2 router"},
203 {0x02, "Level 1 router"},
205 {0x04, "Routing layer verification required"},
206 {0x08, "Blocking requested"},
210 static const value_string rt_iinfo_node_type_vals
[] = {
211 {0x01, "Level 2 router"},
212 {0x02, "Level 1 router"},
217 static const value_string rt_flow_control_vals
[] = {
219 {0x01, "do not send data"},
225 static const value_string rt_services_vals
[] = {
227 {0x01, "segment request count"},
228 {0x02, "Session control message request count"},
233 static const value_string rt_info_version_vals
[] = {
234 {0x00, "version 3.2"},
235 {0x01, "version 3.1"},
236 {0x02, "version 4.0"},
241 static const value_string rt_disc_reason_vals
[] = {
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"},
259 #define RT_TYPE_TOPOLOGY_CHANGE 2
260 #define RT_TYPE_HELLO 25
275 uint8_t nsp_msg_type
);
279 do_initialization_msg(
282 proto_tree
*ctl_msg_tree
,
289 proto_tree
*ctl_msg_tree
,
296 proto_tree
*ctl_msg_tree
,
303 proto_tree
*ctl_msg_tree
,
311 proto_tree
*ctl_msg_tree
,
316 handle_connect_contents(
322 handle_disc_init_contents(
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);
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
);
341 set_address(paddr_tgt
, AT_STRINGZ
, 1,
342 wmem_strdup(pinfo
->pool
, addr
));
347 dissect_dec_rt(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
349 uint8_t padding_length
;
352 unsigned rt_visit_count
, rt_zero
= 0;
355 proto_tree
*flags_tree
;
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
);
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,
393 proto_tree_add_uint(flags_tree
, hf_dec_ctl_msgs
, tvb
, offset
, 1,
396 ti
= proto_tree_add_uint(rt_tree
, hf_dec_ctl_msg_hdr
, tvb
, offset
, 1,
398 ctl_msg_tree
= proto_item_add_subtree(ti
, ett_dec_rt_ctl_msg
);
400 /* Get past the msg_flags */
402 switch (ctl_msg_type
) {
403 case RT_CTL_INITIALIZATION
:
404 do_initialization_msg(
405 tvb
, pinfo
, ctl_msg_tree
, offset
);
407 case RT_CTL_VERIFICATION
:
409 tvb
, pinfo
, ctl_msg_tree
, offset
);
411 case RT_CTL_HELLO_TEST
:
413 tvb
, pinfo
, ctl_msg_tree
, offset
);
415 case RT_CTL_LVL1_ROUTING
:
416 case RT_CTL_LVL2_ROUTING
:
418 tvb
, pinfo
, ctl_msg_tree
, offset
, msg_flags
>> 1);
420 case RT_CTL_ETH_ROUTER_HELLO_MSG
:
421 case RT_CTL_ETH_ENDNODE_HELLO_MSG
:
423 tvb
, pinfo
, ctl_msg_tree
, offset
, msg_flags
>> 1);
428 } else if (msg_flags
& RT_FLAGS_LONG_MSG
){
429 static int * const msg_bit_flags
[] = {
433 &hf_dec_rt_inter_eth
,
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
445 ti
= proto_tree_add_item(rt_tree
, hf_dec_rt_dst_addr
, tvb
,
447 addr
= dnet_ntoa(pinfo
->pool
, (const uint8_t *)tvb_memdup(pinfo
->pool
, tvb
, offset
, 6));
449 proto_item_append_text(ti
, " (%s)", addr
);
452 /* Skip 6 bytes for the MAC and
453 2 bytes for DEC area/subarea
456 ti
= proto_tree_add_item(rt_tree
, hf_dec_rt_src_addr
, tvb
,
458 addr
= dnet_ntoa(pinfo
->pool
, (const uint8_t *)tvb_memdup(pinfo
->pool
, tvb
, offset
, 6));
460 proto_item_append_text(ti
, " (%s)", addr
);
463 /* Proceed to the NL2 byte */
465 proto_tree_add_uint(rt_tree
, hf_dec_rt_nl2
, tvb
,
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
);
472 proto_tree_add_uint(rt_tree
, hf_dec_rt_service_class
, tvb
,
475 proto_tree_add_uint(rt_tree
, hf_dec_rt_protocol_type
, tvb
,
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
489 proto_tree_add_item(rt_tree
, hf_dec_rt_dst_node
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
491 proto_tree_add_item(rt_tree
, hf_dec_rt_src_node
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
493 forward
= tvb_get_uint8(tvb
, offset
);
494 proto_tree_add_uint(rt_tree
, hf_dec_rt_visited_nodes
, tvb
,
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 */
512 nsp_msg_tree
= proto_item_add_subtree(ti_local
, ett_dec_rt_nsp_msg
);
513 /* Get past the nsp_msg_type */
515 proto_tree_add_item(nsp_msg_tree
, hf_dec_rt_dst_node
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
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 */
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
);
532 return tvb_captured_length(tvb
);
536 do_initialization_msg(
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
);
550 proto_tree_add_item(tree
, hf_dec_rt_tiinfo
, tvb
,
551 my_offset
, 2, ENC_LITTLE_ENDIAN
);
553 proto_tree_add_item(tree
, hf_dec_rt_blk_size
, tvb
,
554 my_offset
, 2, ENC_LITTLE_ENDIAN
);
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
);
563 proto_tree_add_item(tree
, hf_dec_rt_timer
, tvb
,
564 my_offset
, 2, ENC_LITTLE_ENDIAN
);
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
;
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
);
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
;
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
);
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
;
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 */
638 remainder_count
= tvb_reported_length_remaining(tvb
, my_offset
);
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);
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
,
648 "Segment: count:%d, start Id: %d, hops:%d, cost: %d",
649 count
, startid
, (rtginfo
& 0x7c00) >> 10, rtginfo
& 0x3ff);
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
,
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
);
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
);
679 unsigned my_offset
= offset
;
681 uint16_t version
, eco_nr
, user_eco
;
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
,
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
);
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));
705 proto_item_append_text(ti
, " (%s)", addr
);
708 proto_tree_add_bitmask(tree
, tvb
, my_offset
, hf_dec_rt_iinfo
, ett_dec_rt_info_flags
, info_flags
, ENC_NA
);
711 proto_tree_add_item(tree
, hf_dec_rt_blk_size
, tvb
,
712 my_offset
, 2, ENC_LITTLE_ENDIAN
);
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
);
720 tree
, hf_dec_rt_iprio
, tvb
, my_offset
, 1, priority
);
723 /* Skip the 'area' field common to both hello messages */
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
);
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));
735 proto_item_append_text(ti
, " (%s)", addr
);
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
);
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
;
755 /* image field is preceded by count of remainder of field */
756 image_len
= tvb_get_uint8(tvb
, 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
);
770 /* image field is preceded by count of remainder of field */
771 item_len
= tvb_get_uint8(tvb
, my_offset
);
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));
784 proto_item_append_text(ti_localb
, " (%s)", addr
);
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
,
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
);
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
;
814 uint16_t ack_num
, ack_dat
, ack_oth
, seg_num
;
815 uint8_t ls_flags
, fc_val
, services
;
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
,
829 "Last data segment %s acknowledged: %d",
830 (ack_num
& 0x1000) ? "negatively" : "positively",
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
,
839 "Cross sub-channel %s of other data msg %d",
840 ((ack_oth
& 0x3000) == 0x2000) ? "ACK" : "NAK",
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",
855 } else if (nsp_msg_type
== DATA_SEGMENT_MSG
) {
856 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
857 "msg nr. %d: continuation segment ",
859 } else if (nsp_msg_type
== EOM_MSG
) {
860 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
861 "msg nr. %d: end of segment",
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",
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
);
875 /* Compute the number of bytes in this data segment */
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 */
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
,
891 "Last interrupt/link service msg %s acknowledged: %d",
892 (ack_num
& 0x1000) ? "negatively" : "positively",
895 /* There may still be an ack_dat field */
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
);
903 /* We are done, return my_offset */
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
,
911 "Cross sub-channel %s of data segment msg: %d",
912 ((ack_dat
& 0x3000) == 0x2000) ? "ACK" : "NAK",
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
);
922 /* We are done, return my_offset */
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
,
930 "Last interrupt/link service msg %s acknowledged: %d",
931 (ack_num
& 0x1000) ? "negatively" : "positively",
934 /* There may still be an ack_dat field */
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
);
942 /* We are done, return my_offset */
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
,
950 "Cross sub-channel %s of data segment msg: %d",
951 ((ack_dat
& 0x3000) == 0x2000) ? "ACK" : "NAK",
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
);
960 /* Now follows the ls_flags field */
961 ls_flags
= tvb_get_uint8(tvb
, my_offset
);
963 case 0: /* no change */
964 col_append_str(pinfo
->cinfo
, COL_INFO
,
967 case 1: /* stop sending data */
968 col_append_str(pinfo
->cinfo
, COL_INFO
,
971 case 2: /* send data */
972 col_append_str(pinfo
->cinfo
, COL_INFO
,
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
);
982 proto_item_add_subtree(ti
, ett_dec_flow_control
);
983 proto_tree_add_none_format(flow_control_tree
, hf_dec_rt_fc_val
,
985 "Request for additional %d %s msgs",
986 fc_val
, ((ls_flags
& 0x04) ? "interrupt" : "data"));
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
,
993 "Last data segment %s acknowledged: %d",
994 (ack_num
& 0x1000) ? "negatively" : "positively",
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",
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
,
1009 "Cross sub-channel %s of other data msg %d",
1010 ((ack_oth
& 0x3000) == 0x2000) ? "ACK" : "NAK",
1015 /* We are done, return my_offset */
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
,
1022 "Last interrupt/link service msg %s acknowledged: %d",
1023 (ack_num
& 0x1000) ? "negatively" : "positively",
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
,
1033 "Cross sub-channel %s of data msg %d",
1034 ((ack_dat
& 0x3000) == 0x2000) ? "ACK" : "NAK",
1039 /* We are done, return my_offset */
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
);
1048 proto_tree_add_item(tree
, hf_dec_rt_info
, tvb
, my_offset
, 1, ENC_LITTLE_ENDIAN
);
1050 proto_tree_add_item(tree
, hf_dec_rt_seg_size
, tvb
, my_offset
, 2, ENC_LITTLE_ENDIAN
);
1052 my_offset
= handle_connect_contents(tvb
, tree
, my_offset
);
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
);
1059 if (nsp_msg_type
== DISCONN_INITIATE_MSG
) {
1061 handle_disc_init_contents( my_offset
);
1071 handle_connect_contents(
1076 unsigned my_offset
= offset
;
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
);
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
);
1090 if (dst_format
== 2) {
1091 proto_tree_add_item(contents_tree
, hf_dec_sess_grp_code
, tvb
, my_offset
, 2, ENC_LITTLE_ENDIAN
);
1093 proto_tree_add_item(contents_tree
, hf_dec_sess_usr_code
, tvb
, my_offset
, 2, ENC_LITTLE_ENDIAN
);
1096 if (dst_format
!= 0) {
1097 /* The name field for formats 1 and 2 */
1098 image_len
= tvb_get_uint8(tvb
, 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
);
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
);
1110 if (src_format
== 2) {
1111 proto_tree_add_item(contents_tree
, hf_dec_sess_grp_code
, tvb
, my_offset
, 2, ENC_LITTLE_ENDIAN
);
1113 proto_tree_add_item(contents_tree
, hf_dec_sess_usr_code
, tvb
, my_offset
, 2, ENC_LITTLE_ENDIAN
);
1116 if (dst_format
!= 0) {
1117 /* The name field for formats 1 and 2 */
1118 image_len
= tvb_get_uint8(tvb
, 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
);
1129 proto_tree_add_string(contents_tree
, hf_dec_sess_menu_ver
,
1131 "Version 1.0: RQSTRID, PASSWRD and ACCOUNT fields included");
1133 image_len
= tvb_get_uint8(tvb
, 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
);
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
);
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
;
1152 /* A USRDATA field is handled by dissect_data */
1153 proto_tree_add_string(contents_tree
, hf_dec_sess_menu_ver
,
1155 "Version 1.0: USRDATA field included");
1158 proto_tree_add_string(contents_tree
, hf_dec_sess_menu_ver
,
1160 "Session control version 1.0");
1167 handle_disc_init_contents(
1170 unsigned my_offset
= offset
;
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
,
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
}},
1199 { "Return to Sender Request", "dec_dna.flags.RQR",
1200 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), RT_FLAGS_RQR
,
1203 { "Packet on return trip", "dec_dna.flags.RTS",
1204 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), RT_FLAGS_RTS
,
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
,
1210 { &hf_dec_rt_discard
,
1211 { "Discarded packet", "dec_dna.flags.discard",
1212 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), RT_FLAGS_DISCARD
,
1214 { &hf_dec_rt_dst_addr
,
1215 { "Destination Address", "dec_dna.dst.address",
1216 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
1218 { &hf_dec_rt_src_addr
,
1219 { "Source Address", "dec_dna.src.addr",
1220 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
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,
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,
1247 { "Version info", "dec_dna.nsp.info",
1248 FT_UINT8
, BASE_HEX
, VALS(rt_info_version_vals
), 0x03,
1250 { &hf_dec_rt_dst_node
,
1251 { "Destination node", "dec_dna.dst_node",
1252 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
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,
1262 { &hf_dec_rt_segnum
,
1263 { "Message number", "dec_dna.nsp.segnum",
1264 FT_UINT16
, BASE_DEC
, NULL
, 0x0fff,
1265 "Segment number", HFILL
}},
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,
1274 /* Control message items */
1276 { "Routing control message", "dec_dna.rt.msg_type",
1277 FT_UINT8
, BASE_HEX
, VALS(rt_msg_type_vals
), 0xe,
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,
1284 { "DNA NSP message", "dec_dna.nsp.msg_type",
1285 FT_UINT8
, BASE_HEX
, VALS(nsp_msg_type_vals
), 0x0,
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,
1295 { &hf_dec_rt_tiinfo
,
1296 { "Routing information", "dec_dna.ctl.tiinfo",
1297 FT_UINT16
, BASE_HEX
, VALS(rt_tiinfo_vals
), 0x0,
1299 { &hf_dec_rt_blk_size
,
1300 { "Block size", "dec_dna.ctl.blk_size",
1301 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
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,
1307 { &hf_dec_rt_version
,
1308 { "Version", "dec_dna.ctl.version",
1309 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1310 "Control protocol version", HFILL
}},
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,
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,
1335 { &hf_dec_rt_checksum_status
,
1336 { "Checksum Status", "dec_dna.ctl.checksum.status",
1337 FT_UINT8
, BASE_NONE
, VALS(proto_checksum_vals
), 0x0,
1340 { "Transmitting system ID", "dec_dna.ctl.id",
1341 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
1344 { "Routing information", "dec_dna.ctl.tiinfo",
1345 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
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,
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
}},
1372 { "Routing priority", "dec_dna.ctl.prio",
1373 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1375 { &hf_dec_rt_neighbor
,
1376 { "Neighbor", "dec_dna.ctl_neighbor",
1377 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
1378 "Neighbour ID", HFILL
}},
1380 { "Verification seed", "dec_dna.ctl.seed",
1381 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1384 { "List of router states", "dec_dna.ctl.elist",
1385 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1388 { "Ethernet name", "dec_dna.ctl.ename",
1389 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1391 { &hf_dec_rt_router_id
,
1392 { "Router ID", "dec_dna.ctl.router_id",
1393 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
1395 { &hf_dec_rt_router_state
,
1396 { "Router state", "dec_dna.ctl.router_state",
1397 FT_STRING
, BASE_NONE
, NULL
, 0x0,
1399 { &hf_dec_conn_contents
,
1400 { "Session connect data", "dec_dna.sess.conn",
1401 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1403 { &hf_dec_rt_router_prio
,
1404 { "Router priority", "dec_dna.ctl.router_prio",
1405 FT_UINT8
, BASE_HEX
, NULL
, 0x7f,
1407 { &hf_dec_sess_grp_code
,
1408 { "Session Group code", "dec_dna.sess.grp_code",
1409 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1411 { &hf_dec_sess_usr_code
,
1412 { "Session User code", "dec_dna.sess.usr_code",
1413 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1415 { &hf_dec_sess_dst_name
,
1416 { "Session Destination end user", "dec_dna.sess.dst_name",
1417 FT_STRING
, BASE_NONE
, NULL
, 0x0,
1419 { &hf_dec_sess_src_name
,
1420 { "Session Source end user", "dec_dna.sess.src_name",
1421 FT_STRING
, BASE_NONE
, NULL
, 0x0,
1423 { &hf_dec_sess_obj_type
,
1424 { "Session Object type", "dec_dna.sess.obj_type",
1425 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1427 { &hf_dec_sess_menu_ver
,
1428 { "Session Menu version", "dec_dna.sess.menu_ver",
1429 FT_STRING
, BASE_NONE
, NULL
, 0x0,
1431 { &hf_dec_sess_rqstr_id
,
1432 { "Session Requestor ID", "dec_dna.sess.rqstr_id",
1433 FT_STRING
, BASE_NONE
, NULL
, 0x0,
1438 static int *ett
[] = {
1440 &ett_dec_routing_flags
,
1442 &ett_dec_rt_ctl_msg
,
1443 &ett_dec_rt_nsp_msg
,
1444 &ett_dec_rt_info_flags
,
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
,
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
1483 * indent-tabs-mode: nil
1486 * vi: set shiftwidth=4 tabstop=8 expandtab:
1487 * :indentSize=4:tabSize=8:noTabs=true: