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:
13 * DECnet DIGITAL Network Architecture
14 * Routing Layer Functional Specification
15 * Version 2.0.0 May, 1983
17 * DECnet DIGITAL Network Architecture
18 * NSP Functional Specification
19 * Phase IV, Version 4.0.1, July 1984
21 * DNA FS SESSION CONTROL
27 * http://h71000.www7.hp.com/wizard/decnet/
29 * for some DECnet specifications.
31 * Wireshark - Network traffic analyzer
32 * By Gerald Combs <gerald@wireshark.org>
33 * Copyright 1998 Gerald Combs
35 * This program is free software; you can redistribute it and/or
36 * modify it under the terms of the GNU General Public License
37 * as published by the Free Software Foundation; either version 2
38 * of the License, or (at your option) any later version.
40 * This program is distributed in the hope that it will be useful,
41 * but WITHOUT ANY WARRANTY; without even the implied warranty of
42 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43 * GNU General Public License for more details.
45 * You should have received a copy of the GNU General Public License
46 * along with this program; if not, write to the Free Software
47 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
55 #include <epan/packet.h>
56 #include <epan/emem.h>
57 #include <epan/etypes.h>
58 #include <epan/ppptypes.h>
61 RT_CTL_INITIALIZATION,
66 RT_CTL_ETH_ROUTER_HELLO_MSG,
67 RT_CTL_ETH_ENDNODE_HELLO_MSG
70 #define DEC_RT_SIZE 27
72 #define DATA_SEGMENT_MSG 0x00 /* "Data segment" */
73 #define LINK_SERVICE_MSG 0x10 /* "Link service message" */
74 #define BOM_MSG 0x20 /* "Beginning of segment (BOM)message" */
75 #define EOM_MSG 0x40 /* "End of segment (EOM)message" */
76 #define BOM_EOM_MSG 0x60 /* "BOM / EOM message" */
77 #define INTERRUPT_MSG 0x30 /* "Interrupt message" */
78 #define DATA_ACK_MSG 0x04 /* "Data acknowledgement message" */
79 #define OTHER_DATA_ACK_MSG 0x14 /* "Other data acknowledgement message" */
80 #define CONN_ACK_MSG 0x24 /* "Connect acknowledgement message" */
81 #define NOP_MSG 0x08 /* "NOP" */
82 #define CONN_INITIATE_MSG 0x18 /* "Connect initiate" */
83 #define CONN_CONFIRM_MSG 0x28 /* "Connect confirm" */
84 #define DISCONN_INITIATE_MSG 0x38 /* "Disconnect initiate" */
85 #define DISCONN_CONFIRM_MSG 0x48 /* "Disconnect confirm" */
86 #define RE_XMT_CONN_INIT_MSG 0x68 /* "Retransmitted connect initiate" */
90 #define RT_FLAGS_CTRL_MSG 0x01
91 #define RT_FLAGS_LONG_MSG 0x04 /* Actually: 0x06->long, 0x02->short*/
92 #define RT_FLAGS_RQR 0x08
93 #define RT_FLAGS_RTS 0x10
94 #define RT_FLAGS_INTRA_ETHER 0x20
95 #define RT_FLAGS_DISCARD 0x40
96 #define RT_FLAGS_PAD 0x80
98 static int proto_dec_rt = -1;
100 static int hf_dec_routing_flags = -1;
101 static int hf_dec_rt_ctrl_msg = -1;
102 static int hf_dec_rt_long_msg = -1;
103 static int hf_dec_rt_short_msg = -1;
104 static int hf_dec_rt_rqr = -1;
105 static int hf_dec_rt_rts = -1;
106 static int hf_dec_rt_inter_eth = -1;
107 static int hf_dec_rt_discard = -1;
108 static int hf_dec_rt_dst_addr = -1;
109 static int hf_dec_rt_src_addr = -1;
110 static int hf_dec_rt_nl2 = -1;
111 static int hf_dec_rt_service_class = -1;
112 static int hf_dec_rt_protocol_type = -1;
113 static int hf_dec_rt_visit_count = -1;
114 static int hf_dec_rt_dst_node = -1;
115 static int hf_dec_rt_src_node = -1;
116 /* Routing control messages */
117 static int hf_dec_rt_visited_nodes = -1;
118 static int hf_dec_ctl_msgs = -1;
119 static int hf_dec_ctl_msg_hdr = -1;
120 static int hf_dec_nsp_msgs = -1;
121 static int hf_dec_rt_tiinfo = -1;
122 static int hf_dec_rt_blk_size = -1;
123 static int hf_dec_rt_version = -1;
124 static int hf_dec_rt_timer = -1;
125 static int hf_dec_rt_reserved = -1;
126 static int hf_dec_rt_fcnval = -1;
127 static int hf_dec_rt_test_data = -1;
128 static int hf_dec_rt_segment = -1;
129 static int hf_dec_rt_id = -1;
130 static int hf_dec_rt_iinfo = -1;
131 static int hf_dec_rt_iinfo_node_type = -1;
132 static int hf_dec_rt_iinfo_vrf = -1;
133 static int hf_dec_rt_iinfo_rej = -1;
134 static int hf_dec_rt_iinfo_verf = -1;
135 static int hf_dec_rt_iinfo_mta = -1;
136 static int hf_dec_rt_iinfo_blkreq = -1;
137 static int hf_dec_rt_iprio = -1;
138 static int hf_dec_rt_neighbor = -1;
139 static int hf_dec_rt_seed = -1;
140 static int hf_dec_rt_elist = -1;
141 static int hf_dec_rt_ename = -1;
142 static int hf_dec_rt_router_id = -1;
143 static int hf_dec_rt_router_state = -1;
144 static int hf_dec_rt_router_prio = -1;
145 static int hf_dec_rt_seg_size = -1;
146 static int hf_dec_rt_acknum = -1;
147 static int hf_dec_rt_segnum = -1;
148 static int hf_dec_rt_delay = -1;
149 static int hf_dec_flow_control = -1;
150 static int hf_dec_rt_fc_val = -1;
151 static int hf_dec_rt_services = -1;
152 static int hf_dec_rt_info = -1;
153 static int hf_dec_disc_reason = -1;
154 static int hf_dec_conn_contents = -1;
155 static int hf_dec_sess_obj_type = -1;
156 static int hf_dec_sess_grp_code = -1;
157 static int hf_dec_sess_usr_code = -1;
158 static int hf_dec_sess_dst_name = -1;
159 static int hf_dec_sess_src_name = -1;
160 static int hf_dec_sess_menu_ver = -1;
161 static int hf_dec_sess_rqstr_id = -1;
163 static gint ett_dec_rt = -1;
164 static gint ett_dec_routing_flags = -1;
165 static gint ett_dec_msg_flags = -1;
166 static gint ett_dec_rt_ctl_msg = -1;
167 static gint ett_dec_rt_nsp_msg = -1;
168 static gint ett_dec_rt_info_flags = -1;
169 static gint ett_dec_rt_list = -1;
170 static gint ett_dec_rt_rlist = -1;
171 static gint ett_dec_rt_state = -1;
172 static gint ett_dec_flow_control = -1;
173 static gint ett_dec_sess_contents = -1;
175 static gint dec_dna_total_bytes_this_segment = 0;
176 static gint dec_dna_previous_total = 0;
178 /*static const value_string protocol_id_vals[] = {
179 { 0x6001, "DEC DNA dump/load" },
180 { 0x6002, "DEC DNA Remote Console" },
181 { 0x6003, "DEC DNA routing" },
182 { 0x6004, "DEC DNA Local Area Transport" },
183 { 0x6005, "DEC DNA diagnostics" },
184 { 0x6006, "DEC DNA Customer specific" },
185 { 0x6007, "DEC DNA System Communication Architecture" },
189 static const value_string rt_msg_type_vals[] = {
190 { 0x0 , "Initialization message" },
191 { 0x1 , "Verification message" },
192 { 0x2 , "Hello and test message" },
193 { 0x3 , "Level 1 routing message" },
194 { 0x4 , "Level 2 routing message" },
195 { 0x5 , "Ethernet router hello message" },
196 { 0x6 , "Ethernet endnode hello message" },
200 static const value_string nsp_msg_type_vals[] = {
201 { 0x00 , "Data segment continuation" },
202 { 0x04 , "Data acknowledgement message" },
204 { 0x10 , "Link service message" },
205 { 0x14 , "Other data acknowledgement message" },
206 { 0x18 , "Connect initiate" },
207 { 0x20 , "Beginning of segment message" },
208 { 0x24 , "Connect acknowledgement message" },
209 { 0x28 , "Connect confirm" },
210 { 0x30 , "Interrupt message" },
211 { 0x38 , "Disconnect initiate" },
212 { 0x40 , "End of segment message" },
213 { 0x48 , "Disconnect confirm" },
214 { 0x60 , "Begin of segment / End of segment" },
215 { 0x68 , "Retransmitted connect initiate" },
219 static const value_string rt_tiinfo_vals[] = {
220 {0x01, "Level 2 router"},
221 {0x02, "Level 1 router"},
223 {0x04, "Routing layer verification required"},
224 {0x08, "Blocking requested"},
228 static const value_string rt_iinfo_node_type_vals[] = {
229 {0x01, "Level 2 router"},
230 {0x02, "Level 1 router"},
235 static const value_string rt_flow_control_vals[] = {
237 {0x01, "do not send data"},
243 static const value_string rt_services_vals[] = {
245 {0x04, "segment request count"},
246 {0x08, "Session control message request count"},
251 static const value_string rt_info_version_vals[] = {
252 {0x00, "version 3.2"},
253 {0x01, "version 3.1"},
254 {0x02, "version 4.0"},
259 static const value_string rt_disc_reason_vals[] = {
261 { 3, "The node is shutting down"},
262 { 4, "The destination end user does not exist"},
263 { 5, "A connect message contains an invalid end user name"},
264 { 6, "Destination end user has insufficient resources"},
265 { 7, "Unspecified error"},
266 { 8, "A third party has disconnected the link"},
267 { 9, "An end user has aborted the logical link"},
268 { 32, "The node has insufficient resources"},
269 { 33, "Destination end user has insufficient resources"},
270 { 34, "Connect request rejected because incorrect RQSTRID or PASSWORD"},
271 { 36, "Connect request rejected because of unacceptable ACCOUNT info"},
272 { 38, "End user has timed out, aborted or cancelled a connect request"},
273 { 43, "Connect request RQSTRID, PASSWORD, ACCOUNT or USRDATA too long"},
277 #define RT_TYPE_TOPOLOGY_CHANGE 2
278 #define RT_TYPE_HELLO 25
293 guint8 nsp_msg_type);
297 do_initialization_msg(
300 proto_tree *ctl_msg_tree,
307 proto_tree *ctl_msg_tree,
314 proto_tree *ctl_msg_tree,
321 proto_tree *ctl_msg_tree,
329 proto_tree *ctl_msg_tree,
334 handle_connect_contents(
340 handle_disc_init_contents(
344 dnet_ntoa(const guint8 *data)
346 if (data[0] == 0xAA && data[1] == 0x00 && data[2] == 0x04 && data[3] == 0x00) {
347 guint16 dnet_addr = data[4] | (data[5] << 8);
348 return ep_strdup_printf("%d.%d", dnet_addr >> 10, dnet_addr & 0x03FF);
354 set_dnet_address(address *paddr_src, address *paddr_tgt)
356 if (paddr_tgt->type != AT_STRINGZ && paddr_src->type == AT_ETHER) {
357 char *addr = dnet_ntoa(paddr_src->data);
359 SET_ADDRESS(paddr_tgt, AT_STRINGZ, 1, addr);
364 dissect_dec_rt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
366 guint8 padding_length;
369 guint rt_visit_count, rt_zero = 0;
370 guint16 payload_length;
371 guint16 dst_node, src_node;
373 gboolean long_msg = false;
375 proto_tree *flags_tree;
380 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DEC DNA");
381 col_clear(pinfo->cinfo, COL_INFO);
383 set_dnet_address(&pinfo->dl_src, &pinfo->net_src);
384 set_dnet_address(&pinfo->dl_src, &pinfo->src);
385 set_dnet_address(&pinfo->dl_dst, &pinfo->net_dst);
386 set_dnet_address(&pinfo->dl_dst, &pinfo->dst);
388 payload_length = tvb_get_letohs(tvb, offset);
390 msg_flags = tvb_get_guint8(tvb, offset);
391 ti = proto_tree_add_item(tree, proto_dec_rt, tvb, 0, -1,
393 rt_tree = proto_item_add_subtree(ti, ett_dec_rt);
394 /* When padding, the first byte after the padding has
395 the real routing flags */
396 if (msg_flags & 0x80) {
397 /* There is padding present, skip it */
398 padding_length = msg_flags & 0x7f;
399 offset += padding_length;
402 /* The real routing flag */
403 msg_flags = tvb_get_guint8(tvb, offset);
404 ti = proto_tree_add_uint(rt_tree, hf_dec_routing_flags, tvb,
405 offset, 1, msg_flags);
406 flags_tree = proto_item_add_subtree(ti, ett_dec_routing_flags);
408 if (msg_flags & RT_FLAGS_CTRL_MSG) {
411 proto_tree *ctl_msg_tree;
413 ctl_msg_type = (msg_flags >> 1) & 0x7;
414 proto_tree_add_boolean(flags_tree, hf_dec_rt_ctrl_msg, tvb, offset, 1,
416 proto_tree_add_uint(flags_tree, hf_dec_ctl_msgs, tvb, offset, 1,
419 ti = proto_tree_add_uint(rt_tree, hf_dec_ctl_msg_hdr, tvb, offset, 1,
421 ctl_msg_tree = proto_item_add_subtree(ti, ett_dec_rt_ctl_msg);
423 /* Get past the msg_flags */
425 switch (ctl_msg_type) {
426 case RT_CTL_INITIALIZATION:
428 do_initialization_msg(
429 tvb, pinfo, ctl_msg_tree, offset);
431 case RT_CTL_VERIFICATION:
434 tvb, pinfo, ctl_msg_tree, offset);
436 case RT_CTL_HELLO_TEST:
439 tvb, pinfo, ctl_msg_tree, offset);
441 case RT_CTL_LVL1_ROUTING:
442 case RT_CTL_LVL2_ROUTING:
445 tvb, pinfo, ctl_msg_tree, offset, msg_flags >> 1);
447 case RT_CTL_ETH_ROUTER_HELLO_MSG:
448 case RT_CTL_ETH_ENDNODE_HELLO_MSG:
451 tvb, pinfo, ctl_msg_tree, offset, msg_flags >> 1);
456 } else if (msg_flags & RT_FLAGS_LONG_MSG){
457 proto_tree_add_uint(flags_tree, hf_dec_rt_long_msg,
458 tvb, offset, 1, msg_flags);
459 proto_tree_add_boolean(flags_tree, hf_dec_rt_rqr, tvb,
460 offset, 1, msg_flags);
461 proto_tree_add_boolean(flags_tree, hf_dec_rt_rts, tvb,
462 offset, 1, msg_flags);
463 proto_tree_add_boolean(flags_tree, hf_dec_rt_inter_eth, tvb,
464 offset, 1, msg_flags);
465 proto_tree_add_boolean(flags_tree, hf_dec_rt_discard, tvb,
466 offset, 1, msg_flags);
469 /* Increment offset by three:
470 1 to get past the flags field
471 2 to skip the DEC area/subarea field
474 ti = proto_tree_add_item(rt_tree, hf_dec_rt_dst_addr, tvb,
476 addr = dnet_ntoa(ep_tvb_memdup(tvb, offset, 6));
478 proto_item_append_text(ti, " (%s)", addr);
481 /* Skip 6 bytes for the MAC and
482 2 bytes for DEC area/subarea
485 ti = proto_tree_add_item(rt_tree, hf_dec_rt_src_addr, tvb,
487 addr = dnet_ntoa(ep_tvb_memdup(tvb, offset, 6));
489 proto_item_append_text(ti, " (%s)", addr);
492 /* Proceed to the NL2 byte */
494 proto_tree_add_uint(rt_tree, hf_dec_rt_nl2, tvb,
497 rt_visit_count = tvb_get_guint8(tvb, offset);
498 proto_tree_add_uint(rt_tree, hf_dec_rt_visit_count, tvb,
499 offset, 1, rt_visit_count);
501 proto_tree_add_uint(rt_tree, hf_dec_rt_service_class, tvb,
504 proto_tree_add_uint(rt_tree, hf_dec_rt_protocol_type, tvb,
508 proto_tree_add_uint(flags_tree, hf_dec_rt_short_msg,
509 tvb, offset, 1, msg_flags);
510 proto_tree_add_boolean(flags_tree, hf_dec_rt_rqr, tvb,
511 offset, 1, msg_flags);
512 proto_tree_add_boolean(flags_tree, hf_dec_rt_rts, tvb,
513 offset, 1, msg_flags);
515 /* Increment offset to get past the flags field
518 dst_node = tvb_get_letohs(tvb, offset);
519 proto_tree_add_item(rt_tree, hf_dec_rt_dst_node, tvb,
520 offset, 2, ENC_LITTLE_ENDIAN);
522 src_node = tvb_get_letohs(tvb, offset);
523 proto_tree_add_item(rt_tree, hf_dec_rt_src_node, tvb,
524 offset, 2, ENC_LITTLE_ENDIAN);
526 forward = tvb_get_guint8(tvb, offset);
527 proto_tree_add_uint(rt_tree, hf_dec_rt_visited_nodes, tvb,
532 if (!(msg_flags & RT_FLAGS_CTRL_MSG)) {
533 /* It is not a routing control message */
534 proto_tree *nsp_msg_tree;
535 proto_item *ti_local;
537 guint16 dst_node_local, src_node_local;
539 nsp_msg_type = tvb_get_guint8(tvb, offset);
540 ti_local = proto_tree_add_uint(
541 tree, hf_dec_nsp_msgs, tvb, offset, 1, nsp_msg_type);
542 if (nsp_msg_type == NOP_MSG) {
543 /* Only test data in this msg */
546 nsp_msg_tree = proto_item_add_subtree(ti_local, ett_dec_rt_nsp_msg);
547 /* Get past the nsp_msg_type */
549 dst_node_local = tvb_get_letohs(tvb, offset);
551 nsp_msg_tree, hf_dec_rt_dst_node, tvb, offset, 2, ENC_LITTLE_ENDIAN);
553 if (nsp_msg_type == CONN_ACK_MSG) {
554 col_set_str(pinfo->cinfo, COL_INFO, "NSP connect acknowledgement");
555 /* Done with this msg type */
558 /* All other messages have a source node */
559 src_node_local = tvb_get_letohs(tvb, offset);
561 nsp_msg_tree, hf_dec_rt_src_node, tvb, offset, 2, ENC_LITTLE_ENDIAN);
574 do_initialization_msg(
580 guint my_offset = offset;
581 guint8 version, eco_nr, user_eco;
582 guint8 remainder_count;
584 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, initialization message");
585 proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
586 my_offset, 2, ENC_LITTLE_ENDIAN);
588 proto_tree_add_item(tree, hf_dec_rt_tiinfo, tvb,
589 my_offset, 2, ENC_LITTLE_ENDIAN);
591 proto_tree_add_item(tree, hf_dec_rt_blk_size, tvb,
592 my_offset, 2, ENC_LITTLE_ENDIAN);
594 version = tvb_get_guint8(tvb, my_offset);
595 eco_nr = tvb_get_guint8(tvb, my_offset + 1);
596 user_eco = tvb_get_guint8(tvb, my_offset + 2);
597 proto_tree_add_none_format(tree, hf_dec_rt_version, tvb,
598 my_offset, 3, "Routing Layer version: %d.%d.%d.",
599 version, eco_nr, user_eco);
601 proto_tree_add_item(tree, hf_dec_rt_timer, tvb,
602 my_offset, 2, ENC_LITTLE_ENDIAN);
604 remainder_count = tvb_get_guint8(tvb, my_offset);
605 if (remainder_count != 0) {
606 proto_tree_add_item(tree, hf_dec_rt_reserved, tvb,
607 my_offset, remainder_count, ENC_NA);
608 my_offset += remainder_count;
620 guint my_offset = offset;
621 guint8 remainder_count;
623 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, verification message");
624 proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
625 my_offset, 2, ENC_LITTLE_ENDIAN);
627 remainder_count = tvb_get_guint8(tvb, my_offset);
628 if (remainder_count != 0) {
629 proto_tree_add_item(tree, hf_dec_rt_fcnval, tvb,
630 my_offset, remainder_count, ENC_NA);
631 my_offset += remainder_count;
643 guint my_offset = offset;
644 guint remainder_count;
646 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, hello/test message");
647 proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
648 my_offset, 2, ENC_LITTLE_ENDIAN);
650 remainder_count = tvb_length_remaining(tvb, my_offset);
651 if (remainder_count != 0) {
652 proto_tree_add_item(tree, hf_dec_rt_test_data, tvb,
653 my_offset, remainder_count, ENC_NA);
654 my_offset += remainder_count;
667 guint my_offset = offset;
668 guint32 my_checksum = 1;
670 guint16 count, startid, rtginfo;
671 guint remainder_count;
673 proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
674 my_offset, 2, ENC_LITTLE_ENDIAN);
675 /* Skip the 1-byte reserved field */
677 remainder_count = tvb_length_remaining(tvb, my_offset);
679 /* if the remainder_count == 1, only the checksum remains */
680 count = tvb_get_letohs(tvb, my_offset);
681 startid = tvb_get_letohs(tvb, my_offset + 2);
682 rtginfo = tvb_get_letohs(tvb, my_offset + 4);
684 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, Level 1 routing message");
685 proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
687 "Segment: count:%d, start Id: %d, hops:%d, cost: %d",
688 count, startid, (rtginfo & 0x7c00) >> 10, rtginfo & 0x3ff);
690 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, Level 2 routing message");
691 proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
693 "Segment: count:%d, start area: %d, hops:%d, cost: %d",
694 count, startid, (rtginfo & 0x7c00) >> 10, rtginfo & 0x3ff);
696 my_checksum += (count + startid + rtginfo);
698 remainder_count -= 6;
699 } while (remainder_count > 6);
700 my_offset += remainder_count - 2;
701 /* fold 32 bit sum into 16 bits */
702 while (my_checksum>>16)
703 my_checksum = (my_checksum & 0xffff) + (my_checksum >> 16);
704 checksum = tvb_get_letohs(tvb, my_offset);
705 if (checksum != my_checksum) {
706 proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
708 "Checksum mismatch(computed 0x%x <> received 0x%x)",
709 my_checksum, checksum);
711 proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
713 "Checksum: match (computed 0x%x = received 0x%x)",
714 my_checksum, checksum);
728 guint my_offset = offset;
729 guint8 iinfo, priority;
730 guint16 version, eco_nr, user_eco, timer;
732 proto_tree *iinfo_tree;
735 version = tvb_get_guint8(tvb, my_offset);
736 eco_nr = tvb_get_guint8(tvb, my_offset + 1);
737 user_eco = tvb_get_guint8(tvb, my_offset + 2);
738 proto_tree_add_none_format(tree, hf_dec_rt_version, tvb,
739 my_offset, 3, "Routing Layer Version: %d.%d.%d",
740 version, eco_nr, user_eco);
742 ti = proto_tree_add_item(tree, hf_dec_rt_id, tvb,
743 my_offset, 6, ENC_NA);
744 addr = dnet_ntoa(ep_tvb_memdup(tvb, my_offset, 6));
746 proto_item_append_text(ti, " (%s)", addr);
749 iinfo = tvb_get_guint8(tvb, my_offset);
750 ti = proto_tree_add_uint(
751 tree, hf_dec_rt_iinfo, tvb, my_offset, 1, iinfo);
752 iinfo_tree = proto_item_add_subtree(ti, ett_dec_rt_info_flags);
754 iinfo_tree, hf_dec_rt_iinfo_node_type, tvb, my_offset, 1, iinfo);
755 proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_vrf,
756 tvb, my_offset, 1, iinfo);
757 proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_rej,
758 tvb, my_offset, 1, iinfo);
759 proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_verf,
760 tvb, my_offset, 1, iinfo);
761 proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_mta,
762 tvb, my_offset, 1, iinfo);
763 proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_blkreq,
764 tvb, my_offset, 1, iinfo);
766 proto_tree_add_item(tree, hf_dec_rt_blk_size, tvb,
767 my_offset, 2, ENC_LITTLE_ENDIAN);
770 /* Ethernet router hello message
771 Has a 'priority' field in this position */
772 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, Ethernet Router Hello message");
773 priority = tvb_get_guint8(tvb, my_offset);
775 tree, hf_dec_rt_iprio, tvb, my_offset, 1, priority);
778 /* Skip the 'area' field common to both hello messages */
781 /* The endnode hello message has 'seed' and 'neighbor' fields */
782 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, Endnode Hello message");
783 proto_tree_add_item(tree, hf_dec_rt_seed, tvb,
784 my_offset, 8, ENC_NA);
786 ti = proto_tree_add_item(tree, hf_dec_rt_neighbor, tvb,
787 my_offset, 6, ENC_NA);
788 addr = dnet_ntoa(ep_tvb_memdup(tvb, my_offset, 6));
790 proto_item_append_text(ti, " (%s)", addr);
794 /*'Timer' and 'mpd' fields are common
795 'mpd' field is reserved */
796 timer = tvb_get_letohs(tvb, my_offset);
797 proto_tree_add_item(tree, hf_dec_rt_timer, tvb,
798 my_offset, 2, ENC_LITTLE_ENDIAN);
801 /* The Ethernet router hello message contains
802 a list of router states
803 The Ethernet Endnode Hello Message contains
804 up to 128 bytes of test data at the end.
805 These data are left to be dissected as 'data'.
807 proto_item *ti_locala, *ti_ether;
808 proto_tree *list_tree, *list_ether;
812 /* image field is preceded by count of remainder of field */
813 image_len = tvb_get_guint8(tvb, my_offset);
816 ti_locala = proto_tree_add_item(tree, hf_dec_rt_elist, tvb,
817 my_offset, image_len, ENC_NA);
818 list_tree = proto_item_add_subtree(ti_locala, ett_dec_rt_list);
820 while (image_len > 0) {
821 ti_ether = proto_tree_add_item(list_tree, hf_dec_rt_ename, tvb,
822 my_offset, 7, ENC_NA);
823 list_ether = proto_item_add_subtree(ti_ether, ett_dec_rt_rlist);
827 /* image field is preceded by count of remainder of field */
828 item_len = tvb_get_guint8(tvb, my_offset);
834 proto_item *ti_localb;
835 proto_tree *pstate_tree;
837 ti_localb = proto_tree_add_item(list_ether, hf_dec_rt_router_id,
838 tvb, my_offset, 6, ENC_NA);
839 addr = dnet_ntoa(ep_tvb_memdup(tvb, my_offset, 6));
841 proto_item_append_text(ti_localb, " (%s)", addr);
844 pstate_tree = proto_item_add_subtree(ti_localb, ett_dec_rt_state);
845 pristate = tvb_get_guint8(tvb, my_offset);
846 proto_tree_add_string(pstate_tree, hf_dec_rt_router_state,
848 ((pristate & 0x80) ? "known 2-way": "unknown"));
849 proto_tree_add_uint(pstate_tree, hf_dec_rt_router_prio,
850 tvb, my_offset, 1, pristate);
868 /* Offset in tvb now points at the first byte still to be handled */
869 guint my_offset = offset;
871 guint16 ack_num, ack_dat, ack_oth, seg_num, seg_size, reason;
872 guint8 ls_flags, fc_val, services, info;
874 proto_tree *flow_control_tree;
876 /* 'tree' is now the subtree for the NSP message */
877 switch (nsp_msg_type) {
878 case DATA_SEGMENT_MSG: /* "Data segment" */
879 case BOM_MSG: /* "Beginning of segment message" */
880 case EOM_MSG: /* "End of segment message" */
881 case BOM_EOM_MSG: /* "BOM / EOM message" */
882 ack_num = tvb_get_letohs(tvb, my_offset);
883 if (ack_num & 0x8000) {
884 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
886 "Last data segment %s acknowledged: %d",
887 (ack_num & 0x1000) ? "negatively" : "positively",
890 /* There may still be an ackoth field */
891 ack_oth = tvb_get_letohs(tvb, my_offset);
892 if (ack_oth & 0x8000) {
893 /* There is an ack_oth field */
894 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
896 "Cross sub-channel %s of other data msg %d",
897 ((ack_oth & 0x3000) == 0x2000) ? "ACK" : "NAK",
903 * The optional ACKNUM and ACKOTH fields are not present
904 * There is still the segnum field
906 seg_num = tvb_get_letohs(tvb, my_offset);
907 if (nsp_msg_type == BOM_MSG) {
908 dec_dna_total_bytes_this_segment = 0;
909 col_append_fstr(pinfo->cinfo, COL_INFO,
910 "msg nr. %d: start of segment",
912 } else if (nsp_msg_type == DATA_SEGMENT_MSG) {
913 col_append_fstr(pinfo->cinfo, COL_INFO,
914 "msg nr. %d: continuation segment ",
916 } else if (nsp_msg_type == EOM_MSG) {
917 col_append_fstr(pinfo->cinfo, COL_INFO,
918 "msg nr. %d: end of segment",
920 } else if (nsp_msg_type == BOM_EOM_MSG) {
921 dec_dna_total_bytes_this_segment = 0;
922 col_append_fstr(pinfo->cinfo, COL_INFO,
923 "msg nr. %d single segment",
926 /* This is the last field, the rest are data */
927 proto_tree_add_item(tree, hf_dec_rt_segnum,
928 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
929 proto_tree_add_boolean(tree, hf_dec_rt_delay,
930 tvb, my_offset, 2, seg_num);
932 /* Compute the number of bytes in this data segment */
934 tvb_reported_length_remaining(tvb, my_offset);
935 dec_dna_previous_total = dec_dna_total_bytes_this_segment;
936 dec_dna_total_bytes_this_segment += data_length;
937 col_append_fstr(pinfo->cinfo, COL_INFO,
938 ", bytes this segment: %d, total so far:%d",
939 data_length, dec_dna_total_bytes_this_segment);
940 /* We are done, return my_offset */
942 case INTERRUPT_MSG: /* "Interrupt message" */
943 col_set_str(pinfo->cinfo, COL_INFO, "NSP interrupt message");
944 ack_num = tvb_get_letohs(tvb, my_offset);
945 if (ack_num & 0x8000) {
946 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
948 "Last interrupt/link service msg %s acknowledged: %d",
949 (ack_num & 0x1000) ? "negatively" : "positively",
952 /* There may still be an ack_dat field */
954 /* There are no ack/nak fields */
955 proto_tree_add_item(tree, hf_dec_rt_segnum,
956 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
957 proto_tree_add_boolean(tree, hf_dec_rt_delay,
958 tvb, my_offset, 2, ack_num);
960 /* We are done, return my_offset */
963 ack_dat = tvb_get_letohs(tvb, my_offset);
964 if (ack_dat & 0x8000) {
965 /* There is an ack_dat field */
966 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
968 "Cross sub-channel %s of data segment msg: %d",
969 ((ack_dat & 0x3000) == 0x2000) ? "ACK" : "NAK",
973 seg_num = tvb_get_letohs(tvb, my_offset);
974 /* This is the last field, the rest are data */
975 proto_tree_add_item(tree, hf_dec_rt_segnum,
976 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
977 proto_tree_add_boolean(tree, hf_dec_rt_delay,
978 tvb, my_offset, 2, seg_num);
980 /* We are done, return my_offset */
982 case LINK_SERVICE_MSG: /* "Link service message" */
983 col_set_str(pinfo->cinfo, COL_INFO, "NSP link control message");
984 ack_num = tvb_get_letohs(tvb, my_offset);
985 if (ack_num & 0x8000) {
986 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
988 "Last interrupt/link service msg %s acknowledged: %d",
989 (ack_num & 0x1000) ? "negatively" : "positively",
992 /* There may still be an ack_dat field */
994 /* There are no ack/nak fields */
995 proto_tree_add_item(tree, hf_dec_rt_segnum,
996 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
997 proto_tree_add_boolean(tree, hf_dec_rt_delay,
998 tvb, my_offset, 2, ack_num);
1000 /* We are done, return my_offset */
1003 ack_dat = tvb_get_letohs(tvb, my_offset);
1004 if (ack_dat & 0x8000) {
1005 /* There is an ack_dat field */
1006 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1008 "Cross sub-channel %s of data segment msg: %d",
1009 ((ack_dat & 0x3000) == 0x2000) ? "ACK" : "NAK",
1013 seg_num = tvb_get_letohs(tvb, my_offset);
1014 proto_tree_add_item(tree, hf_dec_rt_segnum,
1015 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
1016 proto_tree_add_boolean(tree, hf_dec_rt_delay,
1017 tvb, my_offset, 2, seg_num);
1019 /* Now follows the ls_flags field */
1020 ls_flags = tvb_get_guint8(tvb, my_offset);
1022 case 0: /* no change */
1023 col_append_str(pinfo->cinfo, COL_INFO,
1026 case 1: /* stop sending data */
1027 col_append_str(pinfo->cinfo, COL_INFO,
1030 case 2: /* send data */
1031 col_append_str(pinfo->cinfo, COL_INFO,
1037 fc_val = tvb_get_guint8(tvb, my_offset + 1);
1038 ti = proto_tree_add_uint(tree, hf_dec_flow_control, tvb,
1039 my_offset, 1, ls_flags);
1041 proto_item_add_subtree(ti, ett_dec_flow_control);
1042 proto_tree_add_none_format(flow_control_tree, hf_dec_rt_fc_val,
1044 "Request for additional %d %s msgs",
1045 fc_val, ((ls_flags & 0x04) ? "interrupt" : "data"));
1048 case DATA_ACK_MSG: /* "Data acknowledgement message" */
1049 ack_num = tvb_get_letohs(tvb, my_offset);
1050 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1052 "Last data segment %s acknowledged: %d",
1053 (ack_num & 0x1000) ? "negatively" : "positively",
1056 /* There may be an optional ack_oth field */
1057 col_append_fstr(pinfo->cinfo, COL_INFO,
1058 "NSP data %s message(%d)",
1059 (ack_num & 0x1000) ? "NAK" : "ACK",
1062 if (tvb_length_remaining(tvb, my_offset) > 0) {
1063 ack_oth = tvb_get_letohs(tvb, my_offset);
1064 if (ack_oth & 0x8000) {
1065 /* There is an ack_oth field */
1066 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1068 "Cross sub-channel %s of other data msg %d",
1069 ((ack_oth & 0x3000) == 0x2000) ? "ACK" : "NAK",
1074 /* We are done, return my_offset */
1076 case OTHER_DATA_ACK_MSG: /* "Other data acknowledgement message" */
1077 col_set_str(pinfo->cinfo, COL_INFO, "NSP other data ACK message");
1078 ack_num = tvb_get_letohs(tvb, my_offset);
1079 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1081 "Last interrupt/link service msg %s acknowledged: %d",
1082 (ack_num & 0x1000) ? "negatively" : "positively",
1085 /* There may be an optional ack_dat field */
1086 if (tvb_length_remaining(tvb, my_offset) > 0) {
1087 ack_dat = tvb_get_letohs(tvb, my_offset);
1088 if (ack_dat & 0x8000) {
1089 /* There is an ack_dat field */
1090 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1092 "Cross sub-channel %s of data msg %d",
1093 ((ack_dat & 0x3000) == 0x2000) ? "ACK" : "NAK",
1098 /* We are done, return my_offset */
1100 case CONN_CONFIRM_MSG: /* "Connect confirm" */
1101 case CONN_INITIATE_MSG: /* "Connect initiate" */
1102 col_set_str(pinfo->cinfo, COL_INFO, "NSP connect confirm/initiate message");
1103 services = tvb_get_guint8(tvb, my_offset);
1104 proto_tree_add_uint(tree, hf_dec_rt_services, tvb,
1105 my_offset, 1, services);
1107 info = tvb_get_guint8(tvb, my_offset);
1108 proto_tree_add_uint(tree, hf_dec_rt_info, tvb,
1109 my_offset, 1, info);
1111 seg_size = tvb_get_letohs(tvb, my_offset);
1112 proto_tree_add_item(tree, hf_dec_rt_seg_size, tvb,
1113 my_offset, 2, ENC_LITTLE_ENDIAN);
1116 handle_connect_contents(
1117 tvb, tree, my_offset);
1119 case DISCONN_INITIATE_MSG: /* "Disconnect initiate" */
1120 case DISCONN_CONFIRM_MSG: /* "Disconnect confirm" */
1121 col_set_str(pinfo->cinfo, COL_INFO, "NSP disconnect initiate/confirm message");
1122 reason = tvb_get_letohs(tvb, my_offset);
1123 proto_tree_add_item(tree, hf_dec_disc_reason, tvb,
1124 my_offset, 2, ENC_LITTLE_ENDIAN);
1126 if (nsp_msg_type == DISCONN_INITIATE_MSG) {
1128 handle_disc_init_contents( my_offset);
1138 handle_connect_contents(
1143 guint my_offset = offset;
1145 proto_tree *contents_tree;
1146 guint8 dst_format, src_format, obj_type, image_len, menu_ver;
1147 guint16 grp_code, usr_code;
1149 ti = proto_tree_add_item(tree, hf_dec_conn_contents,
1150 tvb, my_offset, -1, ENC_NA);
1151 contents_tree = proto_item_add_subtree(ti, ett_dec_sess_contents);
1152 /* The destination end user */
1153 dst_format = tvb_get_guint8(tvb, my_offset);
1155 obj_type = tvb_get_guint8(tvb, my_offset);
1156 proto_tree_add_uint(contents_tree, hf_dec_sess_obj_type,
1157 tvb, my_offset, 1, obj_type);
1159 if (dst_format == 2) {
1160 grp_code = tvb_get_letohs(tvb, my_offset);
1161 proto_tree_add_item(contents_tree, hf_dec_sess_grp_code,
1162 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
1164 usr_code = tvb_get_letohs(tvb, my_offset);
1165 proto_tree_add_item(contents_tree, hf_dec_sess_usr_code,
1166 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
1169 if (dst_format != 0) {
1170 /* The name field for formats 1 and 2 */
1171 image_len = tvb_get_guint8(tvb, my_offset);
1173 proto_tree_add_item(contents_tree, hf_dec_sess_dst_name,
1174 tvb, my_offset, image_len, ENC_ASCII|ENC_NA);
1175 my_offset += image_len;
1177 /* The source end user */
1178 src_format = tvb_get_guint8(tvb, my_offset);
1180 obj_type = tvb_get_guint8(tvb, my_offset);
1181 proto_tree_add_uint(contents_tree, hf_dec_sess_obj_type,
1182 tvb, my_offset, 1, obj_type);
1184 if (src_format == 2) {
1185 grp_code = tvb_get_letohs(tvb, my_offset);
1186 proto_tree_add_item(contents_tree, hf_dec_sess_grp_code,
1187 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
1189 usr_code = tvb_get_letohs(tvb, my_offset);
1190 proto_tree_add_item(contents_tree, hf_dec_sess_usr_code,
1191 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
1194 if (dst_format != 0) {
1195 /* The name field for formats 1 and 2 */
1196 image_len = tvb_get_guint8(tvb, my_offset);
1198 proto_tree_add_item(contents_tree, hf_dec_sess_src_name,
1199 tvb, my_offset, image_len, ENC_ASCII|ENC_NA);
1200 my_offset += image_len;
1202 /* Now the MENUVER field */
1203 menu_ver = tvb_get_guint8(tvb, my_offset);
1207 proto_tree_add_string(contents_tree, hf_dec_sess_menu_ver,
1209 "Version 1.0: RQSTRID, PASSWRD and ACCOUNT fields included");
1211 image_len = tvb_get_guint8(tvb, my_offset);
1213 proto_tree_add_item(contents_tree, hf_dec_sess_rqstr_id,
1214 tvb, my_offset, image_len, ENC_ASCII|ENC_NA);
1215 my_offset += image_len;
1216 image_len = tvb_get_guint8(tvb, my_offset);
1218 proto_tree_add_item(contents_tree, hf_dec_sess_rqstr_id,
1219 tvb, my_offset, image_len, ENC_ASCII|ENC_NA);
1220 my_offset += image_len;
1221 image_len = tvb_get_guint8(tvb, my_offset);
1223 proto_tree_add_item(contents_tree, hf_dec_sess_rqstr_id,
1224 tvb, my_offset, image_len, ENC_ASCII|ENC_NA);
1225 my_offset += image_len;
1230 /* A USRDATA field is handled by dissect_data */
1231 proto_tree_add_string(contents_tree, hf_dec_sess_menu_ver,
1233 "Version 1.0: USRDATA field included");
1236 proto_tree_add_string(contents_tree, hf_dec_sess_menu_ver,
1238 "Session control version 1.0");
1245 handle_disc_init_contents(
1248 guint my_offset = offset;
1255 proto_register_dec_rt(void)
1258 static hf_register_info hf[] = {
1259 /* Mesage header items */
1260 { &hf_dec_routing_flags,
1261 { "Routing flags", "dec_dna.flags",
1262 FT_UINT8, BASE_HEX, NULL, 0x0,
1263 "DNA routing flag", HFILL }},
1264 { &hf_dec_rt_ctrl_msg,
1265 { "Control packet", "dec_dna.flags.control",
1266 FT_BOOLEAN, 8, TFS(&tfs_yes_no), RT_FLAGS_CTRL_MSG,
1268 { &hf_dec_rt_long_msg,
1269 { "Long data packet format", "dec_dna.flags.msglen",
1270 FT_UINT8, BASE_HEX, NULL, 0x06,
1271 "Long message indicator", HFILL }},
1272 { &hf_dec_rt_short_msg,
1273 { "Short data packet format", "dec_dna.flags.msglen",
1274 FT_UINT8, BASE_HEX, NULL, 0x06,
1275 "Short message indicator", HFILL }},
1277 { "Return to Sender Request", "dec_dna.flags.RQR",
1278 FT_BOOLEAN, 8, TFS(&tfs_yes_no), RT_FLAGS_RQR,
1279 "Return to Sender", HFILL }},
1281 { "Packet on return trip", "dec_dna.flags.RTS",
1282 FT_BOOLEAN, 8, TFS(&tfs_yes_no), RT_FLAGS_RTS,
1284 { &hf_dec_rt_inter_eth,
1285 { "Intra-ethernet packet", "dec_dna.flags.intra_eth",
1286 FT_BOOLEAN, 8, TFS(&tfs_yes_no), RT_FLAGS_INTRA_ETHER,
1288 { &hf_dec_rt_discard,
1289 { "Discarded packet", "dec_dna.flags.discard",
1290 FT_BOOLEAN, 8, TFS(&tfs_yes_no), RT_FLAGS_DISCARD,
1292 { &hf_dec_rt_dst_addr,
1293 { "Destination Address", "dec_dna.dst.address",
1294 FT_ETHER, BASE_NONE, NULL, 0x0,
1296 { &hf_dec_rt_src_addr,
1297 { "Source Address", "dec_dna.src.addr",
1298 FT_ETHER, BASE_NONE, NULL, 0x0,
1301 { "Next level 2 router", "dec_dna.nl2",
1302 FT_UINT8, BASE_HEX, NULL, 0x0,
1303 "reserved", HFILL }},
1304 { &hf_dec_rt_service_class,
1305 { "Service class", "dec_dna.svc_cls",
1306 FT_UINT8, BASE_HEX, NULL, 0x0,
1307 "reserved", HFILL }},
1308 { &hf_dec_rt_protocol_type,
1309 { "Protocol type", "dec_dna.proto_type",
1310 FT_UINT8, BASE_HEX, NULL, 0x0,
1311 "reserved", HFILL }},
1312 { &hf_dec_rt_visit_count,
1313 { "Visit count", "dec_dna.visit_cnt",
1314 FT_UINT8, BASE_HEX, NULL, 0x0,
1316 { &hf_dec_flow_control,
1317 { "Flow control", "dec_dna.nsp.flow_control",
1318 FT_UINT8, BASE_HEX, VALS(rt_flow_control_vals), 0x3,
1319 "Flow control(stop, go)", HFILL }},
1320 { &hf_dec_rt_services,
1321 { "Requested services", "dec_dna.nsp.services",
1322 FT_UINT8, BASE_HEX, VALS(rt_services_vals), 0x0c,
1323 "Services requested", HFILL }},
1325 { "Version info", "dec_dna.nsp.info",
1326 FT_UINT8, BASE_HEX, VALS(rt_info_version_vals), 0x03,
1328 { &hf_dec_rt_dst_node,
1329 { "Destination node", "dec_dna.dst_node",
1330 FT_UINT16, BASE_HEX, NULL, 0x0,
1332 { &hf_dec_rt_seg_size,
1333 { "Maximum data segment size", "dec_dna.nsp.segsize",
1334 FT_UINT16, BASE_DEC, NULL, 0x0,
1335 "Max. segment size", HFILL }},
1336 { &hf_dec_rt_src_node,
1337 { "Source node", "dec_dna.src_node",
1338 FT_UINT16, BASE_HEX, NULL, 0x0,
1340 { &hf_dec_rt_segnum,
1341 { "Message number", "dec_dna.nsp.segnum",
1342 FT_UINT16, BASE_DEC, NULL, 0xfff,
1343 "Segment number", HFILL }},
1345 { "Delayed ACK allowed", "dec_dna.nsp.delay",
1346 FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x1000,
1347 "Delayed ACK allowed?", HFILL }},
1348 { &hf_dec_rt_visited_nodes,
1349 { "Nodes visited ty this package", "dec_dna.vst_node",
1350 FT_UINT8, BASE_DEC, NULL, 0x0,
1351 "Nodes visited", HFILL }},
1352 /* Control messsage items */
1354 { "Routing control message", "dec_dna.rt.msg_type",
1355 FT_UINT8, BASE_HEX, VALS(rt_msg_type_vals), 0xe,
1356 "Routing control", HFILL }},
1357 { &hf_dec_ctl_msg_hdr,
1358 { "Routing control message", "dec_dna.rt.msg_type",
1359 FT_UINT8, BASE_HEX, VALS(rt_msg_type_vals), 0xe,
1360 "Routing control", HFILL }},
1362 { "DNA NSP message", "dec_dna.nsp.msg_type",
1363 FT_UINT8, BASE_HEX, VALS(nsp_msg_type_vals), 0x0,
1364 "NSP message", HFILL }},
1365 { &hf_dec_rt_acknum,
1366 { "Ack/Nak", "dec_dna.ctl.acknum",
1367 FT_NONE, BASE_NONE, NULL, 0x0,
1368 "ack/nak number", HFILL }},
1369 { &hf_dec_rt_fc_val,
1370 { "Flow control", "dec_dna.nsp.fc_val",
1371 FT_NONE, BASE_NONE, NULL, 0x0,
1373 { &hf_dec_rt_tiinfo,
1374 { "Routing information", "dec_dna.ctl.tiinfo",
1375 FT_UINT8, BASE_HEX, VALS(rt_tiinfo_vals), 0x0,
1377 { &hf_dec_rt_blk_size,
1378 { "Block size", "dec_dna.ctl.blk_size",
1379 FT_UINT16, BASE_DEC, NULL, 0x0,
1381 { &hf_dec_disc_reason,
1382 { "Reason for disconnect","dec_dna.nsp.disc_reason",
1383 FT_UINT16, BASE_HEX, VALS(rt_disc_reason_vals), 0x0,
1384 "Disconnect reason", HFILL }},
1385 { &hf_dec_rt_version,
1386 { "Version", "dec_dna.ctl.version",
1387 FT_NONE, BASE_NONE, NULL, 0x0,
1388 "Control protocol version", HFILL }},
1390 { "Hello timer(seconds)", "dec_dna.ctl.timer",
1391 FT_UINT16, BASE_DEC, NULL, 0x0,
1392 "Hello timer in seconds", HFILL }},
1393 { &hf_dec_rt_reserved,
1394 { "Reserved", "dec_dna.ctl.reserved",
1395 FT_BYTES, BASE_NONE, NULL, 0x0,
1397 { &hf_dec_rt_fcnval,
1398 { "Verification message function value", "dec_dna.ctl.fcnval",
1399 FT_BYTES, BASE_NONE, NULL, 0x0,
1400 "Routing Verification function", HFILL }},
1401 { &hf_dec_rt_test_data,
1402 { "Test message data", "dec_dna.ctl.test_data",
1403 FT_BYTES, BASE_NONE, NULL, 0x0,
1404 "Routing Test message data", HFILL }},
1405 { &hf_dec_rt_segment,
1406 { "Segment", "dec_dna.ctl.segment",
1407 FT_NONE, BASE_NONE, NULL, 0x0,
1408 "Routing Segment", HFILL }},
1410 { "Transmitting system ID", "dec_dna.ctl.id",
1411 FT_ETHER, BASE_NONE, NULL, 0x0,
1414 { "Routing information", "dec_dna.ctl.tiinfo",
1415 FT_UINT8, BASE_HEX, NULL, 0x0,
1417 { &hf_dec_rt_iinfo_node_type,
1418 { "Node type", "dec_dna.ctl.iinfo.node_type",
1419 FT_UINT8, BASE_HEX, VALS(rt_iinfo_node_type_vals), 0x03,
1421 { &hf_dec_rt_iinfo_vrf,
1422 { "Verification required", "dec_dna.ctl.iinfo.vrf",
1423 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x4,
1424 "Verification required?", HFILL }},
1425 { &hf_dec_rt_iinfo_rej,
1426 { "Rejected", "dec_dna.ctl.iinfo.rej",
1427 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x8,
1428 "Rejected message", HFILL }},
1429 { &hf_dec_rt_iinfo_verf,
1430 { "Verification failed", "dec_dna.ctl.iinfo.verf",
1431 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
1432 "Verification failed?", HFILL }},
1433 { &hf_dec_rt_iinfo_mta,
1434 { "Accepts multicast traffic", "dec_dna.ctl.iinfo.mta",
1435 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
1436 "Accepts multicast traffic?", HFILL }},
1437 { &hf_dec_rt_iinfo_blkreq,
1438 { "Blocking requested", "dec_dna.ctl.iinfo.blkreq",
1439 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
1440 "Blocking requested?", HFILL }},
1442 { "Routing priority", "dec_dna.ctl.prio",
1443 FT_UINT8, BASE_HEX, NULL, 0x0,
1445 { &hf_dec_rt_neighbor,
1446 { "Neighbor", "dec_dna.ctl_neighbor",
1447 FT_ETHER, BASE_NONE, NULL, 0x0,
1448 "Neighbour ID", HFILL }},
1450 { "Verification seed", "dec_dna.ctl.seed",
1451 FT_BYTES, BASE_NONE, NULL, 0x0,
1454 { "List of router states", "dec_dna.ctl.elist",
1455 FT_NONE, BASE_NONE, NULL, 0x0,
1456 "Router states", HFILL }},
1458 { "Ethernet name", "dec_dna.ctl.ename",
1459 FT_BYTES, BASE_NONE, NULL, 0x0,
1461 { &hf_dec_rt_router_id,
1462 { "Router ID", "dec_dna.ctl.router_id",
1463 FT_ETHER, BASE_NONE, NULL, 0x0,
1465 { &hf_dec_rt_router_state,
1466 { "Router state", "dec_dna.ctl.router_state",
1467 FT_STRING, BASE_NONE, NULL, 0x0,
1469 { &hf_dec_conn_contents,
1470 { "Session connect data", "dec_dna.sess.conn",
1471 FT_NONE, BASE_NONE, NULL, 0x0,
1473 { &hf_dec_rt_router_prio,
1474 { "Router priority", "dec_dna.ctl.router_prio",
1475 FT_UINT8, BASE_HEX, NULL, 0x7f,
1477 { &hf_dec_sess_grp_code,
1478 { "Session Group code", "dec_dna.sess.grp_code",
1479 FT_UINT16, BASE_HEX, NULL, 0x0,
1481 { &hf_dec_sess_usr_code,
1482 { "Session User code", "dec_dna.sess.usr_code",
1483 FT_UINT16, BASE_HEX, NULL, 0x0,
1485 { &hf_dec_sess_dst_name,
1486 { "Session Destination end user", "dec_dna.sess.dst_name",
1487 FT_STRING, BASE_NONE, NULL, 0x0,
1489 { &hf_dec_sess_src_name,
1490 { "Session Source end user", "dec_dna.sess.src_name",
1491 FT_STRING, BASE_NONE, NULL, 0x0,
1493 { &hf_dec_sess_obj_type,
1494 { "Session Object type", "dec_dna.sess.obj_type",
1495 FT_UINT8, BASE_HEX, NULL, 0x0,
1497 { &hf_dec_sess_menu_ver,
1498 { "Session Menu version", "dec_dna.sess.menu_ver",
1499 FT_STRING, BASE_NONE, NULL, 0x0,
1501 { &hf_dec_sess_rqstr_id,
1502 { "Session Requestor ID", "dec_dna.sess.rqstr_id",
1503 FT_STRING, BASE_NONE, NULL, 0x0,
1508 static gint *ett[] = {
1510 &ett_dec_routing_flags,
1512 &ett_dec_rt_ctl_msg,
1513 &ett_dec_rt_nsp_msg,
1514 &ett_dec_rt_info_flags,
1518 &ett_dec_flow_control,
1519 &ett_dec_sess_contents,
1522 proto_dec_rt = proto_register_protocol("DEC DNA Routing Protocol",
1523 "DEC_DNA", "dec_dna");
1524 proto_register_field_array(proto_dec_rt, hf, array_length(hf));
1525 proto_register_subtree_array(ett, array_length(ett));
1529 proto_reg_handoff_dec_rt(void)
1531 dissector_handle_t dec_rt_handle;
1533 dec_rt_handle = create_dissector_handle(dissect_dec_rt,
1535 dissector_add_uint("ethertype", ETHERTYPE_DNA_RT, dec_rt_handle);
1536 dissector_add_uint("chdlctype", ETHERTYPE_DNA_RT, dec_rt_handle);
1537 dissector_add_uint("ppp.protocol", PPP_DEC4, dec_rt_handle);
1538 /* dissector_add_uint("ppp.protocol", PPP_DECNETCP, dec_rt_handle);*/