linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* question on ip_masq_irc.c
@ 2001-03-29 11:48 Deja User
  2001-03-29 17:55 ` S. Shore
  0 siblings, 1 reply; 2+ messages in thread
From: Deja User @ 2001-03-29 11:48 UTC (permalink / raw)
  To: linux-kernel

Hi all,
I am working on a NAT product and trying provide mIRC support in it. I am looking into ip_masq_irc.c file of Linux 2.2.12 for reference, and have some doubts.
1. In 2.2.12 ip_masq_irc.c, DCC RESUME protocol is not supported. In which patch can I find it?
2. I have pre-patch-2.2.18-5 linux.18p5/net/ipv4/ip_masq_irc.c, which has support for DCC RESUME. Is this the final patch? I have checked with documentation in mIRC help files about DCC RESUME command string. It says the command string in the pay load looks 
   DCC RESUME filename port position
   But, in the above file, the string hunted is 
   "\1DCC RESUME chat AAAAAAAA P\1\n"

Can anybody please clarify, what exactly should be searched?

thanks in advance
--Amar







------------------------------------------------------------
--== Sent via Deja.com ==--
http://www.deja.com/



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: question on ip_masq_irc.c
  2001-03-29 11:48 question on ip_masq_irc.c Deja User
@ 2001-03-29 17:55 ` S. Shore
  0 siblings, 0 replies; 2+ messages in thread
From: S. Shore @ 2001-03-29 17:55 UTC (permalink / raw)
  To: Deja User; +Cc: linux-kernel

On Thu, 29 Mar 2001, Deja User wrote:
> I am working on a NAT product and trying provide mIRC support in it. I am looking into ip_masq_irc.c file of Linux 2.2.12 for reference, and have some doubts.
> 1. In 2.2.12 ip_masq_irc.c, DCC RESUME protocol is not supported. In which patch can I find it?
> 2. I have pre-patch-2.2.18-5 linux.18p5/net/ipv4/ip_masq_irc.c, which has support for DCC RESUME. Is this the final patch? I have checked with documentation in mIRC help files about DCC RESUME command string. It says the command string in the pay load looks
>    DCC RESUME filename port position
>    But, in the above file, the string hunted is
>    "\1DCC RESUME chat AAAAAAAA P\1\n"

You're right, it's broken. I submitted a patch for people to test, but
somehow it got into the production kernel without testing.

I created a second patch shortly after realizing the problem, tested and
submitted it, but it doesn't look like it ever made it in.

I'm including the patch. It's a diff against the ip_masq_irc.c from 2.2.17
(which was current at the time), so you may have to get this file
seperately if you're not using 2.2.17. Many apologies.

Scottie Shore                | "Experience is the worst teacher -
<sshore@escape.ca>           |  it teaches you what you need to know
			     |  after you needed to know it."

--- ip_masq_irc.c.orig	Wed Sep 27 22:07:15 2000
+++ ip_masq_irc.c	Sun Oct  1 21:30:41 2000
@@ -20,9 +20,11 @@
  *	Juan Jose Ciarlante	:  put new ms entry to listen()
  *	Scottie Shore		:  added support for clients that add extra args
  *	  <sshore@escape.ca>
+ *	Scottie Shore		:  added support for mIRC DCC resume negotiation
+ *	  <sshore@escape.ca>
  *
- * FIXME:
- *	- detect also previous "PRIVMSG" string ?.
+ * FIXME: take common code from ip_masq_in and ip_masq_out, put into seperate
+ *        function
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -78,22 +80,24 @@
  * List of supported DCC protocols
  */

-#define NUM_DCCPROTO 5
+#define NUM_DCCPROTO 6

 struct dccproto
 {
   char *match;
   int matchlen;
+  int addr;
 };

 struct dccproto dccprotos[NUM_DCCPROTO] = {
- { "SEND ", 5 },
- { "CHAT ", 5 },
- { "MOVE ", 5 },
- { "TSEND ", 6 },
- { "SCHAT ", 6 }
+ { "SEND ", 5, 1 },
+ { "CHAT ", 5, 1 },
+ { "MOVE ", 5, 1 },
+ { "TSEND ", 6, 1 },
+ { "SCHAT ", 6, 1 },
+ { "ACCEPT ", 7, 0 },
 };
-#define MAXMATCHLEN 6
+#define MAXMATCHLEN 7

 static int
 masq_irc_init_1 (struct ip_masq_app *mapp, struct ip_masq *ms)
@@ -118,7 +122,7 @@
 	char *data, *data_limit;
 	__u32 s_addr;
 	__u16 s_port;
-	struct ip_masq *n_ms;
+	struct ip_masq *n_ms = NULL;
 	char buf[20];		/* "m_addr m_port" (dec base)*/
         unsigned buf_len;
 	int diff;
@@ -137,16 +141,18 @@
 	 *	strlen("\1DCC SEND F AAAAAAAA P S\1\n")=26
 	 *	strlen("\1DCC MOVE F AAAAAAAA P S\1\n")=26
 	 *	strlen("\1DCC TSEND F AAAAAAAA P S\1\n")=27
+	 *	strlen("\1DCC ACCEPT F P O\1\n")=19
 	 *		AAAAAAAAA: bound addr (1.0.0.0==16777216, min 8 digits)
 	 *		P:         bound port (min 1 d )
 	 *		F:         filename   (min 1 d )
 	 *		S:         size       (min 1 d )
+	 *		O:	   offset     (min 1 d )
 	 *		0x01, \n:  terminators
          */

         data_limit = skb->h.raw + skb->len;

-	while (data < (data_limit - ( 22 + MAXMATCHLEN ) ) )
+	while (data < (data_limit - ( 12 + MAXMATCHLEN ) ) )
 	{
 		int i;
 		if (memcmp(data,"\1DCC ",5))  {
@@ -171,52 +177,60 @@
 				 *	skip next string.
 				 */

-				while( *data++ != ' ')
+				while ( *data++ != ' ')
+					if (data > (data_limit-5)) return 0;
+				addr_beg_p = data;

+				if (dccprotos[i].addr == 1)
+				{
 					/*
-					 *	must still parse, at least, "AAAAAAAA P\1\n",
-					 *      12 bytes left.
+					 *	client bound address in dec base
 					 */
-					if (data > (data_limit-12)) return 0;
-
-
-				addr_beg_p = data;

-				/*
-				 *	client bound address in dec base
-				 */
-
-				s_addr = simple_strtoul(data,&data,10);
-				if (*data++ !=' ')
-					continue;
+					s_addr = simple_strtoul(data,&data,10);
+					if (*data++ !=' ')
+						continue;

-				/*
-				 *	client bound port in dec base
-				 */
+					/*
+					 *	client bound port in dec base
+					 */

-				s_port = simple_strtoul(data,&data,10);
-				addr_end_p = data;
+					s_port = simple_strtoul(data,&data,10);
+					addr_end_p = data;

-				/*
-				 *	Now create an masquerade entry for it
-				 * 	must set NO_DPORT and NO_DADDR because
-				 *	connection is requested by another client.
-				 */
+					/*
+					 * 	We must set NO_DPORT and NO_DADDR because
+					 *	connection is requested by another client.
+					 */

-				n_ms = ip_masq_new(IPPROTO_TCP,
+					n_ms = ip_masq_new(IPPROTO_TCP,
 						maddr, 0,
 						htonl(s_addr),htons(s_port),
 						0, 0,
 						IP_MASQ_F_NO_DPORT|IP_MASQ_F_NO_DADDR);
-				if (n_ms==NULL)
-					return 0;

-				/*
-				 * Replace the old "address port" with the new one
-				 */
+					if (n_ms==NULL)
+						return 0;
+					ip_masq_listen(n_ms);

-				buf_len = sprintf(buf,"%lu %u",
+					/*
+					 * Replace the old "address port" with the new one
+					 */
+					buf_len = sprintf(buf,"%lu %u",
 						ntohl(n_ms->maddr),ntohs(n_ms->mport));
+				} else {
+					/* client bound port in decimal */
+					s_port = simple_strtoul(data,&data,10);
+					addr_end_p = data;
+
+					n_ms = ip_masq_out_get (IPPROTO_TCP,
+						ms->saddr,htons(s_port),
+						0, 0);
+					if (n_ms == NULL)
+						return 0;
+
+					buf_len = sprintf(buf,"%u",ntohs(n_ms->mport));
+				}

 				/*
 				 * Calculate required delta-offset to keep TCP happy
@@ -242,7 +256,6 @@
 							addr_beg_p, addr_end_p-addr_beg_p,
 							buf, buf_len);
 				}
-				ip_masq_listen(n_ms);
 				ip_masq_put(n_ms);
 				return diff;
 			}
@@ -252,6 +265,122 @@

 }

+int
+masq_irc_in (struct ip_masq_app *mapp, struct ip_masq *ms, struct sk_buff **skb_p, __u32 maddr)
+{
+        struct sk_buff *skb;
+	struct iphdr *iph;
+	struct tcphdr *th;
+	char *data, *data_limit;
+	__u32 s_addr;
+	__u16 s_port;
+	struct ip_masq *n_ms;
+	char buf[20];		/* "m_addr m_port" (dec base)*/
+        unsigned buf_len;
+	int diff;
+        char *dcc_p, *addr_beg_p, *addr_end_p;
+
+        skb = *skb_p;
+	iph = skb->nh.iph;
+        th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);
+        data = (char *)&th[1];
+
+        /*
+	 *	Hunt irc DCC RESUME string:
+	 *
+	 *	strlen("\1DCC RESUME F P O\1\n")=19
+	 *		F:         filename   (min 1 c )
+	 *		P:         bound port (min 1 d )
+	 *		O:	   offset     (min 1 d )
+	 *		0x01, \n:  terminators
+         */
+
+        data_limit = skb->h.raw + skb->len;
+
+	while (data < (data_limit - 19 ) )
+	{
+		if (memcmp(data,"\1DCC RESUME ",12))  {
+			data ++;
+			continue;
+		}
+
+		dcc_p = data;
+		data += 12;
+
+		while( *data++ != ' ')
+			/*
+			 *	must still parse, at least, "F P O\1\n",
+			 *      7 bytes left.
+			 */
+			if (data > (data_limit-7)) return 0;
+
+
+		addr_beg_p = data;
+
+		/*
+		 *	masq bound port in dec base
+		 */
+
+		s_port = simple_strtoul(data,&data,10);
+		addr_end_p = data;
+
+		/*
+		 *	Find the masq entry associated with this connection.
+		 *	The entry should have no dest addr/port yet.
+		 *	If there is no entry, return 0.
+		 *
+		 *	mIRC & co. assume that a port can uniquely identify
+		 *	a connection. It's true 99% of the time, but it's still
+		 *	a stupid assumption.
+		 */
+
+		n_ms = ip_masq_in_get(IPPROTO_TCP,
+			0, 0,
+			ms->maddr, htons(s_port));
+
+		if (n_ms==NULL) {
+			return 0;
+		} else {
+			ip_masq_put(n_ms);
+		}
+
+		/*
+		 * Replace the outside address with the inside address
+		 */
+
+		buf_len = sprintf(buf,"%u",
+			ntohs(n_ms->sport));
+
+		/*
+		 * Calculate required delta-offset to keep TCP happy
+		 */
+
+		diff = buf_len - (addr_end_p-addr_beg_p);
+
+		*addr_beg_p = '\0';
+
+		/*
+		 *	No shift.
+		 */
+
+		if (diff==0) {
+			/*
+			 * simple case, just copy.
+			 */
+			memcpy(addr_beg_p,buf,buf_len);
+		} else {
+			*skb_p = ip_masq_skb_replace(skb, GFP_ATOMIC,
+				addr_beg_p, addr_end_p-addr_beg_p,
+				buf, buf_len);
+		}
+
+		return diff;
+
+	}
+	return 0;
+
+}
+
 /*
  *	Main irc object
  *     	You need 1 object per port in case you need
@@ -263,12 +392,12 @@
 struct ip_masq_app ip_masq_irc = {
         NULL,			/* next */
 	"irc",			/* name */
-        0,                      /* type */
-        0,                      /* n_attach */
-        masq_irc_init_1,        /* init_1 */
-        masq_irc_done_1,        /* done_1 */
-        masq_irc_out,           /* pkt_out */
-        NULL                    /* pkt_in */
+        0,			/* type */
+        0,			/* n_attach */
+        masq_irc_init_1,	/* init_1 */
+        masq_irc_done_1,	/* done_1 */
+        masq_irc_out,		/* pkt_out */
+        masq_irc_in		/* pkt_in */
 };

 /*



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2001-03-29 17:56 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-03-29 11:48 question on ip_masq_irc.c Deja User
2001-03-29 17:55 ` S. Shore

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).