Ethereal-dev: [Ethereal-dev] New dissector for PPP multiplexing

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

From: "Jayaram V.R" <vjayar@xxxxxxxxx>
Date: Tue, 01 Jan 2002 19:34:42 +0530
Hi,

I have modified the PPP dissector code to add support for PPP
Multiplexing and PPPMuxCP and thought it will be useful to add these
changes back into the main source repository. Please find attached the
patch files for packet-ppp.c and ppptypes.h. I have compiled and tested
this with the latest source code. Please let me know if these can be
checked in.

Thanks and Happy New Year every one,
Jayaram
Index: packet-ppp.c
===================================================================
RCS file: /cvsroot/ethereal/packet-ppp.c,v
retrieving revision 1.83
diff -u -r1.83 packet-ppp.c
--- packet-ppp.c	2001/12/20 06:22:24	1.83
+++ packet-ppp.c	2002/01/01 13:47:24
@@ -111,6 +111,20 @@
 
 static gint ett_comp_data = -1;
 
+static int proto_pppmuxcp = -1;
+
+static gint ett_pppmuxcp = -1;
+static gint ett_pppmuxcp_options = -1;
+static gint ett_pppmuxcp_def_pid_opt = -1;
+
+static int proto_pppmux = -1;
+
+static gint ett_pppmux = -1;
+static gint ett_pppmux_subframe = -1;
+static gint ett_pppmux_subframe_hdr = -1;
+static gint ett_pppmux_subframe_flags = -1;
+static gint ett_pppmux_subframe_info = -1;
+
 static int proto_mp = -1;
 static int hf_mp_frag_first = -1;
 static int hf_mp_frag_last = -1;
@@ -143,6 +157,14 @@
 #define FCS_16 1
 #define FCS_32 2
 gboolean ppp_vj_decomp = TRUE; /* Default to VJ header decompression */
+				
+/*
+ * For Default Protocol ID negotiated with PPPMuxCP. We need to
+ * this ID so that if the first subframe doesn't have protocol
+ * ID, we can use it
+ */
+
+static guint pppmux_def_prot_id = 0;
 
 /* PPP definitions */
 
@@ -157,6 +179,7 @@
 	{PPP_VINES,     "Vines"          },
         {PPP_MP,	"Multilink"},
 	{PPP_IPV6,      "IPv6"           },
+        {PPP_MUX,       "PPP Multiplexing"},
 	{PPP_COMP,	"compressed packet" },
 	{PPP_DEC_LB,	"DEC LANBridge100 Spanning Tree"},
 	{PPP_MPLS_UNI,  "MPLS Unicast"},
@@ -165,6 +188,7 @@
 	{PPP_OSICP,     "OSI Control Protocol" },
 	{PPP_ATCP,	"AppleTalk Control Protocol" },
 	{PPP_IPXCP,	"IPX Control Protocol" },
+	{PPP_MUXCP,     "PPPMux Control Protocol"},
 	{PPP_CCP,	"Compression Control Protocol" },
 	{PPP_LCP,	"Link Control Protocol" },
 	{PPP_PAP,	"Password Authentication Protocol"  },
@@ -1096,6 +1120,35 @@
 
 static void dissect_chap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
 
+static const value_string pppmuxcp_vals[] = {
+	{CONFREQ,    "Configuration Request" },
+	{CONFACK,    "Configuration Ack" },
+	{0,          NULL}
+};
+
+/*
+ * PPPMuxCP options
+ */
+
+#define CI_DEFAULT_PID   1
+
+static void dissect_pppmuxcp_def_pid_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
+			int offset, guint length, packet_info *pinfo, proto_tree *tree);
+
+
+static const ip_tcp_opt pppmuxcp_opts[] = {
+	{
+		CI_DEFAULT_PID,
+		"Default Protocol ID",
+		&ett_pppmuxcp_def_pid_opt,
+		FIXED_LENGTH,
+		4,
+		dissect_pppmuxcp_def_pid_opt
+	}
+};
+
+#define N_PPPMUXCP_OPTS (sizeof pppmuxcp_opts / sizeof pppmuxcp_opts[0])
+
 const unsigned int fcstab_32[256] =
       {
       0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
@@ -1649,6 +1702,15 @@
 			ip_to_str(tvb_get_ptr(tvb, offset + 2, 4)));
 }
 
+static void dissect_pppmuxcp_def_pid_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
+			int offset, guint length, packet_info *pinfo, proto_tree *tree)
+{ 
+  pppmux_def_prot_id = tvb_get_ntohs(tvb, offset + 2);
+  proto_tree_add_text(tree, tvb, offset + 2, length - 2, "%s: %s (0x%02x)",optp->name,
+		      val_to_str(pppmux_def_prot_id, ppp_vals, "Unknown"), pppmux_def_prot_id);
+}
+
+
 static void
 dissect_ccp_stac_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
 			int offset, guint length, packet_info *pinfo,
@@ -2192,6 +2254,116 @@
   }
 }
 
+static void
+dissect_pppmuxcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+  dissect_cp(tvb,proto_pppmuxcp,ett_pppmuxcp,pppmuxcp_vals,
+	     ett_pppmuxcp_options,pppmuxcp_opts,N_PPPMUXCP_OPTS,pinfo,tree);
+}
+
+#define PPPMUX_FLAGS_MASK          0xc0
+#define PPPMUX_PFF_BIT_SET         0x80
+#define PPPMUX_LXT_BIT_SET         0x40
+
+static void 
+dissect_pppmux(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+  proto_tree *mux_tree, *hdr_tree, *sub_tree, *flag_tree;
+  proto_tree *info_tree;
+  proto_item *ti = NULL,*sub_ti = NULL;
+  guint8 flags, byte;
+  guint16 length;
+  static guint16 pid;
+  tvbuff_t *next_tvb;    
+  int offset = 0, length_remaining;
+  int length_field = 0, pid_field = 0,hdr_length = 0;
+  dissector_handle_t prot_handle; 
+  
+  if (check_col(pinfo->cinfo, COL_PROTOCOL))
+    col_set_str(pinfo->cinfo,COL_PROTOCOL, "PPP PPPMux");
+	
+  if (check_col(pinfo->cinfo, COL_INFO))
+    col_set_str(pinfo->cinfo, COL_INFO, "PPP Multiplexing");
+	
+  length_remaining = tvb_length(tvb);
+  
+  if (tree) {
+    ti = proto_tree_add_item(tree, proto_pppmux, tvb, 0, length_remaining,
+			     FALSE);
+    mux_tree = proto_item_add_subtree(ti,ett_pppmux);
+    
+    while (length_remaining > 0) {
+	
+      flags = tvb_get_guint8(tvb,offset) & PPPMUX_FLAGS_MASK;
+      
+      if (flags && PPPMUX_LXT_BIT_SET ) {
+	length = tvb_get_ntohs(tvb,offset) & 0x3fff;
+	length_field = 2;
+      } else {
+	length = tvb_get_guint8(tvb,offset) & 0x3f;
+	length_field = 1;
+      }
+      
+      if (flags && PPPMUX_PFF_BIT_SET) {
+	byte = tvb_get_guint8(tvb,offset + length_field);
+	if (byte && PFC_BIT) {		  /* Compressed PID field*/
+	  pid = byte;
+	  pid_field = 1;
+	} else {		  /*PID field is 2 bytes*/
+	  pid = tvb_get_ntohs(tvb,offset + length_field);
+	  pid_field = 2;
+	}
+      } else {
+	if (!pid){	 /*No Last PID, hence use the default */
+	  if (pppmux_def_prot_id) 
+	    pid = pppmux_def_prot_id;
+	}
+      }
+      
+      hdr_length = length_field + pid_field;
+      
+      ti = proto_tree_add_text(mux_tree, tvb, offset, length + length_field,
+			       "PPPMux Sub-frame");
+      sub_tree = proto_item_add_subtree(ti,ett_pppmux_subframe);
+      sub_ti = proto_tree_add_text(sub_tree, tvb, offset,
+				   hdr_length,"Header field");
+      
+      hdr_tree = proto_item_add_subtree(sub_ti,ett_pppmux_subframe_hdr);
+      ti = proto_tree_add_text(hdr_tree, tvb, offset, length_field, "PFF/LXT: 0x%02X",
+			       flags);
+      
+      flag_tree = proto_item_add_subtree(ti,ett_pppmux_subframe_flags);
+      proto_tree_add_text(flag_tree,tvb,offset,length_field,"%s",
+			  decode_boolean_bitfield(flags,0x80,8,"PID Present","PID not present"));
+      proto_tree_add_text(flag_tree,tvb,offset,length_field,"%s",
+			  decode_boolean_bitfield(flags,0x40,8,"2 bytes ength field ","1 byte length field"));
+      
+      ti = proto_tree_add_text(hdr_tree,tvb,offset,length_field,"Sub-frame Length = %u",length);
+      
+      if (flags && PPPMUX_PFF_BIT_SET)
+	proto_tree_add_text(hdr_tree,tvb,offset + length_field,pid_field,"%s: %s(0x%02x)",
+			    "Protocol ID",val_to_str(pid,ppp_vals,"Unknown"), pid);
+      
+      offset += hdr_length;
+      length_remaining -= hdr_length;
+      length -= pid_field;
+      
+      sub_ti = proto_tree_add_text(sub_tree,tvb,offset,length,"Information Field");
+      info_tree = proto_item_add_subtree(sub_ti,ett_pppmux_subframe_info);
+      
+      next_tvb = tvb_new_subset(tvb,offset,length,-1); 
+      
+      if (!dissector_try_port(subdissector_table, pid, next_tvb, pinfo, info_tree)) {
+	call_dissector(data_handle, next_tvb, pinfo, info_tree);
+      }
+      offset += length;
+      length_remaining -= length;
+    }  /* While length_remaining */
+    pid = 0; 
+  } /* if tree */  
+}
+
+
 #define MP_FRAG_MASK     0xC0
 #define MP_FRAG(bits)    ((bits) & MP_FRAG_MASK)
 #define MP_FRAG_FIRST    0x80
@@ -2608,6 +2780,11 @@
     "PPP Van Jacobson Compression",
     "Whether Van Jacobson-compressed PPP frames should be decompressed",
     &ppp_vj_decomp);
+
+  prefs_register_uint_preference(ppp_module, "default_proto_id",
+				 "PPPMuxCP Default PID",
+				 "Default Protocol ID to be used",
+				 16, &pppmux_def_prot_id);
 }
 
 void
@@ -2956,3 +3133,68 @@
    */
   dissector_add("ethertype", PPP_CHAP, chap_handle);
 }
+
+void
+proto_register_pppmuxcp(void)
+{
+  static gint *ett[] = {
+    &ett_pppmuxcp,
+    &ett_pppmuxcp_options,
+    &ett_pppmuxcp_def_pid_opt,
+  };
+
+  proto_pppmuxcp = proto_register_protocol("PPPMux Control Protocol", 
+				       "PPP PPPMuxCP",
+				      "pppmuxcp");
+  proto_register_subtree_array(ett, array_length(ett));
+}
+
+
+void
+proto_reg_handoff_pppmuxcp(void)
+{ 
+  dissector_handle_t muxcp_handle; 
+ 
+  muxcp_handle = create_dissector_handle(dissect_pppmuxcp, proto_pppmuxcp);
+  dissector_add("ppp.protocol", PPP_MUXCP, muxcp_handle);
+
+  /*
+   * See above comment about NDISWAN for an explanation of why we're
+   * registering with the "ethertype" dissector table.
+   */
+  dissector_add("ethertype", PPP_MUXCP, muxcp_handle);
+}
+
+
+void 
+proto_register_pppmux(void) 
+{ 
+  static gint *ett[] = { 
+    &ett_pppmux, 
+    &ett_pppmux_subframe, 
+    &ett_pppmux_subframe_hdr, 
+    &ett_pppmux_subframe_flags, 
+    &ett_pppmux_subframe_info, 
+  }; 
+ 
+  proto_pppmux = proto_register_protocol("PPP Multiplexing",  
+				       "PPP PPPMux", 
+				      "pppmux"); 
+  proto_register_subtree_array(ett, array_length(ett)); 
+} 
+ 
+void 
+proto_reg_handoff_pppmux(void) 
+{ 
+  dissector_handle_t pppmux_handle; 
+ 
+  pppmux_handle = create_dissector_handle(dissect_pppmux, proto_pppmux); 
+  dissector_add("ppp.protocol", PPP_MUX, pppmux_handle); 
+ 
+  /* 
+   * See above comment about NDISWAN for an explanation of why we're 
+   * registering with the "ethertype" dissector table. 
+   */ 
+  dissector_add("ethertype", PPP_MUX, pppmux_handle); 
+} 
+
Index: ppptypes.h
===================================================================
RCS file: /cvsroot/ethereal/ppptypes.h,v
retrieving revision 1.10
diff -u -r1.10 ppptypes.h
--- ppptypes.h	2001/12/08 01:03:19	1.10
+++ ppptypes.h	2002/01/01 13:47:40
@@ -41,6 +41,7 @@
 #define	PPP_VINES	0x35	/* Banyan Vines */
 #define PPP_MP		0x3d	/* Multilink PPP */
 #define PPP_IPV6	0x57	/* Internet Protocol Version 6 */
+#define PPP_MUX         0x59    /* PPP Multiplexing */
 #define PPP_COMP	0xfd	/* compressed packet */
 #define PPP_DEC_LB	0x0205	/* DEC LANBridge100 Spanning Tree */
 #define PPP_MPLS_UNI	0x0281	/* MPLS Unicast */
@@ -49,6 +50,7 @@
 #define PPP_OSICP	0x8023  /* OSI Control Protocol */
 #define PPP_ATCP	0x8029	/* AppleTalk Control Protocol */
 #define PPP_IPXCP	0x802b	/* IPX Control Protocol */
+#define PPP_MUXCP       0x8059  /* PPPMux Control Protocol */ 
 #define PPP_CCP		0x80fd	/* Compression Control Protocol */
 #define PPP_LCP		0xc021	/* Link Control Protocol */
 #define PPP_PAP		0xc023	/* Password Authentication Protocol */