MSWSP: add two more Property Sets
[wireshark-wip.git] / epan / dissectors / packet-dec-dnart.c
blob3e4ef23a3059dfda0db0ae18db265c7de51cf3b8
1 /* packet-dec-dnart.c
3 * Routines for DECnet NSP/RT disassembly
5 * Copyright 2003-2005 Philips Medical Systems
6 * Copyright 2003-2005 Fred Hoekstra, Philips Medical Systems.
7 * (fred.hoekstra@philips.com)
9 * $Id$
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
22 * SECON.RNO [31,1]
23 * EDITED 10/17/80
25 * See
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
50 #include "config.h"
52 #include <glib.h>
53 #include <epan/packet.h>
54 #include <epan/wmem/wmem.h>
55 #include <epan/etypes.h>
56 #include <epan/ppptypes.h>
58 typedef enum {
59 RT_CTL_INITIALIZATION,
60 RT_CTL_VERIFICATION,
61 RT_CTL_HELLO_TEST,
62 RT_CTL_LVL1_ROUTING,
63 RT_CTL_LVL2_ROUTING,
64 RT_CTL_ETH_ROUTER_HELLO_MSG,
65 RT_CTL_ETH_ENDNODE_HELLO_MSG
66 } ctl_msg_types;
68 #define DEC_RT_SIZE 27
70 #define DATA_SEGMENT_MSG 0x00 /* "Data segment" */
71 #define LINK_SERVICE_MSG 0x10 /* "Link service message" */
72 #define BOM_MSG 0x20 /* "Beginning of segment (BOM)message" */
73 #define EOM_MSG 0x40 /* "End of segment (EOM)message" */
74 #define BOM_EOM_MSG 0x60 /* "BOM / EOM message" */
75 #define INTERRUPT_MSG 0x30 /* "Interrupt message" */
76 #define DATA_ACK_MSG 0x04 /* "Data acknowledgement message" */
77 #define OTHER_DATA_ACK_MSG 0x14 /* "Other data acknowledgement message" */
78 #define CONN_ACK_MSG 0x24 /* "Connect acknowledgement message" */
79 #define NOP_MSG 0x08 /* "NOP" */
80 #define CONN_INITIATE_MSG 0x18 /* "Connect initiate" */
81 #define CONN_CONFIRM_MSG 0x28 /* "Connect confirm" */
82 #define DISCONN_INITIATE_MSG 0x38 /* "Disconnect initiate" */
83 #define DISCONN_CONFIRM_MSG 0x48 /* "Disconnect confirm" */
84 #define RE_XMT_CONN_INIT_MSG 0x68 /* "Retransmitted connect initiate" */
86 /* Flag bits */
88 #define RT_FLAGS_CTRL_MSG 0x01
89 #define RT_FLAGS_LONG_MSG 0x04 /* Actually: 0x06->long, 0x02->short*/
90 #define RT_FLAGS_RQR 0x08
91 #define RT_FLAGS_RTS 0x10
92 #define RT_FLAGS_INTRA_ETHER 0x20
93 #define RT_FLAGS_DISCARD 0x40
94 #define RT_FLAGS_PAD 0x80
96 void proto_register_dec_rt(void);
97 void proto_reg_handoff_dec_rt(void);
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" },
187 { 0, NULL }
188 };*/
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" },
198 { 0, NULL }
201 static const value_string nsp_msg_type_vals[] = {
202 { 0x00 , "Data segment continuation" },
203 { 0x04 , "Data acknowledgement message" },
204 { 0x08 , "NOP" },
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" },
217 { 0, NULL }
220 static const value_string rt_tiinfo_vals[] = {
221 {0x01, "Level 2 router"},
222 {0x02, "Level 1 router"},
223 {0x03, "End node"},
224 {0x04, "Routing layer verification required"},
225 {0x08, "Blocking requested"},
226 {0x0, NULL}
229 static const value_string rt_iinfo_node_type_vals[] = {
230 {0x01, "Level 2 router"},
231 {0x02, "Level 1 router"},
232 {0x03, "End node"},
233 {0x0, NULL}
236 static const value_string rt_flow_control_vals[] = {
237 {0x00, "no change"},
238 {0x01, "do not send data"},
239 {0x02, "send data"},
240 {0x03, "reserved"},
241 {0x0, NULL}
244 static const value_string rt_services_vals[] = {
245 {0x00, "none"},
246 {0x04, "segment request count"},
247 {0x08, "Session control message request count"},
248 {0x0c, "reserved"},
249 {0x0, NULL}
252 static const value_string rt_info_version_vals[] = {
253 {0x00, "version 3.2"},
254 {0x01, "version 3.1"},
255 {0x02, "version 4.0"},
256 {0x03, "reserved"},
257 {0x0, NULL}
260 static const value_string rt_disc_reason_vals[] = {
261 { 0, "no error"},
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"},
275 { 0, NULL}
278 #define RT_TYPE_TOPOLOGY_CHANGE 2
279 #define RT_TYPE_HELLO 25
281 #if ! defined true
282 #define true 1
283 #endif
284 #if ! defined false
285 #define false 0
286 #endif
288 static int
289 handle_nsp_msg(
290 tvbuff_t *tvb,
291 packet_info *pinfo,
292 proto_tree *tree,
293 guint offset,
294 guint8 nsp_msg_type);
297 static int
298 do_initialization_msg(
299 tvbuff_t *tvb,
300 packet_info *pinfo,
301 proto_tree *ctl_msg_tree,
302 guint offset);
304 static int
305 do_verification_msg(
306 tvbuff_t *tvb,
307 packet_info *pinfo,
308 proto_tree *ctl_msg_tree,
309 guint offset);
311 static int
312 do_hello_test_msg(
313 tvbuff_t *tvb,
314 packet_info *pinfo,
315 proto_tree *ctl_msg_tree,
316 guint offset);
318 static int
319 do_routing_msg(
320 tvbuff_t *tvb,
321 packet_info *pinfo,
322 proto_tree *ctl_msg_tree,
323 guint offset,
324 guint msg);
326 static int
327 do_hello_msg(
328 tvbuff_t *tvb,
329 packet_info *pinfo,
330 proto_tree *ctl_msg_tree,
331 guint offset,
332 guint msg);
334 static int
335 handle_connect_contents(
336 tvbuff_t *tvb,
337 proto_tree *tree,
338 guint offset);
340 static int
341 handle_disc_init_contents(
342 guint offset);
344 static char *
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 wmem_strdup_printf(wmem_packet_scope(), "%d.%d", dnet_addr >> 10, dnet_addr & 0x03FF);
351 return NULL;
354 static void
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((const guint8 *)paddr_src->data);
359 if (addr != NULL)
360 SET_ADDRESS(paddr_tgt, AT_STRINGZ, 1, addr);
364 static void
365 dissect_dec_rt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
367 guint8 padding_length;
368 guint8 forward;
369 guint8 msg_flags;
370 guint rt_visit_count, rt_zero = 0;
371 gint offset;
372 proto_tree *rt_tree;
373 proto_tree *flags_tree;
374 proto_item *ti;
375 char *addr;
377 offset = 0;
378 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DEC DNA");
379 col_clear(pinfo->cinfo, COL_INFO);
381 set_dnet_address(&pinfo->dl_src, &pinfo->net_src);
382 set_dnet_address(&pinfo->dl_src, &pinfo->src);
383 set_dnet_address(&pinfo->dl_dst, &pinfo->net_dst);
384 set_dnet_address(&pinfo->dl_dst, &pinfo->dst);
386 offset += 2;
387 msg_flags = tvb_get_guint8(tvb, offset);
388 ti = proto_tree_add_item(tree, proto_dec_rt, tvb, 0, -1, ENC_NA);
389 rt_tree = proto_item_add_subtree(ti, ett_dec_rt);
390 /* When padding, the first byte after the padding has
391 the real routing flags */
392 if (msg_flags & 0x80) {
393 /* There is padding present, skip it */
394 padding_length = msg_flags & 0x7f;
395 offset += padding_length;
398 /* The real routing flag */
399 msg_flags = tvb_get_guint8(tvb, offset);
400 ti = proto_tree_add_uint(rt_tree, hf_dec_routing_flags, tvb,
401 offset, 1, msg_flags);
402 flags_tree = proto_item_add_subtree(ti, ett_dec_routing_flags);
404 if (msg_flags & RT_FLAGS_CTRL_MSG) {
405 guint8 ctl_msg_type;
406 proto_tree *ctl_msg_tree;
408 ctl_msg_type = (msg_flags >> 1) & 0x7;
409 proto_tree_add_boolean(flags_tree, hf_dec_rt_ctrl_msg, tvb, offset, 1,
410 msg_flags);
411 proto_tree_add_uint(flags_tree, hf_dec_ctl_msgs, tvb, offset, 1,
412 msg_flags);
414 ti = proto_tree_add_uint(rt_tree, hf_dec_ctl_msg_hdr, tvb, offset, 1,
415 ctl_msg_type);
416 ctl_msg_tree = proto_item_add_subtree(ti, ett_dec_rt_ctl_msg);
418 /* Get past the msg_flags */
419 offset++;
420 switch (ctl_msg_type) {
421 case RT_CTL_INITIALIZATION:
422 do_initialization_msg(
423 tvb, pinfo, ctl_msg_tree, offset);
424 break;
425 case RT_CTL_VERIFICATION:
426 do_verification_msg(
427 tvb, pinfo, ctl_msg_tree, offset);
428 break;
429 case RT_CTL_HELLO_TEST:
430 do_hello_test_msg(
431 tvb, pinfo, ctl_msg_tree, offset);
432 break;
433 case RT_CTL_LVL1_ROUTING:
434 case RT_CTL_LVL2_ROUTING:
435 do_routing_msg(
436 tvb, pinfo, ctl_msg_tree, offset, msg_flags >> 1);
437 break;
438 case RT_CTL_ETH_ROUTER_HELLO_MSG:
439 case RT_CTL_ETH_ENDNODE_HELLO_MSG:
440 do_hello_msg(
441 tvb, pinfo, ctl_msg_tree, offset, msg_flags >> 1);
442 break;
443 default:
444 break;
446 } else if (msg_flags & RT_FLAGS_LONG_MSG){
447 proto_tree_add_uint(flags_tree, hf_dec_rt_long_msg,
448 tvb, offset, 1, msg_flags);
449 proto_tree_add_boolean(flags_tree, hf_dec_rt_rqr, tvb,
450 offset, 1, msg_flags);
451 proto_tree_add_boolean(flags_tree, hf_dec_rt_rts, tvb,
452 offset, 1, msg_flags);
453 proto_tree_add_boolean(flags_tree, hf_dec_rt_inter_eth, tvb,
454 offset, 1, msg_flags);
455 proto_tree_add_boolean(flags_tree, hf_dec_rt_discard, tvb,
456 offset, 1, msg_flags);
458 /* Increment offset by three:
459 1 to get past the flags field
460 2 to skip the DEC area/subarea field
462 offset += 3;
463 ti = proto_tree_add_item(rt_tree, hf_dec_rt_dst_addr, tvb,
464 offset, 6, ENC_NA);
465 addr = dnet_ntoa((const guint8 *)tvb_memdup(wmem_packet_scope(), tvb, offset, 6));
466 if (addr != NULL) {
467 proto_item_append_text(ti, " (%s)", addr);
470 /* Skip 6 bytes for the MAC and
471 2 bytes for DEC area/subarea
473 offset += 8;
474 ti = proto_tree_add_item(rt_tree, hf_dec_rt_src_addr, tvb,
475 offset, 6, ENC_NA);
476 addr = dnet_ntoa((const guint8 *)tvb_memdup(wmem_packet_scope(), tvb, offset, 6));
477 if (addr != NULL) {
478 proto_item_append_text(ti, " (%s)", addr);
481 /* Proceed to the NL2 byte */
482 offset += 6;
483 proto_tree_add_uint(rt_tree, hf_dec_rt_nl2, tvb,
484 offset, 1, rt_zero);
485 offset++;
486 rt_visit_count = tvb_get_guint8(tvb, offset);
487 proto_tree_add_uint(rt_tree, hf_dec_rt_visit_count, tvb,
488 offset, 1, rt_visit_count);
489 offset++;
490 proto_tree_add_uint(rt_tree, hf_dec_rt_service_class, tvb,
491 offset, 1, rt_zero);
492 offset++;
493 proto_tree_add_uint(rt_tree, hf_dec_rt_protocol_type, tvb,
494 offset, 1, rt_zero);
495 offset++;
496 } else {
497 proto_tree_add_uint(flags_tree, hf_dec_rt_short_msg,
498 tvb, offset, 1, msg_flags);
499 proto_tree_add_boolean(flags_tree, hf_dec_rt_rqr, tvb,
500 offset, 1, msg_flags);
501 proto_tree_add_boolean(flags_tree, hf_dec_rt_rts, tvb,
502 offset, 1, msg_flags);
504 /* Increment offset to get past the flags field
506 offset++;
507 proto_tree_add_item(rt_tree, hf_dec_rt_dst_node, tvb, offset, 2, ENC_LITTLE_ENDIAN);
508 offset += 2;
509 proto_tree_add_item(rt_tree, hf_dec_rt_src_node, tvb, offset, 2, ENC_LITTLE_ENDIAN);
510 offset += 2;
511 forward = tvb_get_guint8(tvb, offset);
512 proto_tree_add_uint(rt_tree, hf_dec_rt_visited_nodes, tvb,
513 offset, 1, forward);
514 offset++;
517 if (!(msg_flags & RT_FLAGS_CTRL_MSG)) {
518 /* It is not a routing control message */
519 proto_tree *nsp_msg_tree;
520 proto_item *ti_local;
521 guint8 nsp_msg_type;
523 nsp_msg_type = tvb_get_guint8(tvb, offset);
524 ti_local = proto_tree_add_uint(
525 tree, hf_dec_nsp_msgs, tvb, offset, 1, nsp_msg_type);
526 if (nsp_msg_type == NOP_MSG) {
527 /* Only test data in this msg */
528 return;
530 nsp_msg_tree = proto_item_add_subtree(ti_local, ett_dec_rt_nsp_msg);
531 /* Get past the nsp_msg_type */
532 offset++;
533 proto_tree_add_item(nsp_msg_tree, hf_dec_rt_dst_node, tvb, offset, 2, ENC_LITTLE_ENDIAN);
534 offset += 2;
535 if (nsp_msg_type == CONN_ACK_MSG) {
536 col_set_str(pinfo->cinfo, COL_INFO, "NSP connect acknowledgement");
537 /* Done with this msg type */
538 return;
540 /* All other messages have a source node */
541 proto_tree_add_item(nsp_msg_tree, hf_dec_rt_src_node, tvb, offset, 2, ENC_LITTLE_ENDIAN);
542 offset += 2;
544 handle_nsp_msg(tvb,
545 pinfo,
546 nsp_msg_tree,
547 offset,
548 nsp_msg_type);
552 static int
553 do_initialization_msg(
554 tvbuff_t *tvb,
555 packet_info *pinfo,
556 proto_tree *tree,
557 guint offset)
559 guint my_offset = offset;
560 guint8 version, eco_nr, user_eco;
561 guint8 remainder_count;
563 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, initialization message");
564 proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
565 my_offset, 2, ENC_LITTLE_ENDIAN);
566 my_offset += 2;
567 proto_tree_add_item(tree, hf_dec_rt_tiinfo, tvb,
568 my_offset, 2, ENC_LITTLE_ENDIAN);
569 my_offset += 2;
570 proto_tree_add_item(tree, hf_dec_rt_blk_size, tvb,
571 my_offset, 2, ENC_LITTLE_ENDIAN);
572 my_offset += 2;
573 version = tvb_get_guint8(tvb, my_offset);
574 eco_nr = tvb_get_guint8(tvb, my_offset + 1);
575 user_eco = tvb_get_guint8(tvb, my_offset + 2);
576 proto_tree_add_none_format(tree, hf_dec_rt_version, tvb,
577 my_offset, 3, "Routing Layer version: %d.%d.%d.",
578 version, eco_nr, user_eco);
579 my_offset +=3;
580 proto_tree_add_item(tree, hf_dec_rt_timer, tvb,
581 my_offset, 2, ENC_LITTLE_ENDIAN);
582 my_offset += 2;
583 remainder_count = tvb_get_guint8(tvb, my_offset);
584 if (remainder_count != 0) {
585 proto_tree_add_item(tree, hf_dec_rt_reserved, tvb,
586 my_offset, remainder_count, ENC_NA);
587 my_offset += remainder_count;
589 return (my_offset);
592 static int
593 do_verification_msg(
594 tvbuff_t *tvb,
595 packet_info *pinfo,
596 proto_tree *tree,
597 guint offset)
599 guint my_offset = offset;
600 guint8 remainder_count;
602 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, verification message");
603 proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
604 my_offset, 2, ENC_LITTLE_ENDIAN);
605 my_offset += 2;
606 remainder_count = tvb_get_guint8(tvb, my_offset);
607 if (remainder_count != 0) {
608 proto_tree_add_item(tree, hf_dec_rt_fcnval, tvb,
609 my_offset, remainder_count, ENC_NA);
610 my_offset += remainder_count;
612 return (my_offset);
615 static int
616 do_hello_test_msg(
617 tvbuff_t *tvb,
618 packet_info *pinfo,
619 proto_tree *tree,
620 guint offset)
622 guint my_offset = offset;
623 guint remainder_count;
625 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, hello/test message");
626 proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
627 my_offset, 2, ENC_LITTLE_ENDIAN);
628 my_offset += 2;
629 remainder_count = tvb_length_remaining(tvb, my_offset);
630 if (remainder_count != 0) {
631 proto_tree_add_item(tree, hf_dec_rt_test_data, tvb,
632 my_offset, remainder_count, ENC_NA);
633 my_offset += remainder_count;
635 return (my_offset);
638 static int
639 do_routing_msg(
640 tvbuff_t *tvb,
641 packet_info *pinfo,
642 proto_tree *tree,
643 guint offset,
644 guint msg)
646 guint my_offset = offset;
647 guint32 my_checksum = 1;
648 guint16 checksum;
649 guint16 count, startid, rtginfo;
650 guint remainder_count;
652 proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
653 my_offset, 2, ENC_LITTLE_ENDIAN);
654 /* Skip the 1-byte reserved field */
655 my_offset += 3;
656 remainder_count = tvb_length_remaining(tvb, my_offset);
657 do {
658 /* if the remainder_count == 1, only the checksum remains */
659 count = tvb_get_letohs(tvb, my_offset);
660 startid = tvb_get_letohs(tvb, my_offset + 2);
661 rtginfo = tvb_get_letohs(tvb, my_offset + 4);
662 if (msg == 3) {
663 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, Level 1 routing message");
664 proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
665 my_offset, 6,
666 "Segment: count:%d, start Id: %d, hops:%d, cost: %d",
667 count, startid, (rtginfo & 0x7c00) >> 10, rtginfo & 0x3ff);
668 } else {
669 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, Level 2 routing message");
670 proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
671 my_offset, 6,
672 "Segment: count:%d, start area: %d, hops:%d, cost: %d",
673 count, startid, (rtginfo & 0x7c00) >> 10, rtginfo & 0x3ff);
675 my_checksum += (count + startid + rtginfo);
676 my_offset += 6;
677 remainder_count -= 6;
678 } while (remainder_count > 6);
679 my_offset += remainder_count - 2;
680 /* fold 32 bit sum into 16 bits */
681 while (my_checksum>>16)
682 my_checksum = (my_checksum & 0xffff) + (my_checksum >> 16);
683 checksum = tvb_get_letohs(tvb, my_offset);
684 if (checksum != my_checksum) {
685 proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
686 my_offset, 2,
687 "Checksum mismatch(computed 0x%x <> received 0x%x)",
688 my_checksum, checksum);
689 } else {
690 proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
691 my_offset, 2,
692 "Checksum: match (computed 0x%x = received 0x%x)",
693 my_checksum, checksum);
695 my_offset += 2;
696 return (my_offset);
699 static int
700 do_hello_msg(
701 tvbuff_t *tvb,
702 packet_info *pinfo,
703 proto_tree *tree,
704 guint offset,
705 guint msg)
707 guint my_offset = offset;
708 guint8 iinfo, priority;
709 guint16 version, eco_nr, user_eco;
710 proto_item *ti;
711 proto_tree *iinfo_tree;
712 char *addr;
714 version = tvb_get_guint8(tvb, my_offset);
715 eco_nr = tvb_get_guint8(tvb, my_offset + 1);
716 user_eco = tvb_get_guint8(tvb, my_offset + 2);
717 proto_tree_add_none_format(tree, hf_dec_rt_version, tvb,
718 my_offset, 3, "Routing Layer Version: %d.%d.%d",
719 version, eco_nr, user_eco);
720 my_offset +=3;
721 ti = proto_tree_add_item(tree, hf_dec_rt_id, tvb,
722 my_offset, 6, ENC_NA);
723 addr = dnet_ntoa((const guint8 *)tvb_memdup(wmem_packet_scope(), tvb, my_offset, 6));
724 if (addr != NULL) {
725 proto_item_append_text(ti, " (%s)", addr);
727 my_offset += 6;
728 iinfo = tvb_get_guint8(tvb, my_offset);
729 ti = proto_tree_add_uint(
730 tree, hf_dec_rt_iinfo, tvb, my_offset, 1, iinfo);
731 iinfo_tree = proto_item_add_subtree(ti, ett_dec_rt_info_flags);
732 proto_tree_add_uint(
733 iinfo_tree, hf_dec_rt_iinfo_node_type, tvb, my_offset, 1, iinfo);
734 proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_vrf,
735 tvb, my_offset, 1, iinfo);
736 proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_rej,
737 tvb, my_offset, 1, iinfo);
738 proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_verf,
739 tvb, my_offset, 1, iinfo);
740 proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_mta,
741 tvb, my_offset, 1, iinfo);
742 proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_blkreq,
743 tvb, my_offset, 1, iinfo);
744 my_offset++;
745 proto_tree_add_item(tree, hf_dec_rt_blk_size, tvb,
746 my_offset, 2, ENC_LITTLE_ENDIAN);
747 my_offset += 2;
748 if (msg == 5) {
749 /* Ethernet router hello message
750 Has a 'priority' field in this position */
751 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, Ethernet Router Hello message");
752 priority = tvb_get_guint8(tvb, my_offset);
753 proto_tree_add_uint(
754 tree, hf_dec_rt_iprio, tvb, my_offset, 1, priority);
755 my_offset++;
757 /* Skip the 'area' field common to both hello messages */
758 my_offset += 1;
759 if (msg == 6) {
760 /* The endnode hello message has 'seed' and 'neighbor' fields */
761 col_set_str(pinfo->cinfo, COL_INFO, "Routing control, Endnode Hello message");
762 proto_tree_add_item(tree, hf_dec_rt_seed, tvb,
763 my_offset, 8, ENC_NA);
764 my_offset += 8;
765 ti = proto_tree_add_item(tree, hf_dec_rt_neighbor, tvb,
766 my_offset, 6, ENC_NA);
767 addr = dnet_ntoa((const guint8 *)tvb_memdup(wmem_packet_scope(), tvb, my_offset, 6));
768 if (addr != NULL) {
769 proto_item_append_text(ti, " (%s)", addr);
771 my_offset += 6;
773 /*'Timer' and 'mpd' fields are common
774 'mpd' field is reserved */
775 proto_tree_add_item(tree, hf_dec_rt_timer, tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
776 my_offset += 3;
777 if (msg == 5) {
778 /* The Ethernet router hello message contains
779 a list of router states
780 The Ethernet Endnode Hello Message contains
781 up to 128 bytes of test data at the end.
782 These data are left to be dissected as 'data'.
784 proto_item *ti_locala, *ti_ether;
785 proto_tree *list_tree, *list_ether;
786 guint8 image_len;
787 guint8 item_len;
789 /* image field is preceded by count of remainder of field */
790 image_len = tvb_get_guint8(tvb, my_offset);
791 my_offset++;
793 ti_locala = proto_tree_add_item(tree, hf_dec_rt_elist, tvb,
794 my_offset, image_len, ENC_NA);
795 list_tree = proto_item_add_subtree(ti_locala, ett_dec_rt_list);
797 while (image_len > 0) {
798 ti_ether = proto_tree_add_item(list_tree, hf_dec_rt_ename, tvb,
799 my_offset, 7, ENC_NA);
800 list_ether = proto_item_add_subtree(ti_ether, ett_dec_rt_rlist);
801 my_offset += 7;
802 image_len -= 7;
804 /* image field is preceded by count of remainder of field */
805 item_len = tvb_get_guint8(tvb, my_offset);
806 my_offset++;
807 image_len -= 1;
808 while (item_len > 0)
810 guint8 pristate;
811 proto_item *ti_localb;
812 proto_tree *pstate_tree;
814 ti_localb = proto_tree_add_item(list_ether, hf_dec_rt_router_id,
815 tvb, my_offset, 6, ENC_NA);
816 addr = dnet_ntoa((const guint8 *)tvb_memdup(wmem_packet_scope(), tvb, my_offset, 6));
817 if (addr != NULL) {
818 proto_item_append_text(ti_localb, " (%s)", addr);
820 my_offset += 6;
821 pstate_tree = proto_item_add_subtree(ti_localb, ett_dec_rt_state);
822 pristate = tvb_get_guint8(tvb, my_offset);
823 proto_tree_add_string(pstate_tree, hf_dec_rt_router_state,
824 tvb, my_offset, 1,
825 ((pristate & 0x80) ? "known 2-way": "unknown"));
826 proto_tree_add_uint(pstate_tree, hf_dec_rt_router_prio,
827 tvb, my_offset, 1, pristate);
828 my_offset++;
829 item_len -= 7;
830 image_len -= 7;
834 return (my_offset);
837 static int
838 handle_nsp_msg(
839 tvbuff_t *tvb,
840 packet_info *pinfo,
841 proto_tree *tree,
842 guint offset,
843 guint8 nsp_msg_type)
845 /* Offset in tvb now points at the first byte still to be handled */
846 guint my_offset = offset;
847 gint data_length;
848 guint16 ack_num, ack_dat, ack_oth, seg_num;
849 guint8 ls_flags, fc_val, services;
850 proto_item *ti;
851 proto_tree *flow_control_tree;
853 /* 'tree' is now the subtree for the NSP message */
854 switch (nsp_msg_type) {
855 case DATA_SEGMENT_MSG: /* "Data segment" */
856 case BOM_MSG: /* "Beginning of segment message" */
857 case EOM_MSG: /* "End of segment message" */
858 case BOM_EOM_MSG: /* "BOM / EOM message" */
859 ack_num = tvb_get_letohs(tvb, my_offset);
860 if (ack_num & 0x8000) {
861 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
862 tvb, my_offset, 2,
863 "Last data segment %s acknowledged: %d",
864 (ack_num & 0x1000) ? "negatively" : "positively",
865 ack_num & 0xfff);
866 my_offset += 2;
867 /* There may still be an ackoth field */
868 ack_oth = tvb_get_letohs(tvb, my_offset);
869 if (ack_oth & 0x8000) {
870 /* There is an ack_oth field */
871 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
872 tvb, my_offset, 2,
873 "Cross sub-channel %s of other data msg %d",
874 ((ack_oth & 0x3000) == 0x2000) ? "ACK" : "NAK",
875 ack_oth & 0xfff);
876 my_offset += 2;
880 * The optional ACKNUM and ACKOTH fields are not present
881 * There is still the segnum field
883 seg_num = tvb_get_letohs(tvb, my_offset);
884 if (nsp_msg_type == BOM_MSG) {
885 dec_dna_total_bytes_this_segment = 0;
886 col_append_fstr(pinfo->cinfo, COL_INFO,
887 "msg nr. %d: start of segment",
888 seg_num & 0xfff);
889 } else if (nsp_msg_type == DATA_SEGMENT_MSG) {
890 col_append_fstr(pinfo->cinfo, COL_INFO,
891 "msg nr. %d: continuation segment ",
892 seg_num & 0xfff);
893 } else if (nsp_msg_type == EOM_MSG) {
894 col_append_fstr(pinfo->cinfo, COL_INFO,
895 "msg nr. %d: end of segment",
896 seg_num & 0xfff);
897 } else if (nsp_msg_type == BOM_EOM_MSG) {
898 dec_dna_total_bytes_this_segment = 0;
899 col_append_fstr(pinfo->cinfo, COL_INFO,
900 "msg nr. %d single segment",
901 seg_num & 0xfff);
903 /* This is the last field, the rest are data */
904 proto_tree_add_item(tree, hf_dec_rt_segnum,
905 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
906 proto_tree_add_boolean(tree, hf_dec_rt_delay,
907 tvb, my_offset, 2, seg_num);
908 my_offset += 2;
909 /* Compute the number of bytes in this data segment */
910 data_length =
911 tvb_reported_length_remaining(tvb, my_offset);
912 dec_dna_previous_total = dec_dna_total_bytes_this_segment;
913 dec_dna_total_bytes_this_segment += data_length;
914 col_append_fstr(pinfo->cinfo, COL_INFO,
915 ", bytes this segment: %d, total so far:%d",
916 data_length, dec_dna_total_bytes_this_segment);
917 /* We are done, return my_offset */
918 break;
919 case INTERRUPT_MSG: /* "Interrupt message" */
920 col_set_str(pinfo->cinfo, COL_INFO, "NSP interrupt 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,
924 tvb, my_offset, 2,
925 "Last interrupt/link service msg %s acknowledged: %d",
926 (ack_num & 0x1000) ? "negatively" : "positively",
927 ack_num & 0xfff);
928 my_offset += 2;
929 /* There may still be an ack_dat field */
930 } else {
931 /* There are no ack/nak fields */
932 proto_tree_add_item(tree, hf_dec_rt_segnum,
933 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
934 proto_tree_add_boolean(tree, hf_dec_rt_delay,
935 tvb, my_offset, 2, ack_num);
936 my_offset += 2;
937 /* We are done, return my_offset */
938 break;
940 ack_dat = tvb_get_letohs(tvb, my_offset);
941 if (ack_dat & 0x8000) {
942 /* There is an ack_dat field */
943 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
944 tvb, my_offset, 2,
945 "Cross sub-channel %s of data segment msg: %d",
946 ((ack_dat & 0x3000) == 0x2000) ? "ACK" : "NAK",
947 ack_dat & 0xfff);
948 my_offset += 2;
950 seg_num = tvb_get_letohs(tvb, my_offset);
951 /* This is the last field, the rest are data */
952 proto_tree_add_item(tree, hf_dec_rt_segnum,
953 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
954 proto_tree_add_boolean(tree, hf_dec_rt_delay,
955 tvb, my_offset, 2, seg_num);
956 my_offset += 2;
957 /* We are done, return my_offset */
958 break;
959 case LINK_SERVICE_MSG: /* "Link service message" */
960 col_set_str(pinfo->cinfo, COL_INFO, "NSP link control message");
961 ack_num = tvb_get_letohs(tvb, my_offset);
962 if (ack_num & 0x8000) {
963 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
964 tvb, my_offset, 2,
965 "Last interrupt/link service msg %s acknowledged: %d",
966 (ack_num & 0x1000) ? "negatively" : "positively",
967 ack_num & 0xfff);
968 my_offset += 2;
969 /* There may still be an ack_dat field */
970 } else {
971 /* There are no ack/nak fields */
972 proto_tree_add_item(tree, hf_dec_rt_segnum,
973 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
974 proto_tree_add_boolean(tree, hf_dec_rt_delay,
975 tvb, my_offset, 2, ack_num);
976 my_offset += 2;
977 /* We are done, return my_offset */
978 break;
980 ack_dat = tvb_get_letohs(tvb, my_offset);
981 if (ack_dat & 0x8000) {
982 /* There is an ack_dat field */
983 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
984 tvb, my_offset, 2,
985 "Cross sub-channel %s of data segment msg: %d",
986 ((ack_dat & 0x3000) == 0x2000) ? "ACK" : "NAK",
987 ack_dat & 0xfff);
988 my_offset += 2;
990 seg_num = tvb_get_letohs(tvb, my_offset);
991 proto_tree_add_item(tree, hf_dec_rt_segnum,
992 tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
993 proto_tree_add_boolean(tree, hf_dec_rt_delay,
994 tvb, my_offset, 2, seg_num);
995 my_offset += 2;
996 /* Now follows the ls_flags field */
997 ls_flags = tvb_get_guint8(tvb, my_offset);
998 switch(ls_flags) {
999 case 0: /* no change */
1000 col_append_str(pinfo->cinfo, COL_INFO,
1001 "(no change)");
1002 break;
1003 case 1: /* stop sending data */
1004 col_append_str(pinfo->cinfo, COL_INFO,
1005 "(stop)");
1006 break;
1007 case 2: /* send data */
1008 col_append_str(pinfo->cinfo, COL_INFO,
1009 "(go)");
1010 break;
1011 default:
1012 break;
1014 fc_val = tvb_get_guint8(tvb, my_offset + 1);
1015 ti = proto_tree_add_uint(tree, hf_dec_flow_control, tvb,
1016 my_offset, 1, ls_flags);
1017 flow_control_tree =
1018 proto_item_add_subtree(ti, ett_dec_flow_control);
1019 proto_tree_add_none_format(flow_control_tree, hf_dec_rt_fc_val,
1020 tvb, my_offset, 2,
1021 "Request for additional %d %s msgs",
1022 fc_val, ((ls_flags & 0x04) ? "interrupt" : "data"));
1023 my_offset += 2;
1024 break;
1025 case DATA_ACK_MSG: /* "Data acknowledgement message" */
1026 ack_num = tvb_get_letohs(tvb, my_offset);
1027 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1028 tvb, my_offset, 2,
1029 "Last data segment %s acknowledged: %d",
1030 (ack_num & 0x1000) ? "negatively" : "positively",
1031 ack_num & 0xfff);
1032 my_offset += 2;
1033 /* There may be an optional ack_oth field */
1034 col_append_fstr(pinfo->cinfo, COL_INFO,
1035 "NSP data %s message(%d)",
1036 (ack_num & 0x1000) ? "NAK" : "ACK",
1037 ack_num & 0xfff);
1039 if (tvb_length_remaining(tvb, my_offset) > 0) {
1040 ack_oth = tvb_get_letohs(tvb, my_offset);
1041 if (ack_oth & 0x8000) {
1042 /* There is an ack_oth field */
1043 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1044 tvb, my_offset, 2,
1045 "Cross sub-channel %s of other data msg %d",
1046 ((ack_oth & 0x3000) == 0x2000) ? "ACK" : "NAK",
1047 ack_oth & 0xfff);
1048 my_offset += 2;
1051 /* We are done, return my_offset */
1052 break;
1053 case OTHER_DATA_ACK_MSG: /* "Other data acknowledgement message" */
1054 col_set_str(pinfo->cinfo, COL_INFO, "NSP other data ACK message");
1055 ack_num = tvb_get_letohs(tvb, my_offset);
1056 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1057 tvb, my_offset, 2,
1058 "Last interrupt/link service msg %s acknowledged: %d",
1059 (ack_num & 0x1000) ? "negatively" : "positively",
1060 ack_num & 0xfff);
1061 my_offset += 2;
1062 /* There may be an optional ack_dat field */
1063 if (tvb_length_remaining(tvb, my_offset) > 0) {
1064 ack_dat = tvb_get_letohs(tvb, my_offset);
1065 if (ack_dat & 0x8000) {
1066 /* There is an ack_dat field */
1067 proto_tree_add_none_format(tree, hf_dec_rt_acknum,
1068 tvb, my_offset, 2,
1069 "Cross sub-channel %s of data msg %d",
1070 ((ack_dat & 0x3000) == 0x2000) ? "ACK" : "NAK",
1071 ack_dat & 0xfff);
1072 my_offset += 2;
1075 /* We are done, return my_offset */
1076 break;
1077 case CONN_CONFIRM_MSG: /* "Connect confirm" */
1078 case CONN_INITIATE_MSG: /* "Connect initiate" */
1079 col_set_str(pinfo->cinfo, COL_INFO, "NSP connect confirm/initiate message");
1080 services = tvb_get_guint8(tvb, my_offset);
1081 proto_tree_add_uint(tree, hf_dec_rt_services, tvb,
1082 my_offset, 1, services);
1083 my_offset++;
1084 proto_tree_add_item(tree, hf_dec_rt_info, tvb, my_offset, 1, ENC_LITTLE_ENDIAN);
1085 my_offset++;
1086 proto_tree_add_item(tree, hf_dec_rt_seg_size, tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
1087 my_offset += 2;
1088 my_offset = handle_connect_contents(tvb, tree, my_offset);
1089 break;
1090 case DISCONN_INITIATE_MSG: /* "Disconnect initiate" */
1091 case DISCONN_CONFIRM_MSG: /* "Disconnect confirm" */
1092 col_set_str(pinfo->cinfo, COL_INFO, "NSP disconnect initiate/confirm message");
1093 proto_tree_add_item(tree, hf_dec_disc_reason, tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
1094 my_offset += 2;
1095 if (nsp_msg_type == DISCONN_INITIATE_MSG) {
1096 my_offset =
1097 handle_disc_init_contents( my_offset);
1099 break;
1100 default:
1101 break;
1103 return (my_offset);
1106 static int
1107 handle_connect_contents(
1108 tvbuff_t *tvb,
1109 proto_tree *tree,
1110 guint offset)
1112 guint my_offset = offset;
1113 proto_item *ti;
1114 proto_tree *contents_tree;
1115 guint8 dst_format, src_format, obj_type, image_len, menu_ver;
1117 ti = proto_tree_add_item(tree, hf_dec_conn_contents,
1118 tvb, my_offset, -1, ENC_NA);
1119 contents_tree = proto_item_add_subtree(ti, ett_dec_sess_contents);
1120 /* The destination end user */
1121 dst_format = tvb_get_guint8(tvb, my_offset);
1122 my_offset++;
1123 obj_type = tvb_get_guint8(tvb, my_offset);
1124 proto_tree_add_uint(contents_tree, hf_dec_sess_obj_type, tvb, my_offset, 1, obj_type);
1125 my_offset++;
1126 if (dst_format == 2) {
1127 proto_tree_add_item(contents_tree, hf_dec_sess_grp_code, tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
1128 my_offset += 2;
1129 proto_tree_add_item(contents_tree, hf_dec_sess_usr_code, tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
1130 my_offset += 2;
1132 if (dst_format != 0) {
1133 /* The name field for formats 1 and 2 */
1134 image_len = tvb_get_guint8(tvb, my_offset);
1135 my_offset++;
1136 proto_tree_add_item(contents_tree, hf_dec_sess_dst_name, tvb, my_offset, image_len, ENC_ASCII|ENC_NA);
1137 my_offset += image_len;
1139 /* The source end user */
1140 src_format = tvb_get_guint8(tvb, my_offset);
1141 my_offset++;
1142 obj_type = tvb_get_guint8(tvb, my_offset);
1143 proto_tree_add_uint(contents_tree, hf_dec_sess_obj_type,
1144 tvb, my_offset, 1, obj_type);
1145 my_offset++;
1146 if (src_format == 2) {
1147 proto_tree_add_item(contents_tree, hf_dec_sess_grp_code, tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
1148 my_offset += 2;
1149 proto_tree_add_item(contents_tree, hf_dec_sess_usr_code, tvb, my_offset, 2, ENC_LITTLE_ENDIAN);
1150 my_offset += 2;
1152 if (dst_format != 0) {
1153 /* The name field for formats 1 and 2 */
1154 image_len = tvb_get_guint8(tvb, my_offset);
1155 my_offset++;
1156 proto_tree_add_item(contents_tree, hf_dec_sess_src_name,
1157 tvb, my_offset, image_len, ENC_ASCII|ENC_NA);
1158 my_offset += image_len;
1160 /* Now the MENUVER field */
1161 menu_ver = tvb_get_guint8(tvb, my_offset);
1162 switch (menu_ver) {
1163 case 1:
1164 case 3:
1165 proto_tree_add_string(contents_tree, hf_dec_sess_menu_ver,
1166 tvb, my_offset, 1,
1167 "Version 1.0: RQSTRID, PASSWRD and ACCOUNT fields included");
1168 my_offset++;
1169 image_len = tvb_get_guint8(tvb, my_offset);
1170 my_offset++;
1171 proto_tree_add_item(contents_tree, hf_dec_sess_rqstr_id,
1172 tvb, my_offset, image_len, ENC_ASCII|ENC_NA);
1173 my_offset += image_len;
1174 image_len = tvb_get_guint8(tvb, my_offset);
1175 my_offset++;
1176 proto_tree_add_item(contents_tree, hf_dec_sess_rqstr_id,
1177 tvb, my_offset, image_len, ENC_ASCII|ENC_NA);
1178 my_offset += image_len;
1179 image_len = tvb_get_guint8(tvb, my_offset);
1180 my_offset++;
1181 proto_tree_add_item(contents_tree, hf_dec_sess_rqstr_id,
1182 tvb, my_offset, image_len, ENC_ASCII|ENC_NA);
1183 my_offset += image_len;
1186 break;
1187 case 2:
1188 /* A USRDATA field is handled by dissect_data */
1189 proto_tree_add_string(contents_tree, hf_dec_sess_menu_ver,
1190 tvb, my_offset, 1,
1191 "Version 1.0: USRDATA field included");
1192 break;
1193 default:
1194 proto_tree_add_string(contents_tree, hf_dec_sess_menu_ver,
1195 tvb, my_offset, 1,
1196 "Session control version 1.0");
1197 break;
1199 return (my_offset);
1202 static int
1203 handle_disc_init_contents(
1204 guint offset)
1206 guint my_offset = offset;
1208 return (my_offset);
1212 void
1213 proto_register_dec_rt(void)
1216 static hf_register_info hf[] = {
1217 /* Mesage header items */
1218 { &hf_dec_routing_flags,
1219 { "Routing flags", "dec_dna.flags",
1220 FT_UINT8, BASE_HEX, NULL, 0x0,
1221 "DNA routing flag", HFILL }},
1222 { &hf_dec_rt_ctrl_msg,
1223 { "Control packet", "dec_dna.flags.control",
1224 FT_BOOLEAN, 8, TFS(&tfs_yes_no), RT_FLAGS_CTRL_MSG,
1225 NULL, HFILL }},
1226 { &hf_dec_rt_long_msg,
1227 { "Long data packet format", "dec_dna.flags.msglen",
1228 FT_UINT8, BASE_HEX, NULL, 0x06,
1229 "Long message indicator", HFILL }},
1230 { &hf_dec_rt_short_msg,
1231 { "Short data packet format", "dec_dna.flags.msglen",
1232 FT_UINT8, BASE_HEX, NULL, 0x06,
1233 "Short message indicator", HFILL }},
1234 { &hf_dec_rt_rqr,
1235 { "Return to Sender Request", "dec_dna.flags.RQR",
1236 FT_BOOLEAN, 8, TFS(&tfs_yes_no), RT_FLAGS_RQR,
1237 "Return to Sender", HFILL }},
1238 { &hf_dec_rt_rts,
1239 { "Packet on return trip", "dec_dna.flags.RTS",
1240 FT_BOOLEAN, 8, TFS(&tfs_yes_no), RT_FLAGS_RTS,
1241 NULL, HFILL }},
1242 { &hf_dec_rt_inter_eth,
1243 { "Intra-ethernet packet", "dec_dna.flags.intra_eth",
1244 FT_BOOLEAN, 8, TFS(&tfs_yes_no), RT_FLAGS_INTRA_ETHER,
1245 NULL, HFILL }},
1246 { &hf_dec_rt_discard,
1247 { "Discarded packet", "dec_dna.flags.discard",
1248 FT_BOOLEAN, 8, TFS(&tfs_yes_no), RT_FLAGS_DISCARD,
1249 NULL, HFILL }},
1250 { &hf_dec_rt_dst_addr,
1251 { "Destination Address", "dec_dna.dst.address",
1252 FT_ETHER, BASE_NONE, NULL, 0x0,
1253 NULL, HFILL }},
1254 { &hf_dec_rt_src_addr,
1255 { "Source Address", "dec_dna.src.addr",
1256 FT_ETHER, BASE_NONE, NULL, 0x0,
1257 NULL, HFILL }},
1258 { &hf_dec_rt_nl2,
1259 { "Next level 2 router", "dec_dna.nl2",
1260 FT_UINT8, BASE_HEX, NULL, 0x0,
1261 "reserved", HFILL }},
1262 { &hf_dec_rt_service_class,
1263 { "Service class", "dec_dna.svc_cls",
1264 FT_UINT8, BASE_HEX, NULL, 0x0,
1265 "reserved", HFILL }},
1266 { &hf_dec_rt_protocol_type,
1267 { "Protocol type", "dec_dna.proto_type",
1268 FT_UINT8, BASE_HEX, NULL, 0x0,
1269 "reserved", HFILL }},
1270 { &hf_dec_rt_visit_count,
1271 { "Visit count", "dec_dna.visit_cnt",
1272 FT_UINT8, BASE_HEX, NULL, 0x0,
1273 NULL, HFILL }},
1274 { &hf_dec_flow_control,
1275 { "Flow control", "dec_dna.nsp.flow_control",
1276 FT_UINT8, BASE_HEX, VALS(rt_flow_control_vals), 0x3,
1277 "Flow control(stop, go)", HFILL }},
1278 { &hf_dec_rt_services,
1279 { "Requested services", "dec_dna.nsp.services",
1280 FT_UINT8, BASE_HEX, VALS(rt_services_vals), 0x0c,
1281 "Services requested", HFILL }},
1282 { &hf_dec_rt_info,
1283 { "Version info", "dec_dna.nsp.info",
1284 FT_UINT8, BASE_HEX, VALS(rt_info_version_vals), 0x03,
1285 NULL, HFILL }},
1286 { &hf_dec_rt_dst_node,
1287 { "Destination node", "dec_dna.dst_node",
1288 FT_UINT16, BASE_HEX, NULL, 0x0,
1289 NULL, HFILL }},
1290 { &hf_dec_rt_seg_size,
1291 { "Maximum data segment size", "dec_dna.nsp.segsize",
1292 FT_UINT16, BASE_DEC, NULL, 0x0,
1293 "Max. segment size", HFILL }},
1294 { &hf_dec_rt_src_node,
1295 { "Source node", "dec_dna.src_node",
1296 FT_UINT16, BASE_HEX, NULL, 0x0,
1297 NULL, HFILL }},
1298 { &hf_dec_rt_segnum,
1299 { "Message number", "dec_dna.nsp.segnum",
1300 FT_UINT16, BASE_DEC, NULL, 0xfff,
1301 "Segment number", HFILL }},
1302 { &hf_dec_rt_delay,
1303 { "Delayed ACK allowed", "dec_dna.nsp.delay",
1304 FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x1000,
1305 "Delayed ACK allowed?", HFILL }},
1306 { &hf_dec_rt_visited_nodes,
1307 { "Nodes visited ty this package", "dec_dna.vst_node",
1308 FT_UINT8, BASE_DEC, NULL, 0x0,
1309 "Nodes visited", HFILL }},
1310 /* Control messsage items */
1311 { &hf_dec_ctl_msgs,
1312 { "Routing control message", "dec_dna.rt.msg_type",
1313 FT_UINT8, BASE_HEX, VALS(rt_msg_type_vals), 0xe,
1314 "Routing control", HFILL }},
1315 { &hf_dec_ctl_msg_hdr,
1316 { "Routing control message", "dec_dna.rt.msg_type",
1317 FT_UINT8, BASE_HEX, VALS(rt_msg_type_vals), 0xe,
1318 "Routing control", HFILL }},
1319 { &hf_dec_nsp_msgs,
1320 { "DNA NSP message", "dec_dna.nsp.msg_type",
1321 FT_UINT8, BASE_HEX, VALS(nsp_msg_type_vals), 0x0,
1322 "NSP message", HFILL }},
1323 { &hf_dec_rt_acknum,
1324 { "Ack/Nak", "dec_dna.ctl.acknum",
1325 FT_NONE, BASE_NONE, NULL, 0x0,
1326 "ack/nak number", HFILL }},
1327 { &hf_dec_rt_fc_val,
1328 { "Flow control", "dec_dna.nsp.fc_val",
1329 FT_NONE, BASE_NONE, NULL, 0x0,
1330 NULL, HFILL }},
1331 { &hf_dec_rt_tiinfo,
1332 { "Routing information", "dec_dna.ctl.tiinfo",
1333 FT_UINT8, BASE_HEX, VALS(rt_tiinfo_vals), 0x0,
1334 NULL, HFILL }},
1335 { &hf_dec_rt_blk_size,
1336 { "Block size", "dec_dna.ctl.blk_size",
1337 FT_UINT16, BASE_DEC, NULL, 0x0,
1338 NULL, HFILL }},
1339 { &hf_dec_disc_reason,
1340 { "Reason for disconnect","dec_dna.nsp.disc_reason",
1341 FT_UINT16, BASE_HEX, VALS(rt_disc_reason_vals), 0x0,
1342 "Disconnect reason", HFILL }},
1343 { &hf_dec_rt_version,
1344 { "Version", "dec_dna.ctl.version",
1345 FT_NONE, BASE_NONE, NULL, 0x0,
1346 "Control protocol version", HFILL }},
1347 { &hf_dec_rt_timer,
1348 { "Hello timer(seconds)", "dec_dna.ctl.timer",
1349 FT_UINT16, BASE_DEC, NULL, 0x0,
1350 "Hello timer in seconds", HFILL }},
1351 { &hf_dec_rt_reserved,
1352 { "Reserved", "dec_dna.ctl.reserved",
1353 FT_BYTES, BASE_NONE, NULL, 0x0,
1354 NULL, HFILL }},
1355 { &hf_dec_rt_fcnval,
1356 { "Verification message function value", "dec_dna.ctl.fcnval",
1357 FT_BYTES, BASE_NONE, NULL, 0x0,
1358 "Routing Verification function", HFILL }},
1359 { &hf_dec_rt_test_data,
1360 { "Test message data", "dec_dna.ctl.test_data",
1361 FT_BYTES, BASE_NONE, NULL, 0x0,
1362 "Routing Test message data", HFILL }},
1363 { &hf_dec_rt_segment,
1364 { "Segment", "dec_dna.ctl.segment",
1365 FT_NONE, BASE_NONE, NULL, 0x0,
1366 "Routing Segment", HFILL }},
1367 { &hf_dec_rt_id,
1368 { "Transmitting system ID", "dec_dna.ctl.id",
1369 FT_ETHER, BASE_NONE, NULL, 0x0,
1370 NULL, HFILL }},
1371 { &hf_dec_rt_iinfo,
1372 { "Routing information", "dec_dna.ctl.tiinfo",
1373 FT_UINT8, BASE_HEX, NULL, 0x0,
1374 NULL, HFILL }},
1375 { &hf_dec_rt_iinfo_node_type,
1376 { "Node type", "dec_dna.ctl.iinfo.node_type",
1377 FT_UINT8, BASE_HEX, VALS(rt_iinfo_node_type_vals), 0x03,
1378 NULL, HFILL }},
1379 { &hf_dec_rt_iinfo_vrf,
1380 { "Verification required", "dec_dna.ctl.iinfo.vrf",
1381 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x4,
1382 "Verification required?", HFILL }},
1383 { &hf_dec_rt_iinfo_rej,
1384 { "Rejected", "dec_dna.ctl.iinfo.rej",
1385 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x8,
1386 "Rejected message", HFILL }},
1387 { &hf_dec_rt_iinfo_verf,
1388 { "Verification failed", "dec_dna.ctl.iinfo.verf",
1389 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
1390 "Verification failed?", HFILL }},
1391 { &hf_dec_rt_iinfo_mta,
1392 { "Accepts multicast traffic", "dec_dna.ctl.iinfo.mta",
1393 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
1394 "Accepts multicast traffic?", HFILL }},
1395 { &hf_dec_rt_iinfo_blkreq,
1396 { "Blocking requested", "dec_dna.ctl.iinfo.blkreq",
1397 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
1398 "Blocking requested?", HFILL }},
1399 { &hf_dec_rt_iprio,
1400 { "Routing priority", "dec_dna.ctl.prio",
1401 FT_UINT8, BASE_HEX, NULL, 0x0,
1402 NULL, HFILL }},
1403 { &hf_dec_rt_neighbor,
1404 { "Neighbor", "dec_dna.ctl_neighbor",
1405 FT_ETHER, BASE_NONE, NULL, 0x0,
1406 "Neighbour ID", HFILL }},
1407 { &hf_dec_rt_seed,
1408 { "Verification seed", "dec_dna.ctl.seed",
1409 FT_BYTES, BASE_NONE, NULL, 0x0,
1410 NULL, HFILL }},
1411 { &hf_dec_rt_elist,
1412 { "List of router states", "dec_dna.ctl.elist",
1413 FT_NONE, BASE_NONE, NULL, 0x0,
1414 "Router states", HFILL }},
1415 { &hf_dec_rt_ename,
1416 { "Ethernet name", "dec_dna.ctl.ename",
1417 FT_BYTES, BASE_NONE, NULL, 0x0,
1418 NULL, HFILL }},
1419 { &hf_dec_rt_router_id,
1420 { "Router ID", "dec_dna.ctl.router_id",
1421 FT_ETHER, BASE_NONE, NULL, 0x0,
1422 NULL, HFILL }},
1423 { &hf_dec_rt_router_state,
1424 { "Router state", "dec_dna.ctl.router_state",
1425 FT_STRING, BASE_NONE, NULL, 0x0,
1426 NULL, HFILL }},
1427 { &hf_dec_conn_contents,
1428 { "Session connect data", "dec_dna.sess.conn",
1429 FT_NONE, BASE_NONE, NULL, 0x0,
1430 NULL, HFILL }},
1431 { &hf_dec_rt_router_prio,
1432 { "Router priority", "dec_dna.ctl.router_prio",
1433 FT_UINT8, BASE_HEX, NULL, 0x7f,
1434 NULL, HFILL }},
1435 { &hf_dec_sess_grp_code,
1436 { "Session Group code", "dec_dna.sess.grp_code",
1437 FT_UINT16, BASE_HEX, NULL, 0x0,
1438 NULL, HFILL }},
1439 { &hf_dec_sess_usr_code,
1440 { "Session User code", "dec_dna.sess.usr_code",
1441 FT_UINT16, BASE_HEX, NULL, 0x0,
1442 NULL, HFILL }},
1443 { &hf_dec_sess_dst_name,
1444 { "Session Destination end user", "dec_dna.sess.dst_name",
1445 FT_STRING, BASE_NONE, NULL, 0x0,
1446 NULL, HFILL }},
1447 { &hf_dec_sess_src_name,
1448 { "Session Source end user", "dec_dna.sess.src_name",
1449 FT_STRING, BASE_NONE, NULL, 0x0,
1450 NULL, HFILL }},
1451 { &hf_dec_sess_obj_type,
1452 { "Session Object type", "dec_dna.sess.obj_type",
1453 FT_UINT8, BASE_HEX, NULL, 0x0,
1454 NULL, HFILL }},
1455 { &hf_dec_sess_menu_ver,
1456 { "Session Menu version", "dec_dna.sess.menu_ver",
1457 FT_STRING, BASE_NONE, NULL, 0x0,
1458 NULL, HFILL }},
1459 { &hf_dec_sess_rqstr_id,
1460 { "Session Requestor ID", "dec_dna.sess.rqstr_id",
1461 FT_STRING, BASE_NONE, NULL, 0x0,
1462 NULL, HFILL }},
1466 static gint *ett[] = {
1467 &ett_dec_rt,
1468 &ett_dec_routing_flags,
1469 &ett_dec_msg_flags,
1470 &ett_dec_rt_ctl_msg,
1471 &ett_dec_rt_nsp_msg,
1472 &ett_dec_rt_info_flags,
1473 &ett_dec_rt_list,
1474 &ett_dec_rt_rlist,
1475 &ett_dec_rt_state,
1476 &ett_dec_flow_control,
1477 &ett_dec_sess_contents,
1480 proto_dec_rt = proto_register_protocol("DEC DNA Routing Protocol",
1481 "DEC_DNA", "dec_dna");
1482 proto_register_field_array(proto_dec_rt, hf, array_length(hf));
1483 proto_register_subtree_array(ett, array_length(ett));
1486 void
1487 proto_reg_handoff_dec_rt(void)
1489 dissector_handle_t dec_rt_handle;
1491 dec_rt_handle = create_dissector_handle(dissect_dec_rt,
1492 proto_dec_rt);
1493 dissector_add_uint("ethertype", ETHERTYPE_DNA_RT, dec_rt_handle);
1494 dissector_add_uint("chdlc.protocol", ETHERTYPE_DNA_RT, dec_rt_handle);
1495 dissector_add_uint("ppp.protocol", PPP_DEC4, dec_rt_handle);
1496 /* dissector_add_uint("ppp.protocol", PPP_DECNETCP, dec_rt_handle);*/