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)
11 * Use was made of the following documentation:
12 * (See URL http://linux-decnet.sourceforge.net/docs).
14 * DECnet DIGITAL Network Architecture
15 * Routing Layer Functional Specification
16 * Version 2.0.0 May, 1983
18 * DECnet DIGITAL Network Architecture
19 * NSP Functional Specification
20 * Phase IV, Version 4.0.1, July 1984
22 * DNA FS SESSION CONTROL
26 * Wireshark - Network traffic analyzer
27 * By Gerald Combs <gerald@wireshark.org>
28 * Copyright 1998 Gerald Combs
30 * This program is free software; you can redistribute it and/or
31 * modify it under the terms of the GNU General Public License
32 * as published by the Free Software Foundation; either version 2
33 * of the License, or (at your option) any later version.
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
40 * You should have received a copy of the GNU General Public License
41 * along with this program; if not, write to the Free Software
42 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
54 #include <epan/packet.h>
55 #include <epan/proto.h>
56 #include <epan/emem.h>
57 #include "packet-tcp.h"
58 #include <epan/etypes.h>
59 #include <epan/ppptypes.h>
62 RT_CTL_INITIALIZATION,
67 RT_CTL_ETH_ROUTER_HELLO_MSG,
68 RT_CTL_ETH_ENDNODE_HELLO_MSG
71 #define DEC_RT_SIZE 27
73 #define DATA_SEGMENT_MSG 0x00 /* "Data segment" */
74 #define LINK_SERVICE_MSG 0x10 /* "Link service message" */
75 #define BOM_MSG 0x20 /* "Beginning of segment (BOM)message" */
76 #define EOM_MSG 0x40 /* "End of segment (EOM)message" */
77 #define BOM_EOM_MSG 0x60 /* "BOM / EOM message" */
78 #define INTERRUPT_MSG 0x30 /* "Interrupt message" */
79 #define DATA_ACK_MSG 0x04 /* "Data acknowledgement message" */
80 #define OTHER_DATA_ACK_MSG 0x14 /* "Other data acknowledgement message" */
81 #define CONN_ACK_MSG 0x24 /* "Connect acknowledgement message" */
82 #define NOP_MSG 0x08 /* "NOP" */
83 #define CONN_INITIATE_MSG 0x18 /* "Connect initiate" */
84 #define CONN_CONFIRM_MSG 0x28 /* "Connect confirm" */
85 #define DISCONN_INITIATE_MSG 0x38 /* "Disconnect initiate" */
86 #define DISCONN_CONFIRM_MSG 0x48 /* "Disconnect confirm" */
87 #define RE_XMT_CONN_INIT_MSG 0x68 /* "Retransmitted connect initiate" */
91 #define RT_FLAGS_CTRL_MSG 0x01
92 #define RT_FLAGS_LONG_MSG 0x04 /* Actually: 0x06->long, 0x02->short*/
93 #define RT_FLAGS_RQR 0x08
94 #define RT_FLAGS_RTS 0x10
95 #define RT_FLAGS_INTRA_ETHER 0x20
96 #define RT_FLAGS_DISCARD 0x40
97 #define RT_FLAGS_PAD 0x80
99 static int proto_dec_rt = -1;
101 static int hf_dec_routing_flags = -1;
102 static int hf_dec_rt_ctrl_msg = -1;
103 static int hf_dec_rt_long_msg = -1;
104 static int hf_dec_rt_short_msg = -1;
105 static int hf_dec_rt_rqr = -1;
106 static int hf_dec_rt_rts = -1;
107 static int hf_dec_rt_inter_eth = -1;
108 static int hf_dec_rt_discard = -1;
109 static int hf_dec_rt_dst_addr = -1;
110 static int hf_dec_rt_src_addr = -1;
111 static int hf_dec_rt_nl2 = -1;
112 static int hf_dec_rt_service_class = -1;
113 static int hf_dec_rt_protocol_type = -1;
114 static int hf_dec_rt_visit_count = -1;
115 static int hf_dec_rt_dst_node = -1;
116 static int hf_dec_rt_src_node = -1;
117 /* Routing control messages */
118 static int hf_dec_rt_visited_nodes = -1;
119 static int hf_dec_ctl_msgs = -1;
120 static int hf_dec_ctl_msg_hdr = -1;
121 static int hf_dec_nsp_msgs = -1;
122 static int hf_dec_rt_tiinfo = -1;
123 static int hf_dec_rt_blk_size = -1;
124 static int hf_dec_rt_version = -1;
125 static int hf_dec_rt_timer = -1;
126 static int hf_dec_rt_reserved = -1;
127 static int hf_dec_rt_fcnval = -1;
128 static int hf_dec_rt_test_data = -1;
129 static int hf_dec_rt_segment = -1;
130 static int hf_dec_rt_id = -1;
131 static int hf_dec_rt_iinfo = -1;
132 static int hf_dec_rt_iinfo_node_type = -1;
133 static int hf_dec_rt_iinfo_vrf = -1;
134 static int hf_dec_rt_iinfo_rej = -1;
135 static int hf_dec_rt_iinfo_verf = -1;
136 static int hf_dec_rt_iinfo_mta = -1;
137 static int hf_dec_rt_iinfo_blkreq = -1;
138 static int hf_dec_rt_iprio = -1;
139 static int hf_dec_rt_neighbor = -1;
140 static int hf_dec_rt_seed = -1;
141 static int hf_dec_rt_elist = -1;
142 static int hf_dec_rt_ename = -1;
143 static int hf_dec_rt_router_id = -1;
144 static int hf_dec_rt_router_state = -1;
145 static int hf_dec_rt_router_prio = -1;
146 static int hf_dec_rt_seg_size = -1;
147 static int hf_dec_rt_acknum = -1;
148 static int hf_dec_rt_segnum = -1;
149 static int hf_dec_rt_delay = -1;
150 static int hf_dec_flow_control = -1;
151 static int hf_dec_rt_fc_val = -1;
152 static int hf_dec_rt_services = -1;
153 static int hf_dec_rt_info = -1;
154 static int hf_dec_disc_reason = -1;
155 static int hf_dec_conn_contents = -1;
156 static int hf_dec_sess_obj_type = -1;
157 static int hf_dec_sess_grp_code = -1;
158 static int hf_dec_sess_usr_code = -1;
159 static int hf_dec_sess_dst_name = -1;
160 static int hf_dec_sess_src_name = -1;
161 static int hf_dec_sess_menu_ver = -1;
162 static int hf_dec_sess_rqstr_id = -1;
164 static gint ett_dec_rt = -1;
165 static gint ett_dec_routing_flags = -1;
166 static gint ett_dec_msg_flags = -1;
167 static gint ett_dec_rt_ctl_msg = -1;
168 static gint ett_dec_rt_nsp_msg = -1;
169 static gint ett_dec_rt_info_flags = -1;
170 static gint ett_dec_rt_list = -1;
171 static gint ett_dec_rt_rlist = -1;
172 static gint ett_dec_rt_state = -1;
173 static gint ett_dec_flow_control = -1;
174 static gint ett_dec_sess_contents = -1;
176 static gint dec_dna_total_bytes_this_segment = 0;
177 static gint dec_dna_previous_total = 0;
179 /*static const value_string protocol_id_vals[] = {
180 { 0x6001, "DEC DNA dump/load" },
181 { 0x6002, "DEC DNA Remote Console" },
182 { 0x6003, "DEC DNA routing" },
183 { 0x6004, "DEC DNA Local Area Transport" },
184 { 0x6005, "DEC DNA diagnostics" },
185 { 0x6006, "DEC DNA Customer specific" },
186 { 0x6007, "DEC DNA System Communication Architecture" },
190 static const value_string rt_msg_type_vals[] = {
191 { 0x0 , "Initialization message" },
192 { 0x1 , "Verification message" },
193 { 0x2 , "Hello and test message" },
194 { 0x3 , "Level 1 routing message" },
195 { 0x4 , "Level 2 routing message" },
196 { 0x5 , "Ethernet router hello message" },
197 { 0x6 , "Ethernet endnode hello message" },
201 static const value_string nsp_msg_type_vals[] = {
202 { 0x00 , "Data segment continuation" },
203 { 0x04 , "Data acknowledgement message" },
205 { 0x10 , "Link service message" },
206 { 0x14 , "Other data acknowledgement message" },
207 { 0x18 , "Connect initiate" },
208 { 0x20 , "Beginning of segment message" },
209 { 0x24 , "Connect acknowledgement message" },
210 { 0x28 , "Connect confirm" },
211 { 0x30 , "Interrupt message" },
212 { 0x38 , "Disconnect initiate" },
213 { 0x40 , "End of segment message" },
214 { 0x48 , "Disconnect confirm" },
215 { 0x60 , "Begin of segment / End of segment" },
216 { 0x68 , "Retransmitted connect initiate" },
220 static const value_string rt_tiinfo_vals[] = {
221 {0x01, "Level 2 router"},
222 {0x02, "Level 1 router"},
224 {0x04, "Routing layer verification required"},
225 {0x08, "Blocking requested"},
229 static const value_string rt_iinfo_node_type_vals[] = {
230 {0x01, "Level 2 router"},
231 {0x02, "Level 1 router"},
236 static const value_string rt_flow_control_vals[] = {
238 {0x01, "do not send data"},
244 static const value_string rt_services_vals[] = {
246 {0x04, "segment request count"},
247 {0x08, "Session control message request count"},
252 static const value_string rt_info_version_vals[] = {
253 {0x00, "version 3.2"},
254 {0x01, "version 3.1"},
255 {0x02, "version 4.0"},
260 static const value_string rt_disc_reason_vals[] = {
262 { 3, "The node is shutting down"},
263 { 4, "The destination end user does not exist"},
264 { 5, "A connect message contains an invalid end user name"},
265 { 6, "Destination end user has insufficient resources"},
266 { 7, "Unspecified error"},
267 { 8, "A third party has disconnected the link"},
268 { 9, "An end user has aborted the logical link"},
269 { 32, "The node has insufficient resources"},
270 { 33, "Destination end user has insufficient resources"},
271 { 34, "Connect request rejected because incorrect RQSTRID or PASSWORD"},
272 { 36, "Connect request rejected because of unacceptable ACCOUNT info"},
273 { 38, "End user has timed out, aborted or cancelled a connect request"},
274 { 43, "Connect request RQSTRID, PASSWORD, ACCOUNT or USRDATA too long"},
278 #define RT_TYPE_TOPOLOGY_CHANGE 2
279 #define RT_TYPE_HELLO 25
294 guint8 nsp_msg_type);
298 do_initialization_msg(
301 proto_tree *ctl_msg_tree,
308 proto_tree *ctl_msg_tree,
315 proto_tree *ctl_msg_tree,
322 proto_tree *ctl_msg_tree,
330 proto_tree *ctl_msg_tree,
335 handle_connect_contents(
341 handle_disc_init_contents(
345 dnet_ntoa(const guint8 *data)
347 if (data[0] == 0xAA && data[1] == 0x00 && data[2] == 0x04 && data[3] == 0x00) {
348 guint16 dnet_addr = data[4] | (data[5] << 8);
349 return ep_strdup_printf("%d.%d", dnet_addr >> 10, dnet_addr & 0x03FF);
355 set_dnet_address(address *paddr_src, address *paddr_tgt)
357 if (paddr_tgt->type != AT_STRINGZ && paddr_src->type == AT_ETHER) {
358 char *addr = dnet_ntoa(paddr_src->data);
360 SET_ADDRESS(paddr_tgt, AT_STRINGZ, 1, addr);
365 dissect_dec_rt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
367 guint8 padding_length;
370 guint rt_visit_count, rt_zero = 0;
371 guint16 payload_length;
372 guint16 dst_node, src_node;
374 gboolean long_msg = false;
376 proto_tree *flags_tree;
381 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
382 col_clear(pinfo->cinfo, COL_PROTOCOL);
384 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
385 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DEC DNA");
387 if (check_col(pinfo->cinfo, COL_INFO)) {
388 col_clear(pinfo->cinfo, COL_INFO);
391 set_dnet_address(&pinfo->dl_src, &pinfo->net_src);
392 set_dnet_address(&pinfo->dl_src, &pinfo->src);
393 set_dnet_address(&pinfo->dl_dst, &pinfo->net_dst);
394 set_dnet_address(&pinfo->dl_dst, &pinfo->dst);
396 payload_length = tvb_get_letohs(tvb, offset);
398 msg_flags = tvb_get_guint8(tvb, offset);
399 ti = proto_tree_add_item(tree, proto_dec_rt, tvb, 0, -1,
401 rt_tree = proto_item_add_subtree(ti, ett_dec_rt);
402 /* When padding, the first byte after the padding has
403 the real routing flags */
404 if (msg_flags & 0x80) {
405 /* There is padding present, skip it */
406 padding_length = msg_flags & 0x7f;
407 offset += padding_length;
410 /* The real routing flag */
411 msg_flags = tvb_get_guint8(tvb, offset);
412 ti = proto_tree_add_uint(rt_tree, hf_dec_routing_flags, tvb,
413 offset, 1, msg_flags);
414 flags_tree = proto_item_add_subtree(ti, ett_dec_routing_flags);
416 if (msg_flags & RT_FLAGS_CTRL_MSG) {
419 proto_tree *ctl_msg_tree;
421 ctl_msg_type = (msg_flags >> 1) & 0x7;
422 proto_tree_add_boolean(flags_tree, hf_dec_rt_ctrl_msg, tvb, offset, 1,
424 proto_tree_add_uint(flags_tree, hf_dec_ctl_msgs, tvb, offset, 1,
427 ti = proto_tree_add_uint(rt_tree, hf_dec_ctl_msg_hdr, tvb, offset, 1,
429 ctl_msg_tree = proto_item_add_subtree(ti, ett_dec_rt_ctl_msg);
431 /* Get past the msg_flags */
433 switch (ctl_msg_type) {
434 case RT_CTL_INITIALIZATION:
436 do_initialization_msg(
437 tvb, pinfo, ctl_msg_tree, offset);
439 case RT_CTL_VERIFICATION:
442 tvb, pinfo, ctl_msg_tree, offset);
444 case RT_CTL_HELLO_TEST:
447 tvb, pinfo, ctl_msg_tree, offset);
449 case RT_CTL_LVL1_ROUTING:
450 case RT_CTL_LVL2_ROUTING:
453 tvb, pinfo, ctl_msg_tree, offset, msg_flags >> 1);
455 case RT_CTL_ETH_ROUTER_HELLO_MSG:
456 case RT_CTL_ETH_ENDNODE_HELLO_MSG:
459 tvb, pinfo, ctl_msg_tree, offset, msg_flags >> 1);
464 } else if (msg_flags & RT_FLAGS_LONG_MSG){
465 proto_tree_add_uint(flags_tree, hf_dec_rt_long_msg,
466 tvb, offset, 1, msg_flags);
467 proto_tree_add_boolean(flags_tree, hf_dec_rt_rqr, tvb,
468 offset, 1, msg_flags);
469 proto_tree_add_boolean(flags_tree, hf_dec_rt_rts, tvb,
470 offset, 1, msg_flags);
471 proto_tree_add_boolean(flags_tree, hf_dec_rt_inter_eth, tvb,
472 offset, 1, msg_flags);
473 proto_tree_add_boolean(flags_tree, hf_dec_rt_discard, tvb,
474 offset, 1, msg_flags);
477 /* Increment offset by three:
478 1 to get past the flags field
479 2 to skip the DEC area/subarea field
482 ti = proto_tree_add_item(rt_tree, hf_dec_rt_dst_addr, tvb,
484 addr = dnet_ntoa(ep_tvb_memdup(tvb, offset, 6));
486 proto_item_append_text(ti, " (%s)", addr);
489 /* Skip 6 bytes for the MAC and
490 2 bytes for DEC area/subarea
493 ti = proto_tree_add_item(rt_tree, hf_dec_rt_src_addr, tvb,
495 addr = dnet_ntoa(ep_tvb_memdup(tvb, offset, 6));
497 proto_item_append_text(ti, " (%s)", addr);
500 /* Proceed to the NL2 byte */
502 proto_tree_add_uint(rt_tree, hf_dec_rt_nl2, tvb,
505 rt_visit_count = tvb_get_guint8(tvb, offset);
506 proto_tree_add_uint(rt_tree, hf_dec_rt_visit_count, tvb,
507 offset, 1, rt_visit_count);
509 proto_tree_add_uint(rt_tree, hf_dec_rt_service_class, tvb,
512 proto_tree_add_uint(rt_tree, hf_dec_rt_protocol_type, tvb,
516 proto_tree_add_item(flags_tree, hf_dec_rt_short_msg,
517 tvb, offset, 1, msg_flags);
518 proto_tree_add_boolean(flags_tree, hf_dec_rt_rqr, tvb,
519 offset, 1, msg_flags);
520 proto_tree_add_boolean(flags_tree, hf_dec_rt_rts, tvb,
521 offset, 1, msg_flags);
523 /* Increment offset to get past the flags field
526 dst_node = tvb_get_letohs(tvb, offset);
527 proto_tree_add_item(rt_tree, hf_dec_rt_dst_node, tvb,
530 src_node = tvb_get_letohs(tvb, offset);
531 proto_tree_add_item(rt_tree, hf_dec_rt_src_node, tvb,
534 forward = tvb_get_guint8(tvb, offset);
535 proto_tree_add_uint(rt_tree, hf_dec_rt_visited_nodes, tvb,
540 if (!(msg_flags & RT_FLAGS_CTRL_MSG)) {
541 /* It is not a routing control message */
542 proto_tree *nsp_msg_tree;
543 proto_item *ti_local;
545 guint16 dst_node_local, src_node_local;
547 nsp_msg_type = tvb_get_guint8(tvb, offset);
548 ti_local = proto_tree_add_uint(
549 tree, hf_dec_nsp_msgs, tvb, offset, 1, nsp_msg_type);
550 if (nsp_msg_type == NOP_MSG) {
551 /* Only test data in this msg */
554 nsp_msg_tree = proto_item_add_subtree(ti_local, ett_dec_rt_nsp_msg);
555 /* Get past the nsp_msg_type */
557 dst_node_local = tvb_get_letohs(tvb, offset);
559 nsp_msg_tree, hf_dec_rt_dst_node, tvb, offset, 2, TRUE);
561 if (nsp_msg_type == CONN_ACK_MSG) {
562 if (check_col(pinfo->cinfo, COL_INFO)) {
563 col_set_str(pinfo->cinfo, COL_INFO,
564 "NSP connect acknowledgement");
565 /* Done with this msg type */
569 /* All other messages have a source node */
570 src_node_local = tvb_get_letohs(tvb, offset);
572 nsp_msg_tree, hf_dec_rt_src_node, tvb, offset, 2, TRUE);
585 do_initialization_msg(
591 guint my_offset = offset;
592 guint8 version, eco_nr, user_eco;
593 guint8 remainder_count;
595 if (check_col(pinfo->cinfo, COL_INFO)) {
596 col_set_str(pinfo->cinfo, COL_INFO,
597 "Routing control, initialization message");
599 proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
602 proto_tree_add_item(tree, hf_dec_rt_tiinfo, tvb,
605 proto_tree_add_item(tree, hf_dec_rt_blk_size, tvb,
608 version = tvb_get_guint8(tvb, my_offset);
609 eco_nr = tvb_get_guint8(tvb, my_offset + 1);
610 user_eco = tvb_get_guint8(tvb, my_offset + 2);
611 proto_tree_add_none_format(tree, hf_dec_rt_version, tvb,
612 my_offset, 3, "Routing Layer version: %d.%d.%d.",
613 version, eco_nr, user_eco);
615 proto_tree_add_item(tree, hf_dec_rt_timer, tvb,
618 remainder_count = tvb_get_guint8(tvb, my_offset);
619 if (remainder_count != 0) {
620 proto_tree_add_bytes(tree, hf_dec_rt_reserved, tvb,
621 my_offset, remainder_count,
622 tvb_get_ptr(tvb, my_offset, remainder_count));
623 my_offset += remainder_count;
635 guint my_offset = offset;
636 guint8 remainder_count;
638 if (check_col(pinfo->cinfo, COL_INFO)) {
639 col_set_str(pinfo->cinfo, COL_INFO,
640 "Routing control, verification message");
642 proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
645 remainder_count = tvb_get_guint8(tvb, my_offset);
646 if (remainder_count != 0) {
647 proto_tree_add_bytes(tree, hf_dec_rt_fcnval, tvb,
648 my_offset, remainder_count,
649 tvb_get_ptr(tvb, my_offset, remainder_count));
650 my_offset += remainder_count;
662 guint my_offset = offset;
663 guint remainder_count;
665 if (check_col(pinfo->cinfo, COL_INFO)) {
666 col_set_str(pinfo->cinfo, COL_INFO,
667 "Routing control, hello/test message");
669 proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
672 remainder_count = tvb_length_remaining(tvb, my_offset);
673 if (remainder_count != 0) {
674 proto_tree_add_bytes(tree, hf_dec_rt_test_data, tvb,
675 my_offset, remainder_count,
676 tvb_get_ptr(tvb, my_offset, remainder_count));
677 my_offset += remainder_count;
690 guint my_offset = offset;
691 guint32 my_checksum = 1;
693 guint16 count, startid, rtginfo;
694 guint remainder_count;
696 proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
698 /* Skip the 1-byte reserved field */
700 remainder_count = tvb_length_remaining(tvb, my_offset);
702 /* if the remainder_count == 1, only the checksum remains */
703 count = tvb_get_letohs(tvb, my_offset);
704 startid = tvb_get_letohs(tvb, my_offset + 2);
705 rtginfo = tvb_get_letohs(tvb, my_offset + 4);
707 if (check_col(pinfo->cinfo, COL_INFO)) {
708 col_set_str(pinfo->cinfo, COL_INFO,
709 "Routing control, Level 1 routing message");
711 proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
713 "Segment: count:%d, start Id: %d, hops:%d, cost: %d",
714 count, startid, (rtginfo & 0x7c00) >> 10, rtginfo & 0x3ff);
716 if (check_col(pinfo->cinfo, COL_INFO)) {
717 col_set_str(pinfo->cinfo, COL_INFO,
718 "Routing control, Level 2 routing message");
720 proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
722 "Segment: count:%d, start area: %d, hops:%d, cost: %d",
723 count, startid, (rtginfo & 0x7c00) >> 10, rtginfo & 0x3ff);
725 my_checksum += (count + startid + rtginfo);
727 remainder_count -= 6;
728 } while (remainder_count > 6);
729 my_offset += remainder_count - 2;
730 /* fold 32 bit sum into 16 bits */
731 while (my_checksum>>16)
732 my_checksum = (my_checksum & 0xffff) + (my_checksum >> 16);
733 checksum = tvb_get_letohs(tvb, my_offset);
734 if (checksum != my_checksum) {
735 proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
737 "Checksum mismatch(computed 0x%x <> received 0x%x)",
738 my_checksum, checksum);
740 proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
742 "Checksum: match (computed 0x%x = received 0x%x)",
743 my_checksum, checksum);
757 guint my_offset = offset;
758 guint8 iinfo, priority;
759 guint16 version, eco_nr, user_eco, timer;
761 proto_tree *iinfo_tree;
764 version = tvb_get_guint8(tvb, my_offset);
765 eco_nr = tvb_get_guint8(tvb, my_offset + 1);
766 user_eco = tvb_get_guint8(tvb, my_offset + 2);
767 proto_tree_add_none_format(tree, hf_dec_rt_version, tvb,
768 my_offset, 3, "Routing Layer Version: %d.%d.%d",
769 version, eco_nr, user_eco);
771 ti = proto_tree_add_item(tree, hf_dec_rt_id, tvb,
773 addr = dnet_ntoa(ep_tvb_memdup(tvb, my_offset, 6));
775 proto_item_append_text(ti, " (%s)", addr);
778 iinfo = tvb_get_guint8(tvb, my_offset);
779 ti = proto_tree_add_uint(
780 tree, hf_dec_rt_iinfo, tvb, my_offset, 1, iinfo);
781 iinfo_tree = proto_item_add_subtree(ti, ett_dec_rt_info_flags);
783 iinfo_tree, hf_dec_rt_iinfo_node_type, tvb, my_offset, 1, iinfo);
784 proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_vrf,
785 tvb, my_offset, 1, iinfo);
786 proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_rej,
787 tvb, my_offset, 1, iinfo);
788 proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_verf,
789 tvb, my_offset, 1, iinfo);
790 proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_mta,
791 tvb, my_offset, 1, iinfo);
792 proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_blkreq,
793 tvb, my_offset, 1, iinfo);
795 proto_tree_add_item(tree, hf_dec_rt_blk_size, tvb,
799 /* Ethernet router hello message
800 Has a 'priority' field in this position */
801 if (check_col(pinfo->cinfo, COL_INFO)) {
802 col_set_str(pinfo->cinfo, COL_INFO,
803 "Routing control, Ethernet Router Hello message");
805 priority = tvb_get_guint8(tvb, my_offset);
807 tree, hf_dec_rt_iprio, tvb, my_offset, 1, priority);
810 /* Skip the 'area' field common to both hello messages */
813 /* The endnode hello message has 'seed' and 'neighbor' fields */
816 if (check_col(pinfo->cinfo, COL_INFO)) {
817 col_set_str(pinfo->cinfo, COL_INFO,
818 "Routing control, Endnode Hello message");
820 seed = tvb_get_guint8(tvb, my_offset);
821 proto_tree_add_item(tree, hf_dec_rt_seed, tvb,
824 ti = proto_tree_add_item(tree, hf_dec_rt_neighbor, tvb,
826 addr = dnet_ntoa(ep_tvb_memdup(tvb, my_offset, 6));
828 proto_item_append_text(ti, " (%s)", addr);
832 /*'Timer' and 'mpd' fields are common
833 'mpd' field is reserved */
834 timer = tvb_get_letohs(tvb, my_offset);
835 proto_tree_add_item(tree, hf_dec_rt_timer, tvb,
839 /* The Ethernet router hello message contains
840 a list of router states
841 The Ethernet Endnode Hello Message contains
842 up to 128 bytes of test data at the end.
843 These data are left to be dissected as 'data'.
845 proto_item *ti_locala, *ti_ether;
846 proto_tree *list_tree, *list_ether;
850 ti_locala = proto_tree_add_item(tree, hf_dec_rt_elist, tvb,
853 /* image field is preceded by count of remainder of field */
854 image_len = tvb_get_guint8(tvb, my_offset);
856 ti_locala = proto_tree_add_none_format(tree, hf_dec_rt_elist,
857 tvb, my_offset, 1, "Router States");
858 list_tree = proto_item_add_subtree(ti_locala, ett_dec_rt_list);
859 while (image_len > 0) {
860 ti_ether = proto_tree_add_bytes(list_tree, hf_dec_rt_ename, tvb,
861 my_offset, 7, tvb_get_ptr(tvb, my_offset, 7));
862 list_ether = proto_item_add_subtree(ti_ether, ett_dec_rt_rlist);
866 /* image field is preceded by count of remainder of field */
867 item_len = tvb_get_guint8(tvb, my_offset);
873 proto_item *ti_localb;
874 proto_tree *pstate_tree;
876 ti_localb = proto_tree_add_item(list_ether, hf_dec_rt_router_id,
877 tvb, my_offset, 6, TRUE);
878 addr = dnet_ntoa(ep_tvb_memdup(tvb, my_offset, 6));
880 proto_item_append_text(ti_localb, " (%s)", addr);
883 pstate_tree = proto_item_add_subtree(ti_localb, ett_dec_rt_state);
884 pristate = tvb_get_guint8(tvb, my_offset);
885 proto_tree_add_string(list_ether, hf_dec_rt_router_state,
887 ((pristate & 0x80) ? "known 2-way": "unknown"));
888 proto_tree_add_uint(list_ether, hf_dec_rt_router_prio,
889 tvb, my_offset, 1, pristate);
907 /* Offset in tvb now points at the first byte still to be handled */
908 guint my_offset = offset;
910 guint16 ack_num, ack_dat, ack_oth, seg_num, seg_size, reason;
911 guint8 ls_flags, fc_val, services, info;
913 proto_tree *flow_control_tree;
915 /* 'tree' is now the subtree for the NSP message */
916 switch (nsp_msg_type) {
917 case DATA_SEGMENT_MSG: /* "Data segment" */
918 case BOM_MSG: /* "Beginning of segment message" */
919 case EOM_MSG: /* "End of segment message" */
920 case BOM_EOM_MSG: /* "BOM / EOM message" */
921 ack_num = tvb_get_letohs(tvb, my_offset);
922 if (ack_num & 0x8000) {
923 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
925 "Last data segment %s acknowledged: %d",
926 (ack_num & 0x1000) ? "negatively" : "positively",
929 /* There may still be an ackoth field */
930 ack_oth = tvb_get_letohs(tvb, my_offset);
931 if (ack_oth & 0x8000) {
932 /* There is an ack_oth field */
933 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
935 "Cross sub-channel %s of other data msg %d",
936 ((ack_oth & 0x3000) == 0x2000) ? "ACK" : "NAK",
942 * The optional ACKNUM and ACKOTH fields are not present
943 * There is still the segnum field
945 seg_num = tvb_get_letohs(tvb, my_offset);
946 if (check_col(pinfo->cinfo, COL_INFO)) {
947 if (nsp_msg_type == BOM_MSG) {
948 dec_dna_total_bytes_this_segment = 0;
949 col_append_fstr(pinfo->cinfo, COL_INFO,
950 "msg nr. %d: start of segment",
952 } else if (nsp_msg_type == DATA_SEGMENT_MSG) {
953 col_append_fstr(pinfo->cinfo, COL_INFO,
954 "msg nr. %d: continuation segment ",
956 } else if (nsp_msg_type == EOM_MSG) {
957 col_append_fstr(pinfo->cinfo, COL_INFO,
958 "msg nr. %d: end of segment",
960 } else if (nsp_msg_type == BOM_EOM_MSG) {
961 dec_dna_total_bytes_this_segment = 0;
962 col_append_fstr(pinfo->cinfo, COL_INFO,
963 "msg nr. %d single segment",
967 /* This is the last field, the rest are data */
968 proto_tree_add_item(tree, hf_dec_rt_segnum,
969 tvb, my_offset, 2, TRUE);
970 proto_tree_add_boolean(tree, hf_dec_rt_delay,
971 tvb, my_offset, 2, seg_num);
973 /* Compute the number of bytes in this data segment */
975 tvb_reported_length_remaining(tvb, my_offset);
976 dec_dna_previous_total = dec_dna_total_bytes_this_segment;
977 dec_dna_total_bytes_this_segment += data_length;
978 if (check_col(pinfo->cinfo, COL_INFO)) {
979 col_append_fstr(pinfo->cinfo, COL_INFO,
980 ", bytes this segment: %d, total so far:%d",
981 data_length, dec_dna_total_bytes_this_segment);
983 /* We are done, return my_offset */
985 case INTERRUPT_MSG: /* "Interrupt message" */
986 if (check_col(pinfo->cinfo, COL_INFO)) {
987 col_set_str(pinfo->cinfo, COL_INFO,
988 "NSP interrupt message");
990 ack_num = tvb_get_letohs(tvb, my_offset);
991 if (ack_num & 0x8000) {
992 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
994 "Last interrupt/link service msg %s acknowledged: %d",
995 (ack_num & 0x1000) ? "negatively" : "positively",
998 /* There may still be an ack_dat field */
1000 /* There are no ack/nak fields */
1001 proto_tree_add_item(tree, hf_dec_rt_segnum,
1002 tvb, my_offset, 2, TRUE);
1003 proto_tree_add_boolean(tree, hf_dec_rt_delay,
1004 tvb, my_offset, 2, ack_num);
1006 /* We are done, return my_offset */
1009 ack_dat = tvb_get_letohs(tvb, my_offset);
1010 if (ack_dat & 0x8000) {
1011 /* There is an ack_dat field */
1012 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1014 "Cross sub-channel %s of data segment msg: %d",
1015 ((ack_dat & 0x3000) == 0x2000) ? "ACK" : "NAK",
1019 seg_num = tvb_get_letohs(tvb, my_offset);
1020 /* This is the last field, the rest are data */
1021 proto_tree_add_item(tree, hf_dec_rt_segnum,
1022 tvb, my_offset, 2, TRUE);
1023 proto_tree_add_boolean(tree, hf_dec_rt_delay,
1024 tvb, my_offset, 2, seg_num);
1026 /* We are done, return my_offset */
1028 case LINK_SERVICE_MSG: /* "Link service message" */
1029 if (check_col(pinfo->cinfo, COL_INFO)) {
1030 col_set_str(pinfo->cinfo, COL_INFO,
1031 "NSP link control message");
1033 ack_num = tvb_get_letohs(tvb, my_offset);
1034 if (ack_num & 0x8000) {
1035 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1037 "Last interrupt/link service msg %s acknowledged: %d",
1038 (ack_num & 0x1000) ? "negatively" : "positively",
1041 /* There may still be an ack_dat field */
1043 /* There are no ack/nak fields */
1044 proto_tree_add_item(tree, hf_dec_rt_segnum,
1045 tvb, my_offset, 2, TRUE);
1046 proto_tree_add_boolean(tree, hf_dec_rt_delay,
1047 tvb, my_offset, 2, ack_num);
1049 /* We are done, return my_offset */
1052 ack_dat = tvb_get_letohs(tvb, my_offset);
1053 if (ack_dat & 0x8000) {
1054 /* There is an ack_dat field */
1055 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1057 "Cross sub-channel %s of data segment msg: %d",
1058 ((ack_dat & 0x3000) == 0x2000) ? "ACK" : "NAK",
1062 seg_num = tvb_get_letohs(tvb, my_offset);
1063 proto_tree_add_item(tree, hf_dec_rt_segnum,
1064 tvb, my_offset, 2, TRUE);
1065 proto_tree_add_boolean(tree, hf_dec_rt_delay,
1066 tvb, my_offset, 2, seg_num);
1068 /* Now follows the ls_flags field */
1069 ls_flags = tvb_get_guint8(tvb, my_offset);
1070 if (check_col(pinfo->cinfo, COL_INFO)) {
1072 case 0: /* no change */
1073 col_append_str(pinfo->cinfo, COL_INFO,
1076 case 1: /* stop sending data */
1077 col_append_str(pinfo->cinfo, COL_INFO,
1080 case 2: /* send data */
1081 col_append_str(pinfo->cinfo, COL_INFO,
1088 fc_val = tvb_get_guint8(tvb, my_offset + 1);
1089 ti = proto_tree_add_uint(tree, hf_dec_flow_control, tvb,
1090 my_offset, 1, ls_flags);
1092 proto_item_add_subtree(ti, ett_dec_flow_control);
1093 proto_tree_add_none_format(flow_control_tree, hf_dec_rt_fc_val,
1095 "Request for additional %d %s msgs",
1096 fc_val, ((ls_flags & 0x04) ? "interrupt" : "data"));
1099 case DATA_ACK_MSG: /* "Data acknowledgement message" */
1100 ack_num = tvb_get_letohs(tvb, my_offset);
1101 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1103 "Last data segment %s acknowledged: %d",
1104 (ack_num & 0x1000) ? "negatively" : "positively",
1107 /* There may be an optional ack_oth field */
1108 if (check_col(pinfo->cinfo, COL_INFO)) {
1109 col_append_fstr(pinfo->cinfo, COL_INFO,
1110 "NSP data %s message(%d)",
1111 (ack_num & 0x1000) ? "NAK" : "ACK",
1114 if (tvb_length_remaining(tvb, my_offset) > 0) {
1115 ack_oth = tvb_get_letohs(tvb, my_offset);
1116 if (ack_oth & 0x8000) {
1117 /* There is an ack_oth field */
1118 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1120 "Cross sub-channel %s of other data msg %d",
1121 ((ack_oth & 0x3000) == 0x2000) ? "ACK" : "NAK",
1126 /* We are done, return my_offset */
1128 case OTHER_DATA_ACK_MSG: /* "Other data acknowledgement message" */
1129 if (check_col(pinfo->cinfo, COL_INFO)) {
1130 col_set_str(pinfo->cinfo, COL_INFO,
1131 "NSP other data ACK message");
1133 ack_num = tvb_get_letohs(tvb, my_offset);
1134 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1136 "Last interrupt/link service msg %s acknowledged: %d",
1137 (ack_num & 0x1000) ? "negatively" : "positively",
1140 /* There may be an optional ack_dat field */
1141 if (tvb_length_remaining(tvb, my_offset) > 0) {
1142 ack_dat = tvb_get_letohs(tvb, my_offset);
1143 if (ack_dat & 0x8000) {
1144 /* There is an ack_dat field */
1145 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1147 "Cross sub-channel %s of data msg %d",
1148 ((ack_dat & 0x3000) == 0x2000) ? "ACK" : "NAK",
1153 /* We are done, return my_offset */
1155 case CONN_CONFIRM_MSG: /* "Connect confirm" */
1156 case CONN_INITIATE_MSG: /* "Connect initiate" */
1157 if (check_col(pinfo->cinfo, COL_INFO)) {
1158 col_set_str(pinfo->cinfo, COL_INFO,
1159 "NSP connect confirm/initiate message");
1161 services = tvb_get_guint8(tvb, my_offset);
1162 proto_tree_add_uint(tree, hf_dec_rt_services, tvb,
1163 my_offset, 1, services);
1165 info = tvb_get_guint8(tvb, my_offset);
1166 proto_tree_add_uint(tree, hf_dec_rt_info, tvb,
1167 my_offset, 1, info);
1169 seg_size = tvb_get_letohs(tvb, my_offset);
1170 proto_tree_add_item(tree, hf_dec_rt_seg_size, tvb,
1171 my_offset, 2, TRUE);
1174 handle_connect_contents(
1175 tvb, tree, my_offset);
1177 case DISCONN_INITIATE_MSG: /* "Disconnect initiate" */
1178 case DISCONN_CONFIRM_MSG: /* "Disconnect confirm" */
1179 if (check_col(pinfo->cinfo, COL_INFO)) {
1180 col_set_str(pinfo->cinfo, COL_INFO,
1181 "NSP disconnect initiate/confirm message");
1183 reason = tvb_get_letohs(tvb, my_offset);
1184 proto_tree_add_item(tree, hf_dec_disc_reason, tvb,
1185 my_offset, 2, TRUE);
1187 if (nsp_msg_type == DISCONN_INITIATE_MSG) {
1189 handle_disc_init_contents( my_offset);
1199 handle_connect_contents(
1204 guint my_offset = offset;
1206 proto_tree *contents_tree;
1207 guint8 dst_format, src_format, obj_type, image_len, menu_ver;
1208 guint16 grp_code, usr_code;
1210 ti = proto_tree_add_item(tree, hf_dec_conn_contents,
1211 tvb, my_offset, -1, TRUE);
1212 contents_tree = proto_item_add_subtree(ti, ett_dec_sess_contents);
1213 /* The destination end user */
1214 dst_format = tvb_get_guint8(tvb, my_offset);
1216 obj_type = tvb_get_guint8(tvb, my_offset);
1217 proto_tree_add_uint(contents_tree, hf_dec_sess_obj_type,
1218 tvb, my_offset, 1, obj_type);
1220 if (dst_format == 2) {
1221 grp_code = tvb_get_letohs(tvb, my_offset);
1222 proto_tree_add_item(contents_tree, hf_dec_sess_grp_code,
1223 tvb, my_offset, 2, TRUE);
1225 usr_code = tvb_get_letohs(tvb, my_offset);
1226 proto_tree_add_item(contents_tree, hf_dec_sess_usr_code,
1227 tvb, my_offset, 2, TRUE);
1230 if (dst_format != 0) {
1231 /* The name field for formats 1 and 2 */
1232 image_len = tvb_get_guint8(tvb, my_offset);
1234 proto_tree_add_item(contents_tree, hf_dec_sess_dst_name,
1235 tvb, my_offset, image_len, TRUE);
1236 my_offset += image_len;
1238 /* The source end user */
1239 src_format = tvb_get_guint8(tvb, my_offset);
1241 obj_type = tvb_get_guint8(tvb, my_offset);
1242 proto_tree_add_uint(contents_tree, hf_dec_sess_obj_type,
1243 tvb, my_offset, 1, obj_type);
1245 if (src_format == 2) {
1246 grp_code = tvb_get_letohs(tvb, my_offset);
1247 proto_tree_add_item(contents_tree, hf_dec_sess_grp_code,
1248 tvb, my_offset, 2, TRUE);
1250 usr_code = tvb_get_letohs(tvb, my_offset);
1251 proto_tree_add_item(contents_tree, hf_dec_sess_usr_code,
1252 tvb, my_offset, 2, TRUE);
1255 if (dst_format != 0) {
1256 /* The name field for formats 1 and 2 */
1257 image_len = tvb_get_guint8(tvb, my_offset);
1259 proto_tree_add_item(contents_tree, hf_dec_sess_src_name,
1260 tvb, my_offset, image_len, TRUE);
1261 my_offset += image_len;
1263 /* Now the MENUVER field */
1264 menu_ver = tvb_get_guint8(tvb, my_offset);
1268 proto_tree_add_string(contents_tree, hf_dec_sess_menu_ver,
1270 "Version 1.0: RQSTRID, PASSWRD and ACCOUNT fields included");
1272 image_len = tvb_get_guint8(tvb, my_offset);
1274 proto_tree_add_item(contents_tree, hf_dec_sess_rqstr_id,
1275 tvb, my_offset, image_len, TRUE);
1276 my_offset += image_len;
1277 image_len = tvb_get_guint8(tvb, my_offset);
1279 proto_tree_add_item(contents_tree, hf_dec_sess_rqstr_id,
1280 tvb, my_offset, image_len, TRUE);
1281 my_offset += image_len;
1282 image_len = tvb_get_guint8(tvb, my_offset);
1284 proto_tree_add_item(contents_tree, hf_dec_sess_rqstr_id,
1285 tvb, my_offset, image_len, TRUE);
1286 my_offset += image_len;
1291 /* A USRDATA field is handled by dissect_data */
1292 proto_tree_add_string(contents_tree, hf_dec_sess_menu_ver,
1294 "Version 1.0: USRDATA field included");
1297 proto_tree_add_string(contents_tree, hf_dec_sess_menu_ver,
1299 "Session control version 1.0");
1306 handle_disc_init_contents(
1309 guint my_offset = offset;
1315 static const true_false_string yesno = {
1321 proto_register_dec_rt(void)
1324 static hf_register_info hf[] = {
1325 /* Mesage header items */
1326 { &hf_dec_routing_flags,
1327 { "Routing flags", "dec_dna.flags",
1328 FT_UINT8, BASE_HEX, NULL, 0x0,
1329 "DNA routing flag", HFILL }},
1330 { &hf_dec_rt_ctrl_msg,
1331 { "Control packet", "dec_dna.flags.control",
1332 FT_BOOLEAN, 8, TFS(&yesno), RT_FLAGS_CTRL_MSG,
1333 "Control packet", HFILL }},
1334 { &hf_dec_rt_long_msg,
1335 { "Long data packet format", "dec_dna.flags.msglen",
1336 FT_UINT8, BASE_HEX, NULL, 0x06,
1337 "Long message indicator", HFILL }},
1338 { &hf_dec_rt_short_msg,
1339 { "Short data packet format", "dec_dna.flags.msglen",
1340 FT_UINT8, BASE_HEX, NULL, 0x06,
1341 "Short message indicator", HFILL }},
1343 { "Return to Sender Request", "dec_dna.flags.RQR",
1344 FT_BOOLEAN, 8, TFS(&yesno), RT_FLAGS_RQR,
1345 "Return to Sender", HFILL }},
1347 { "Packet on return trip", "dec_dna.flags.RTS",
1348 FT_BOOLEAN, 8, TFS(&yesno), RT_FLAGS_RTS,
1349 "Packet on return trip", HFILL }},
1350 { &hf_dec_rt_inter_eth,
1351 { "Intra-ethernet packet", "dec_dna.flags.intra_eth",
1352 FT_BOOLEAN, 8, TFS(&yesno), RT_FLAGS_INTRA_ETHER,
1353 "Intra-ethernet packet", HFILL }},
1354 { &hf_dec_rt_discard,
1355 { "Discarded packet", "dec_dna.flags.discard",
1356 FT_BOOLEAN, 8, TFS(&yesno), RT_FLAGS_DISCARD,
1357 "Discarded packet", HFILL }},
1358 { &hf_dec_rt_dst_addr,
1359 { "Destination Address", "dec_dna.dst.address",
1360 FT_ETHER, BASE_NONE, NULL, 0x0,
1361 "Destination address", HFILL }},
1362 { &hf_dec_rt_src_addr,
1363 { "Source Address", "dec_dna.src.addr",
1364 FT_ETHER, BASE_NONE, NULL, 0x0,
1365 "Source address", HFILL }},
1367 { "Next level 2 router", "dec_dna.nl2",
1368 FT_UINT8, BASE_HEX, NULL, 0x0,
1369 "reserved", HFILL }},
1370 { &hf_dec_rt_service_class,
1371 { "Service class", "dec_dna.svc_cls",
1372 FT_UINT8, BASE_HEX, NULL, 0x0,
1373 "reserved", HFILL }},
1374 { &hf_dec_rt_protocol_type,
1375 { "Protocol type", "dec_dna.proto_type",
1376 FT_UINT8, BASE_HEX, NULL, 0x0,
1377 "reserved", HFILL }},
1378 { &hf_dec_rt_visit_count,
1379 { "Visit count", "dec_dna.visit_cnt",
1380 FT_UINT8, BASE_HEX, NULL, 0x0,
1381 "Visit count", HFILL }},
1382 { &hf_dec_flow_control,
1383 { "Flow control", "dec_dna.nsp.flow_control",
1384 FT_UINT8, BASE_HEX, VALS(&rt_flow_control_vals), 0x3,
1385 "Flow control(stop, go)", HFILL }},
1386 { &hf_dec_rt_services,
1387 { "Requested services", "dec_dna.nsp.services",
1388 FT_UINT8, BASE_HEX, VALS(&rt_services_vals), 0x0c,
1389 "Services requested", HFILL }},
1391 { "Version info", "dec_dna.nsp.info",
1392 FT_UINT8, BASE_HEX, VALS(&rt_info_version_vals), 0x03,
1393 "Version info", HFILL }},
1394 { &hf_dec_rt_dst_node,
1395 { "Destination node", "dec_dna.dst_node",
1396 FT_UINT16, BASE_HEX, NULL, 0x0,
1397 "Destination node", HFILL }},
1398 { &hf_dec_rt_seg_size,
1399 { "Maximum data segment size", "dec_dna.nsp.segsize",
1400 FT_UINT16, BASE_DEC, NULL, 0x0,
1401 "Max. segment size", HFILL }},
1402 { &hf_dec_rt_src_node,
1403 { "Source node", "dec_dna.src_node",
1404 FT_UINT16, BASE_HEX, NULL, 0x0,
1405 "Source node", HFILL }},
1406 { &hf_dec_rt_segnum,
1407 { "Message number", "dec_dna.nsp.segnum",
1408 FT_UINT16, BASE_DEC, NULL, 0xfff,
1409 "Segment number", HFILL }},
1411 { "Delayed ACK allowed", "dec_dna.nsp.delay",
1412 FT_BOOLEAN, 16, TFS(&yesno), 0x1000,
1413 "Delayed ACK allowed?", HFILL }},
1414 { &hf_dec_rt_visited_nodes,
1415 { "Nodes visited ty this package", "dec_dna.vst_node",
1416 FT_UINT8, BASE_DEC, NULL, 0x0,
1417 "Nodes visited", HFILL }},
1418 /* Control messsage items */
1420 { "Routing control message", "dec_dna.rt.msg_type",
1421 FT_UINT8, BASE_HEX, VALS(&rt_msg_type_vals), 0xe,
1422 "Routing control", HFILL }},
1423 { &hf_dec_ctl_msg_hdr,
1424 { "Routing control message", "dec_dna.rt.msg_type",
1425 FT_UINT8, BASE_HEX, VALS(&rt_msg_type_vals), 0xe,
1426 "Routing control", HFILL }},
1428 { "DNA NSP message", "dec_dna.nsp.msg_type",
1429 FT_UINT8, BASE_HEX, VALS(&nsp_msg_type_vals), 0x0,
1430 "NSP message", HFILL }},
1431 { &hf_dec_rt_acknum,
1432 { "Ack/Nak", "dec_dna.ctl.acknum",
1433 FT_NONE, BASE_NONE, NULL, 0x0,
1434 "ack/nak number", HFILL }},
1435 { &hf_dec_rt_fc_val,
1436 { "Flow control", "dec_dna.nsp.fc_val",
1437 FT_NONE, BASE_NONE, NULL, 0x0,
1438 "Flow control", HFILL }},
1439 { &hf_dec_rt_tiinfo,
1440 { "Routing information", "dec_dna.ctl.tiinfo",
1441 FT_UINT8, BASE_HEX, VALS(&rt_tiinfo_vals), 0x0,
1442 "Routing information", HFILL }},
1443 { &hf_dec_rt_blk_size,
1444 { "Block size", "dec_dna.ctl.blk_size",
1445 FT_UINT16, BASE_DEC, NULL, 0x0,
1446 "Block size", HFILL }},
1447 { &hf_dec_disc_reason,
1448 { "Reason for disconnect","dec_dna.nsp.disc_reason",
1449 FT_UINT16, BASE_HEX, VALS(&rt_disc_reason_vals), 0x0,
1450 "Disconnect reason", HFILL }},
1451 { &hf_dec_rt_version,
1452 { "Version", "dec_dna.ctl.version",
1453 FT_NONE, BASE_NONE, NULL, 0x0,
1454 "Control protocol version", HFILL }},
1456 { "Hello timer(seconds)", "dec_dna.ctl.timer",
1457 FT_UINT16, BASE_DEC, NULL, 0x0,
1458 "Hello timer in seconds", HFILL }},
1459 { &hf_dec_rt_reserved,
1460 { "Reserved", "dec_dna.ctl.reserved",
1461 FT_BYTES, BASE_NONE, NULL, 0x0,
1462 "Reserved", HFILL }},
1463 { &hf_dec_rt_fcnval,
1464 { "Verification message function value", "dec_dna.ctl.fcnval",
1465 FT_BYTES, BASE_NONE, NULL, 0x0,
1466 "Routing Verification function", HFILL }},
1467 { &hf_dec_rt_test_data,
1468 { "Test message data", "dec_dna.ctl.test_data",
1469 FT_BYTES, BASE_NONE, NULL, 0x0,
1470 "Routing Test message data", HFILL }},
1471 { &hf_dec_rt_segment,
1472 { "Segment", "dec_dna.ctl.segment",
1473 FT_NONE, BASE_NONE, NULL, 0x0,
1474 "Routing Segment", HFILL }},
1476 { "Transmitting system ID", "dec_dna.ctl.id",
1477 FT_ETHER, BASE_NONE, NULL, 0x0,
1478 "Transmitting system ID", HFILL }},
1480 { "Routing information", "dec_dna.ctl.tiinfo",
1481 FT_UINT8, BASE_HEX, NULL, 0x0,
1482 "Routing information", HFILL }},
1483 { &hf_dec_rt_iinfo_node_type,
1484 { "Node type", "dec_dna.ctl.iinfo.node_type",
1485 FT_UINT8, BASE_HEX, VALS(&rt_iinfo_node_type_vals), 0x03,
1486 "Node type", HFILL }},
1487 { &hf_dec_rt_iinfo_vrf,
1488 { "Verification required", "dec_dna.ctl.iinfo.vrf",
1489 FT_BOOLEAN, 8, TFS(&yesno), 0x4,
1490 "Verification required?", HFILL }},
1491 { &hf_dec_rt_iinfo_rej,
1492 { "Rejected", "dec_dna.ctl.iinfo.rej",
1493 FT_BOOLEAN, 8, TFS(&yesno), 0x8,
1494 "Rejected message", HFILL }},
1495 { &hf_dec_rt_iinfo_verf,
1496 { "Verification failed", "dec_dna.ctl.iinfo.verf",
1497 FT_BOOLEAN, 8, TFS(&yesno), 0x10,
1498 "Verification failed?", HFILL }},
1499 { &hf_dec_rt_iinfo_mta,
1500 { "Accepts multicast traffic", "dec_dna.ctl.iinfo.mta",
1501 FT_BOOLEAN, 8, TFS(&yesno), 0x20,
1502 "Accepts multicast traffic?", HFILL }},
1503 { &hf_dec_rt_iinfo_blkreq,
1504 { "Blocking requested", "dec_dna.ctl.iinfo.blkreq",
1505 FT_BOOLEAN, 8, TFS(&yesno), 0x40,
1506 "Blocking requested?", HFILL }},
1508 { "Routing priority", "dec_dna.ctl.prio",
1509 FT_UINT8, BASE_HEX, NULL, 0x0,
1510 "Routing priority", HFILL }},
1511 { &hf_dec_rt_neighbor,
1512 { "Neighbor", "dec_dna.ctl_neighbor",
1513 FT_ETHER, BASE_NONE, NULL, 0x0,
1514 "Neighbour ID", HFILL }},
1516 { "Verification seed", "dec_dna.ctl.seed",
1517 FT_BYTES, BASE_NONE, NULL, 0x0,
1518 "Verification seed", HFILL }},
1520 { "List of router states", "dec_dna.ctl.elist",
1521 FT_NONE, BASE_NONE, NULL, 0x0,
1522 "Router states", HFILL }},
1524 { "Ethernet name", "dec_dna.ctl.ename",
1525 FT_BYTES, BASE_HEX, NULL, 0x0,
1526 "Ethernet name", HFILL }},
1527 { &hf_dec_rt_router_id,
1528 { "Router ID", "dec_dna.ctl.router_id",
1529 FT_ETHER, BASE_NONE, NULL, 0x0,
1530 "Router ID", HFILL }},
1531 { &hf_dec_rt_router_state,
1532 { "Router state", "dec_dna.ctl.router_state",
1533 FT_STRING, BASE_NONE, NULL, 0x0,
1534 "Router state", HFILL }},
1535 { &hf_dec_conn_contents,
1536 { "Session connect data", "dec_dna.sess.conn",
1537 FT_NONE, BASE_NONE, NULL, 0x0,
1538 "Session connect data", HFILL }},
1539 { &hf_dec_rt_router_prio,
1540 { "Router priority", "dec_dna.ctl.router_prio",
1541 FT_UINT8, BASE_HEX, NULL, 0x7f,
1542 "Router priority", HFILL }},
1543 { &hf_dec_sess_grp_code,
1544 { "Session Group code", "dec_dna.sess.grp_code",
1545 FT_UINT16, BASE_HEX, NULL, 0x0,
1546 "Session group code", HFILL }},
1547 { &hf_dec_sess_usr_code,
1548 { "Session User code", "dec_dna.sess.usr_code",
1549 FT_UINT16, BASE_HEX, NULL, 0x0,
1550 "Session User code", HFILL }},
1551 { &hf_dec_sess_dst_name,
1552 { "Session Destination end user", "dec_dna.sess.dst_name",
1553 FT_STRING, BASE_NONE, NULL, 0x0,
1554 "Session Destination end user", HFILL }},
1555 { &hf_dec_sess_src_name,
1556 { "Session Source end user", "dec_dna.sess.src_name",
1557 FT_STRING, BASE_NONE, NULL, 0x0,
1558 "Session Source end user", HFILL }},
1559 { &hf_dec_sess_obj_type,
1560 { "Session Object type", "dec_dna.sess.obj_type",
1561 FT_UINT8, BASE_HEX, NULL, 0x0,
1562 "Session object type", HFILL }},
1563 { &hf_dec_sess_menu_ver,
1564 { "Session Menu version", "dec_dna.sess.menu_ver",
1565 FT_STRING, BASE_NONE, NULL, 0x0,
1566 "Session menu version", HFILL }},
1567 { &hf_dec_sess_rqstr_id,
1568 { "Session Requestor ID", "dec_dna.sess.rqstr_id",
1569 FT_STRING, BASE_NONE, NULL, 0x0,
1570 "Session requestor ID", HFILL }},
1574 static gint *ett[] = {
1576 &ett_dec_routing_flags,
1578 &ett_dec_rt_ctl_msg,
1579 &ett_dec_rt_nsp_msg,
1580 &ett_dec_rt_info_flags,
1584 &ett_dec_flow_control,
1585 &ett_dec_sess_contents,
1588 proto_dec_rt = proto_register_protocol("DEC DNA Routing Protocol",
1589 "DEC_DNA", "dec_dna");
1590 proto_register_field_array(proto_dec_rt, hf, array_length(hf));
1591 proto_register_subtree_array(ett, array_length(ett));
1595 proto_reg_handoff_dec_rt(void)
1597 dissector_handle_t dec_rt_handle;
1599 dec_rt_handle = create_dissector_handle(dissect_dec_rt,
1601 dissector_add("ethertype", ETHERTYPE_DNA_RT, dec_rt_handle);
1602 dissector_add("chdlctype", ETHERTYPE_DNA_RT, dec_rt_handle);
1603 dissector_add("ppp.protocol", PPP_DEC4, dec_rt_handle);
1604 /* dissector_add("ppp.protocol", PPP_DECNETCP, dec_rt_handle);*/