Ethereal-dev: [Ethereal-dev] Patch for packet-dec-dnart.c revision 16349

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Fred Hoekstra <fred.hoekstra@xxxxxxxxxxxx>
Date: Fri, 04 Nov 2005 20:55:26 +0100
Hi,

Martin Hill has examined packet-dec-dnart.c and found some errors and
made some improvements.

Attached is a diff file for patching packet-dec-dnart.c, revision 16349,
to incorporate these corrections.

The file with applied patch has been fuzz tested up to Pass 3450 with
a capture file of 5 MByte.

Could these please be applied?

Thanks, 
Fred Hoekstra

--- packet-dec-dnart.c	2005-11-04 16:03:44.000000000 +0100
+++ packet-dec-dnart.c.patch	2005-11-04 16:04:07.000000000 +0100
@@ -11,11 +11,11 @@
  * Use was made of the following documentation:
  * (See URL http://linux-decnet.sourceforge.net/docs).
  *
- * 		DECnet DIGITAL Network Architecture
+ *         DECnet DIGITAL Network Architecture
  *      Routing Layer Functional Specification
  *      Version 2.0.0 May, 1983
  *
- * 		DECnet DIGITAL Network Architecture
+ *         DECnet DIGITAL Network Architecture
  *      NSP Functional Specification
  *      Phase IV, Version 4.0.1, July 1984
  *
@@ -67,7 +67,7 @@
     RT_CTL_ETH_ENDNODE_HELLO_MSG
 } ctl_msg_types;
 
-#define DEC_RT_SIZE		27
+#define DEC_RT_SIZE        27
 
 #define DATA_SEGMENT_MSG     0x00 /* "Data segment" */
 #define LINK_SERVICE_MSG     0x10 /* "Link service message" */
@@ -87,24 +87,26 @@
 
 /* Flag bits */
 
-#define RT_FLAGS_LONG_MSG	   0x04 /* Actually: 0x06->long, 0x02->short*/
-#define RT_FLAGS_RQR		   0x08
-#define RT_FLAGS_RTS		   0x10
+#define RT_FLAGS_CTRL_MSG      0x01
+#define RT_FLAGS_LONG_MSG      0x04 /* Actually: 0x06->long, 0x02->short*/
+#define RT_FLAGS_RQR           0x08
+#define RT_FLAGS_RTS           0x10
 #define RT_FLAGS_INTRA_ETHER   0x20
-#define RT_FLAGS_DISCARD	   0x40
-#define RT_FLAGS_PAD		   0x80
+#define RT_FLAGS_DISCARD       0x40
+#define RT_FLAGS_PAD           0x80
 
 static int proto_dec_rt = -1;
 
 static int hf_dec_routing_flags = -1;
+static int hf_dec_rt_ctrl_msg = -1;
 static int hf_dec_rt_long_msg = -1;
 static int hf_dec_rt_short_msg = -1;
 static int hf_dec_rt_rqr = -1;
 static int hf_dec_rt_rts = -1;
 static int hf_dec_rt_inter_eth = -1;
 static int hf_dec_rt_discard = -1;
-static int hf_dec_rt_dst_mac = -1;
-static int hf_dec_rt_src_mac = -1;
+static int hf_dec_rt_dst_addr = -1;
+static int hf_dec_rt_src_addr = -1;
 static int hf_dec_rt_nl2 = -1;
 static int hf_dec_rt_service_class = -1;
 static int hf_dec_rt_protocol_type = -1;
@@ -114,6 +116,7 @@
 /* Routing control messages */
 static int hf_dec_rt_visited_nodes = -1;
 static int hf_dec_ctl_msgs = -1;
+static int hf_dec_ctl_msg_hdr = -1;
 static int hf_dec_nsp_msgs = -1;
 static int hf_dec_rt_tiinfo = -1;
 static int hf_dec_rt_blk_size = -1;
@@ -135,6 +138,7 @@
 static int hf_dec_rt_neighbor = -1;
 static int hf_dec_rt_seed = -1;
 static int hf_dec_rt_elist = -1;
+static int hf_dec_rt_ename = -1;
 static int hf_dec_rt_router_id = -1;
 static int hf_dec_rt_router_state = -1;
 static int hf_dec_rt_router_prio = -1;
@@ -163,6 +167,7 @@
 static gint ett_dec_rt_nsp_msg = -1;
 static gint ett_dec_rt_info_flags = -1;
 static gint ett_dec_rt_list = -1;
+static gint ett_dec_rt_rlist = -1;
 static gint ett_dec_rt_state = -1;
 static gint ett_dec_flow_control = -1;
 static gint ett_dec_sess_contents = -1;
@@ -171,14 +176,14 @@
 static gint dec_dna_previous_total = 0;
 
 /*static const value_string protocol_id_vals[] = {
-	{ 0x6001, "DEC DNA dump/load" },
-	{ 0x6002, "DEC DNA Remote Console" },
-	{ 0x6003, "DEC DNA routing" },
-	{ 0x6004, "DEC DNA Local Area Transport" },
-	{ 0x6005, "DEC DNA diagnostics" },
-	{ 0x6006, "DEC DNA Customer specific" },
-	{ 0x6007, "DEC DNA System Communication Architecture" },
-	{ 0,    NULL }
+    { 0x6001, "DEC DNA dump/load" },
+    { 0x6002, "DEC DNA Remote Console" },
+    { 0x6003, "DEC DNA routing" },
+    { 0x6004, "DEC DNA Local Area Transport" },
+    { 0x6005, "DEC DNA diagnostics" },
+    { 0x6006, "DEC DNA Customer specific" },
+    { 0x6007, "DEC DNA System Communication Architecture" },
+    { 0,    NULL }
 };*/
 
 static const value_string rt_msg_type_vals[] = {
@@ -189,7 +194,7 @@
     { 0x4   , "Level 2 routing message" },
     { 0x5   , "Ethernet router hello message" },
     { 0x6   , "Ethernet endnode hello message" },
-	{ 0,    NULL }
+    { 0,    NULL }
 };
 
 static const value_string nsp_msg_type_vals[] = {
@@ -208,17 +213,7 @@
     { 0x48   , "Disconnect confirm" },
     { 0x60   , "Begin of segment / End of segment" },
     { 0x68   , "Retransmitted connect initiate" },
-	{ 0,    NULL }
-};
-
-static const value_string routing_flags[] = {
-    {0x02,  "Short data packet format"},
-    {0x06,  "Long data packet format"},
-    {0x08,  "Return to sender request"},
-    {0x10,  "Packet on return trip"},
-    {0x20,  "Intra-Ethernet packet"},
-    {0x40,  "Discarded packet"},
-    {0x0,  NULL}
+    { 0,    NULL }
 };
 
 static const value_string rt_iinfo_flags[] = {
@@ -290,18 +285,8 @@
     { 0,    NULL}
 };
 
-#define RT_TYPE_TOPOLOGY_CHANGE	2
-#define RT_TYPE_HELLO			25
-
-static const char initial_sep[] = " (";
-static const char cont_sep[] = ", ";
-
-#define APPEND_BOOLEAN_FLAG(flag, item, string) \
-	if(flag){							\
-		if(item)						\
-			proto_item_append_text(item, string, sep);	\
-		sep = cont_sep;						\
-	}
+#define RT_TYPE_TOPOLOGY_CHANGE    2
+#define RT_TYPE_HELLO            25
 
 #if ! defined true
 #define true 1
@@ -366,6 +351,26 @@
 handle_disc_init_contents(
     guint offset);
 
+static char *
+dnet_ntoa(const guint8 *data)
+{
+    if (data[0] == 0xAA && data[1] == 0x00 && data[2] == 0x04 && data[3] == 0x00) {
+        guint16 dnet_addr = data[4] | (data[5] << 8);
+        return g_strdup_printf("%d.%d", dnet_addr >> 10, dnet_addr & 0x03FF);
+    }
+    return NULL;
+}
+
+static void
+set_dnet_address(address *paddr_src, address *paddr_tgt)
+{
+    if (paddr_tgt->type != AT_STRINGZ && paddr_src->type == AT_ETHER) {
+        char *addr = dnet_ntoa(paddr_src->data);
+        if (addr != NULL)
+            SET_ADDRESS(paddr_tgt, AT_STRINGZ, 1, addr);
+    }
+}
+
 static void
 dissect_dec_rt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
@@ -380,144 +385,62 @@
     proto_tree *rt_tree;
     proto_tree *flags_tree;
     proto_item *ti;
-    const char *sep;
+    char *addr;
 
     offset = 0;
     if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
-	    col_clear(pinfo->cinfo, COL_PROTOCOL);
+        col_clear(pinfo->cinfo, COL_PROTOCOL);
     }
     if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
-	    col_set_str(pinfo->cinfo, COL_PROTOCOL, "NSP");
+        col_set_str(pinfo->cinfo, COL_PROTOCOL, "DEC DNA");
     }
     if (check_col(pinfo->cinfo, COL_INFO)) {
-	    col_clear(pinfo->cinfo, COL_INFO);
+        col_clear(pinfo->cinfo, COL_INFO);
     }
-    payload_length = tvb_get_ntohs(tvb, offset);
+
+    set_dnet_address(&pinfo->dl_src, &pinfo->net_src);
+    set_dnet_address(&pinfo->dl_src, &pinfo->src);
+    set_dnet_address(&pinfo->dl_dst, &pinfo->net_dst);
+    set_dnet_address(&pinfo->dl_dst, &pinfo->dst);
+
+    payload_length = tvb_get_letohs(tvb, offset);
     offset += 2;
     msg_flags = tvb_get_guint8(tvb, offset);
-	ti = proto_tree_add_item(tree, proto_dec_rt, tvb, 0, -1,
-			    TRUE);
-	rt_tree = proto_item_add_subtree(ti, ett_dec_rt);
+    ti = proto_tree_add_item(tree, proto_dec_rt, tvb, 0, -1,
+                TRUE);
+    rt_tree = proto_item_add_subtree(ti, ett_dec_rt);
     /* When padding, the first byte after the padding has
        the real routing flags */
     if (msg_flags & 0x80) {
         /* There is padding present, skip it */
         padding_length = msg_flags & 0x7f;
         offset += padding_length;
-        /* The real routing flag */
-        msg_flags = tvb_get_guint8(tvb, offset);
-	    ti = proto_tree_add_uint(rt_tree, hf_dec_routing_flags, tvb,
-				     offset, 1, msg_flags);
-	    flags_tree = proto_item_add_subtree(ti, ett_dec_routing_flags);
-	    sep = initial_sep;
-        if (msg_flags & RT_FLAGS_LONG_MSG) {
-            APPEND_BOOLEAN_FLAG(msg_flags & RT_FLAGS_LONG_MSG, ti,
-				"%sLong message");
-	        proto_tree_add_uint(flags_tree, hf_dec_rt_long_msg,
-                 tvb, offset, 1, msg_flags & 0x03);
-            long_msg = true;
-        } else {
-	        APPEND_BOOLEAN_FLAG(msg_flags & RT_FLAGS_LONG_MSG, ti,
-				"%sShort message");
-	        proto_tree_add_item(flags_tree, hf_dec_rt_short_msg,
-                 tvb, offset, 1, msg_flags & 0x03);
-        }
-        APPEND_BOOLEAN_FLAG(msg_flags & RT_FLAGS_RQR, ti,
-			"%sReturn to Sender");
-	    proto_tree_add_boolean(flags_tree, hf_dec_rt_rqr, tvb,
-				   offset, 1, msg_flags);
-        APPEND_BOOLEAN_FLAG(msg_flags & RT_FLAGS_RTS, ti,
-			"%sReturn trip");
-	    proto_tree_add_boolean(flags_tree, hf_dec_rt_rts, tvb,
-				   offset, 1, msg_flags);
-        APPEND_BOOLEAN_FLAG(msg_flags & RT_FLAGS_INTRA_ETHER, ti,
-			"%sIntra Ethernet");
-	    proto_tree_add_boolean(flags_tree, hf_dec_rt_inter_eth, tvb,
-				   offset, 1, msg_flags);
-        APPEND_BOOLEAN_FLAG(msg_flags & RT_FLAGS_DISCARD, ti,
-			"%sDiscarded");
-	    proto_tree_add_boolean(flags_tree, hf_dec_rt_discard, tvb,
-				   offset, 1, msg_flags);
- 	    if (sep != initial_sep) {
-	        /* We put something in; put in the terminating ")" */
-	        proto_item_append_text(ti, ")");
-	    }
-        /* That finished the routing flags field
-            Now we must discriminate between short and long messages
-            We handle long messages first.
-         */
-        if (long_msg) {
-            /* Increment offset by three:
-                 1 to get past the flags field
-                 2 to skip the DEC area/subarea field
-             */
-            offset += 3;
-	        proto_tree_add_item(rt_tree, hf_dec_rt_dst_mac, tvb,
-				    offset, 6, FALSE);
-            /* Skip 6 bytes for the MAC and
-                    2 bytes for DEC area/subarea
-             */
-            offset += 8;
-	        proto_tree_add_item(rt_tree, hf_dec_rt_src_mac, tvb,
-				offset, 6, FALSE);
-            /* Proceed to the NL2 byte */
-            offset += 6;
-	        proto_tree_add_uint(rt_tree, hf_dec_rt_nl2, tvb,
-				offset, 1, rt_zero);
-            offset++;
-            rt_visit_count = tvb_get_guint8(tvb, offset);
-	        proto_tree_add_uint(rt_tree, hf_dec_rt_visit_count, tvb,
-				offset, 1, rt_visit_count);
-            offset++;
-	        proto_tree_add_uint(rt_tree, hf_dec_rt_service_class, tvb,
-				offset, 1, rt_zero);
-            offset++;
-	        proto_tree_add_uint(rt_tree, hf_dec_rt_protocol_type, tvb,
-				offset, 1, rt_zero);
-            offset++;
-        } else {
-            /* Now the short message format
-               Increment offset to get past the flags field
-             */
-            offset++;
-            dst_node = tvb_get_letohs(tvb, offset);
-	        proto_tree_add_item(rt_tree, hf_dec_rt_dst_node, tvb,
-				offset, 2, TRUE);
-            offset += 2;
-            src_node = tvb_get_letohs(tvb, offset);
-	        proto_tree_add_item(rt_tree, hf_dec_rt_src_node, tvb,
-				offset, 2, TRUE);
-            offset += 2;
-            forward = tvb_get_guint8(tvb, offset);
-	        proto_tree_add_uint(rt_tree, hf_dec_rt_visited_nodes, tvb,
-				offset, 1, forward);
-            offset++;
-        }
     }
+
+    /* The real routing flag */
     msg_flags = tvb_get_guint8(tvb, offset);
-    /* This gives us either the routing control msg flag or the
-       NSP message identifier
-    */
-    if (msg_flags & 0x01) {
-        /* This is a control message
-           Documentation is somewhat confusing at this point
-           Data messages have a short or long header prepended,
-           however, the Routing Layer control messages do not have
-           a header prepended. Routing Layer control messages are
-           signalled by having the least significant bit set.
-           If this bit is set, ignore the header.
-           This branch is taken for Routing Layer control messages.
-         */
+    ti = proto_tree_add_uint(rt_tree, hf_dec_routing_flags, tvb,
+                    offset, 1, msg_flags);
+    flags_tree = proto_item_add_subtree(ti, ett_dec_routing_flags);
+
+    if (msg_flags & RT_FLAGS_CTRL_MSG) {
         guint   new_offset;
+        guint8  ctl_msg_type;
         proto_tree *ctl_msg_tree;
-        proto_item *ti;
 
-   	    ti = proto_tree_add_uint(
-            rt_tree, hf_dec_ctl_msgs, tvb, offset, 1, msg_flags);
+        ctl_msg_type = (msg_flags >> 1) & 0x7;
+        proto_tree_add_boolean(flags_tree, hf_dec_rt_ctrl_msg, tvb, offset, 1,
+            msg_flags);
+        proto_tree_add_uint(flags_tree, hf_dec_ctl_msgs, tvb, offset, 1,
+            msg_flags);
+
+        ti = proto_tree_add_uint(rt_tree, hf_dec_ctl_msg_hdr, tvb, offset, 1,
+            ctl_msg_type);
         ctl_msg_tree = proto_item_add_subtree(ti, ett_dec_rt_ctl_msg);
+
         /* Get past the msg_flags */
         offset++;
-        switch ((msg_flags >> 1) & 0x7) {
+        switch (ctl_msg_type) {
             case RT_CTL_INITIALIZATION:
                 new_offset =
                     do_initialization_msg(
@@ -548,7 +471,85 @@
             default:
             break;
         }
+    } else if (msg_flags & RT_FLAGS_LONG_MSG){
+        proto_tree_add_uint(flags_tree, hf_dec_rt_long_msg,
+                tvb, offset, 1, msg_flags);
+        proto_tree_add_boolean(flags_tree, hf_dec_rt_rqr, tvb,
+                    offset, 1, msg_flags);
+        proto_tree_add_boolean(flags_tree, hf_dec_rt_rts, tvb,
+                    offset, 1, msg_flags);
+        proto_tree_add_boolean(flags_tree, hf_dec_rt_inter_eth, tvb,
+                    offset, 1, msg_flags);
+        proto_tree_add_boolean(flags_tree, hf_dec_rt_discard, tvb,
+                    offset, 1, msg_flags);
+        long_msg = true;
+
+        /* Increment offset by three:
+                1 to get past the flags field
+                2 to skip the DEC area/subarea field
+         */
+        offset += 3;
+        ti = proto_tree_add_item(rt_tree, hf_dec_rt_dst_addr, tvb,
+                offset, 6, FALSE);
+        addr = dnet_ntoa(ep_tvb_memdup(tvb, offset, 6));
+        if (addr != NULL) {
+            proto_item_append_text(ti, " (%s)", addr);
+            g_free(addr);
+        }
+
+        /* Skip 6 bytes for the MAC and
+                2 bytes for DEC area/subarea
+            */
+        offset += 8;
+        ti = proto_tree_add_item(rt_tree, hf_dec_rt_src_addr, tvb,
+            offset, 6, FALSE);
+        addr = dnet_ntoa(ep_tvb_memdup(tvb, offset, 6));
+        if (addr != NULL) {
+            proto_item_append_text(ti, " (%s)", addr);
+            g_free(addr);
+        }
+
+        /* Proceed to the NL2 byte */
+        offset += 6;
+        proto_tree_add_uint(rt_tree, hf_dec_rt_nl2, tvb,
+            offset, 1, rt_zero);
+        offset++;
+        rt_visit_count = tvb_get_guint8(tvb, offset);
+        proto_tree_add_uint(rt_tree, hf_dec_rt_visit_count, tvb,
+            offset, 1, rt_visit_count);
+        offset++;
+        proto_tree_add_uint(rt_tree, hf_dec_rt_service_class, tvb,
+            offset, 1, rt_zero);
+        offset++;
+        proto_tree_add_uint(rt_tree, hf_dec_rt_protocol_type, tvb,
+            offset, 1, rt_zero);
+        offset++;
     } else {
+        proto_tree_add_item(flags_tree, hf_dec_rt_short_msg,
+                tvb, offset, 1, msg_flags);
+        proto_tree_add_boolean(flags_tree, hf_dec_rt_rqr, tvb,
+                    offset, 1, msg_flags);
+        proto_tree_add_boolean(flags_tree, hf_dec_rt_rts, tvb,
+                    offset, 1, msg_flags);
+
+        /* Increment offset to get past the flags field
+         */
+        offset++;
+        dst_node = tvb_get_letohs(tvb, offset);
+        proto_tree_add_item(rt_tree, hf_dec_rt_dst_node, tvb,
+            offset, 2, TRUE);
+        offset += 2;
+        src_node = tvb_get_letohs(tvb, offset);
+        proto_tree_add_item(rt_tree, hf_dec_rt_src_node, tvb,
+            offset, 2, TRUE);
+        offset += 2;
+        forward = tvb_get_guint8(tvb, offset);
+        proto_tree_add_uint(rt_tree, hf_dec_rt_visited_nodes, tvb,
+            offset, 1, forward);
+        offset++;
+    }
+
+    if (!(msg_flags & RT_FLAGS_CTRL_MSG)) {
         /* It is not a routing control message */
         proto_tree *nsp_msg_tree;
         proto_item *ti;
@@ -556,14 +557,13 @@
         guint16    dst_node, src_node;
 
         nsp_msg_type = tvb_get_guint8(tvb, offset);
-   	    ti = proto_tree_add_uint(
+           ti = proto_tree_add_uint(
             tree, hf_dec_nsp_msgs, tvb, offset, 1, nsp_msg_type);
         if (nsp_msg_type == NOP_MSG) {
             /* Only test data in this msg */
             return;
         }
-        nsp_msg_tree =
-            proto_item_add_subtree(ti, ett_dec_rt_nsp_msg);
+        nsp_msg_tree = proto_item_add_subtree(ti, ett_dec_rt_nsp_msg);
         /* Get past the nsp_msg_type */
         offset++;
         dst_node = tvb_get_letohs(tvb, offset);
@@ -572,8 +572,8 @@
         offset += 2;
         if (nsp_msg_type == CONN_ACK_MSG) {
             if (check_col(pinfo->cinfo, COL_INFO)) {
-	            col_add_str(pinfo->cinfo, COL_INFO,
-		          "NSP connect acknowledgement");
+                col_add_str(pinfo->cinfo, COL_INFO,
+                  "NSP connect acknowledgement");
                 /* Done with this msg type */
                 return;
             }
@@ -605,27 +605,27 @@
     guint8  remainder_count;
 
     if (check_col(pinfo->cinfo, COL_INFO)) {
-	    col_add_str(pinfo->cinfo, COL_INFO,
-		  "Routing control, initialization message");
+        col_add_str(pinfo->cinfo, COL_INFO,
+          "Routing control, initialization message");
     }
-	proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
-		my_offset, 2, TRUE);
+    proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
+        my_offset, 2, TRUE);
     offset += 2;
-	proto_tree_add_item(tree, hf_dec_rt_tiinfo, tvb,
-		my_offset, 2, TRUE);
+    proto_tree_add_item(tree, hf_dec_rt_tiinfo, tvb,
+        my_offset, 2, TRUE);
     my_offset += 2;
-	proto_tree_add_item(tree, hf_dec_rt_blk_size, tvb,
-		my_offset, 2, TRUE);
+    proto_tree_add_item(tree, hf_dec_rt_blk_size, tvb,
+        my_offset, 2, TRUE);
     my_offset += 2;
     version = tvb_get_guint8(tvb, my_offset);
     eco_nr = tvb_get_guint8(tvb, my_offset + 1);
     user_eco = tvb_get_guint8(tvb, my_offset + 2);
-	proto_tree_add_none_format(tree, hf_dec_rt_version, tvb,
+    proto_tree_add_none_format(tree, hf_dec_rt_version, tvb,
         my_offset, 3, "Routing Layer version: %d.%d.%d.",
             version, eco_nr, user_eco);
     my_offset +=3;
-	proto_tree_add_item(tree, hf_dec_rt_timer, tvb,
-		my_offset, 2, TRUE);
+    proto_tree_add_item(tree, hf_dec_rt_timer, tvb,
+        my_offset, 2, TRUE);
     my_offset += 2;
     remainder_count = tvb_get_guint8(tvb, my_offset);
     if (remainder_count != 0) {
@@ -648,11 +648,11 @@
     guint8  remainder_count;
 
     if (check_col(pinfo->cinfo, COL_INFO)) {
-	  col_add_str(pinfo->cinfo, COL_INFO,
-		  "Routing control, verification message");
+      col_add_str(pinfo->cinfo, COL_INFO,
+          "Routing control, verification message");
     }
-	proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
-		my_offset, 2, TRUE);
+    proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
+        my_offset, 2, TRUE);
     offset += 2;
     remainder_count = tvb_get_guint8(tvb, my_offset);
     if (remainder_count != 0) {
@@ -672,14 +672,14 @@
     guint offset)
 {
     guint   my_offset = offset;
-    guint8  remainder_count;
+    guint   remainder_count;
 
     if (check_col(pinfo->cinfo, COL_INFO)) {
-	  col_add_str(pinfo->cinfo, COL_INFO,
-		  "Routing control, hello/test message");
+      col_add_str(pinfo->cinfo, COL_INFO,
+          "Routing control, hello/test message");
     }
-	proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
-		my_offset, 2, TRUE);
+    proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
+        my_offset, 2, TRUE);
     my_offset += 2;
     remainder_count = tvb_length_remaining(tvb, my_offset);
     if (remainder_count != 0) {
@@ -700,12 +700,13 @@
     guint msg)
 {
     guint   my_offset = offset;
-    guint16 checksum = 1;
+    guint32 my_checksum = 1;
+    guint16 checksum;
     guint16 count, startid, rtginfo;
-    guint8  remainder_count;
+    guint   remainder_count;
 
-	proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
-		my_offset, 2, TRUE);
+    proto_tree_add_item(tree, hf_dec_rt_src_node, tvb,
+        my_offset, 2, TRUE);
     /* Skip the 1-byte reserved field */
     my_offset += 3;
     remainder_count = tvb_length_remaining(tvb, my_offset);
@@ -714,34 +715,44 @@
         count = tvb_get_letohs(tvb, my_offset);
         startid = tvb_get_letohs(tvb, my_offset + 2);
         rtginfo = tvb_get_letohs(tvb, my_offset + 4);
-        my_offset += 6;
         if (msg == 3) {
             if (check_col(pinfo->cinfo, COL_INFO)) {
-	          col_add_str(pinfo->cinfo, COL_INFO,
-		          "Routing control, Level 1 routing message");
+              col_add_str(pinfo->cinfo, COL_INFO,
+                  "Routing control, Level 1 routing message");
             }
-	        proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
+            proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
                 my_offset, 6,
                 "Segment: count:%d, start Id: %d, hops:%d, cost: %d",
                 count, startid, (rtginfo & 0x7c00) >> 10, rtginfo & 0x3ff);
         } else {
             if (check_col(pinfo->cinfo, COL_INFO)) {
-	          col_add_str(pinfo->cinfo, COL_INFO,
-		          "Routing control, Level 2 routing message");
+              col_add_str(pinfo->cinfo, COL_INFO,
+                  "Routing control, Level 2 routing message");
             }
-	        proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
+            proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
                 my_offset, 6,
                 "Segment: count:%d, start area: %d, hops:%d, cost: %d",
                 count, startid, (rtginfo & 0x7c00) >> 10, rtginfo & 0x3ff);
         };
-        checksum += (count + startid + rtginfo);
+        my_checksum += (count + startid + rtginfo);
+        my_offset += 6;
         remainder_count -= 6;
-    } while (remainder_count > 1);
-    if (checksum != tvb_get_letohs(tvb, my_offset)) {
-	    proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
+    } while (remainder_count > 6);
+    my_offset += remainder_count - 2;
+    /* fold 32 bit sum into 16 bits */
+    while (my_checksum>>16)
+        my_checksum = (my_checksum & 0xffff) + (my_checksum >> 16);
+    checksum = tvb_get_letohs(tvb, my_offset);
+    if (checksum != my_checksum) {
+        proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
+            my_offset, 2,
+            "Checksum mismatch(computed 0x%x <> received 0x%x)",
+            my_checksum, checksum);
+    } else {
+        proto_tree_add_none_format(tree, hf_dec_rt_segment, tvb,
             my_offset, 2,
-            "Segment: checksum mismatch(computed 0x%x != received 0x%x)",
-            checksum, tvb_get_letohs(tvb, my_offset));
+            "Checksum: match (computed 0x%x = received 0x%x)",
+            my_checksum, checksum);
     }
     my_offset += 2;
     return (my_offset);
@@ -756,93 +767,88 @@
     guint msg)
 {
     guint   my_offset = offset;
-    guint8  remainder_count, iinfo, priority;
+    guint8  iinfo, priority;
     guint16 version, eco_nr, user_eco, timer;
     proto_item *ti;
     proto_tree *iinfo_tree;
-    const char *sep;
+    char *addr;
 
     version = tvb_get_guint8(tvb, my_offset);
     eco_nr = tvb_get_guint8(tvb, my_offset + 1);
     user_eco = tvb_get_guint8(tvb, my_offset + 2);
-	proto_tree_add_none_format(tree, hf_dec_rt_version, tvb,
+    proto_tree_add_none_format(tree, hf_dec_rt_version, tvb,
         my_offset, 3, "Routing Layer Version: %d.%d.%d",
         version, eco_nr, user_eco);
     my_offset +=3;
-	proto_tree_add_item(tree, hf_dec_rt_id, tvb,
-	    my_offset, 6, TRUE);
+    ti = proto_tree_add_item(tree, hf_dec_rt_id, tvb,
+        my_offset, 6, TRUE);
+    addr = dnet_ntoa(ep_tvb_memdup(tvb, my_offset, 6));
+    if (addr != NULL) {
+        proto_item_append_text(ti, " (%s)", addr);
+        g_free(addr);
+    }
     my_offset += 6;
     iinfo = tvb_get_guint8(tvb, my_offset);
-   	ti = proto_tree_add_uint(
+    ti = proto_tree_add_uint(
         tree, hf_dec_rt_iinfo, tvb, my_offset, 1, iinfo);
-	iinfo_tree = proto_item_add_subtree(ti, ett_dec_rt_info_flags);
-	sep = initial_sep;
-   	proto_tree_add_uint(
+    iinfo_tree = proto_item_add_subtree(ti, ett_dec_rt_info_flags);
+    proto_tree_add_uint(
         iinfo_tree, hf_dec_rt_iinfo_node_type, tvb, my_offset, 1, iinfo);
-	APPEND_BOOLEAN_FLAG(iinfo & 0x4, ti,
-		"%sVerification required");
     proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_vrf,
         tvb, my_offset, 1, iinfo);
-	APPEND_BOOLEAN_FLAG(iinfo & 0x8, ti,
-		"%sRejected");
     proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_rej,
         tvb, my_offset, 1, iinfo);
-	APPEND_BOOLEAN_FLAG(iinfo & 0x10, ti,
-		"%sVerification failed");
     proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_verf,
         tvb, my_offset, 1, iinfo);
-	APPEND_BOOLEAN_FLAG(iinfo & 0x20, ti,
-		"%sNo multicast traffic");
     proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_mta,
         tvb, my_offset, 1, iinfo);
-	APPEND_BOOLEAN_FLAG(iinfo & 0x4, ti,
-		"%sBlocking requested");
- 	if (sep != initial_sep) {
-	    /* We put something in; put in the terminating ")" */
-	    proto_item_append_text(ti, ")");
-	}
     proto_tree_add_boolean(iinfo_tree, hf_dec_rt_iinfo_blkreq,
         tvb, my_offset, 1, iinfo);
     my_offset++;
-	proto_tree_add_item(tree, hf_dec_rt_blk_size, tvb,
-		my_offset, 2, TRUE);
+    proto_tree_add_item(tree, hf_dec_rt_blk_size, tvb,
+        my_offset, 2, TRUE);
     my_offset += 2;
     if (msg == 5) {
         /* Ethernet router hello message
            Has a 'priority' field in this position */
         if (check_col(pinfo->cinfo, COL_INFO)) {
-	      col_add_str(pinfo->cinfo, COL_INFO,
-		      "Routing control, Ethernet Router Hello  message");
+            col_add_str(pinfo->cinfo, COL_INFO,
+                 "Routing control, Ethernet Router Hello  message");
         }
         priority = tvb_get_guint8(tvb, my_offset);
-   	    proto_tree_add_uint(
+        proto_tree_add_uint(
             tree, hf_dec_rt_iprio, tvb, my_offset, 1, priority);
         my_offset++;
     }
     /* Skip the 'area' field common to both hello messages */
-    my_offset += 2;
+    my_offset += 1;
     if (msg == 6) {
         /* The endnode hello message has 'seed' and 'neighbor' fields */
         guint8  seed;
 
         if (check_col(pinfo->cinfo, COL_INFO)) {
-	      col_add_str(pinfo->cinfo, COL_INFO,
-		      "Routing control, Endnode Hello message");
+            col_add_str(pinfo->cinfo, COL_INFO,
+                "Routing control, Endnode Hello message");
         }
         seed = tvb_get_guint8(tvb, my_offset);
-        proto_tree_add_uint(
-            tree, hf_dec_rt_seed, tvb, my_offset, 1, seed);
-        my_offset++;
-	    proto_tree_add_item(tree, hf_dec_rt_neighbor, tvb,
-			my_offset, 6, TRUE);
+        proto_tree_add_item(tree, hf_dec_rt_seed, tvb,
+            my_offset, 8, seed);
+        my_offset += 8;
+        ti = proto_tree_add_item(tree, hf_dec_rt_neighbor, tvb,
+                my_offset, 6, TRUE);
+        addr = dnet_ntoa(ep_tvb_memdup(tvb, my_offset, 6));
+        if (addr != NULL) {
+            proto_item_append_text(ti, " (%s)", addr);
+            g_free(addr);
+        }
         my_offset += 6;
     }
     /*'Timer' and 'mpd' fields are common
       'mpd' field is reserved */
     timer = tvb_get_letohs(tvb, my_offset);
     proto_tree_add_item(tree, hf_dec_rt_timer, tvb,
-		my_offset, 2, TRUE);
-    my_offset += 2;
+        my_offset, 2, TRUE);
+    my_offset += 3;
     if (msg == 5) {
         /* The Ethernet router hello message contains
            a list of router states
@@ -850,35 +856,57 @@
            up to 128 bytes of test data at the end.
            These data are left to be dissected as 'data'.
          */
-        proto_item  *ti;
-        proto_tree *list_tree;
+        proto_item  *ti, *ti_ether;
+        proto_tree *list_tree, *list_ether;
+        guint8 image_len;
+        guint8 item_len;
 
         ti = proto_tree_add_item(tree, hf_dec_rt_elist, tvb,
-			my_offset, 7, TRUE);
+            my_offset, 7, TRUE);
         my_offset += 7;
+        /* image field is preceded by count of remainder of field */
+        image_len = tvb_get_guint8(tvb, my_offset);
+        my_offset++;
+        ti = proto_tree_add_none_format(tree, hf_dec_rt_elist,
+                    tvb, my_offset, 1, "Router States");
         list_tree = proto_item_add_subtree(ti, ett_dec_rt_list);
-        remainder_count =
-            tvb_reported_length_remaining(tvb, my_offset);
-        do {
-            /* if the remainder_count < 7, there are
-               no more router/state items */
-            guint8  pristate;
-            proto_item  *ti;
-            proto_tree *pstate_tree;
-
-	        ti = proto_tree_add_item(list_tree, hf_dec_rt_router_id,
-			    tvb, my_offset, 6, TRUE);
-            my_offset += 6;
-            pstate_tree = proto_item_add_subtree(ti, ett_dec_rt_state);
-            pristate = tvb_get_guint8(tvb, my_offset);
-            proto_tree_add_string(list_tree, hf_dec_rt_router_state,
-                tvb, my_offset, 1,
-                ((pristate & 0x80) ? "known 2-way": "unknown"));
-            proto_tree_add_uint(list_tree, hf_dec_rt_router_prio,
-                tvb, my_offset, 1, pristate);
+        while (image_len > 0) {
+            ti_ether = proto_tree_add_bytes(list_tree, hf_dec_rt_ename, tvb,
+                my_offset, 7, tvb_get_ptr(tvb, my_offset, 7));
+            list_ether = proto_item_add_subtree(ti_ether, ett_dec_rt_rlist);
+            my_offset += 7;
+            image_len -= 7;
+
+            /* image field is preceded by count of remainder of field */
+            item_len = tvb_get_guint8(tvb, my_offset);
             my_offset++;
-            remainder_count -= 7;
-        } while (remainder_count >= 7);
+            image_len -= 1;
+            while (item_len > 0)
+            {
+                guint8  pristate;
+                proto_item  *ti;
+                proto_tree *pstate_tree;
+
+                ti = proto_tree_add_item(list_ether, hf_dec_rt_router_id,
+                    tvb, my_offset, 6, TRUE);
+                addr = dnet_ntoa(ep_tvb_memdup(tvb, my_offset, 6));
+                if (addr != NULL) {
+                    proto_item_append_text(ti, " (%s)", addr);
+                    g_free(addr);
+                }
+                my_offset += 6;
+                pstate_tree = proto_item_add_subtree(ti, ett_dec_rt_state);
+                pristate = tvb_get_guint8(tvb, my_offset);
+                proto_tree_add_string(list_ether, hf_dec_rt_router_state,
+                    tvb, my_offset, 1,
+                    ((pristate & 0x80) ? "known 2-way": "unknown"));
+                proto_tree_add_uint(list_ether, hf_dec_rt_router_prio,
+                    tvb, my_offset, 1, pristate);
+                my_offset++;
+                item_len -= 7;
+                image_len -= 7;
+            }
+        }
     }
     return (my_offset);
 }
@@ -933,21 +961,21 @@
             if (check_col(pinfo->cinfo, COL_INFO)) {
                 if (nsp_msg_type == BOM_MSG) {
                     dec_dna_total_bytes_this_segment = 0;
-	                col_append_fstr(pinfo->cinfo, COL_INFO,
-		                "msg nr. %d: start of segment",
+                    col_append_fstr(pinfo->cinfo, COL_INFO,
+                        "msg nr. %d: start of segment",
                         seg_num & 0xfff);
                 } else if (nsp_msg_type == DATA_SEGMENT_MSG) {
-	                col_append_fstr(pinfo->cinfo, COL_INFO,
-		                "msg nr. %d: continuation segment ",
+                    col_append_fstr(pinfo->cinfo, COL_INFO,
+                        "msg nr. %d: continuation segment ",
                         seg_num & 0xfff);
                 } else if (nsp_msg_type == EOM_MSG) {
                     col_append_fstr(pinfo->cinfo, COL_INFO,
-		                "msg nr. %d: end of segment",
+                        "msg nr. %d: end of segment",
                         seg_num & 0xfff);
                 } else if (nsp_msg_type == BOM_EOM_MSG) {
                     dec_dna_total_bytes_this_segment = 0;
                     col_append_fstr(pinfo->cinfo, COL_INFO,
-		                "msg nr. %d single segment",
+                        "msg nr. %d single segment",
                         seg_num & 0xfff);
                 }
             }
@@ -963,16 +991,16 @@
             dec_dna_previous_total = dec_dna_total_bytes_this_segment;
             dec_dna_total_bytes_this_segment += data_length;
             if (check_col(pinfo->cinfo, COL_INFO)) {
-	            col_append_fstr(pinfo->cinfo, COL_INFO,
-		            ", bytes this segment: %d, total sofar:%d",
+                col_append_fstr(pinfo->cinfo, COL_INFO,
+                    ", bytes this segment: %d, total so far:%d",
                     data_length, dec_dna_total_bytes_this_segment);
             }
             /* We are done, return my_offset */
             break;
         case INTERRUPT_MSG:        /* "Interrupt message" */
             if (check_col(pinfo->cinfo, COL_INFO)) {
-	          col_add_str(pinfo->cinfo, COL_INFO,
-		          "NSP interrupt message");
+              col_add_str(pinfo->cinfo, COL_INFO,
+                  "NSP interrupt message");
             }
             ack_num = tvb_get_letohs(tvb, my_offset);
             if (ack_num & 0x8000) {
@@ -1014,8 +1042,8 @@
             break;
         case LINK_SERVICE_MSG:     /* "Link service message" */
             if (check_col(pinfo->cinfo, COL_INFO)) {
-	          col_add_str(pinfo->cinfo, COL_INFO,
-		          "NSP link control message");
+              col_add_str(pinfo->cinfo, COL_INFO,
+                  "NSP link control message");
             }
             ack_num = tvb_get_letohs(tvb, my_offset);
             if (ack_num & 0x8000) {
@@ -1057,25 +1085,25 @@
             if (check_col(pinfo->cinfo, COL_INFO)) {
               switch(ls_flags) {
                   case 0: /* no change */
-	                  col_append_str(pinfo->cinfo, COL_INFO,
-		                 "(no change)");
+                      col_append_str(pinfo->cinfo, COL_INFO,
+                         "(no change)");
                   break;
                   case 1: /* stop sending data */
-	                  col_append_str(pinfo->cinfo, COL_INFO,
-		                 "(stop)");
+                      col_append_str(pinfo->cinfo, COL_INFO,
+                         "(stop)");
                   break;
                   case 2: /* send data */
-	                  col_append_str(pinfo->cinfo, COL_INFO,
-		                 "(go)");
+                      col_append_str(pinfo->cinfo, COL_INFO,
+                         "(go)");
                   break;
                   default:
                   break;
               }
             }
             fc_val = tvb_get_guint8(tvb, my_offset + 1);
-	        ti = proto_tree_add_uint(tree, hf_dec_flow_control, tvb,
-				         my_offset, 1, ls_flags);
-	        flow_control_tree =
+            ti = proto_tree_add_uint(tree, hf_dec_flow_control, tvb,
+                         my_offset, 1, ls_flags);
+            flow_control_tree =
                 proto_item_add_subtree(ti, ett_dec_flow_control);
             proto_tree_add_none_format(flow_control_tree, hf_dec_rt_fc_val,
                 tvb, my_offset, 2,
@@ -1093,8 +1121,8 @@
             my_offset += 2;
             /* There may be an optional ack_oth field */
             if (check_col(pinfo->cinfo, COL_INFO)) {
-	          col_append_fstr(pinfo->cinfo, COL_INFO,
-		          "NSP data %s message(%d)",
+              col_append_fstr(pinfo->cinfo, COL_INFO,
+                  "NSP data %s message(%d)",
                       (ack_num & 0x1000) ? "NAK" : "ACK",
                       ack_num & 0xfff);
             }
@@ -1114,8 +1142,8 @@
             break;
         case OTHER_DATA_ACK_MSG:   /* "Other data acknowledgement message" */
             if (check_col(pinfo->cinfo, COL_INFO)) {
-	          col_add_str(pinfo->cinfo, COL_INFO,
-		          "NSP other data ACK message");
+              col_add_str(pinfo->cinfo, COL_INFO,
+                  "NSP other data ACK message");
             }
             ack_num = tvb_get_letohs(tvb, my_offset);
             proto_tree_add_none_format(tree, hf_dec_rt_acknum,
@@ -1142,20 +1170,20 @@
         case CONN_CONFIRM_MSG:     /* "Connect confirm" */
         case CONN_INITIATE_MSG:    /* "Connect initiate" */
             if (check_col(pinfo->cinfo, COL_INFO)) {
-	          col_add_str(pinfo->cinfo, COL_INFO,
-		          "NSP connect confirm/initiate message");
+              col_add_str(pinfo->cinfo, COL_INFO,
+                  "NSP connect confirm/initiate message");
             }
             services = tvb_get_guint8(tvb, my_offset);
-	        proto_tree_add_uint(tree, hf_dec_rt_services, tvb,
-				         my_offset, 1, services);
+            proto_tree_add_uint(tree, hf_dec_rt_services, tvb,
+                         my_offset, 1, services);
             my_offset++;
             info = tvb_get_guint8(tvb, my_offset);
-	        proto_tree_add_uint(tree, hf_dec_rt_info, tvb,
-				         my_offset, 1, info);
+            proto_tree_add_uint(tree, hf_dec_rt_info, tvb,
+                         my_offset, 1, info);
             my_offset++;
             seg_size = tvb_get_letohs(tvb, my_offset);
-	        proto_tree_add_item(tree, hf_dec_rt_seg_size, tvb,
-				         my_offset, 2, TRUE);
+            proto_tree_add_item(tree, hf_dec_rt_seg_size, tvb,
+                         my_offset, 2, TRUE);
             my_offset += 2;
             my_offset =
                 handle_connect_contents(
@@ -1164,12 +1192,12 @@
         case DISCONN_INITIATE_MSG: /* "Disconnect initiate" */
         case DISCONN_CONFIRM_MSG:  /* "Disconnect confirm" */
             if (check_col(pinfo->cinfo, COL_INFO)) {
-	          col_add_str(pinfo->cinfo, COL_INFO,
-		          "NSP disconnect initiate/confirm message");
+              col_add_str(pinfo->cinfo, COL_INFO,
+                  "NSP disconnect initiate/confirm message");
             }
             reason = tvb_get_letohs(tvb, my_offset);
             proto_tree_add_item(tree, hf_dec_disc_reason, tvb,
-				 my_offset, 2, TRUE);
+                 my_offset, 2, TRUE);
             my_offset += 2;
             if (nsp_msg_type == DISCONN_INITIATE_MSG) {
                 my_offset =
@@ -1300,8 +1328,8 @@
 
 
 static const true_false_string yesno = {
-	"Yes",
-	"No"
+    "Yes",
+    "No"
 };
 
 void
@@ -1311,238 +1339,250 @@
   static hf_register_info hf[] = {
     /* Mesage header items */
     { &hf_dec_routing_flags,
-      { "Routing flags",	        "dec_dna.flags",
-	    FT_UINT8,	BASE_HEX,	VALS(&routing_flags),	0x0,
-      	"DNA routing flag", HFILL }},
+      { "Routing flags",            "dec_dna.flags",
+        FT_UINT8,    BASE_HEX,    NULL,    0x0,
+          "DNA routing flag", HFILL }},
+    { &hf_dec_rt_ctrl_msg,
+      { "Control packet",            "dec_dna.flags.control",
+        FT_BOOLEAN,    8,        TFS(&yesno),    RT_FLAGS_CTRL_MSG,
+          "Control packet", HFILL }},
     { &hf_dec_rt_long_msg,
-      { "Long message",		        "dec_dna.flags.msglen",
-	    FT_UINT8,	BASE_HEX,	NULL, 0x0,
-      	"Long message indicator", HFILL }},
+      { "Long data packet format",     "dec_dna.flags.msglen",
+        FT_UINT8,    BASE_HEX,    NULL, 0x06,
+          "Long message indicator", HFILL }},
     { &hf_dec_rt_short_msg,
-      { "Short message",		    "dec_dna.flags.msglen",
-	    FT_UINT8,	BASE_HEX,	NULL, 0x0,
-      	"Short message indicator", HFILL }},
+      { "Short data packet format",     "dec_dna.flags.msglen",
+        FT_UINT8,    BASE_HEX,    NULL, 0x06,
+          "Short message indicator", HFILL }},
     { &hf_dec_rt_rqr,
-      { "Return to Sender Request",	"dec_dna.flags.RQR",
-	    FT_BOOLEAN,	8,		TFS(&yesno),	RT_FLAGS_RQR,
-      	"Return to Sender", HFILL }},
+      { "Return to Sender Request",    "dec_dna.flags.RQR",
+        FT_BOOLEAN,    8,        TFS(&yesno),    RT_FLAGS_RQR,
+          "Return to Sender", HFILL }},
     { &hf_dec_rt_rts,
-      { "Packet on return trip",	"dec_dna.flags.RTS",
-	    FT_BOOLEAN,	8,		TFS(&yesno),	RT_FLAGS_RTS,
-      	"Packet on return trip", HFILL }},
+      { "Packet on return trip",    "dec_dna.flags.RTS",
+        FT_BOOLEAN,    8,        TFS(&yesno),    RT_FLAGS_RTS,
+          "Packet on return trip", HFILL }},
     { &hf_dec_rt_inter_eth,
-      { "Intra-ethernet packet",	"dec_dna.flags.intra_eth",
-	    FT_BOOLEAN,	8,		TFS(&yesno),	RT_FLAGS_INTRA_ETHER,
-      	"Intra-ethernet packet", HFILL }},
+      { "Intra-ethernet packet",    "dec_dna.flags.intra_eth",
+        FT_BOOLEAN,    8,        TFS(&yesno),    RT_FLAGS_INTRA_ETHER,
+          "Intra-ethernet packet", HFILL }},
     { &hf_dec_rt_discard,
-      { "Discarded packet",		    "dec_dna.flags.discard",
-	    FT_BOOLEAN,	8,		TFS(&yesno),	RT_FLAGS_DISCARD,
-      	"Discarded packet", HFILL }},
-    { &hf_dec_rt_dst_mac,
-      { "Destination MAC",			"dec_dna.dst.mac",
-	    FT_ETHER,	BASE_NONE,	NULL,	0x0,
-      	"Destination MAC address", HFILL }},
-    { &hf_dec_rt_src_mac,
-      { "Source MAC",			"dec_dna.src.mac",
-	    FT_ETHER,	BASE_NONE,	NULL,	0x0,
-      	"Source MAC address", HFILL }},
+      { "Discarded packet",            "dec_dna.flags.discard",
+        FT_BOOLEAN,    8,        TFS(&yesno),    RT_FLAGS_DISCARD,
+          "Discarded packet", HFILL }},
+    { &hf_dec_rt_dst_addr,
+      { "Destination Address",        "dec_dna.dst.address",
+        FT_ETHER,    BASE_NONE,    NULL,    0x0,
+          "Destination address", HFILL }},
+    { &hf_dec_rt_src_addr,
+      { "Source Address",            "dec_dna.src.addr",
+        FT_ETHER,    BASE_NONE,    NULL,    0x0,
+          "Source address", HFILL }},
     { &hf_dec_rt_nl2,
-      { "Next level 2 router",		"dec_dna.nl2",
-	    FT_UINT8,	BASE_HEX,	NULL,   0x0,
-      	"reserved", HFILL }},
+      { "Next level 2 router",        "dec_dna.nl2",
+        FT_UINT8,    BASE_HEX,    NULL,   0x0,
+          "reserved", HFILL }},
     { &hf_dec_rt_service_class,
-      { "Service class",		    "dec_dna.svc_cls",
-	    FT_UINT8,	BASE_HEX,	NULL,   0x0,
-      	"reserved", HFILL }},
+      { "Service class",            "dec_dna.svc_cls",
+        FT_UINT8,    BASE_HEX,    NULL,   0x0,
+          "reserved", HFILL }},
     { &hf_dec_rt_protocol_type,
-      { "Protocol type",		    "dec_dna.proto_type",
-	    FT_UINT8,	BASE_HEX,	NULL,   0x0,
-      	"reserved", HFILL }},
+      { "Protocol type",            "dec_dna.proto_type",
+        FT_UINT8,    BASE_HEX,    NULL,   0x0,
+          "reserved", HFILL }},
     { &hf_dec_rt_visit_count,
-      { "Visit count",		    "dec_dna.visit_cnt",
-	    FT_UINT8,	BASE_HEX,	NULL,   0x0,
-      	"Visit count", HFILL }},
+      { "Visit count",            "dec_dna.visit_cnt",
+        FT_UINT8,    BASE_HEX,    NULL,   0x0,
+          "Visit count", HFILL }},
     { &hf_dec_flow_control,
-      { "Flow control",		    "dec_dna.nsp.flow_control",
-	    FT_UINT8,	BASE_HEX,	VALS(&rt_flow_control_vals),   0x3,
-      	"Flow control(stop, go)", HFILL }},
+      { "Flow control",            "dec_dna.nsp.flow_control",
+        FT_UINT8,    BASE_HEX,    VALS(&rt_flow_control_vals),   0x3,
+          "Flow control(stop, go)", HFILL }},
     { &hf_dec_rt_services,
       { "Requested services",   "dec_dna.nsp.services",
-	    FT_UINT8,	BASE_HEX,	VALS(&rt_services_vals),   0x0c,
-      	"Services requested", HFILL }},
+        FT_UINT8,    BASE_HEX,    VALS(&rt_services_vals),   0x0c,
+          "Services requested", HFILL }},
     { &hf_dec_rt_info,
-      { "Version info",		    "dec_dna.nsp.info",
-	    FT_UINT8,	BASE_HEX,	VALS(&rt_info_version_vals),   0x03,
-      	"Version info", HFILL }},
+      { "Version info",            "dec_dna.nsp.info",
+        FT_UINT8,    BASE_HEX,    VALS(&rt_info_version_vals),   0x03,
+          "Version info", HFILL }},
     { &hf_dec_rt_dst_node,
-      { "Destination node",		    "dec_dna.dst_node",
-	    FT_UINT16,	BASE_HEX,	NULL,   0x0,
-      	"Destination node", HFILL }},
+      { "Destination node",            "dec_dna.dst_node",
+        FT_UINT16,    BASE_HEX,    NULL,   0x0,
+          "Destination node", HFILL }},
     { &hf_dec_rt_seg_size,
       { "Maximum data segment size", "dec_dna.nsp.segsize",
-	    FT_UINT16,	BASE_DEC,	NULL,   0x0,
-      	"Max. segment size", HFILL }},
+        FT_UINT16,    BASE_DEC,    NULL,   0x0,
+          "Max. segment size", HFILL }},
     { &hf_dec_rt_src_node,
-      { "Source node",		    "dec_dna.src_node",
-	    FT_UINT16,	BASE_HEX,	NULL,   0x0,
-      	"Source node", HFILL }},
+      { "Source node",            "dec_dna.src_node",
+        FT_UINT16,    BASE_HEX,    NULL,   0x0,
+          "Source node", HFILL }},
     { &hf_dec_rt_segnum,
-      { "Message number",		"dec_dna.nsp.segnum",
-	    FT_UINT16,	BASE_DEC,	NULL,   0xfff,
-      	"Segment number", HFILL }},
+      { "Message number",        "dec_dna.nsp.segnum",
+        FT_UINT16,    BASE_DEC,    NULL,   0xfff,
+          "Segment number", HFILL }},
     { &hf_dec_rt_delay,
       { "Delayed ACK allowed",  "dec_dna.nsp.delay",
-	    FT_BOOLEAN,	16,		TFS(&yesno),	0x1000,
-      	"Delayed ACK allowed?", HFILL }},
+        FT_BOOLEAN,    16,        TFS(&yesno),    0x1000,
+          "Delayed ACK allowed?", HFILL }},
     { &hf_dec_rt_visited_nodes,
       { "Nodes visited ty this package", "dec_dna.vst_node",
-	    FT_UINT8,	BASE_DEC,	NULL,   0x0,
-      	"Nodes visited", HFILL }},
+        FT_UINT8,    BASE_DEC,    NULL,   0x0,
+          "Nodes visited", HFILL }},
     /* Control messsage items */
     { &hf_dec_ctl_msgs,
-      { "Routing control message",		"dec_dna.rt.msg_type",
-	    FT_UINT8,	BASE_HEX,	VALS(&rt_msg_type_vals),	0xe,
-      	"Routing control", HFILL }},
+      { "Routing control message",        "dec_dna.rt.msg_type",
+        FT_UINT8,    BASE_HEX,    VALS(&rt_msg_type_vals),    0xe,
+          "Routing control", HFILL }},
+    { &hf_dec_ctl_msg_hdr,
+      { "Routing control message",    "dec_dna.rt.msg_type",
+        FT_UINT8,    BASE_HEX,    VALS(&rt_msg_type_vals),    0xe,
+          "Routing control", HFILL }},
     { &hf_dec_nsp_msgs,
-      { "DNA NSP message",		"dec_dna.nsp.msg_type",
-	    FT_UINT8,	BASE_HEX,	VALS(&nsp_msg_type_vals),	0x0,
-      	"NSP message", HFILL }},
+      { "DNA NSP message",        "dec_dna.nsp.msg_type",
+        FT_UINT8,    BASE_HEX,    VALS(&nsp_msg_type_vals),    0x0,
+          "NSP message", HFILL }},
     { &hf_dec_rt_acknum,
-      { "Ack/Nak",		        "dec_dna.ctl.acknum",
-	    FT_NONE,	BASE_NONE,	NULL,	0x0,
-      	"ack/nak number", HFILL }},
+      { "Ack/Nak",                "dec_dna.ctl.acknum",
+        FT_NONE,    BASE_NONE,    NULL,    0x0,
+          "ack/nak number", HFILL }},
     { &hf_dec_rt_fc_val,
-      { "Flow control",		    "dec_dna.nsp.fc_val",
-	    FT_NONE,	BASE_NONE,	NULL,	0x0,
-      	"Flow control", HFILL }},
+      { "Flow control",            "dec_dna.nsp.fc_val",
+        FT_NONE,    BASE_NONE,    NULL,    0x0,
+          "Flow control", HFILL }},
     { &hf_dec_rt_tiinfo,
-      { "Routing information",	"dec_dna.ctl.tiinfo",
-	    FT_UINT8,	BASE_HEX,	VALS(&rt_tiinfo_vals), 0x0,
-      	"Routing information", HFILL }},
+      { "Routing information",    "dec_dna.ctl.tiinfo",
+        FT_UINT8,    BASE_HEX,    VALS(&rt_tiinfo_vals), 0x0,
+          "Routing information", HFILL }},
     { &hf_dec_rt_blk_size,
-      { "Block size",		    "dec_dna.ctl.blk_size",
-	    FT_UINT16,	BASE_DEC,	NULL,	0x0,
-      	"Block size", HFILL }},
+      { "Block size",            "dec_dna.ctl.blk_size",
+        FT_UINT16,    BASE_DEC,    NULL,    0x0,
+          "Block size", HFILL }},
     { &hf_dec_disc_reason,
       { "Reason for disconnect","dec_dna.nsp.disc_reason",
-	    FT_UINT16,	BASE_HEX,	VALS(&rt_disc_reason_vals),	0x0,
-      	"Disconnect reason", HFILL }},
+        FT_UINT16,    BASE_HEX,    VALS(&rt_disc_reason_vals),    0x0,
+          "Disconnect reason", HFILL }},
     { &hf_dec_rt_version,
-      { "Version",		        "dec_dna.ctl.version",
-	    FT_NONE,	BASE_NONE,	NULL,	0x0,
-      	"Control protocol version", HFILL }},
+      { "Version",                "dec_dna.ctl.version",
+        FT_NONE,    BASE_NONE,    NULL,    0x0,
+          "Control protocol version", HFILL }},
     { &hf_dec_rt_timer,
       { "Hello timer(seconds)",  "dec_dna.ctl.timer",
-	    FT_UINT16,	BASE_DEC,	NULL,   0x0,
-      	"Hello timer in seconds", HFILL }},
+        FT_UINT16,    BASE_DEC,    NULL,   0x0,
+          "Hello timer in seconds", HFILL }},
     { &hf_dec_rt_reserved,
       { "Reserved", "dec_dna.ctl.reserved",
-	     FT_BYTES, BASE_NONE, NULL, 0x0,
-	     "Reserved", HFILL }},
+         FT_BYTES, BASE_NONE, NULL, 0x0,
+         "Reserved", HFILL }},
     { &hf_dec_rt_fcnval,
       { "Verification message function value", "dec_dna.ctl.fcnval",
-	     FT_BYTES, BASE_NONE, NULL, 0x0,
-	     "Routing Verification function", HFILL }},
+         FT_BYTES, BASE_NONE, NULL, 0x0,
+         "Routing Verification function", HFILL }},
     { &hf_dec_rt_test_data,
       { "Test message data", "dec_dna.ctl.test_data",
-	    FT_BYTES, BASE_NONE, NULL, 0x0,
-	    "Routing Test message data", HFILL }},
+        FT_BYTES, BASE_NONE, NULL, 0x0,
+        "Routing Test message data", HFILL }},
     { &hf_dec_rt_segment,
-      { "Segment",		        "dec_dna.ctl.segment",
-	    FT_NONE,	BASE_NONE,	NULL,	0x0,
-      	"Routing Segment", HFILL }},
+      { "Segment",                "dec_dna.ctl.segment",
+        FT_NONE,    BASE_NONE,    NULL,    0x0,
+          "Routing Segment", HFILL }},
     { &hf_dec_rt_id,
-      { "Transmitting system ID",			"dec_dna.ctl.id",
-	    FT_ETHER,	BASE_NONE,	NULL,	0x0,
-      	"Transmitting system ID", HFILL }},
+      { "Transmitting system ID",            "dec_dna.ctl.id",
+        FT_ETHER,    BASE_NONE,    NULL,    0x0,
+          "Transmitting system ID", HFILL }},
     { &hf_dec_rt_iinfo,
-      { "Routing information",		"dec_dna.ctl.tiinfo",
-	    FT_UINT8,	BASE_HEX,	NULL, 0x0,
-      	"Routing information", HFILL }},
+      { "Routing information",        "dec_dna.ctl.tiinfo",
+        FT_UINT8,    BASE_HEX,    NULL, 0x0,
+          "Routing information", HFILL }},
     { &hf_dec_rt_iinfo_node_type,
-      { "Node type",	        "dec_dna.ctl.iinfo.node_type",
-	    FT_UINT8,	BASE_HEX,	VALS(&rt_iinfo_node_type_vals),	0x03,
-      	"Node type", HFILL }},
+      { "Node type",            "dec_dna.ctl.iinfo.node_type",
+        FT_UINT8,    BASE_HEX,    VALS(&rt_iinfo_node_type_vals),    0x03,
+          "Node type", HFILL }},
     { &hf_dec_rt_iinfo_vrf,
-      { "Verification required",		    "dec_dna.ctl.iinfo.vrf",
-	    FT_BOOLEAN,	8,		TFS(&yesno),	0x4,
-      	"Verification required?", HFILL }},
+      { "Verification required",            "dec_dna.ctl.iinfo.vrf",
+        FT_BOOLEAN,    8,        TFS(&yesno),    0x4,
+          "Verification required?", HFILL }},
     { &hf_dec_rt_iinfo_rej,
-      { "Rejected",		    "dec_dna.ctl.iinfo.rej",
-	    FT_BOOLEAN,	8,		TFS(&yesno),	0x8,
-      	"Rejected message", HFILL }},
+      { "Rejected",            "dec_dna.ctl.iinfo.rej",
+        FT_BOOLEAN,    8,        TFS(&yesno),    0x8,
+          "Rejected message", HFILL }},
     { &hf_dec_rt_iinfo_verf,
-      { "Verification failed",		    "dec_dna.ctl.iinfo.verf",
-	    FT_BOOLEAN,	8,		TFS(&yesno),	0x10,
-      	"Verification failed?", HFILL }},
+      { "Verification failed",            "dec_dna.ctl.iinfo.verf",
+        FT_BOOLEAN,    8,        TFS(&yesno),    0x10,
+          "Verification failed?", HFILL }},
     { &hf_dec_rt_iinfo_mta,
-      { "Accepts multicast traffic",		    "dec_dna.ctl.iinfo.mta",
-	    FT_BOOLEAN,	8,		TFS(&yesno),	0x20,
-      	"Accepts multicast traffic?", HFILL }},
+      { "Accepts multicast traffic",            "dec_dna.ctl.iinfo.mta",
+        FT_BOOLEAN,    8,        TFS(&yesno),    0x20,
+          "Accepts multicast traffic?", HFILL }},
     { &hf_dec_rt_iinfo_blkreq,
-      { "Blocking requested",		    "dec_dna.ctl.iinfo.blkreq",
-	    FT_BOOLEAN,	8,		TFS(&yesno),	0x40,
-      	"Blocking requested?", HFILL }},
+      { "Blocking requested",            "dec_dna.ctl.iinfo.blkreq",
+        FT_BOOLEAN,    8,        TFS(&yesno),    0x40,
+          "Blocking requested?", HFILL }},
     { &hf_dec_rt_iprio,
-      { "Routing priority",		"dec_dna.ctl.prio",
-	    FT_UINT8,	BASE_HEX,	NULL, 0x0,
-      	"Routing priority", HFILL }},
+      { "Routing priority",        "dec_dna.ctl.prio",
+        FT_UINT8,    BASE_HEX,    NULL, 0x0,
+          "Routing priority", HFILL }},
     { &hf_dec_rt_neighbor,
-      { "Neighbor",		        "dec_dna.ctl_neighbor",
-	    FT_ETHER,	BASE_NONE,	NULL,	0x0,
-      	"Neighbour ID", HFILL }},
+      { "Neighbor",                "dec_dna.ctl_neighbor",
+        FT_ETHER,    BASE_NONE,    NULL,    0x0,
+          "Neighbour ID", HFILL }},
     { &hf_dec_rt_seed,
-      { "Verification seed",	"dec_dna.ctl.seed",
-	    FT_UINT8,	BASE_HEX,	NULL, 0x0,
-      	"Verification seed", HFILL }},
+      { "Verification seed",    "dec_dna.ctl.seed",
+        FT_BYTES,    BASE_NONE,    NULL, 0x0,
+          "Verification seed", HFILL }},
     { &hf_dec_rt_elist,
-      { "List of router states",	"dec_dna.ctl.elist",
-	    FT_STRING,	BASE_NONE,	NULL, 0x0,
-      	"Router states", HFILL }},
+      { "List of router states",    "dec_dna.ctl.elist",
+        FT_NONE,    BASE_NONE,    NULL, 0x0,
+          "Router states", HFILL }},
+    { &hf_dec_rt_ename,
+      { "Ethernet name",      "dec_dna.ctl.ename",
+        FT_BYTES,    BASE_HEX,    NULL,    0x0,
+          "Ethernet name", HFILL }},
     { &hf_dec_rt_router_id,
-      { "Router ID",		        "dec_dna.ctl.router_id",
-	    FT_ETHER,	BASE_NONE,	NULL,	0x0,
-      	"Router ID", HFILL }},
+      { "Router ID",                "dec_dna.ctl.router_id",
+        FT_ETHER,    BASE_NONE,    NULL,    0x0,
+          "Router ID", HFILL }},
     { &hf_dec_rt_router_state,
-      { "Router state",	"dec_dna.ctl.router_state",
-	    FT_STRING,	BASE_NONE,	NULL, 0x00,
-      	"Router state", HFILL }},
+      { "Router state",    "dec_dna.ctl.router_state",
+        FT_STRING,    BASE_NONE,    NULL, 0x80,
+          "Router state", HFILL }},
     { &hf_dec_conn_contents,
-      { "Session connect data",	"dec_dna.sess.conn",
-	    FT_NONE,	BASE_NONE,	NULL, 0x0,
-      	"Session connect data", HFILL }},
+      { "Session connect data",    "dec_dna.sess.conn",
+        FT_NONE,    BASE_NONE,    NULL, 0x0,
+          "Session connect data", HFILL }},
     { &hf_dec_rt_router_prio,
-      { "Router priority",	"dec_dna.ctl.router_prio",
-	    FT_UINT8,	BASE_HEX,	NULL, 0x7f,
-      	"Router priority", HFILL }},
+      { "Router priority",    "dec_dna.ctl.router_prio",
+        FT_UINT8,    BASE_HEX,    NULL, 0x7f,
+          "Router priority", HFILL }},
     { &hf_dec_sess_grp_code,
-      { "Session Group code",	"dec_dna.sess.grp_code",
-	    FT_UINT16,	BASE_HEX,	NULL, 0x0,
-      	"Session group code", HFILL }},
+      { "Session Group code",    "dec_dna.sess.grp_code",
+        FT_UINT16,    BASE_HEX,    NULL, 0x0,
+          "Session group code", HFILL }},
     { &hf_dec_sess_usr_code,
-      { "Session User code",	"dec_dna.sess.usr_code",
-	    FT_UINT16,	BASE_HEX,	NULL, 0x0,
-      	"Session User code", HFILL }},
+      { "Session User code",    "dec_dna.sess.usr_code",
+        FT_UINT16,    BASE_HEX,    NULL, 0x0,
+          "Session User code", HFILL }},
     { &hf_dec_sess_dst_name,
-      { "SessionDestination end user",	"dec_dna.sess.dst_name",
-	    FT_STRING,	BASE_NONE,	NULL, 0x0,
-      	"Session Destination end user", HFILL }},
+      { "Session Destination end user",    "dec_dna.sess.dst_name",
+        FT_STRING,    BASE_NONE,    NULL, 0x0,
+          "Session Destination end user", HFILL }},
     { &hf_dec_sess_src_name,
-      { "Session Source end user",	"dec_dna.sess.src_name",
-	    FT_STRING,	BASE_NONE,	NULL, 0x0,
-      	"Session Source end user", HFILL }},
+      { "Session Source end user",    "dec_dna.sess.src_name",
+        FT_STRING,    BASE_NONE,    NULL, 0x0,
+          "Session Source end user", HFILL }},
     { &hf_dec_sess_obj_type,
-      { "Session Object type",	"dec_dna.sess.obj_type",
-	    FT_UINT8,	BASE_HEX,	NULL, 0x0,
-      	"Session object type", HFILL }},
+      { "Session Object type",    "dec_dna.sess.obj_type",
+        FT_UINT8,    BASE_HEX,    NULL, 0x0,
+          "Session object type", HFILL }},
     { &hf_dec_sess_menu_ver,
-      { "Session Menu version",	"dec_dna.sess.menu_ver",
-	    FT_STRING,	BASE_NONE,	NULL, 0x0,
-      	"Session menu version", HFILL }},
+      { "Session Menu version",    "dec_dna.sess.menu_ver",
+        FT_STRING,    BASE_NONE,    NULL, 0x0,
+          "Session menu version", HFILL }},
     { &hf_dec_sess_rqstr_id,
-      { "Session Requestor ID",	"dec_dna.sess.rqstr_id",
-	    FT_STRING,	BASE_NONE,	NULL, 0x0,
-      	"Session requestor ID", HFILL }},
+      { "Session Requestor ID",    "dec_dna.sess.rqstr_id",
+        FT_STRING,    BASE_NONE,    NULL, 0x0,
+          "Session requestor ID", HFILL }},
 
 
   };
@@ -1554,13 +1594,14 @@
     &ett_dec_rt_nsp_msg,
     &ett_dec_rt_info_flags,
     &ett_dec_rt_list,
+    &ett_dec_rt_rlist,
     &ett_dec_rt_state,
     &ett_dec_flow_control,
     &ett_dec_sess_contents,
   };
 
   proto_dec_rt = proto_register_protocol("DEC DNA Routing Protocol",
-					   "DEC_DNA", "dec_dna");
+                       "DEC_DNA", "dec_dna");
   proto_register_field_array(proto_dec_rt, hf, array_length(hf));
   proto_register_subtree_array(ett, array_length(ett));
 }
@@ -1571,7 +1612,7 @@
   dissector_handle_t dec_rt_handle;
 
   dec_rt_handle = create_dissector_handle(dissect_dec_rt,
-					    proto_dec_rt);
+                        proto_dec_rt);
   dissector_add("ethertype", ETHERTYPE_DNA_RT, dec_rt_handle);
   dissector_add("chdlctype", ETHERTYPE_DNA_RT, dec_rt_handle);
   dissector_add("ppp.protocol", PPP_DEC4, dec_rt_handle);