All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] wanted: testers for ip_nat_cuseeme module
@ 2002-11-05  1:37 Filip Sneppe (Cronos)
  2002-11-05  6:17 ` Kevin McConnell
  0 siblings, 1 reply; 4+ messages in thread
From: Filip Sneppe (Cronos) @ 2002-11-05  1:37 UTC (permalink / raw)
  To: netfilter-devel, netfilter; +Cc: james

[-- Attachment #1: Type: text/plain, Size: 2569 bytes --]

Hi,

(cross-post to netfilter-devel & netfilter)

As per James' request, I've written a cuseeme nat module for 
netfilter/iptables.

Since I am not a CuSeeMe user (and I don't even have a webcam or 
any other video conferencing hardware), I'd like some more people 
to test it out and report their success/failure stories to me privately,
before I submit this code for patch-o-matic. Discussions about
the code are best kept on netfilter-devel though, etc...

At the very least, the module should allow SNAT/MASQUERADE like the
2.2 ip_masq_cuseeme module. DNAT should also work. 

Some points of attention:

- My patch requires the newnat-udp-helper.patch written by
  Brian J. Murrell that is currently pending for kernel
  inclusion, as it makes use of "ip_nat_mangle_udp_packet()".
  I guess that patch won't make it in 2.4.20, so you'll have
  to get it from CVS (patch-o-matic/pending/newnat-udp-helper.patch)
  or here: 
http://cvs.netfilter.org/cgi-bin/cvsweb/netfilter/patch-o-matic/pending/newnat-udp-helper.patch

  and apply it manually.

- You will find that there is only an ip_nat_cuseeme module.
  Since there are no random ports being opened, but payloads
  do contain embedded IP addresses, there is only a need for
  packet payload "mangling" in NAT scenarios.
  I was quite happy to find out that netfilter/iptables
  happily supports this!

- If you're running into problems, please let me know. I will
  ask you to recompile with debugging enabled (change the "#if 0" to
  "#if 1" in ip_nat_cuseeme.c), and capture traffic on both sides of 
  the NAT box, so you know ahead.
  I am curious if a lot of people will be getting many messages like 
  this in their system logs:

    expected incoming client 195.162.210.199:7648, but got 0.0.0.0:7648

  This shouldn't happen, but from what I get from the specs,
  it's not always strictly necessary to follow the specs to get
  a working implementation.

Regards,
Filip

ps. Unless someone else has started working on this, I will probably
end up writing a conntrack/nat helper for Microsoft MSN Messenger, 
now that I still have a Windows partition on a test box, so feel free
to volunteer as a tester for that too :-)

-----Original Message-----
From:	James Bryan [mailto:james@penguintowne.com]
Sent:	Sun 27/10/2002 5:47
To:	Sneppe Filip
Cc:	
Subject:	RE: Question about Porting the cu-seeme ipchains module to
iptables.

Filip,
  I haven't found anyone else yet who's ported the module or is working
on it. I'd  be delighted if you could port it over to a conntrack/nat
module. 

Regards,
James



[-- Attachment #2: diff.netfilter.cuseeme.20021104-1 --]
[-- Type: text/x-patch, Size: 17597 bytes --]

diff -urN -X dontdiff linux-2.4.20-pre11/Documentation/Configure.help linux-2.4.20-pre11-msn/Documentation/Configure.help
--- linux-2.4.20-pre11/Documentation/Configure.help	2002-10-29 02:18:22.000000000 +0100
+++ linux-2.4.20-pre11-msn/Documentation/Configure.help	2002-11-05 01:57:49.000000000 +0100
@@ -2508,6 +2508,17 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+CuSeeMe protocol support
+CONFIG_IP_NF_CUSEEME
+  The CuSeeMe conferencing protocol is problematic when used in
+  conjunction with NAT; even though there are no random ports used for
+  extra connections, the messages contain IP addresses inside them.
+  This NAT helper mangles the IP address inside packets so both
+  parties don't get confused.
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  If unsure, say `Y'.
+
 IRC Send/Chat protocol support
 CONFIG_IP_NF_IRC
   There is a commonly-used extension to IRC called
diff -urN -X dontdiff linux-2.4.20-pre11/include/linux/netfilter_ipv4/ip_conntrack_cuseeme.h linux-2.4.20-pre11-msn/include/linux/netfilter_ipv4/ip_conntrack_cuseeme.h
--- linux-2.4.20-pre11/include/linux/netfilter_ipv4/ip_conntrack_cuseeme.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20-pre11-msn/include/linux/netfilter_ipv4/ip_conntrack_cuseeme.h	2002-11-04 18:20:59.000000000 +0100
@@ -0,0 +1,68 @@
+#ifndef _IP_CT_CUSEEME
+#define _IP_CT_CUSEEME
+
+#define CUSEEME_PORT 7648
+
+/* These structs come from the 2.2 ip_masq_cuseeme code... */
+
+/* CuSeeMe data header */
+struct cu_header {
+	u_int16_t	dest_family;
+	u_int16_t	dest_port;
+	u_int32_t	dest_addr;
+	u_int16_t	family;
+	u_int16_t	port;
+	u_int32_t	addr;
+	u_int32_t	seq;
+	u_int16_t	msg;
+	u_int16_t	data_type;
+				/* possible values:
+				 * 1	small video
+				 * 2	big video
+				 * 3	audio
+				 * 100	acknowledge connectivity when there
+				 * 	is nothing else to send
+				 * 101	OpenContinue packet
+				 * 104	display a text message and 
+				 * 	disconnect (used by reflector to
+				 * 	kick clients off)
+				 * 105	display a text message (welcome
+				 * 	message from reflector)
+				 * 106	exchanged among reflectors for
+				 * 	reflector interoperation
+				 * 107	carry aux stream data when there is
+				 *	no video to piggy-back on
+				 * 108	obsolete (used in Mac alpha version)
+				 * 109	obsolete (used in Mac alpha version)
+				 * 110	used for data rate control
+				 * 111	used for data rate control
+				 * 256	aux data control messages
+				 * 257	aux data packets
+				 * */
+	u_int16_t	packet_len;
+};
+
+/* Open Continue Header */
+struct oc_header {
+	struct cu_header	cu_head;
+	u_int16_t	client_count; /* Number of client info structs */
+	u_int32_t	seq_no;
+	char		user_name[20];
+	char		stuff[4];     /* Flags, version stuff, etc */
+};
+
+/* Client info structures */
+struct client_info {
+	u_int32_t	address;      /* Client address */
+	u_int32_t	stuff[8];     /* Flags, pruning bitfield, packet counts, etc */
+};
+
+/* This structure is per expected connection */
+struct ip_ct_cuseeme_expect {
+};
+
+/* This structure exists only once per master */
+struct ip_ct_cuseeme_master {
+};
+
+#endif /* _IP_CT_CUSEEME */
diff -urN -X dontdiff linux-2.4.20-pre11/net/ipv4/netfilter/Config.in linux-2.4.20-pre11-msn/net/ipv4/netfilter/Config.in
--- linux-2.4.20-pre11/net/ipv4/netfilter/Config.in	2002-10-29 02:19:16.000000000 +0100
+++ linux-2.4.20-pre11-msn/net/ipv4/netfilter/Config.in	2002-10-30 00:52:42.000000000 +0100
@@ -8,6 +8,7 @@
 if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
   dep_tristate '  FTP protocol support' CONFIG_IP_NF_FTP $CONFIG_IP_NF_CONNTRACK
   dep_tristate '  IRC protocol support' CONFIG_IP_NF_IRC $CONFIG_IP_NF_CONNTRACK
+  dep_tristate '  CuSeeMe protocol support' CONFIG_IP_NF_CUSEEME $CONFIG_IP_NF_CONNTRACK
 fi
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
@@ -67,6 +69,13 @@
           define_tristate CONFIG_IP_NF_NAT_IRC $CONFIG_IP_NF_NAT
         fi
       fi
+      if [ "$CONFIG_IP_NF_CUSEEME" = "m" ]; then
+        define_tristate CONFIG_IP_NF_NAT_CUSEEME m
+      else
+        if [ "$CONFIG_IP_NF_CUSEEME" = "y" ]; then
+         define_tristate CONFIG_IP_NF_NAT_CUSEEME $CONFIG_IP_NF_NAT
+        fi
+      fi
       # If they want FTP, set to $CONFIG_IP_NF_NAT (m or y), 
       # or $CONFIG_IP_NF_FTP (m or y), whichever is weaker.  Argh.
       if [ "$CONFIG_IP_NF_FTP" = "m" ]; then
diff -urN -X dontdiff linux-2.4.20-pre11/net/ipv4/netfilter/Makefile linux-2.4.20-pre11-msn/net/ipv4/netfilter/Makefile
--- linux-2.4.20-pre11/net/ipv4/netfilter/Makefile	2002-10-29 02:19:16.000000000 +0100
+++ linux-2.4.20-pre11-msn/net/ipv4/netfilter/Makefile	2002-11-02 21:01:26.000000000 +0100
@@ -45,6 +53,7 @@
 # NAT helpers 
 obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o
 obj-$(CONFIG_IP_NF_NAT_IRC) += ip_nat_irc.o
+obj-$(CONFIG_IP_NF_NAT_CUSEEME) += ip_nat_cuseeme.o
 
 # generic IP tables 
 obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
diff -urN -X dontdiff linux-2.4.20-pre11/net/ipv4/netfilter/ip_nat_cuseeme.c linux-2.4.20-pre11-msn/net/ipv4/netfilter/ip_nat_cuseeme.c
--- linux-2.4.20-pre11/net/ipv4/netfilter/ip_nat_cuseeme.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20-pre11-msn/net/ipv4/netfilter/ip_nat_cuseeme.c	2002-11-05 01:45:42.000000000 +0100
@@ -0,0 +1,285 @@
+/* CuSeeMe extension for UDP NAT alteration.
+ * (C) 2002 by Filip Sneppe <filip.sneppe@cronos.be>
+ * based on ip_masq_cuseeme.c in 2.2 kernels
+ *
+ * ip_nat_cuseeme.c v0.0.4 2002-11-04
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ *
+ *      Module load syntax:
+ *      insmod ip_nat_cuseeme.o ports=port1,port2,...port<MAX_PORTS>
+ *
+ *      Please give the ports of the CuSeeMe traffic you want to track.
+ *      If you don't specify ports, the default will be UDP port 7648.
+ *
+ *      CuSeeMe Protocol Documentation:
+ *      http://cu-seeme.net/squeek/tech/contents.html
+ */
+
+#include <linux/module.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+#include <linux/netfilter_ipv4/ip_conntrack_cuseeme.h>
+#include <linux/netfilter_ipv4/ip_nat_helper.h>
+#include <linux/netfilter_ipv4/ip_nat_rule.h>
+
+MODULE_AUTHOR("Filip Sneppe <filip.sneppe@cronos.be>");
+MODULE_DESCRIPTION("Netfilter NAT helper for CuSeeMe");
+MODULE_LICENSE("GPL");
+
+#define MAX_PORTS 8
+
+static int ports[MAX_PORTS];
+static int ports_c = 0;
+#ifdef MODULE_PARM
+MODULE_PARM(ports,"1-" __MODULE_STRING(MAX_PORTS) "i");
+MODULE_PARM_DESC(ports, "port numbers of CuSeeMe hosts");
+#endif
+
+#if 0 
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+/* process packet from client->reflector, possibly manipulate client IP in payload */
+void cuseeme_mangle_outgoing(struct ip_conntrack *ct,
+                             struct ip_nat_info *info,
+                             enum ip_conntrack_info ctinfo,
+                             struct sk_buff **pskb,
+                             char *data,
+                             unsigned int datalen)
+{
+	char new_port_ip[6];
+	struct cu_header *cu_head=(struct cu_header *)data;
+	
+	DEBUGP("ip_nat_cuseeme: outgoing packet, ID %u, dest_family %u\n", 
+	       ntohs(cu_head->data_type), ntohs(cu_head->dest_family));
+		
+	/* At least check that the data at offset 10 is the client's port and IP address */
+	if ((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip == cu_head->addr) &&
+	    (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port == cu_head->port)) {
+		DEBUGP("ip_nat_cuseeme: rewrite outgoing client %u.%u.%u.%u:%u->%u.%u.%u.%u:%u at offset 10\n", 
+		       NIPQUAD(cu_head->addr),
+		       ntohs(cu_head->port),
+		       NIPQUAD(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip),
+		       ntohs(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.udp.port));
+		*((u_int16_t *)new_port_ip) = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.udp.port;
+		*((u_int32_t *)(new_port_ip+2)) = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
+		/* at offset 10, replace 6 bytes containing port + IP address */
+		ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
+		                         10, 6, (char *)(new_port_ip), 6);
+	} else 
+		if (net_ratelimit())
+			printk("ip_nat_cuseeme: expected outgoing client %u.%u.%u.%u:%u, but got %u.%u.%u.%u:%u\n",
+			       NIPQUAD(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip),
+			       ntohs(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port),
+			       NIPQUAD(cu_head->addr),
+			       ntohs(cu_head->port));
+}
+
+/* process packet from reflector->client, possibly manipulate client IP & reflector IP in payload */
+void cuseeme_mangle_incoming(struct ip_conntrack *ct,
+                             struct ip_nat_info *info,
+                             enum ip_conntrack_info ctinfo,
+                             struct sk_buff **pskb,
+                             char *data,
+                             unsigned int datalen)
+{
+	char new_port_ip[6];
+	struct cu_header *cu_head = (struct cu_header *)data;
+	struct oc_header *oc_head = (struct oc_header *)data; 
+	struct client_info *ci; 
+	unsigned int client_info_size = sizeof(struct oc_header);
+	int i;
+	
+	DEBUGP("ip_nat_cuseeme: incoming packet, ID %u, dest_family %u\n", 
+	       ntohs(cu_head->data_type), ntohs(cu_head->dest_family));
+		
+	/* Check if we're really dealing with the client's port + IP address before rewriting */
+	if((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip == cu_head->dest_addr) &&
+	   (ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.udp.port == cu_head->dest_port)) {
+		DEBUGP("ip_nat_cuseeme: rewrite incoming client %u.%u.%u.%u:%u->%u.%u.%u.%u:%u at offset 2\n",
+		       NIPQUAD(cu_head->dest_addr),
+		       ntohs(cu_head->dest_port),
+		       NIPQUAD(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip),
+		       ntohs(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port));
+		*((u_int16_t *)new_port_ip) = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port;
+		*((u_int32_t *)(new_port_ip+2)) = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
+		/* at offset 2, replace 6 bytes containing port + IP address */
+		ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
+		                         2, 6, (char *)(new_port_ip), 6);
+	} else 
+		if (net_ratelimit())
+			printk("ip_nat_cuseeme: expected incoming client %u.%u.%u.%u:%u, but got %u.%u.%u.%u:%u\n",
+			       NIPQUAD(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip),
+			       ntohs(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.udp.port),
+			       NIPQUAD(cu_head->dest_addr),
+			       ntohs(cu_head->dest_port));
+	
+	/* Check if we're really dealing with the server's port + IP address before rewriting. 
+	   In some cases, the IP address == 0.0.0.0 so we don't rewrite anything */
+	if((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip == cu_head->addr) &&
+	   (ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.udp.port == cu_head->port)) {
+		DEBUGP("in_nat_cuseeme: rewrite incoming server %u.%u.%u.%u:%u->%u.%u.%u.%u:%u at offset 10\n",
+		       NIPQUAD(cu_head->addr),
+		       ntohs(cu_head->port),
+		       NIPQUAD(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip),
+		       ntohs(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.udp.port));
+		*((u_int16_t *)new_port_ip) = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.udp.port;
+		*((u_int32_t *)(new_port_ip+2)) = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
+		/* at offset 10, replace 6 bytes containing port + IP address */
+		ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
+		                         10, 6, (char *)(new_port_ip), 6);
+	} else 
+		/* Sometimes we find 0.0.0.0, sometimes an IP address - the docs say this field
+		   is not that important so we're not logging this unless we're debugging */
+		DEBUGP("ip_nat_cuseeme: no biggie, expected incoming server %u.%u.%u.%u:%u, but got %u.%u.%u.%u:%u\n",
+		       NIPQUAD(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip),
+		       ntohs(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.udp.port),
+		       NIPQUAD(cu_head->addr),
+		       ntohs(cu_head->port));
+	
+	/* Spin through client_info structs until we find our own */
+	if((ntohs(cu_head->data_type) == 101) && (datalen >= sizeof(struct oc_header))) {
+/*		oc_head = (struct oc_header *) &udph[1]; */
+/*		client_info_size = sizeof(struct oc_header); */
+		DEBUGP("ip_nat_cuseeme: looping through %u client_info structs\n", oc_head->client_count);
+		for(i=0; 
+		    (i<oc_head->client_count) && 
+		    (sizeof(struct client_info)+client_info_size<=datalen); 
+		    ++i, client_info_size+=sizeof(struct client_info)) {
+			ci=(struct client_info *)(cu_head+client_info_size);
+			DEBUGP("ip_nat_cuseeme: here's a possible address: %u.%u.%u.%u\n", NIPQUAD(ci->address));
+			if(ci->address == ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip) {
+				/* mangle this IP address */
+				ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
+				                         (unsigned int)((void *)&ci->address - (void *)cu_head), 4, 
+				                         (char *)(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip), 4);
+				break;
+			}
+		}
+	}
+}
+
+static unsigned int 
+cuseeme_nat_help(struct ip_conntrack *ct,
+                 struct ip_conntrack_expect *exp,
+                 struct ip_nat_info *info,
+                 enum ip_conntrack_info ctinfo,
+                 unsigned int hooknum,
+                 struct sk_buff **pskb)
+{
+	struct iphdr *iph = (*pskb)->nh.iph;
+	struct udphdr *udph = (void *)iph + iph->ihl * 4;
+	int dir = CTINFO2DIR(ctinfo);
+	unsigned int datalen = (*pskb)->len - iph->ihl * 4 - sizeof(struct udphdr);
+	char *data = (char *) &udph[1];
+	
+	DEBUGP("ip_nat_cuseeme: cuseeme_nat_help, direction: %s hook: %s\n",
+	       dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
+	       hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
+	       : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
+	       : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"
+	      );
+/*	DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); */
+/*	DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); */
+	
+	/* Only mangle things once: original direction in POST_ROUTING
+	   and reply direction on PRE_ROUTING. */
+	if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL)
+	    || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) {
+		DEBUGP("ip_nat_cuseeme: not touching dir %s at hook %s\n",
+		       dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
+		       hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
+		       : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
+		       : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "????");
+		return NF_ACCEPT;
+	}
+	
+	if(datalen < sizeof(struct cu_header)) {
+		/* packet too small */
+		if (net_ratelimit())
+			printk("ip_nat_cuseeme: payload too small (%u, should be >= %u)\n", 
+			       datalen, sizeof(struct cu_header));
+		return NF_ACCEPT;
+	}
+
+
+	/* In the debugging output, "outgoing" is from client to server, and
+	   "incoming" is from server to client */
+	if(HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) 
+		cuseeme_mangle_outgoing(ct, info, ctinfo, pskb, data, datalen);
+	else 
+		cuseeme_mangle_incoming(ct, info, ctinfo, pskb, data, datalen);
+
+	return NF_ACCEPT;
+}
+
+static struct ip_nat_helper cuseeme[MAX_PORTS];
+static char cuseeme_names[MAX_PORTS][14];  /* cuseeme-65535 */
+
+static void fini(void)
+{
+	int i;
+	
+	for (i = 0 ; i < ports_c; i++) {
+		DEBUGP("ip_nat_cuseeme: unregistering helper for port %d\n", ports[i]);
+		       ip_nat_helper_unregister(&cuseeme[i]);
+	}
+}
+
+static int __init init(void)
+{
+	int i, ret = 0;
+	char *tmpname;
+
+	if (!ports[0])
+		ports[0] = CUSEEME_PORT;
+		
+	for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) {
+		memset(&cuseeme[i], 0, sizeof(struct ip_nat_helper));
+
+		cuseeme[i].tuple.dst.protonum = IPPROTO_UDP;
+		cuseeme[i].tuple.dst.u.udp.port = htons(ports[i]);
+		cuseeme[i].mask.dst.protonum = 0xFFFF;
+		cuseeme[i].mask.dst.u.udp.port = 0xFFFF;
+		cuseeme[i].help = cuseeme_nat_help;
+		cuseeme[i].flags = IP_NAT_HELPER_F_STANDALONE + 
+		                   IP_NAT_HELPER_F_ALWAYS; /* dunno if IP_NAT_HELPER_F_ALWAYS
+		                                              is stricly needed... */
+		cuseeme[i].me = THIS_MODULE;
+		cuseeme[i].expect = NULL; /* cuseeme_nat_expected; */
+			
+		tmpname = &cuseeme_names[i][0];
+		if (ports[i] == CUSEEME_PORT)
+			sprintf(tmpname, "cuseeme");
+		else
+			sprintf(tmpname, "cuseeme-%d", i);
+		cuseeme[i].name = tmpname;
+			
+		DEBUGP("ip_nat_cuseeme: registering helper for port %d: name %s\n",
+		       ports[i], cuseeme[i].name);
+		ret = ip_nat_helper_register(&cuseeme[i]);
+			
+		if (ret) {
+			printk("ip_nat_cuseeme: unable to register helper for port %d\n",
+			       ports[i]);
+			fini();
+			return ret;
+		}
+		ports_c++;
+	}
+	return ret;
+}
+	
+module_init(init);
+module_exit(fini);

^ permalink raw reply	[flat|nested] 4+ messages in thread
* [PATCH] wanted: testers for ip_nat_cuseeme module
@ 2002-11-05  1:37 Filip Sneppe (Cronos)
  0 siblings, 0 replies; 4+ messages in thread
From: Filip Sneppe (Cronos) @ 2002-11-05  1:37 UTC (permalink / raw)
  To: netfilter-devel, netfilter; +Cc: james

[-- Attachment #1: Type: text/plain, Size: 2569 bytes --]

Hi,

(cross-post to netfilter-devel & netfilter)

As per James' request, I've written a cuseeme nat module for 
netfilter/iptables.

Since I am not a CuSeeMe user (and I don't even have a webcam or 
any other video conferencing hardware), I'd like some more people 
to test it out and report their success/failure stories to me privately,
before I submit this code for patch-o-matic. Discussions about
the code are best kept on netfilter-devel though, etc...

At the very least, the module should allow SNAT/MASQUERADE like the
2.2 ip_masq_cuseeme module. DNAT should also work. 

Some points of attention:

- My patch requires the newnat-udp-helper.patch written by
  Brian J. Murrell that is currently pending for kernel
  inclusion, as it makes use of "ip_nat_mangle_udp_packet()".
  I guess that patch won't make it in 2.4.20, so you'll have
  to get it from CVS (patch-o-matic/pending/newnat-udp-helper.patch)
  or here: 
http://cvs.netfilter.org/cgi-bin/cvsweb/netfilter/patch-o-matic/pending/newnat-udp-helper.patch

  and apply it manually.

- You will find that there is only an ip_nat_cuseeme module.
  Since there are no random ports being opened, but payloads
  do contain embedded IP addresses, there is only a need for
  packet payload "mangling" in NAT scenarios.
  I was quite happy to find out that netfilter/iptables
  happily supports this!

- If you're running into problems, please let me know. I will
  ask you to recompile with debugging enabled (change the "#if 0" to
  "#if 1" in ip_nat_cuseeme.c), and capture traffic on both sides of 
  the NAT box, so you know ahead.
  I am curious if a lot of people will be getting many messages like 
  this in their system logs:

    expected incoming client 195.162.210.199:7648, but got 0.0.0.0:7648

  This shouldn't happen, but from what I get from the specs,
  it's not always strictly necessary to follow the specs to get
  a working implementation.

Regards,
Filip

ps. Unless someone else has started working on this, I will probably
end up writing a conntrack/nat helper for Microsoft MSN Messenger, 
now that I still have a Windows partition on a test box, so feel free
to volunteer as a tester for that too :-)

-----Original Message-----
From:	James Bryan [mailto:james@penguintowne.com]
Sent:	Sun 27/10/2002 5:47
To:	Sneppe Filip
Cc:	
Subject:	RE: Question about Porting the cu-seeme ipchains module to
iptables.

Filip,
  I haven't found anyone else yet who's ported the module or is working
on it. I'd  be delighted if you could port it over to a conntrack/nat
module. 

Regards,
James



[-- Attachment #2: diff.netfilter.cuseeme.20021104-1 --]
[-- Type: text/x-patch, Size: 17597 bytes --]

diff -urN -X dontdiff linux-2.4.20-pre11/Documentation/Configure.help linux-2.4.20-pre11-msn/Documentation/Configure.help
--- linux-2.4.20-pre11/Documentation/Configure.help	2002-10-29 02:18:22.000000000 +0100
+++ linux-2.4.20-pre11-msn/Documentation/Configure.help	2002-11-05 01:57:49.000000000 +0100
@@ -2508,6 +2508,17 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+CuSeeMe protocol support
+CONFIG_IP_NF_CUSEEME
+  The CuSeeMe conferencing protocol is problematic when used in
+  conjunction with NAT; even though there are no random ports used for
+  extra connections, the messages contain IP addresses inside them.
+  This NAT helper mangles the IP address inside packets so both
+  parties don't get confused.
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  If unsure, say `Y'.
+
 IRC Send/Chat protocol support
 CONFIG_IP_NF_IRC
   There is a commonly-used extension to IRC called
diff -urN -X dontdiff linux-2.4.20-pre11/include/linux/netfilter_ipv4/ip_conntrack_cuseeme.h linux-2.4.20-pre11-msn/include/linux/netfilter_ipv4/ip_conntrack_cuseeme.h
--- linux-2.4.20-pre11/include/linux/netfilter_ipv4/ip_conntrack_cuseeme.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20-pre11-msn/include/linux/netfilter_ipv4/ip_conntrack_cuseeme.h	2002-11-04 18:20:59.000000000 +0100
@@ -0,0 +1,68 @@
+#ifndef _IP_CT_CUSEEME
+#define _IP_CT_CUSEEME
+
+#define CUSEEME_PORT 7648
+
+/* These structs come from the 2.2 ip_masq_cuseeme code... */
+
+/* CuSeeMe data header */
+struct cu_header {
+	u_int16_t	dest_family;
+	u_int16_t	dest_port;
+	u_int32_t	dest_addr;
+	u_int16_t	family;
+	u_int16_t	port;
+	u_int32_t	addr;
+	u_int32_t	seq;
+	u_int16_t	msg;
+	u_int16_t	data_type;
+				/* possible values:
+				 * 1	small video
+				 * 2	big video
+				 * 3	audio
+				 * 100	acknowledge connectivity when there
+				 * 	is nothing else to send
+				 * 101	OpenContinue packet
+				 * 104	display a text message and 
+				 * 	disconnect (used by reflector to
+				 * 	kick clients off)
+				 * 105	display a text message (welcome
+				 * 	message from reflector)
+				 * 106	exchanged among reflectors for
+				 * 	reflector interoperation
+				 * 107	carry aux stream data when there is
+				 *	no video to piggy-back on
+				 * 108	obsolete (used in Mac alpha version)
+				 * 109	obsolete (used in Mac alpha version)
+				 * 110	used for data rate control
+				 * 111	used for data rate control
+				 * 256	aux data control messages
+				 * 257	aux data packets
+				 * */
+	u_int16_t	packet_len;
+};
+
+/* Open Continue Header */
+struct oc_header {
+	struct cu_header	cu_head;
+	u_int16_t	client_count; /* Number of client info structs */
+	u_int32_t	seq_no;
+	char		user_name[20];
+	char		stuff[4];     /* Flags, version stuff, etc */
+};
+
+/* Client info structures */
+struct client_info {
+	u_int32_t	address;      /* Client address */
+	u_int32_t	stuff[8];     /* Flags, pruning bitfield, packet counts, etc */
+};
+
+/* This structure is per expected connection */
+struct ip_ct_cuseeme_expect {
+};
+
+/* This structure exists only once per master */
+struct ip_ct_cuseeme_master {
+};
+
+#endif /* _IP_CT_CUSEEME */
diff -urN -X dontdiff linux-2.4.20-pre11/net/ipv4/netfilter/Config.in linux-2.4.20-pre11-msn/net/ipv4/netfilter/Config.in
--- linux-2.4.20-pre11/net/ipv4/netfilter/Config.in	2002-10-29 02:19:16.000000000 +0100
+++ linux-2.4.20-pre11-msn/net/ipv4/netfilter/Config.in	2002-10-30 00:52:42.000000000 +0100
@@ -8,6 +8,7 @@
 if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
   dep_tristate '  FTP protocol support' CONFIG_IP_NF_FTP $CONFIG_IP_NF_CONNTRACK
   dep_tristate '  IRC protocol support' CONFIG_IP_NF_IRC $CONFIG_IP_NF_CONNTRACK
+  dep_tristate '  CuSeeMe protocol support' CONFIG_IP_NF_CUSEEME $CONFIG_IP_NF_CONNTRACK
 fi
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
@@ -67,6 +69,13 @@
           define_tristate CONFIG_IP_NF_NAT_IRC $CONFIG_IP_NF_NAT
         fi
       fi
+      if [ "$CONFIG_IP_NF_CUSEEME" = "m" ]; then
+        define_tristate CONFIG_IP_NF_NAT_CUSEEME m
+      else
+        if [ "$CONFIG_IP_NF_CUSEEME" = "y" ]; then
+         define_tristate CONFIG_IP_NF_NAT_CUSEEME $CONFIG_IP_NF_NAT
+        fi
+      fi
       # If they want FTP, set to $CONFIG_IP_NF_NAT (m or y), 
       # or $CONFIG_IP_NF_FTP (m or y), whichever is weaker.  Argh.
       if [ "$CONFIG_IP_NF_FTP" = "m" ]; then
diff -urN -X dontdiff linux-2.4.20-pre11/net/ipv4/netfilter/Makefile linux-2.4.20-pre11-msn/net/ipv4/netfilter/Makefile
--- linux-2.4.20-pre11/net/ipv4/netfilter/Makefile	2002-10-29 02:19:16.000000000 +0100
+++ linux-2.4.20-pre11-msn/net/ipv4/netfilter/Makefile	2002-11-02 21:01:26.000000000 +0100
@@ -45,6 +53,7 @@
 # NAT helpers 
 obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o
 obj-$(CONFIG_IP_NF_NAT_IRC) += ip_nat_irc.o
+obj-$(CONFIG_IP_NF_NAT_CUSEEME) += ip_nat_cuseeme.o
 
 # generic IP tables 
 obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
diff -urN -X dontdiff linux-2.4.20-pre11/net/ipv4/netfilter/ip_nat_cuseeme.c linux-2.4.20-pre11-msn/net/ipv4/netfilter/ip_nat_cuseeme.c
--- linux-2.4.20-pre11/net/ipv4/netfilter/ip_nat_cuseeme.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20-pre11-msn/net/ipv4/netfilter/ip_nat_cuseeme.c	2002-11-05 01:45:42.000000000 +0100
@@ -0,0 +1,285 @@
+/* CuSeeMe extension for UDP NAT alteration.
+ * (C) 2002 by Filip Sneppe <filip.sneppe@cronos.be>
+ * based on ip_masq_cuseeme.c in 2.2 kernels
+ *
+ * ip_nat_cuseeme.c v0.0.4 2002-11-04
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ *
+ *      Module load syntax:
+ *      insmod ip_nat_cuseeme.o ports=port1,port2,...port<MAX_PORTS>
+ *
+ *      Please give the ports of the CuSeeMe traffic you want to track.
+ *      If you don't specify ports, the default will be UDP port 7648.
+ *
+ *      CuSeeMe Protocol Documentation:
+ *      http://cu-seeme.net/squeek/tech/contents.html
+ */
+
+#include <linux/module.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+#include <linux/netfilter_ipv4/ip_conntrack_cuseeme.h>
+#include <linux/netfilter_ipv4/ip_nat_helper.h>
+#include <linux/netfilter_ipv4/ip_nat_rule.h>
+
+MODULE_AUTHOR("Filip Sneppe <filip.sneppe@cronos.be>");
+MODULE_DESCRIPTION("Netfilter NAT helper for CuSeeMe");
+MODULE_LICENSE("GPL");
+
+#define MAX_PORTS 8
+
+static int ports[MAX_PORTS];
+static int ports_c = 0;
+#ifdef MODULE_PARM
+MODULE_PARM(ports,"1-" __MODULE_STRING(MAX_PORTS) "i");
+MODULE_PARM_DESC(ports, "port numbers of CuSeeMe hosts");
+#endif
+
+#if 0 
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+/* process packet from client->reflector, possibly manipulate client IP in payload */
+void cuseeme_mangle_outgoing(struct ip_conntrack *ct,
+                             struct ip_nat_info *info,
+                             enum ip_conntrack_info ctinfo,
+                             struct sk_buff **pskb,
+                             char *data,
+                             unsigned int datalen)
+{
+	char new_port_ip[6];
+	struct cu_header *cu_head=(struct cu_header *)data;
+	
+	DEBUGP("ip_nat_cuseeme: outgoing packet, ID %u, dest_family %u\n", 
+	       ntohs(cu_head->data_type), ntohs(cu_head->dest_family));
+		
+	/* At least check that the data at offset 10 is the client's port and IP address */
+	if ((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip == cu_head->addr) &&
+	    (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port == cu_head->port)) {
+		DEBUGP("ip_nat_cuseeme: rewrite outgoing client %u.%u.%u.%u:%u->%u.%u.%u.%u:%u at offset 10\n", 
+		       NIPQUAD(cu_head->addr),
+		       ntohs(cu_head->port),
+		       NIPQUAD(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip),
+		       ntohs(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.udp.port));
+		*((u_int16_t *)new_port_ip) = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.udp.port;
+		*((u_int32_t *)(new_port_ip+2)) = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
+		/* at offset 10, replace 6 bytes containing port + IP address */
+		ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
+		                         10, 6, (char *)(new_port_ip), 6);
+	} else 
+		if (net_ratelimit())
+			printk("ip_nat_cuseeme: expected outgoing client %u.%u.%u.%u:%u, but got %u.%u.%u.%u:%u\n",
+			       NIPQUAD(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip),
+			       ntohs(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port),
+			       NIPQUAD(cu_head->addr),
+			       ntohs(cu_head->port));
+}
+
+/* process packet from reflector->client, possibly manipulate client IP & reflector IP in payload */
+void cuseeme_mangle_incoming(struct ip_conntrack *ct,
+                             struct ip_nat_info *info,
+                             enum ip_conntrack_info ctinfo,
+                             struct sk_buff **pskb,
+                             char *data,
+                             unsigned int datalen)
+{
+	char new_port_ip[6];
+	struct cu_header *cu_head = (struct cu_header *)data;
+	struct oc_header *oc_head = (struct oc_header *)data; 
+	struct client_info *ci; 
+	unsigned int client_info_size = sizeof(struct oc_header);
+	int i;
+	
+	DEBUGP("ip_nat_cuseeme: incoming packet, ID %u, dest_family %u\n", 
+	       ntohs(cu_head->data_type), ntohs(cu_head->dest_family));
+		
+	/* Check if we're really dealing with the client's port + IP address before rewriting */
+	if((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip == cu_head->dest_addr) &&
+	   (ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.udp.port == cu_head->dest_port)) {
+		DEBUGP("ip_nat_cuseeme: rewrite incoming client %u.%u.%u.%u:%u->%u.%u.%u.%u:%u at offset 2\n",
+		       NIPQUAD(cu_head->dest_addr),
+		       ntohs(cu_head->dest_port),
+		       NIPQUAD(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip),
+		       ntohs(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port));
+		*((u_int16_t *)new_port_ip) = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port;
+		*((u_int32_t *)(new_port_ip+2)) = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
+		/* at offset 2, replace 6 bytes containing port + IP address */
+		ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
+		                         2, 6, (char *)(new_port_ip), 6);
+	} else 
+		if (net_ratelimit())
+			printk("ip_nat_cuseeme: expected incoming client %u.%u.%u.%u:%u, but got %u.%u.%u.%u:%u\n",
+			       NIPQUAD(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip),
+			       ntohs(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.udp.port),
+			       NIPQUAD(cu_head->dest_addr),
+			       ntohs(cu_head->dest_port));
+	
+	/* Check if we're really dealing with the server's port + IP address before rewriting. 
+	   In some cases, the IP address == 0.0.0.0 so we don't rewrite anything */
+	if((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip == cu_head->addr) &&
+	   (ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.udp.port == cu_head->port)) {
+		DEBUGP("in_nat_cuseeme: rewrite incoming server %u.%u.%u.%u:%u->%u.%u.%u.%u:%u at offset 10\n",
+		       NIPQUAD(cu_head->addr),
+		       ntohs(cu_head->port),
+		       NIPQUAD(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip),
+		       ntohs(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.udp.port));
+		*((u_int16_t *)new_port_ip) = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.udp.port;
+		*((u_int32_t *)(new_port_ip+2)) = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
+		/* at offset 10, replace 6 bytes containing port + IP address */
+		ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
+		                         10, 6, (char *)(new_port_ip), 6);
+	} else 
+		/* Sometimes we find 0.0.0.0, sometimes an IP address - the docs say this field
+		   is not that important so we're not logging this unless we're debugging */
+		DEBUGP("ip_nat_cuseeme: no biggie, expected incoming server %u.%u.%u.%u:%u, but got %u.%u.%u.%u:%u\n",
+		       NIPQUAD(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip),
+		       ntohs(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.udp.port),
+		       NIPQUAD(cu_head->addr),
+		       ntohs(cu_head->port));
+	
+	/* Spin through client_info structs until we find our own */
+	if((ntohs(cu_head->data_type) == 101) && (datalen >= sizeof(struct oc_header))) {
+/*		oc_head = (struct oc_header *) &udph[1]; */
+/*		client_info_size = sizeof(struct oc_header); */
+		DEBUGP("ip_nat_cuseeme: looping through %u client_info structs\n", oc_head->client_count);
+		for(i=0; 
+		    (i<oc_head->client_count) && 
+		    (sizeof(struct client_info)+client_info_size<=datalen); 
+		    ++i, client_info_size+=sizeof(struct client_info)) {
+			ci=(struct client_info *)(cu_head+client_info_size);
+			DEBUGP("ip_nat_cuseeme: here's a possible address: %u.%u.%u.%u\n", NIPQUAD(ci->address));
+			if(ci->address == ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip) {
+				/* mangle this IP address */
+				ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
+				                         (unsigned int)((void *)&ci->address - (void *)cu_head), 4, 
+				                         (char *)(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip), 4);
+				break;
+			}
+		}
+	}
+}
+
+static unsigned int 
+cuseeme_nat_help(struct ip_conntrack *ct,
+                 struct ip_conntrack_expect *exp,
+                 struct ip_nat_info *info,
+                 enum ip_conntrack_info ctinfo,
+                 unsigned int hooknum,
+                 struct sk_buff **pskb)
+{
+	struct iphdr *iph = (*pskb)->nh.iph;
+	struct udphdr *udph = (void *)iph + iph->ihl * 4;
+	int dir = CTINFO2DIR(ctinfo);
+	unsigned int datalen = (*pskb)->len - iph->ihl * 4 - sizeof(struct udphdr);
+	char *data = (char *) &udph[1];
+	
+	DEBUGP("ip_nat_cuseeme: cuseeme_nat_help, direction: %s hook: %s\n",
+	       dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
+	       hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
+	       : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
+	       : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"
+	      );
+/*	DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); */
+/*	DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); */
+	
+	/* Only mangle things once: original direction in POST_ROUTING
+	   and reply direction on PRE_ROUTING. */
+	if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL)
+	    || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) {
+		DEBUGP("ip_nat_cuseeme: not touching dir %s at hook %s\n",
+		       dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
+		       hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
+		       : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
+		       : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "????");
+		return NF_ACCEPT;
+	}
+	
+	if(datalen < sizeof(struct cu_header)) {
+		/* packet too small */
+		if (net_ratelimit())
+			printk("ip_nat_cuseeme: payload too small (%u, should be >= %u)\n", 
+			       datalen, sizeof(struct cu_header));
+		return NF_ACCEPT;
+	}
+
+
+	/* In the debugging output, "outgoing" is from client to server, and
+	   "incoming" is from server to client */
+	if(HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) 
+		cuseeme_mangle_outgoing(ct, info, ctinfo, pskb, data, datalen);
+	else 
+		cuseeme_mangle_incoming(ct, info, ctinfo, pskb, data, datalen);
+
+	return NF_ACCEPT;
+}
+
+static struct ip_nat_helper cuseeme[MAX_PORTS];
+static char cuseeme_names[MAX_PORTS][14];  /* cuseeme-65535 */
+
+static void fini(void)
+{
+	int i;
+	
+	for (i = 0 ; i < ports_c; i++) {
+		DEBUGP("ip_nat_cuseeme: unregistering helper for port %d\n", ports[i]);
+		       ip_nat_helper_unregister(&cuseeme[i]);
+	}
+}
+
+static int __init init(void)
+{
+	int i, ret = 0;
+	char *tmpname;
+
+	if (!ports[0])
+		ports[0] = CUSEEME_PORT;
+		
+	for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) {
+		memset(&cuseeme[i], 0, sizeof(struct ip_nat_helper));
+
+		cuseeme[i].tuple.dst.protonum = IPPROTO_UDP;
+		cuseeme[i].tuple.dst.u.udp.port = htons(ports[i]);
+		cuseeme[i].mask.dst.protonum = 0xFFFF;
+		cuseeme[i].mask.dst.u.udp.port = 0xFFFF;
+		cuseeme[i].help = cuseeme_nat_help;
+		cuseeme[i].flags = IP_NAT_HELPER_F_STANDALONE + 
+		                   IP_NAT_HELPER_F_ALWAYS; /* dunno if IP_NAT_HELPER_F_ALWAYS
+		                                              is stricly needed... */
+		cuseeme[i].me = THIS_MODULE;
+		cuseeme[i].expect = NULL; /* cuseeme_nat_expected; */
+			
+		tmpname = &cuseeme_names[i][0];
+		if (ports[i] == CUSEEME_PORT)
+			sprintf(tmpname, "cuseeme");
+		else
+			sprintf(tmpname, "cuseeme-%d", i);
+		cuseeme[i].name = tmpname;
+			
+		DEBUGP("ip_nat_cuseeme: registering helper for port %d: name %s\n",
+		       ports[i], cuseeme[i].name);
+		ret = ip_nat_helper_register(&cuseeme[i]);
+			
+		if (ret) {
+			printk("ip_nat_cuseeme: unable to register helper for port %d\n",
+			       ports[i]);
+			fini();
+			return ret;
+		}
+		ports_c++;
+	}
+	return ret;
+}
+	
+module_init(init);
+module_exit(fini);

^ permalink raw reply	[flat|nested] 4+ messages in thread
* RE: [PATCH] wanted: testers for ip_nat_cuseeme module
@ 2002-11-05  9:09 Sneppe Filip
  0 siblings, 0 replies; 4+ messages in thread
From: Sneppe Filip @ 2002-11-05  9:09 UTC (permalink / raw)
  To: Kevin McConnell, netfilter-devel


[-- Attachment #1.1: Type: text/plain, Size: 745 bytes --]

Hi Kevin,

>So did you add your module into the CVS repository or
>where can we get it from? Is this particular module in
>addition to the H323 patches or or is it in place of?

I guess it's best kept out of CVS until more users are successfully 
using it, as I am not sure it will currently work for everyone. The 
patch was attached to the announcement mail :-)

>I would be happy to test out both modules. Where is
>the first one available and when will the second be
>available?

Ah I've just remembered that yahoo.com users have problems
with some (text?) attachment. Here's a gzipped patch attached.

No due date on the msn helper - it'll be ready when it's ready,
in true open source tradition :-)

Regards,
Filip


[-- Attachment #1.2: Type: text/html, Size: 1244 bytes --]

[-- Attachment #2: diff.netfilter.cuseeme.20021104-1.gz --]
[-- Type: application/gzip, Size: 4791 bytes --]

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

end of thread, other threads:[~2002-11-05  9:09 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-11-05  1:37 [PATCH] wanted: testers for ip_nat_cuseeme module Filip Sneppe (Cronos)
2002-11-05  6:17 ` Kevin McConnell
  -- strict thread matches above, loose matches on Subject: below --
2002-11-05  1:37 Filip Sneppe (Cronos)
2002-11-05  9:09 Sneppe Filip

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.