Ethereal-dev: [Ethereal-dev] 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, 21 Aug 2005 16:18:23 +0100
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

--- packet-dec-dnart-orig.c	2005-08-21 16:05:52.243704000 +0100
+++ packet-dec-dnart.c	2005-08-21 16:00:18.463752000 +0100
@@ -6,7 +6,7 @@
 * Copyright 2003-2005 Fred Hoekstra, Philips Medical Systems.
 *                (fred.hoekstra@xxxxxxxxxxx)
 *
- * $Id$
+ * $Id$
 *
 * Use was made of the following documentation:
 * (See URL http://linux-decnet.sourceforge.net/docs).
@@ -103,8 +103,8 @@
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;
@@ -366,6 +366,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)
{
@@ -381,6 +401,7 @@
    proto_tree *flags_tree;
    proto_item *ti;
    const char *sep;
+	char	*addr;

    offset = 0;
    if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
@@ -392,7 +413,13 @@
    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,100 +431,110 @@
        /* 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
-    */
+	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;
+		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 {
+        /* 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++;
+    }
+
    if (msg_flags & 0x01) {
        /* This is a control message
           Documentation is somewhat confusing at this point
@@ -964,7 +1001,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 */
@@ -1338,14 +1375,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,
@@ -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,