Ethereal-dev: Re: [Ethereal-dev] dissector for FrameRelay

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

From: Paul Ionescu <paul@xxxxxxxx>
Date: Tue, 09 Jan 2001 23:48:46 +0200
Guy Harris wrote:
> 
> It should perhaps also, if the protocol field is 0x0300, treat that as
> RFC 2427-style "Multiprotocol Interconnect over Frame Relay" - the next
> byte after the 0300 is an NLPID, and then, if the NLPID is 0x80
> (NLPID_SNAP), what follows is a SNAP header (a handler for which should
> probably be exported by "packet-llc.c").
> 
> For example, frame 7 of your Frame-Relay-over-GRE capture is probably an
> ARP frame - after the 0300 comes 0x80, for NLPID_SNAP, followed by 3
> bytes of 00, for "encapsulated Ethernet", followed by 0806, or
> ETHERTYPE_ARP.
> 
> (RFC 2427 discusses the full story of the first 2 bytes of the payload -
> the first byte is 0x03, but it may be followed immediately by an NLPID
> or may be followed by a pad byte.)

Hello,
I have made a patch to frame relay dissector to interpret the payload as
in RFC 2427
or cisco encapsulation.
The patch is attached to this email.
If it is ok, please commit.

-- 

Air conditioned. Do _NOT_ open Windows.

Attachment: fr3.cap
Description: Binary data

Attachment: fr1.cap
Description: Binary data

Common subdirectories: eth_orig/CVS and ethereal/CVS
Common subdirectories: eth_orig/debian and ethereal/debian
Common subdirectories: eth_orig/doc and ethereal/doc
Common subdirectories: eth_orig/epan and ethereal/epan
Common subdirectories: eth_orig/gtk and ethereal/gtk
Common subdirectories: eth_orig/image and ethereal/image
Common subdirectories: eth_orig/libltdl and ethereal/libltdl
Common subdirectories: eth_orig/packaging and ethereal/packaging
diff -u eth_orig/packet-arp.c ethereal/packet-arp.c
--- eth_orig/packet-arp.c	Tue Jan  9 19:43:07 2001
+++ ethereal/packet-arp.c	Tue Jan  9 22:36:13 2001
@@ -938,6 +938,8 @@
 				      "ARP/RARP", "arp");
   proto_register_field_array(proto_arp, hf, array_length(hf));
   proto_register_subtree_array(ett, array_length(ett));
+  register_dissector("arp", dissect_arp, proto_arp);
+    
 }
 
 void
diff -u eth_orig/packet-cdp.c ethereal/packet-cdp.c
--- eth_orig/packet-cdp.c	Tue Jan  9 19:43:24 2001
+++ ethereal/packet-cdp.c	Tue Jan  9 23:46:39 2001
@@ -525,4 +525,5 @@
 proto_reg_handoff_cdp(void)
 {
     dissector_add("llc.cisco_pid", 0x2000, dissect_cdp, proto_cdp);
+    dissector_add("fr.cisco", 0x2000, dissect_cdp, proto_cdp);
 }
diff -u eth_orig/packet-clnp.c ethereal/packet-clnp.c
--- eth_orig/packet-clnp.c	Tue Jan  9 19:43:29 2001
+++ ethereal/packet-clnp.c	Tue Jan  9 23:09:11 2001
@@ -1932,4 +1932,6 @@
 	    proto_clnp);
 	dissector_add("osinl", NLPID_NULL, dissect_clnp,
 	    proto_clnp);	/* Inactive subset */
+	dissector_add("fr.ietf", NLPID_ISO8473_CLNP, dissect_clnp,
+	    proto_clnp);	/* Inactive subset */
 }
diff -u eth_orig/packet-esis.c ethereal/packet-esis.c
--- eth_orig/packet-esis.c	Tue Jan  9 19:43:44 2001
+++ ethereal/packet-esis.c	Tue Jan  9 23:08:43 2001
@@ -433,4 +433,5 @@
 proto_reg_handoff_esis(void)
 {
   dissector_add("osinl", NLPID_ISO9542_ESIS, dissect_esis, proto_esis);
+  dissector_add("fr.ietf", NLPID_ISO9542_ESIS, dissect_esis, proto_esis);
 }
diff -u eth_orig/packet-fr.c ethereal/packet-fr.c
--- eth_orig/packet-fr.c	Tue Jan  9 20:49:57 2001
+++ ethereal/packet-fr.c	Tue Jan  9 23:26:52 2001
@@ -36,9 +36,9 @@
 #include <string.h>
 #include <glib.h>
 #include "packet.h"
-#include "packet-ip.h"
-#include "packet-ipx.h"
-#include "packet-arp.h"
+
+#define UI  0x03
+#define XID 0xAF
 
 
 static gint proto_fr    = -1;
@@ -48,17 +48,32 @@
 static gint hf_fr_becn  = -1;
 static gint hf_fr_fecn  = -1;
 static gint hf_fr_de    = -1;
-static gint hf_fr_proto = -1;
+static gint hf_fr_nlpid = -1;
+static gint hf_fr_type  = -1;
+
+static dissector_table_t fr_subdissector_table;
+static dissector_table_t fr_cisco_subdissector_table;
 
 static dissector_handle_t ip_handle;
 static dissector_handle_t ipx_handle;
+static dissector_handle_t bpdu_handle;
+static dissector_handle_t eth_handle;
+static dissector_handle_t tr_handle;
+static dissector_handle_t arp_handle;
+
+static void dissect_lapf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static void dissect_fr_snap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *fr_tree);
+static void dissect_fr_xid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+
+/* see RFC2427 / RFC1490 and Cisco encapsulation */
 
 static void dissect_fr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
   proto_item *ti;
   proto_tree *fr_tree;
-  guint16 fr_header,fr_proto;
-  tvbuff_t   *next_tvb; 
+  guint16 fr_header,fr_type,offset=2; /* default header length of FR is 2 bytes */
+  
+  guint8  fr_nlpid,fr_ctrl;
     
   CHECK_DISPLAY_AS_DATA(proto_fr, tvb, pinfo, tree);
 
@@ -69,14 +84,15 @@
       col_clear(pinfo->fd, COL_INFO);
 
   fr_header = tvb_get_ntohs( tvb, 0 );
-  fr_proto  = tvb_get_ntohs( tvb, 2 );
   if (check_col(pinfo->fd, COL_INFO)) 
-      col_add_fstr(pinfo->fd, COL_INFO, "DLCI %u, proto 0x%04x",
-		   ((fr_header&0x00FF)>>4)+((fr_header&0xFC00)>>6),
-		   fr_proto);
+      col_add_fstr(pinfo->fd, COL_INFO, "DLCI %u",
+		   ((fr_header&0x00FF)>>4)+((fr_header&0xFC00)>>6));
   
   if (tree) {
-	
+
+      fr_header = tvb_get_ntohs( tvb, 0 );
+      fr_ctrl   = tvb_get_guint8( tvb,offset);
+            	
       ti = proto_tree_add_protocol_format(tree, proto_fr, tvb, 0, 4, "Frame Relay");
       fr_tree = proto_item_add_subtree(ti, ett_fr);
      
@@ -86,28 +102,135 @@
       proto_tree_add_boolean(fr_tree, hf_fr_fecn, tvb, 1, 1, fr_header);
       proto_tree_add_boolean(fr_tree, hf_fr_becn, tvb, 1, 1, fr_header);
       proto_tree_add_boolean(fr_tree, hf_fr_de,   tvb, 1, 1, fr_header);
-      proto_tree_add_uint(fr_tree, hf_fr_proto,tvb, 2, 2, fr_proto );
-  }
 
-  next_tvb =  tvb_new_subset(tvb, 4, -1, -1);
+	if (fr_ctrl==UI) 
+		{
+
+		proto_tree_add_text(fr_tree, tvb, offset, 0, "------- IETF Encapsulation -------");
+		proto_tree_add_text(fr_tree, tvb, offset, 1, "Unnumbered Information");
+		offset++;
+		fr_nlpid=tvb_get_guint8 (tvb,offset);
+		if (fr_nlpid==0)
+			{
+			proto_tree_add_text(fr_tree, tvb, offset, 1, "Padding");
+			offset++;
+			fr_nlpid=tvb_get_guint8( tvb,offset);
+			};
+		proto_tree_add_uint(fr_tree, hf_fr_nlpid, tvb, offset, 1, fr_nlpid );
+		offset++;
+
+		if(fr_nlpid== 0x80)
+		  {
+		  dissect_fr_snap(tvb_new_subset(tvb,offset,-1,-1),pinfo,tree,fr_tree);
+		  return;
+		  }
+		                                  
+                if (!dissector_try_port(fr_subdissector_table,fr_nlpid, tvb_new_subset(tvb,offset,-1,-1), pinfo, tree))
+                  dissect_data(tvb_new_subset(tvb,offset,-1,-1), 0, pinfo, tree);
+		return;
+
+		}
+	else
+		{
+		if((fr_header && 0xFCF0)==0) 
+      			{
+      			/* this must be some sort of lapf on DLCI 0 for SVC */
+			/* because DLCI 0 is rezerved for LMI and  SVC signaling encaplulated in lapf */
+			/* and LMI is transmitted in unnumbered information (03) */
+			/* so this must be lapf (guessing) */
+			dissect_lapf(tvb_new_subset(tvb,offset,-1,-1),pinfo,tree);
+			return;
+			}
+		if(fr_ctrl==XID)
+			{
+			dissect_fr_xid(tvb_new_subset(tvb,offset,-1,-1),pinfo,tree);
+			return;
+			}
+
+		/* if the data does not start with unnumbered information (03) and the DLCI# is not 0, */
+		/* then there may be cisco frame relay encapsulation */
+
+		proto_tree_add_text(fr_tree, tvb, offset, 0, "------- Cisco Encapsulation -------");
+		fr_type  = tvb_get_ntohs( tvb, offset);
+		proto_tree_add_uint(fr_tree, hf_fr_type,tvb, offset, 2, fr_type ); 
+                if (!dissector_try_port(fr_cisco_subdissector_table,fr_type, tvb_new_subset(tvb,offset+2,-1,-1), pinfo, tree))
+                  dissect_data(tvb_new_subset(tvb,offset+2,-1,-1), offset+2, pinfo, tree);
+		}
+ }
+}
 
-  switch (fr_proto){
-/*    case 0x0703:
-	dissect_lmi(next_tvb,pinfo,tree);
-	break;
-	this is not yet implemented
-*/
-      case 0x0800:
-	call_dissector(ip_handle,next_tvb,pinfo,tree);
-	break;
-      case 0x8137:
-	call_dissector(ipx_handle,next_tvb,pinfo,tree);
-	break;
-      default:
-	dissect_data(next_tvb,0,pinfo,tree);
-	break;	                                
-  }
-  return;
+static void dissect_fr_snap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *fr_tree)
+{
+	guint32 fr_oui  = tvb_get_ntoh24( tvb, 0);
+        guint16 fr_type  = tvb_get_ntohs( tvb, 3);
+        
+	proto_tree_add_text(fr_tree, tvb, 0, 3, "OUI: %06x",fr_oui);
+	proto_tree_add_uint(fr_tree, hf_fr_type,tvb, 3, 2, fr_type ); 
+
+	switch(fr_oui)
+	{
+	case 0x0080C2:
+		switch (fr_type)
+		{
+		case 0x0001:
+		case 0x0007:
+			call_dissector(eth_handle,tvb_new_subset(tvb,5,-1,-1),pinfo,tree);
+			break;
+/*		case 0x0002:
+		case 0x0008:
+			dissect_802.4(tvb_new_subset(tvb,5,-1,-1),pinfo,tree); 
+			break;
+*/		case 0x0003:
+		case 0x0009:
+			call_dissector(tr_handle,tvb_new_subset(tvb,5,-1,-1),pinfo,tree); 
+			break;
+/*		case 0x0004:
+		case 0x000A:
+			dissect_fddi(tvb_new_subset(tvb,5,-1,-1),pinfo,tree);
+			break;
+		case 0x000B:
+			dissect_802.6(tvb_new_subset(tvb,5,-1,-1),pinfo,tree);
+*/			break;
+		case 0x000D:
+			call_dissector(bpdu_handle,tvb_new_subset(tvb,5,-1,-1),pinfo,tree);
+			break;
+/*		case 0x000E:
+			dissect_fr_fragments(tvb_new_subset(tvb,5,-1,-1),pinfo,tree);
+			break;
+		case 0x000F:
+			dissect_srb(tvb_new_subset(tvb,5,-1,-1),pinfo,tree);
+			break;
+*/		};
+		break;
+		
+	case 0x000000:
+		switch (fr_type)
+		{
+		case 0x0800:
+      			call_dissector(ip_handle,tvb_new_subset(tvb,5,-1,-1),pinfo,tree);
+      			break;
+		case 0x8137:
+			call_dissector(ipx_handle,tvb_new_subset(tvb,5,-1,-1),pinfo,tree);
+			break;
+		case 0x0806:
+			call_dissector(arp_handle,tvb_new_subset(tvb,5,-1,-1),pinfo,tree);
+			break;
+		};
+		break;
+	default:
+		dissect_data(tvb_new_subset(tvb,5,-1,-1),0,pinfo,tree);
+	}
+}
+
+static void dissect_lapf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+		proto_tree_add_text(tree, tvb, 0, 0, "Frame relay lapf not yet implemented");
+		dissect_data(tvb_new_subset(tvb,0,-1,-1),0,pinfo,tree);
+}
+static void dissect_fr_xid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+		proto_tree_add_text(tree, tvb, 0, 0, "Frame relay xid not yet implemented");
+		dissect_data(tvb_new_subset(tvb,0,-1,-1),0,pinfo,tree);
 }
  
 /* Register the protocol with Ethereal */
@@ -129,9 +252,12 @@
         { &hf_fr_de, { 
            "DE", "fr.de", FT_BOOLEAN, 16, 
             NULL, 0x0002, "Discard Eligibility" }},
-        { &hf_fr_proto, { 
-           "Encapsulated Protocol", "fr.proto", FT_UINT16, BASE_HEX, 
-            NULL, 0x0, "FrameRelay Encapsulated Protocol" }},
+        { &hf_fr_nlpid, { 
+           "NLPID", "fr.nlpid", FT_UINT8, BASE_HEX, 
+            NULL, 0x0, "FrameRelay Encapsulated Protocol NLPID" }},
+        { &hf_fr_type, { 
+           "TYPE", "fr.type", FT_UINT16, BASE_HEX, 
+            NULL, 0x0, "FrameRelay SNAP Encapsulated Protocol" }},
   };
 
 
@@ -145,6 +271,10 @@
   proto_register_subtree_array(ett, array_length(ett));
 
   register_dissector("fr", dissect_fr, proto_fr);
+
+  fr_subdissector_table = register_dissector_table("fr.ietf");
+  fr_cisco_subdissector_table = register_dissector_table("fr.cisco");
+
 };
 
 void proto_reg_handoff_fr(void)
@@ -154,6 +284,10 @@
    */
   ip_handle = find_dissector("ip");
   ipx_handle = find_dissector("ipx");
+  bpdu_handle = find_dissector("bpdu");
+  arp_handle = find_dissector("arp");
+  eth_handle = find_dissector("eth");
+  eth_handle = find_dissector("tr");
 
   dissector_add("wtap_encap", WTAP_ENCAP_FRELAY, dissect_fr, proto_fr);
 }
diff -u eth_orig/packet-ip.c ethereal/packet-ip.c
--- eth_orig/packet-ip.c	Tue Jan  9 19:44:13 2001
+++ ethereal/packet-ip.c	Tue Jan  9 23:10:33 2001
@@ -53,6 +53,7 @@
 #include "packet-ip.h"
 #include "packet-ipsec.h"
 #include "in_cksum.h"
+#include "nlpid.h"
 
 static void dissect_icmp(tvbuff_t *, packet_info *, proto_tree *);
 static void dissect_igmp(tvbuff_t *, packet_info *, proto_tree *);
@@ -1486,6 +1487,9 @@
 	dissector_add("ip.proto", IP_PROTO_IPV4, dissect_ip, proto_ip);
 	dissector_add("ip.proto", IP_PROTO_IPIP, dissect_ip, proto_ip);
 	dissector_add("null.type", BSD_AF_INET, dissect_ip, proto_ip);
+        dissector_add("fr.cisco", CISCO_IP, dissect_ip, proto_ip);
+        dissector_add("fr.ietf", NLPID_IP, dissect_ip, proto_ip);
+        
 }
 
 void
diff -u eth_orig/packet-ipx.c ethereal/packet-ipx.c
--- eth_orig/packet-ipx.c	Tue Jan  9 19:44:20 2001
+++ ethereal/packet-ipx.c	Tue Jan  9 23:02:15 2001
@@ -916,6 +916,7 @@
 
 	dissector_add("udp.port", UDP_PORT_IPX, dissect_ipx, proto_ipx);
 	dissector_add("ethertype", ETHERTYPE_IPX, dissect_ipx, proto_ipx);
+	dissector_add("fr.cisco", ETHERTYPE_IPX, dissect_ipx, proto_ipx);
 	dissector_add("ppp.protocol", PPP_IPX, dissect_ipx, proto_ipx);
 	dissector_add("llc.dsap", SAP_NETWARE, dissect_ipx, proto_ipx);
 	dissector_add("null.type", BSD_AF_IPX, dissect_ipx, proto_ipx);
diff -u eth_orig/packet-isis.c ethereal/packet-isis.c
--- eth_orig/packet-isis.c	Tue Jan  9 19:44:34 2001
+++ ethereal/packet-isis.c	Tue Jan  9 23:08:26 2001
@@ -338,4 +338,5 @@
 proto_reg_handoff_isis(void)
 {
     old_dissector_add("osinl", NLPID_ISO10589_ISIS, dissect_isis, proto_isis);
+    old_dissector_add("fr.ietf", NLPID_ISO10589_ISIS, dissect_isis, proto_isis);
 }
diff -u eth_orig/packet-ppp.c ethereal/packet-ppp.c
--- eth_orig/packet-ppp.c	Tue Jan  9 19:45:16 2001
+++ ethereal/packet-ppp.c	Tue Jan  9 23:09:51 2001
@@ -42,7 +42,7 @@
 #include "packet-ipv6.h"
 #include "packet-ipx.h"
 #include "packet-vines.h"
-
+#include "nlpid.h"
 static int proto_ppp = -1;
 
 static gint ett_ppp = -1;
@@ -1470,4 +1470,5 @@
 {
   dissector_add("wtap_encap", WTAP_ENCAP_PPP, dissect_ppp, proto_ppp);
   dissector_add("wtap_encap", WTAP_ENCAP_PPP_WITH_PHDR, dissect_ppp, proto_ppp);
+  dissector_add("fr.ietf", NLPID_PPP, dissect_ppp, proto_ppp);
 }
diff -u eth_orig/packet-tr.c ethereal/packet-tr.c
--- eth_orig/packet-tr.c	Tue Jan  9 19:46:18 2001
+++ ethereal/packet-tr.c	Tue Jan  9 22:37:26 2001
@@ -671,6 +671,8 @@
 	proto_tr = proto_register_protocol("Token-Ring", "Token-Ring", "tr");
 	proto_register_field_array(proto_tr, hf, array_length(hf));
 	proto_register_subtree_array(ett, array_length(ett));
+  	register_dissector("tr", dissect_tr, proto_tr);
+  
 }
 
 void
Common subdirectories: eth_orig/plugins and ethereal/plugins
Common subdirectories: eth_orig/wiretap and ethereal/wiretap

Attachment: fr4.cap
Description: Binary data