Ethereal-dev: [ethereal-dev] Vines coded expanded

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

From: Joerg Mayer <jmayer@xxxxxxxxxxxxx>
Date: Fri, 27 Nov 1998 16:29:03 +0100
Hello,

I'm currently expanding the code for Vines. It's not yet finished,
ARP, IPC, ICP and perhaps better SPP support will follow.  As this is
my first patch to ethereal I'd appreciate your comments.
Also, I've got a few questions:
- The new code contains tons of 
  if (check_col... )  col_add_str...
  Grepping for check_col, col_add_str, col_add_fstr showed that except
  for a few sections they are used in this combination. As the perfomance
  overhead for this check is minimal but readability of the code would
  improve: Would you mind if I integrate the check_col into the col_add_...
  functions and remove the tests elsewhere?
- Has someone written some "standard" code to decode and display the values
  from bitfields?
- I noticed that the values in the protocol field are of different detail
  levels, maybe depending on the author (e.g. "ARP request" vs. ICMP). How
  should this field be used?

Thanks

Jörg
--- ./packet.h.distrib	Wed Nov 18 04:02:35 1998
+++ ./packet.h	Tue Nov 24 22:19:02 1998
@@ -364,6 +364,7 @@
 #define UDP_PORT_IPX    213
 #define UDP_PORT_NBNS	137
 #define UDP_PORT_RIP    520
+#define UDP_PORT_VINES	573
 
 /* TCP Ports */
 
@@ -420,8 +421,13 @@
 	ETT_IPv6,
 	ETT_CLNP,
 	ETT_COTP,
+	ETT_VINES_FRP,
 	ETT_VINES,
-	ETT_VSPP,
+	ETT_VINES_ARP,
+	ETT_VINES_ICP,
+	ETT_VINES_IPC,
+	ETT_VINES_RTP,
+	ETT_VINES_SPP,
 	ETT_IPXRIP,
 	ETT_IPXSAP,
 	ETT_IPXSAP_SERVER,
@@ -547,7 +553,12 @@
 void dissect_trmac(const u_char *, int, frame_data *, GtkTree *);
 void dissect_udp(const u_char *, int, frame_data *, GtkTree *);
 void dissect_vines(const u_char *, int, frame_data *, GtkTree *);
-void dissect_vspp(const u_char *, int, frame_data *, GtkTree *);
+void dissect_vines_arp(const u_char *, int, frame_data *, GtkTree *);
+void dissect_vines_frp(const u_char *, int, frame_data *, GtkTree *);
+void dissect_vines_icp(const u_char *, int, frame_data *, GtkTree *);
+void dissect_vines_ipc(const u_char *, int, frame_data *, GtkTree *);
+void dissect_vines_rtp(const u_char *, int, frame_data *, GtkTree *);
+void dissect_vines_spp(const u_char *, int, frame_data *, GtkTree *);
 
 /* These functions are in ethertype.c */
 gchar *ethertype_to_str(guint16 etype, const char *fmt);
--- ./packet-udp.c.distrib	Thu Nov 19 01:01:20 1998
+++ ./packet-udp.c	Fri Nov 27 02:07:39 1998
@@ -99,11 +99,15 @@
       /* we should check the source port too (RIP: UDP src and dst port 520) */
       dissect_rip(pd, offset, fd, tree);
       break;
-	case UDP_PORT_NBNS:
-	  dissect_nbns(pd, offset, fd, tree);
-	  break;
+    case UDP_PORT_NBNS:
+      dissect_nbns(pd, offset, fd, tree);
+      break;
     case UDP_PORT_IPX: /* RFC 1234 */
       dissect_ipx(pd, offset, fd, tree);
+      break;
+    case UDP_PORT_VINES:
+      /* FIXME: AFAIK, src and dst port must be the same */
+      dissect_vines_frp(pd, offset, fd, tree);
       break;
     default:
       dissect_data(pd, offset, fd, tree);
--- ./packet-vines.c.distrib	Tue Nov 17 05:30:00 1998
+++ ./packet-vines.c	Fri Nov 27 02:19:40 1998
@@ -8,6 +8,7 @@
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@xxxxxxxx>
  * Copyright 1998 Gerald Combs
+ * Joerg Mayer <jmayer@xxxxxxxxxxxxx>
  *
  * 
  * This program is free software; you can redistribute it and/or
@@ -44,55 +45,137 @@
 #include "etypes.h"
 #include "packet-vines.h"
 
-#define VINES_VSPP 2
-#define VINES_DATA 1
+
+/* AFAIK Vines FRP (Fragmentation Protocol) is used on all media except Ethernet
+ * and TR (and probably FDDI) - Fragmentation on these media types is not possible
+ * FIXME: Do we need to use this header with PPP too?
+ */
+
+void
+dissect_vines_frp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
+  guint8   vines_frp_ctrl, vines_frp_seqno; 
+  GtkWidget *vines_frp_tree, *ti;
+  gchar	frp_flags_str[32];
+
+  /* To do: Check for {cap len,pkt len} < struct len */
+  /* Avoids alignment problems on many architectures. */
+  vines_frp_ctrl = pd[offset];
+  vines_frp_seqno = pd[offset+1];
+  
+  if (check_col(fd, COL_PROTOCOL))
+    col_add_str(fd, COL_PROTOCOL, "Vines FRP");
+  /*
+   * 1: first fragment of vines packet
+   * 2: last fragment of vines packet
+   * 4 ... 80: unused
+   */
+  switch (vines_frp_ctrl) {
+  case 0:
+    strcpy(frp_flags_str, "middle");
+    break;
+  case 1:
+    strcpy(frp_flags_str, "first");
+    break;
+  case 2:
+    strcpy(frp_flags_str, "last");
+    break;
+  case 3:
+    strcpy(frp_flags_str, "only");
+    break;
+  default:
+    strcpy(frp_flags_str, "please report: unknown");
+    break;
+  }
+  
+  if (tree) {
+    ti = add_item_to_tree(GTK_WIDGET(tree), offset, 2,
+      "Vines Fragmentation Protocol");
+    vines_frp_tree = gtk_tree_new();
+    add_subtree(ti, vines_frp_tree, ETT_VINES_FRP);
+    add_item_to_tree(vines_frp_tree, offset,     1, "Control Flags: 0x%02x = %s fragment", vines_frp_ctrl, frp_flags_str);
+    add_item_to_tree(vines_frp_tree, offset + 1, 1, "Sequence Number: 0x%02x", vines_frp_seqno);
+  }
+
+  /* Skip over header */
+  offset += 2;
+
+  /* Decode the "real" Vines now */
+  dissect_vines(pd, offset, fd, tree);
+}
 
 void
 dissect_vines(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) 
 	{
-  	e_vip       iph;
+  	e_vip       viph;
   	GtkWidget *vip_tree, *ti;
 /*  	gchar      tos_str[32]; */
+	int  is_broadcast = 0;
+	int  hops = 0;
 
   /* To do: check for runts, errs, etc. */
   /* Avoids alignment problems on many architectures. */
-  	memcpy(&iph, &pd[offset], sizeof(e_vip));
+  	memcpy(&viph, &pd[offset], sizeof(e_vip));
 
-  	iph.vip_sum = pntohs(&pd[offset]);
-  	iph.vip_len = pntohs(&pd[offset+2]);
-  	iph.vip_dnet = pntohl(&pd[offset+6]);
-  	iph.vip_snet = pntohl(&pd[offset+12]);
-  	iph.vip_dsub = pntohs(&pd[offset+10]);
-  	iph.vip_ssub = pntohs(&pd[offset+16]);
-
-    	switch (iph.vip_proto) 
-    		{
-      		case VINES_VSPP:      
-						if (check_col(fd, COL_PROTOCOL))
-        			col_add_str(fd, COL_PROTOCOL, "Vines");
-						if (check_col(fd, COL_INFO))
-        			col_add_fstr(fd, COL_INFO, "VSPP (%02x)", iph.vip_proto);
-        		break;
-      		case VINES_DATA:
-						if (check_col(fd, COL_PROTOCOL))
-	        		col_add_str(fd, COL_PROTOCOL, "Vines IP");
-						if (check_col(fd, COL_INFO))
-  	      		col_add_fstr(fd, COL_INFO, "DATA (%02x)", iph.vip_proto);
-				break;
-      		default:
-						if (check_col(fd, COL_PROTOCOL))
-    	    		col_add_str(fd, COL_PROTOCOL, "Vines IP");
-						if (check_col(fd, COL_INFO))
-      	  		col_add_fstr(fd, COL_INFO, "Unknown VIP protocol (%02x)", iph.vip_proto);
-    		}
+  	viph.vip_chksum = pntohs(&pd[offset]);
+  	viph.vip_pktlen = pntohs(&pd[offset+2]);
+  	viph.vip_dnet = pntohl(&pd[offset+6]);
+  	viph.vip_snet = pntohl(&pd[offset+12]);
+  	viph.vip_dsub = pntohs(&pd[offset+10]);
+  	viph.vip_ssub = pntohs(&pd[offset+16]);
+
+    	switch (viph.vip_proto) {
+       	case VIP_PROTO_IPC:
+		if (check_col(fd, COL_PROTOCOL))
+			col_add_str(fd, COL_PROTOCOL, "Vines IPC");
+		if (check_col(fd, COL_INFO))
+			col_add_fstr(fd, COL_INFO, "IPC (%02x)", viph.vip_proto);
+ 		break;
+       	case VIP_PROTO_SPP:      
+		if (check_col(fd, COL_PROTOCOL))
+        		col_add_str(fd, COL_PROTOCOL, "Vines SPP");
+		if (check_col(fd, COL_INFO))
+			col_add_fstr(fd, COL_INFO, "SPP (%02x)", viph.vip_proto);
+		break;
+	case VIP_PROTO_ARP:
+		if (check_col(fd, COL_PROTOCOL))
+			col_add_str(fd, COL_PROTOCOL, "Vines ARP");
+		if (check_col(fd, COL_INFO))
+			col_add_fstr(fd, COL_INFO, "ARP (%02x)", viph.vip_proto);
+		break;
+	case VIP_PROTO_RTP:
+		if (check_col(fd, COL_PROTOCOL))
+			col_add_str(fd, COL_PROTOCOL, "Vines RTP");
+		if (check_col(fd, COL_INFO))
+			col_add_fstr(fd, COL_INFO, "RTP (%02x)", viph.vip_proto);
+		break;
+	case VIP_PROTO_ICP:
+		if (check_col(fd, COL_PROTOCOL))
+			col_add_str(fd, COL_PROTOCOL, "Vines ICP");
+		if (check_col(fd, COL_INFO))
+			col_add_fstr(fd, COL_INFO, "ICP (%02x)", viph.vip_proto);
+		break;
+	default:
+		if (check_col(fd, COL_PROTOCOL))
+			col_add_str(fd, COL_PROTOCOL, "Vines IP");
+		if (check_col(fd, COL_INFO))
+			col_add_fstr(fd, COL_INFO, "Unknown VIP protocol (%02x)", viph.vip_proto);
+	}
 
 			if (check_col(fd, COL_RES_NET_SRC))
-  	  	col_add_fstr(fd, COL_RES_NET_SRC, "%08x.%04x", iph.vip_snet, iph.vip_ssub);
+  	  	col_add_fstr(fd, COL_RES_NET_SRC, "%08x.%04x", viph.vip_snet, viph.vip_ssub);
 			if (check_col(fd, COL_RES_NET_DST))
-    		col_add_fstr(fd, COL_RES_NET_DST, "%08x.%04x", iph.vip_dnet, iph.vip_dsub);
+    		col_add_fstr(fd, COL_RES_NET_DST, "%08x.%04x", viph.vip_dnet, viph.vip_dsub);
+
+ 	/* helpers to decode flags */
+	/* FIXME: Not used yet */
+ 	if ((viph.vip_dnet == 0xffffffff) && (viph.vip_dsub == 0xffff)) {
+ 		is_broadcast = 1;
+ 	}
+ 	hops = viph.vip_tctl & 0xf; 
+ 
   /*
-  	iph.ip_tos = IPTOS_TOS(iph.ip_tos);
-  	switch (iph.ip_tos) 
+  	viph.ip_tos = IPTOS_TOS(viph.ip_tos);
+  	switch (viph.ip_tos) 
   		{
     	case IPTOS_NONE:
     	  	strcpy(tos_str, "None");
@@ -116,71 +199,71 @@
   */
   	if (tree) 
   		{
-    	ti = add_item_to_tree(GTK_WIDGET(tree), offset, (iph.vip_len),
+    	ti = add_item_to_tree(GTK_WIDGET(tree), offset, (viph.vip_pktlen),
       		"Vines IP");
     	vip_tree = gtk_tree_new();
     	add_subtree(ti, vip_tree, ETT_VINES);
-    	add_item_to_tree(vip_tree, offset,      2, "Header checksum: 0x%04x", iph.vip_sum);
-    	add_item_to_tree(vip_tree, offset +  2, 2, "Header length: 0x%02x (%d)", iph.vip_len, iph.vip_len); 
+    	add_item_to_tree(vip_tree, offset,      2, "Packet checksum: 0x%04x", viph.vip_chksum);
+    	add_item_to_tree(vip_tree, offset +  2, 2, "Packet length: 0x%04x (%d)", viph.vip_pktlen, viph.vip_pktlen); 
     	add_item_to_tree(vip_tree, offset +  4, 1, "Transport control: 0x%02x",
-      		iph.vip_tos);
-    	add_item_to_tree(vip_tree, offset +  5, 1, "Protocol: 0x%02x", iph.vip_proto);
+      		viph.vip_tctl);
+    	add_item_to_tree(vip_tree, offset +  5, 1, "Protocol: 0x%02x", viph.vip_proto);
   		}
 
 
   	offset += 18;
-	switch (iph.vip_proto) 
+	switch (viph.vip_proto) 
 		{
-    	case VINES_VSPP:
-	      	dissect_vspp(pd, offset, fd, tree); 
+    	case VIP_PROTO_SPP:
+		dissect_vines_spp(pd, offset, fd, tree);
     		break;
   		}
 	}
 #define VINES_VSPP_DATA 1
 #define VINES_VSPP_ACK 5
-void dissect_vspp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) 
+void dissect_vines_spp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) 
 	{
-  	e_vspp       iph;
+  	e_vspp       viph;
   	GtkWidget *vspp_tree, *ti;
-/*  	gchar      tos_str[32];*/
 
   /* To do: check for runts, errs, etc. */
   /* Avoids alignment problems on many architectures. */
-  	memcpy(&iph, &pd[offset], sizeof(e_vspp));
+  	memcpy(&viph, &pd[offset], sizeof(e_vspp));
 
-  	iph.vspp_sport = ntohs(iph.vspp_sport);
-  	iph.vspp_dport = ntohs(iph.vspp_dport);
-  	iph.vspp_lclid = ntohs(iph.vspp_lclid);
-  	iph.vspp_rmtid = ntohs(iph.vspp_rmtid);
+  	viph.vspp_sport = ntohs(viph.vspp_sport);
+  	viph.vspp_dport = ntohs(viph.vspp_dport);
+  	viph.vspp_lclid = ntohs(viph.vspp_lclid);
+  	viph.vspp_rmtid = ntohs(viph.vspp_rmtid);
 
-    switch (iph.vspp_pkttype) 
+    switch (viph.vspp_pkttype) 
     	{
-      	case VINES_VSPP_DATA:      
+      	case VSPP_PKTTYPE_DATA:      
 					if (check_col(fd, COL_PROTOCOL))
-   	    		col_add_str(fd, COL_PROTOCOL, "Vines");
-					if (check_col(fd, COL_INFO))
-        		col_add_fstr(fd, COL_INFO, "VSPP Data Port=%04x(Transient) NS=%04x NR=%04x Window=%04x RID=%04x LID=%04x D=%04x S=%04x", 
-	        		iph.vspp_sport, iph.vspp_seq, iph.vspp_ack, iph.vspp_win, iph.vspp_rmtid,
-  	      		iph.vspp_lclid, iph.vspp_dport, iph.vspp_sport);
+			col_add_str(fd, COL_PROTOCOL, "VSPP Data");
         	break;
-      	case VINES_VSPP_ACK:
+      	case VSPP_PKTTYPE_DISC:      
 					if (check_col(fd, COL_PROTOCOL))
-   	    		col_add_str(fd, COL_PROTOCOL, "Vines");
-					if (check_col(fd, COL_INFO))
-        		col_add_fstr(fd, COL_INFO, "VSPP Ack Port=%04x(Transient) NS=%04x NR=%04x Window=%04x RID=%04x LID=%04x", 
-	        		iph.vspp_sport, iph.vspp_seq, iph.vspp_ack, iph.vspp_win, iph.vspp_rmtid,
-  	      		iph.vspp_lclid);
-
-			break;
+			col_add_str(fd, COL_PROTOCOL, "VSPP Disconnect");
+        	break;
+      	case VSPP_PKTTYPE_PROBE:      
+					if (check_col(fd, COL_PROTOCOL))
+			col_add_str(fd, COL_PROTOCOL, "VSPP Probe");
+        	break;
+      	case VSPP_PKTTYPE_ACK:
+					if (check_col(fd, COL_PROTOCOL))
+   	    		col_add_str(fd, COL_PROTOCOL, "VSPP Ack");
+		break;
       	default:
 					if (check_col(fd, COL_PROTOCOL))
-   	    		col_add_str(fd, COL_PROTOCOL, "Vines IP");
-					if (check_col(fd, COL_INFO))
-        		col_add_fstr(fd, COL_INFO, "Unknown VSPP packet type (%02x)", iph.vspp_pkttype);
+   	    		col_add_str(fd, COL_PROTOCOL, "VSPP Unknown");
     	}
+	if (check_col(fd, COL_INFO))
+       		col_add_fstr(fd, COL_INFO, "NS=%04x NR=%04x Window=%04x RID=%04x LID=%04x D=%04x S=%04x", 
+			viph.vspp_seqno, viph.vspp_ack, viph.vspp_win, viph.vspp_rmtid,
+       			viph.vspp_lclid, viph.vspp_dport, viph.vspp_sport);
   /*
-  	iph.ip_tos = IPTOS_TOS(iph.ip_tos);
-  	switch (iph.ip_tos) 
+	iph.ip_tos = IPTOS_TOS(iph.ip_tos);
+	switch (iph.ip_tos)
   		{
     	case IPTOS_NONE:
     	  	strcpy(tos_str, "None");
@@ -204,19 +287,19 @@
 */ 
   	if (tree) 
   		{
-    	ti = add_item_to_tree(GTK_WIDGET(tree), offset, sizeof(iph),
+    	ti = add_item_to_tree(GTK_WIDGET(tree), offset, sizeof(viph),
       		"Vines SPP");
     	vspp_tree = gtk_tree_new();
-    	add_subtree(ti, vspp_tree, ETT_VSPP);
-    	add_item_to_tree(vspp_tree, offset,      2, "Source port: 0x%04x", iph.vspp_sport);
-    	add_item_to_tree(vspp_tree, offset+2,    2, "Destination port: 0x%04x", iph.vspp_dport); 
-    	add_item_to_tree(vspp_tree, offset+4,    1, "Packet type: 0x%02x", iph.vspp_pkttype);
-    	add_item_to_tree(vspp_tree, offset+5,    1, "Control: 0x%02x", iph.vspp_tos);
-    	add_item_to_tree(vspp_tree, offset+6,    2, "Local Connection ID: 0x%04x", iph.vspp_lclid);
-    	add_item_to_tree(vspp_tree, offset+8,    2, "Remote Connection ID: 0x%04x", iph.vspp_rmtid);
-    	add_item_to_tree(vspp_tree, offset+10,   2, "Sequence number: 0x%04x", iph.vspp_seq);
-    	add_item_to_tree(vspp_tree, offset+12,   2, "Ack number: 0x%04x", iph.vspp_ack);
-    	add_item_to_tree(vspp_tree, offset+14,   2, "Window: 0x%04x", iph.vspp_win);
+    	add_subtree(ti, vspp_tree, ETT_VINES_SPP);
+    	add_item_to_tree(vspp_tree, offset,      2, "Source port: 0x%04x", viph.vspp_sport);
+    	add_item_to_tree(vspp_tree, offset+2,    2, "Destination port: 0x%04x", viph.vspp_dport); 
+    	add_item_to_tree(vspp_tree, offset+4,    1, "Packet type: 0x%02x", viph.vspp_pkttype);
+    	add_item_to_tree(vspp_tree, offset+5,    1, "Control: 0x%02x", viph.vspp_control);
+    	add_item_to_tree(vspp_tree, offset+6,    2, "Local Connection ID: 0x%04x", viph.vspp_lclid);
+    	add_item_to_tree(vspp_tree, offset+8,    2, "Remote Connection ID: 0x%04x", viph.vspp_rmtid);
+    	add_item_to_tree(vspp_tree, offset+10,   2, "Sequence number: 0x%04x", viph.vspp_seqno);
+    	add_item_to_tree(vspp_tree, offset+12,   2, "Ack number: 0x%04x", viph.vspp_ack);
+    	add_item_to_tree(vspp_tree, offset+14,   2, "Window: 0x%04x", viph.vspp_win);
   		}
 
 	}
--- ./packet-vines.h.distrib	Sun Nov  8 23:51:16 1998
+++ ./packet-vines.h	Fri Nov 27 02:17:55 1998
@@ -8,6 +8,7 @@
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@xxxxxxxx>
  * Copyright 1998 Gerald Combs
+ * Joerg Mayer <jmayer@xxxxxxxxxxxxx>
  *
  * 
  * This program is free software; you can redistribute it and/or
@@ -25,35 +26,57 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
+/* Information about VINES can be found in
+ *
+ * VINES Protocol Definition
+ * Order Number: DA254-00
+ * Banyan Systems incorporated
+ * February 1990
+ * Part Number: 092093-000
+ */
 
 #ifndef __PACKETVINES_H__
 #define __PACKETVINES_H__
 
 /* VINES IP structs and definitions */
 
+enum {
+  VIP_PROTO_IPC = 1,	 /* Interprocess Communications Protocol (IPC) */
+  VIP_PROTO_SPP = 2,	/* Sequenced Packet Protcol (SPP) */
+  VIP_PROTO_ARP = 4,	/* Address Resolution Protocol (ARP) */
+  VIP_PROTO_RTP = 5,	/* Routing Update Protocol (RTP) / SRTP (Sequenced RTP) */
+  VIP_PROTO_ICP = 6	/* Internet Control Protocol (ICP) */
+};
+
 typedef struct _e_vip {
-  guint16 vip_sum;
-  guint16 vip_len;
-  guint8  vip_tos;
-  guint8  vip_proto;    /* 2 = VSPP */
+  guint16 vip_chksum;
+  guint16 vip_pktlen;
+  guint8  vip_tctl;	/* Transport Control */
+  guint8  vip_proto;
   guint32 vip_dnet;
   guint16 vip_dsub;
   guint32 vip_snet;
   guint16 vip_ssub;
-
 } e_vip;
 
 /* VINES SPP structs and definitions */
 
+enum {
+  VSPP_PKTTYPE_DATA = 1,	/* User Data */
+  VSPP_PKTTYPE_DISC = 3,	/* Diconnect Request */
+  VSPP_PKTTYPE_PROBE = 4,	/* Probe (retransmit) */
+  VSPP_PKTTYPE_ACK = 5		/* Acknowledgement */
+};
+
 typedef struct _e_vspp {
   guint16 vspp_sport;
   guint16 vspp_dport;
-  guint8  vspp_pkttype; /* 5=ack 1=data */
-  guint8  vspp_tos;  /* Unused with type 5 packets */
-  guint16 vspp_lclid;
-  guint16 vspp_rmtid;
-  guint16 vspp_seq; 
-  guint16 vspp_ack;
+  guint8  vspp_pkttype;
+  guint8  vspp_control;
+  guint16 vspp_lclid;	/* Local Connection ID */
+  guint16 vspp_rmtid;	/* Remote Connection ID */
+  guint16 vspp_seqno;	/* Sequence Number */
+  guint16 vspp_ack;	/* Acknowledgement Number */
   guint16 vspp_win;
 } e_vspp;