Ethereal-dev: [Ethereal-dev] Passive FTP patch

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

From: Juan Toledo <toledo@xxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 11 May 2001 18:14:15 +0200
Included is a patch to add support for passive ftp packets.
I've read README.developer and I've tried to follow every
convention, but this is my first contribution and I might
have done things wrong, I don't know.

I've tested it against ncftp and mozilla ftp transactions, and
works with both.

I might have also found a bug, I don't know: When trying
to isolate ftp-passive packets using the display filter, ethereal
complains with

  The string "passive" was unexpected in this context

It would seem that either the parser should be fixed or no protocols
should have a dash in the name. That would affect ftp-passive, ftp-data,
stat-cb, wap-wsp, wap-wsp-wtp and wap-wtls

Regards,
Juan.
-- 
EtherApe, a graphical network monitor modeled after etherman
http://etherape.sourceforge.net/
Index: AUTHORS
===================================================================
RCS file: /cvsroot/ethereal/AUTHORS,v
retrieving revision 1.234
diff -u -r1.234 AUTHORS
--- AUTHORS	2001/05/11 01:09:59	1.234
+++ AUTHORS	2001/05/11 15:59:03
@@ -614,6 +614,10 @@
 	LDAP checks for invalid packets
 }
 
+Juan Toledo <toledo@xxxxxxxxxxxxxxxxxxxxx> {
+	Passive FTP support
+}
+
 Alain Magloire <alainm@xxxxxxxxxxxxxxxxxx> was kind enough to
 give his permission to use his version of snprintf.c.
 
Index: packet-ftp.c
===================================================================
RCS file: /cvsroot/ethereal/packet-ftp.c,v
retrieving revision 1.27
diff -u -r1.27 packet-ftp.c
--- packet-ftp.c	2001/01/22 08:03:45	1.27
+++ packet-ftp.c	2001/05/11 15:59:04
@@ -1,7 +1,8 @@
 /* packet-ftp.c
  * Routines for ftp packet dissection
  * Copyright 1999, Richard Sharpe <rsharpe@xxxxxxxxxx>
- *
+ * Copyright 2001, Juan Toledo <toledo@xxxxxxxxxxxxxxxxxxxxx> (Passive FTP)
+ * 
  * $Id: packet-ftp.c,v 1.27 2001/01/22 08:03:45 guy Exp $
  *
  * Ethereal - Network traffic analyzer
@@ -44,9 +45,11 @@
 #include <glib.h>
 #include "packet.h"
 #include "strutil.h"
+#include "conversation.h"
 
 static int proto_ftp = -1;
 static int proto_ftp_data = -1;
+static int proto_ftp_passive = -1;
 static int hf_ftp_response = -1;
 static int hf_ftp_request = -1;
 static int hf_ftp_request_command = -1;
@@ -56,11 +59,42 @@
 
 static gint ett_ftp = -1;
 static gint ett_ftp_data = -1;
+static gint ett_ftp_passive = -1;
 
 #define TCP_PORT_FTPDATA		20
 #define TCP_PORT_FTP			21
 
 static void
+dissect_ftp_passive(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+        proto_tree      *ti, *ftp_passive_tree;
+        int		data_length;
+
+	if (check_col(pinfo->fd, COL_PROTOCOL))
+		col_set_str(pinfo->fd, COL_PROTOCOL, "FTP-PASSIVE");
+
+	if (check_col(pinfo->fd, COL_INFO)) {
+		col_add_fstr(pinfo->fd, COL_INFO, "FTP Passive Data: %u bytes",
+		    tvb_length(tvb));
+	}
+
+	if (tree) {
+		data_length = tvb_length(tvb);
+
+		ti = proto_tree_add_item(tree, proto_ftp_passive, tvb, 0,
+		    data_length, FALSE);
+		ftp_passive_tree = proto_item_add_subtree(ti, ett_ftp_passive);
+
+		/*
+		 * XXX - if this is binary data, it'll produce
+		 * a *really* long line.
+		 */
+		proto_tree_add_text(ftp_passive_tree, tvb, 0, data_length,
+		    "FTP Passive Data: %s", tvb_format_text(tvb, 0, data_length));
+	}
+}
+
+static void
 dissect_ftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
         gboolean        is_request;
@@ -68,6 +102,7 @@
 	proto_item	*ti;
 	gint		offset = 0;
 	const u_char	*line;
+	guint16		passive_port = 0;
 	gint		next_offset;
 	int		linelen;
 	int		tokenlen;
@@ -100,6 +135,46 @@
 		    is_request ? "Request" : "Response",
 		    format_text(line, linelen));
 	}
+   
+	/*
+	 * Check for passive ftp response. Such response is in the form
+	 * 227 some_text (a,b,c,d,p1,p2) , where a.b.c.d is the IP address
+	 * of the server, and p1, p2 are the hi and low bytes of the tcp
+	 * port the server will open for the client to connect to.
+	 */
+	tokenlen = get_token_len(line, line + linelen, &next_token);
+	if (tokenlen!=0 && !strcmp ("227", format_text (line, tokenlen)))
+	  {
+		u_char          *token;
+		gint		hi_byte;
+		gint		low_byte;
+		guint8 		i;
+		  
+		strtok (format_text(line, linelen), "(,)");
+		for (i = 1; i <= 4; i++)
+	          strtok (NULL, "(,)");
+		  
+		if ( (token = strtok (NULL, "(,)")) && sscanf (token, "%d", &hi_byte)
+		  && (token = strtok (NULL, "(,)")) && sscanf (token, "%d", &low_byte) )
+		  passive_port = hi_byte * 256 + low_byte;
+	  }
+	
+	/*
+	 * If a passive response has been found and a conversation,
+	 * was not registered already, register the new conversation
+	 * and dissector
+	 */
+	if (passive_port && !find_conversation(&pinfo->src, &pinfo->dst, PT_TCP,
+					       passive_port, 0, NO_DST_PORT))
+	  {
+		conversation_t 	*conversation;
+		  
+		conversation = conversation_new(&pinfo->src, &pinfo->dst, PT_TCP,
+						  passive_port, 0, NULL,
+						  NO_DST_PORT);
+		conversation_set_dissector(conversation, dissect_ftp_passive);
+
+	  }
 
 	if (tree) {
 		ti = proto_tree_add_item(tree, proto_ftp, tvb, offset,
@@ -248,11 +323,13 @@
   static gint *ett[] = {
     &ett_ftp,
     &ett_ftp_data,
+    &ett_ftp_passive,
   };
 
   proto_ftp = proto_register_protocol("File Transfer Protocol (FTP)", "FTP",
 				      "ftp");
   proto_ftp_data = proto_register_protocol("FTP Data", "FTP-DATA", "ftp-data");
+  proto_ftp_passive = proto_register_protocol("FTP Passive Data", "FTP-PASSIVE", "ftp-passive");
   proto_register_field_array(proto_ftp, hf, array_length(hf));
   proto_register_subtree_array(ett, array_length(ett));
 }
@@ -262,4 +339,5 @@
 {
   dissector_add("tcp.port", TCP_PORT_FTPDATA, &dissect_ftpdata, proto_ftp_data);
   dissector_add("tcp.port", TCP_PORT_FTP, &dissect_ftp, proto_ftp_data);
+  conv_dissector_add ("tcp", &dissect_ftp_passive, proto_ftp_passive);
 }
Index: doc/ethereal.pod.template
===================================================================
RCS file: /cvsroot/ethereal/doc/ethereal.pod.template,v
retrieving revision 1.174
diff -u -r1.174 doc/ethereal.pod.template
--- doc/ethereal.pod.template	2001/05/08 19:46:32	1.174
+++ doc/ethereal.pod.template	2001/05/11 15:59:09
@@ -1101,6 +1101,7 @@
   Christian Lacunza        <celacunza@xxxxxxx>
   Michael Rozhavsky        <mike@xxxxxxxxxxxxxxxxxxxxx>
   Scott Renfro             <scott@xxxxxxxxxx>
+  Juan Toledo              <toledo@xxxxxxxxxxxxxxxxxxxxx>
 
 Alain Magloire <alainm@xxxxxxxxxxxxxxxxxx> was kind enough to give his
 permission to use his version of snprintf.c.