Ethereal-dev: [Ethereal-dev] patch for MTP3 (+= ANSI support)

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

From: Jeff Morriss <jeff.morriss@xxxxxxxxxxx>
Date: Thu, 21 Jun 2001 17:04:09 -0400
Hello list,

Here's a patch to the MTP3 dissector.  Added is support for the ANSI
standard (Chinese ITU and maybe Japanese still to come?).

The only "damage" to the ITU part is that the "mtp3.sls" field is no
longer bitmasked in the header fields section (since the SLS in ANSI can
be 5 or 8 bits and in ITU it's only 4).  One remaining "TODO" is to add
support for 8-bit SLS in ANSI (it's currently hard coded to only use 5).

Thoughts/suggestions/comments?

Regards,
-Jeff
Index: packet-mtp3.c
===================================================================
RCS file: /cvsroot/ethereal/packet-mtp3.c,v
retrieving revision 1.4
diff -u -r1.4 packet-mtp3.c
--- packet-mtp3.c	2001/06/18 02:17:49	1.4
+++ packet-mtp3.c	2001/06/21 20:55:35
@@ -53,14 +53,23 @@
 static int hf_mtp3_service_indicator = -1;
 static int hf_mtp3_network_indicator = -1;
 static int hf_mtp3_spare = -1;
+static int hf_mtp3_priority = -1;
 static int hf_mtp3_opc = -1;
+static int hf_mtp3_opc_network = -1;
+static int hf_mtp3_opc_cluster = -1;
+static int hf_mtp3_opc_member = -1;
 static int hf_mtp3_dpc = -1;
+static int hf_mtp3_dpc_network = -1;
+static int hf_mtp3_dpc_cluster = -1;
+static int hf_mtp3_dpc_member = -1;
 static int hf_mtp3_sls = -1;
 
 /* Initialize the subtree pointers */
 static gint ett_mtp3 = -1;
 static gint ett_mtp3_sio = -1;
 static gint ett_mtp3_label = -1;
+static gint ett_mtp3_label_dpc = -1;
+static gint ett_mtp3_label_opc = -1;
 
 static dissector_table_t mtp3_sio_dissector_table;
 
@@ -68,24 +77,52 @@
 #define ANSI_STANDARD  2
 
 static gint mtp3_standard = ITU_STANDARD;
- 
-#define ITU_SIO_OFFSET 0
-#define ITU_SIO_LENGTH 1
+
+#define SIO_OFFSET 0
+#define SIO_LENGTH 1
 #define ITU_ROUTING_LABEL_OFFSET 1
 #define ITU_ROUTING_LABEL_LENGTH 4
+#define ITU_SLS_OFFSET 1
+#define ITU_SLS_LENGTH 1
 #define ITU_MTP_PAYLOAD_OFFSET 5
 
+#define ANSI_ROUTING_LABEL_OFFSET 1
+#define ANSI_ROUTING_LABEL_LENGTH 7
+#define ANSI_MTP_PAYLOAD_OFFSET 8
+#define ANSI_DPC_OFFSET 1
+#define ANSI_DPC_LENGTH 3
+#define ANSI_OPC_OFFSET 4
+#define ANSI_OPC_LENGTH 3
+#define ANSI_SLS_OFFSET 7
+#define ANSI_SLS_LENGTH 1
+
+#define ANSI_NCM_LENGTH 1
+#define ANSI_DPC_MEMBER_OFFSET 1
+#define ANSI_DPC_CLUSTER_OFFSET 2
+#define ANSI_DPC_NETWORK_OFFSET 3
+#define ANSI_OPC_MEMBER_OFFSET 4
+#define ANSI_OPC_CLUSTER_OFFSET 5
+#define ANSI_OPC_NETWORK_OFFSET 6
+
 #define SERVICE_INDICATOR_MASK 0x0F
 #define SPARE_MASK 0x30
+#define ANSI_PRIORITY_MASK SPARE_MASK
 #define NETWORK_INDICATOR_MASK 0xC0
-#define DPC_MASK 0x00003FFF
-#define OPC_MASK 0x0FFFC000
-#define SLS_MASK 0xF0000000
+#define ITU_DPC_MASK 0x00003FFF
+#define ITU_OPC_MASK 0x0FFFC000
+#define ITU_SLS_MASK 0xF0
+
+#define ANSI_NETWORK_MASK 0x0000FF
+#define ANSI_CLUSTER_MASK 0x00FF00
+#define ANSI_MEMBER_MASK  0xFF0000
+#define ANSI_5BIT_SLS_MASK 0x1F
+/* TODO: eventually add support for ANSI 8-bit SLS */
+#define ANSI_8BIT_SLS_MASK 0xFF
 
 static const value_string service_indicator_code_vals[] = {
 	{ 0x0,	"Signalling network management message" },
 	{ 0x1,	"Signalling network testing and maintenance message" },
-	{ 0x2,	"Spare" },
+	{ 0x2,	"Signalling network testing and maintenance special message" },
 	{ 0x3,	"SCCP" },
 	{ 0x4,	"TUP" },
 	{ 0x5,	"ISUP" },
@@ -116,42 +153,118 @@
   guint8 sio;
   proto_item *sio_item;
   proto_tree *sio_tree;
-  
-  sio_item = proto_tree_add_text(mtp3_tree, tvb, ITU_SIO_OFFSET, ITU_SIO_LENGTH, "Service information octet");    
+ 
+  sio_item = proto_tree_add_text(mtp3_tree, tvb, SIO_OFFSET, SIO_LENGTH, "Service information octet");
   sio_tree = proto_item_add_subtree(sio_item, ett_mtp3_sio);
 
-  sio = tvb_get_guint8(tvb, ITU_SIO_OFFSET);
+  sio = tvb_get_guint8(tvb, SIO_OFFSET);
   proto_tree_add_uint(sio_tree, hf_mtp3_network_indicator,
-		      tvb, ITU_SIO_OFFSET, ITU_SIO_LENGTH,
+		      tvb, SIO_OFFSET, SIO_LENGTH,
 		      sio);
-  proto_tree_add_uint(sio_tree, hf_mtp3_spare,
-		      tvb, ITU_SIO_OFFSET, ITU_SIO_LENGTH,
-		      sio);
+  if (mtp3_standard == ANSI_STANDARD)
+    proto_tree_add_uint(sio_tree, hf_mtp3_priority,
+			tvb, SIO_OFFSET, SIO_LENGTH,
+			sio);
+  else
+    proto_tree_add_uint(sio_tree, hf_mtp3_spare,
+			tvb, SIO_OFFSET, SIO_LENGTH,
+			sio);
   proto_tree_add_uint(sio_tree, hf_mtp3_service_indicator,
-		      tvb, ITU_SIO_OFFSET, ITU_SIO_LENGTH,
+		      tvb, SIO_OFFSET, SIO_LENGTH,
 		      sio);
 }
 
 static void
 dissect_mtp3_routing_label(tvbuff_t *tvb, proto_tree *mtp3_tree)
 {
-  guint32 label;
-  proto_item *label_item;
-  proto_tree *label_tree;
-  
-  label_item = proto_tree_add_text(mtp3_tree, tvb, ITU_ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH, "Routing label");    
-  label_tree = proto_item_add_subtree(label_item, ett_mtp3_label);
-
-  label = tvb_get_letohl(tvb, ITU_ROUTING_LABEL_OFFSET);
-  proto_tree_add_uint(label_tree, hf_mtp3_dpc,
-		      tvb, ITU_ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH,
-		      label);
-  proto_tree_add_uint(label_tree, hf_mtp3_opc,
-		      tvb, ITU_ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH,
-		      label);
-  proto_tree_add_uint(label_tree, hf_mtp3_sls,
-		      tvb, ITU_ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH,
-		      label);
+  guint32 label, dpc, opc;
+  guint8 sls;
+  proto_item *label_item, *label_dpc_item, *label_opc_item;
+  proto_tree *label_tree, *label_dpc_tree, *label_opc_tree;
+ 
+  switch (mtp3_standard) {
+  case ITU_STANDARD:
+    label_item = proto_tree_add_text(mtp3_tree, tvb, ITU_ROUTING_LABEL_OFFSET,
+				     ITU_ROUTING_LABEL_LENGTH, "Routing label");
+    label_tree = proto_item_add_subtree(label_item, ett_mtp3_label);
+
+    label = tvb_get_letohl(tvb, ITU_ROUTING_LABEL_OFFSET);
+    sls = tvb_get_guint8(tvb, ITU_ROUTING_LABEL_OFFSET);
+
+    proto_tree_add_uint(label_tree, hf_mtp3_dpc, tvb,
+			ITU_ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH,
+			label);
+    proto_tree_add_uint(label_tree, hf_mtp3_opc, tvb,
+			ITU_ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH,
+			label);
+    proto_tree_add_uint(label_tree, hf_mtp3_sls, tvb,
+			ITU_SLS_OFFSET, ITU_SLS_LENGTH,
+			sls & ITU_SLS_MASK);
+    break;
+ 
+  case ANSI_STANDARD:
+    /* this could be 5 or 8 bits */
+    sls = tvb_get_guint8(tvb, ANSI_SLS_OFFSET);
+
+    /* Create the Routing Label Tree */
+    label_item = proto_tree_add_text(mtp3_tree, tvb, ANSI_ROUTING_LABEL_OFFSET,
+				     ANSI_ROUTING_LABEL_LENGTH, "Routing label");
+    label_tree = proto_item_add_subtree(label_item, ett_mtp3_label);
+
+    /* create the DPC tree */
+    dpc = tvb_get_ntoh24(tvb, ANSI_DPC_OFFSET);
+    label_dpc_item = proto_tree_add_text(label_tree, tvb, ANSI_DPC_OFFSET,
+					 ANSI_DPC_LENGTH,
+					 "DPC (%d-%d-%d)",
+					 (dpc & ANSI_NETWORK_MASK),
+					 ((dpc & ANSI_CLUSTER_MASK) >> 8),
+					 ((dpc & ANSI_MEMBER_MASK) >> 16));
+
+    label_dpc_tree = proto_item_add_subtree(label_dpc_item,
+					    ett_mtp3_label_dpc);
+
+    proto_tree_add_uint(label_dpc_tree, hf_mtp3_dpc_member,
+			tvb, ANSI_DPC_MEMBER_OFFSET, ANSI_NCM_LENGTH,
+			dpc);
+    proto_tree_add_uint(label_dpc_tree, hf_mtp3_dpc_cluster,
+			tvb, ANSI_DPC_CLUSTER_OFFSET, ANSI_NCM_LENGTH,
+			dpc);
+    proto_tree_add_uint(label_dpc_tree, hf_mtp3_dpc_network,
+			tvb, ANSI_DPC_NETWORK_OFFSET, ANSI_NCM_LENGTH,
+			dpc);
+
+  /* create the OPC tree */
+    opc = tvb_get_ntoh24(tvb, ANSI_OPC_OFFSET);
+
+    label_opc_item = proto_tree_add_text(label_tree, tvb, ANSI_OPC_OFFSET,
+					 ANSI_OPC_LENGTH,
+					 "OPC (%d-%d-%d)",
+					 (opc & ANSI_NETWORK_MASK),
+					 ((opc & ANSI_CLUSTER_MASK) >> 8),
+					 ((opc & ANSI_MEMBER_MASK) >> 16));
+
+    label_opc_tree = proto_item_add_subtree(label_opc_item,
+					    ett_mtp3_label_opc);
+
+    proto_tree_add_uint(label_opc_tree, hf_mtp3_opc_member,
+			tvb, ANSI_OPC_MEMBER_OFFSET, ANSI_NCM_LENGTH,
+			opc);
+    proto_tree_add_uint(label_opc_tree, hf_mtp3_opc_cluster,
+			tvb, ANSI_OPC_CLUSTER_OFFSET, ANSI_NCM_LENGTH,
+			opc);
+    proto_tree_add_uint(label_opc_tree, hf_mtp3_opc_network,
+			tvb, ANSI_OPC_NETWORK_OFFSET, ANSI_NCM_LENGTH,
+			opc);
+    /* SLS */
+    /* TODO: separate 5-bit and 8-bit SLS */
+    proto_tree_add_uint(label_tree, hf_mtp3_sls, tvb,
+			ANSI_SLS_OFFSET, ANSI_SLS_LENGTH,
+			sls & ANSI_5BIT_SLS_MASK);
+    break;
+
+  default:
+    printf("MTP3: unknown standard: %d\n", mtp3_standard);
+  }
 }
 
 static void
@@ -161,13 +274,25 @@
   guint8 service_indicator;
   tvbuff_t *payload_tvb;
 
-  sio = tvb_get_guint8(tvb, ITU_SIO_OFFSET);
+  sio = tvb_get_guint8(tvb, SIO_OFFSET);
   service_indicator = sio & SERVICE_INDICATOR_MASK;
-  payload_tvb = tvb_new_subset(tvb, ITU_MTP_PAYLOAD_OFFSET, -1, -1);
+
+  switch (mtp3_standard) {
+  case ITU_STANDARD:
+    payload_tvb = tvb_new_subset(tvb, ITU_MTP_PAYLOAD_OFFSET, -1, -1);
+    break;
+  case ANSI_STANDARD:
+    payload_tvb = tvb_new_subset(tvb, ANSI_MTP_PAYLOAD_OFFSET, -1, -1);
+    break;
+  default:
+    printf("MTP3: unknown standard: %d\n", mtp3_standard);
+    return;
+  }
+
   if (!dissector_try_port(mtp3_sio_dissector_table, service_indicator, payload_tvb, pinfo, tree)) {
     proto_tree_add_text(tree, payload_tvb, 0, tvb_length(payload_tvb),
 			"Payload (%u byte%s)",
-			tvb_length(payload_tvb), plurality(tvb_length(payload_tvb), "", "s")); 
+			tvb_length(payload_tvb), plurality(tvb_length(payload_tvb), "", "s"));
   }
 }
 
@@ -181,9 +306,9 @@
   proto_tree *mtp3_tree;
 
   /* Make entries in Protocol column and Info column on summary display */
-  if (check_col(pinfo->fd, COL_PROTOCOL)) 
-    col_set_str(pinfo->fd, COL_PROTOCOL, "MTP3");    
-  if (check_col(pinfo->fd, COL_INFO)) 
+  if (check_col(pinfo->fd, COL_PROTOCOL))
+    col_set_str(pinfo->fd, COL_PROTOCOL, "MTP3");
+  if (check_col(pinfo->fd, COL_INFO))
     col_clear(pinfo->fd, COL_INFO);
 
   /* In the interest of speed, if "tree" is NULL, don't do any work not
@@ -192,71 +317,109 @@
   if (tree) {
 
     /* create display subtree for the protocol */
-    mtp3_item = proto_tree_add_item(tree, proto_mtp3, tvb, 0, tvb_length(tvb), FALSE);    
+    mtp3_item = proto_tree_add_item(tree, proto_mtp3, tvb, 0, tvb_length(tvb),
+				    FALSE);
     mtp3_tree = proto_item_add_subtree(mtp3_item, ett_mtp3);
-    
+
     /* dissect the packet */
     dissect_mtp3_sio(tvb, mtp3_tree);
     dissect_mtp3_routing_label(tvb, mtp3_tree);
-    dissect_mtp3_payload(tvb, pinfo, tree);    
+    dissect_mtp3_payload(tvb, pinfo, mtp3_tree);
   }
 }
 
 void
 proto_register_mtp3(void)
-{                 
-  
+{
+ 
   /* Setup list of header fields  See Section 1.6.1 for details*/
   static hf_register_info hf[] = {
     { &hf_mtp3_service_indicator,
       { "Service indicator",
 	"mtp3.service_indicator",
-	FT_UINT8, BASE_HEX, VALS(service_indicator_code_vals), SERVICE_INDICATOR_MASK,          
-	"", HFILL }}, 
+	FT_UINT8, BASE_HEX, VALS(service_indicator_code_vals), SERVICE_INDICATOR_MASK,
+	"", HFILL }},
     { &hf_mtp3_network_indicator,
       { "Network indicator",
 	"mtp3.network_indicator",
-	FT_UINT8, BASE_HEX, VALS(network_indicator_vals), NETWORK_INDICATOR_MASK,          
-	"", HFILL }}, 
+	FT_UINT8, BASE_HEX, VALS(network_indicator_vals), NETWORK_INDICATOR_MASK,
+	"", HFILL }},
     { &hf_mtp3_spare,
       { "Spare",
 	"mtp3.spare",
-	FT_UINT8, BASE_HEX, NULL, SPARE_MASK,          
-	"", HFILL }}, 
+	FT_UINT8, BASE_HEX, NULL, SPARE_MASK,
+	"", HFILL }},
+    { &hf_mtp3_priority,
+      { "Priority",
+	"mtp3.priority",
+	FT_UINT8, BASE_HEX, NULL, ANSI_PRIORITY_MASK,
+	"", HFILL }},
     { &hf_mtp3_opc,
       { "OPC",
 	"mtp3.opc",
-	FT_UINT32, BASE_DEC, NULL, OPC_MASK,          
+	FT_UINT32, BASE_DEC, NULL, ITU_OPC_MASK,
+	"", HFILL }},
+    { &hf_mtp3_opc_network,
+     { "OPC Network",
+	"mtp3.opc.network",
+	FT_UINT32, BASE_DEC, NULL, ANSI_NETWORK_MASK,
 	"", HFILL }}, 
+    { &hf_mtp3_opc_cluster,
+      { "OPC Cluster",
+	"mtp3.opc.cluster",
+	FT_UINT32, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
+	"", HFILL }}, 
+    { &hf_mtp3_opc_member,
+      { "OPC Member",
+	"mtp3.opc.member",
+	FT_UINT32, BASE_DEC, NULL, ANSI_MEMBER_MASK,
+	"", HFILL }}, 
     { &hf_mtp3_dpc,
       { "DPC",
 	"mtp3.dpc",
-	FT_UINT32, BASE_DEC, NULL, DPC_MASK,          
+	FT_UINT32, BASE_DEC, NULL, ITU_DPC_MASK,
+	"", HFILL }},
+    { &hf_mtp3_dpc_network,
+      { "DPC Network",
+	"mtp3.dpc.network",
+	FT_UINT32, BASE_DEC, NULL, ANSI_NETWORK_MASK,
+	"", HFILL }}, 
+    { &hf_mtp3_dpc_cluster,
+      { "DPC Cluster",
+	"mtp3.dpc.cluster",
+	FT_UINT32, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
 	"", HFILL }}, 
+    { &hf_mtp3_dpc_member,
+      { "DPC Member",
+	"mtp3.dpc.member",
+	FT_UINT32, BASE_DEC, NULL, ANSI_MEMBER_MASK,
+	"", HFILL }}, 
     { &hf_mtp3_sls,
-      { "SLS",
+      { "Signalling Link Selector",
 	"mtp3.sls",
-	FT_UINT32, BASE_DEC, NULL, SLS_MASK,          
-	"", HFILL }}, 
+	FT_UINT32, BASE_DEC, NULL, 0x0,
+	"", HFILL }},
   };
-  
+ 
   /* Setup protocol subtree array */
   static gint *ett[] = {
     &ett_mtp3,
     &ett_mtp3_sio,
-    &ett_mtp3_label
+    &ett_mtp3_label,
+    &ett_mtp3_label_dpc,
+    &ett_mtp3_label_opc
   };
 
   static enum_val_t mtp3_options[] = {
-    {"ITU",  ITU_STANDARD},
-    /*    {"ANSI", ANSI_STANDARD}, */
-    {NULL, 0}
+    { "ITU",  ITU_STANDARD },
+    { "ANSI", ANSI_STANDARD },
+    { NULL, 0 }
   };
-  
+
   /* Register the protocol name and description */
   proto_mtp3 = proto_register_protocol("Message Transfer Part Level 3",
 				       "MTP3", "mtp3");
-  
+
   /* Required function calls to register the header fields and subtrees used */
   proto_register_field_array(proto_mtp3, hf, array_length(hf));
   proto_register_subtree_array(ett, array_length(ett));
@@ -265,13 +428,13 @@
   register_dissector("mtp3", dissect_mtp3, proto_mtp3);
 
   mtp3_sio_dissector_table = register_dissector_table("mtp3.service_indicator");
-  
+
   mtp3_module = prefs_register_protocol(proto_mtp3, NULL);
 
-  prefs_register_enum_preference(mtp3_module, 
+  prefs_register_enum_preference(mtp3_module,
 				 "mtp3_standard",
+				 "MTP3 standard",
 				 "MTP3 standard",
-				 "MTP3 standard", 
 				 &mtp3_standard,
 				 mtp3_options, FALSE);
 }
begin:vcard 
n:Morriss;Jeff
tel;fax:+1-856-222-9947
tel;work:+1-856-787-2824
x-mozilla-html:FALSE
url:http://www.ulticom.com
org:Ulticom, Inc.;Customer Support
version:2.1
email;internet:jeff.morriss@xxxxxxxxxxx
title:Product Support Engineer
adr;quoted-printable:;;Ulticom, Inc.=0D=0A1020 Briggs Rd.=0D=0A;Mount Laurel;NJ;08054;USA
fn:Jeff Morriss
end:vcard