Ethereal-dev: [Ethereal-dev] Re: Patch to packet-dec-dnart.c

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

From: "Martin Hill" <martin_j_hill@xxxxxxxxxxx>
Date: Sun, 04 Sep 2005 15:45:54 +0100
Changed as requested. Also fixed some other bugs in control message decoding.

rgds
Martin Hill


From: ronnie sahlberg <ronniesahlberg@xxxxxxxxx>
To: Ethereal development <ethereal-dev@xxxxxxxxxxxx>
CC: martin_j_hill@xxxxxxxxxxx
Subject: Re: Patch to packet-dec-dnart.c
Date: Wed, 24 Aug 2005 03:39:56 -0400

The patch does not apply to SVN,

can you regenerate it and resend it.


Looking at the dissector,   could you also remove that
APPEND_BOOLEAN_FLAG thing and replace it with proper
proto_tree_add_item()   and hf_fields of type FT_BOOLEAN

It would make the dissector much better.



On 8/21/05, Martin Hill <martin_j_hill@xxxxxxxxxxx> wrote:
> An extremely useful addition, unfortunately it has a bug that prevents it > from correctly decoding messages containing no padding. I also added display
>
> of DECnet addresses in area.node format. Attached is a diff from the latest
>
> trunk.
>
> rgds
> Martin Hill
>
>
>

Index: epan/dissectors/packet-dec-dnart.c
===================================================================
--- epan/dissectors/packet-dec-dnart.c	(revision 15678)
+++ epan/dissectors/packet-dec-dnart.c	(working copy)
@@ -87,6 +87,7 @@

/* Flag bits */

+#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
@@ -97,14 +98,15 @@
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;
@@ -211,16 +216,6 @@
	{ 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}
-};
-
static const value_string rt_iinfo_flags[] = {
    {0x01,  "Level 2 router"},
    {0x02,  "Level 1 router"},
@@ -293,16 +288,6 @@
#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;						\
-	}
-
#if ! defined true
#define true 1
#endif
@@ -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,19 +385,25 @@
    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);
    }
    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);
    }
-    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,
@@ -404,120 +415,29 @@
        /* 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 +468,86 @@
            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;
@@ -562,9 +561,9 @@
            /* Only test data in this msg */
            return;
        }
-        nsp_msg_tree =
-            proto_item_add_subtree(ti, ett_dec_rt_nsp_msg);
-        /* Get past the nsp_msg_type */
+        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);
        proto_tree_add_item(
@@ -672,7 +671,7 @@
    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,
@@ -700,9 +699,10 @@
    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);
@@ -714,7 +714,6 @@
        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,
@@ -734,15 +733,27 @@
                "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)) {
+    } 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,
-            "Segment: checksum mismatch(computed 0x%x != received 0x%x)",
-            checksum, tvb_get_letohs(tvb, my_offset));
+			"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,
+			"Checksum: match (computed 0x%x = received 0x%x)",
+            my_checksum, checksum);
+	}
    my_offset += 2;
    return (my_offset);
}
@@ -756,11 +767,11 @@
    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);
@@ -769,38 +780,28 @@
        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(
        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, 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++;
@@ -820,7 +821,7 @@
        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;
@@ -830,11 +831,16 @@
		      "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
@@ -842,7 +848,7 @@
    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 += 3;
    if (msg == 5) {
        /* The Ethernet router hello message contains
           a list of router states
@@ -850,35 +856,54 @@
           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;
+		/* 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);
-            my_offset++;
-            remainder_count -= 7;
-        } while (remainder_count >= 7);
+		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++;
+			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);
}
@@ -964,7 +989,7 @@
            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",
+		            ", bytes this segment: %d, total so far:%d",
                    data_length, dec_dna_total_bytes_this_segment);
            }
            /* We are done, return my_offset */
@@ -1312,15 +1337,19 @@
    /* Mesage header items */
    { &hf_dec_routing_flags,
      { "Routing flags",	        "dec_dna.flags",
-	    FT_UINT8,	BASE_HEX,	VALS(&routing_flags),	0x0,
-      	"DNA routing flag", HFILL }},
+	    FT_UINT8,	BASE_HEX,	NULL, 0x0,
+      	"DNA routing flags", 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 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 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",
@@ -1338,14 +1367,14 @@
      { "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",
+    { &hf_dec_rt_dst_addr,
+      { "Destination Address",			"dec_dna.dst.address",
	    FT_ETHER,	BASE_NONE,	NULL,	0x0,
-      	"Destination MAC address", HFILL }},
-    { &hf_dec_rt_src_mac,
-      { "Source MAC",			"dec_dna.src.mac",
+      	"Destination address", HFILL }},
+    { &hf_dec_rt_src_addr,
+      { "Source Address",			"dec_dna.src.address",
	    FT_ETHER,	BASE_NONE,	NULL,	0x0,
-      	"Source MAC address", HFILL }},
+      	"Source address", HFILL }},
    { &hf_dec_rt_nl2,
      { "Next level 2 router",		"dec_dna.nl2",
	    FT_UINT8,	BASE_HEX,	NULL,   0x0,
@@ -1403,8 +1432,12 @@
      { "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),	0x0,
+      	"Routing control", HFILL }},
    { &hf_dec_nsp_msgs,
-      { "DNA NSP message",		"dec_dna.nsp.msg_type",
+      { "DEC 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,
@@ -1493,12 +1526,16 @@
      	"Neighbour ID", HFILL }},
    { &hf_dec_rt_seed,
      { "Verification seed",	"dec_dna.ctl.seed",
-	    FT_UINT8,	BASE_HEX,	NULL, 0x0,
+	    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,
+	    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,
@@ -1524,7 +1561,7 @@
	    FT_UINT16,	BASE_HEX,	NULL, 0x0,
      	"Session User code", HFILL }},
    { &hf_dec_sess_dst_name,
-      { "SessionDestination end user",	"dec_dna.sess.dst_name",
+      { "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,
@@ -1554,6 +1591,7 @@
    &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,