patch-2.4.20 linux-2.4.20/net/ipv4/netfilter/ip_conntrack_irc.c
Next file: linux-2.4.20/net/ipv4/netfilter/ip_conntrack_proto_generic.c
Previous file: linux-2.4.20/net/ipv4/netfilter/ip_conntrack_ftp.c
Back to the patch index
Back to the overall index
- Lines: 211
- Date:
Thu Nov 28 15:53:15 2002
- Orig file:
linux-2.4.19/net/ipv4/netfilter/ip_conntrack_irc.c
- Orig date:
Mon Feb 25 11:38:14 2002
diff -urN linux-2.4.19/net/ipv4/netfilter/ip_conntrack_irc.c linux-2.4.20/net/ipv4/netfilter/ip_conntrack_irc.c
@@ -11,12 +11,18 @@
**
* Module load syntax:
* insmod ip_conntrack_irc.o ports=port1,port2,...port<MAX_PORTS>
+ * max_dcc_channels=n dcc_timeout=secs
*
* please give the ports of all IRC servers You wish to connect to.
- * If You don't specify ports, the default will be port 6667
+ * If You don't specify ports, the default will be port 6667.
+ * With max_dcc_channels you can define the maximum number of not
+ * yet answered DCC channels per IRC session (default 8).
+ * With dcc_timeout you can specify how long the system waits for
+ * an expected DCC channel (default 300 seconds).
*
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/ip.h>
@@ -29,7 +35,9 @@
#define MAX_PORTS 8
static int ports[MAX_PORTS];
-static int ports_n_c = 0;
+static int ports_c = 0;
+static int max_dcc_channels = 8;
+static unsigned int dcc_timeout = 300;
MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
MODULE_DESCRIPTION("IRC (DCC) connection tracking module");
@@ -37,6 +45,10 @@
#ifdef MODULE_PARM
MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
MODULE_PARM_DESC(ports, "port numbers of IRC servers");
+MODULE_PARM(max_dcc_channels, "i");
+MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC session");
+MODULE_PARM(dcc_timeout, "i");
+MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels");
#endif
#define NUM_DCCPROTO 5
@@ -103,23 +115,15 @@
u_int32_t tcplen = len - iph->ihl * 4;
u_int32_t datalen = tcplen - tcph->doff * 4;
int dir = CTINFO2DIR(ctinfo);
- struct ip_conntrack_tuple t, mask;
+ struct ip_conntrack_expect expect, *exp = &expect;
+ struct ip_ct_irc_expect *exp_irc_info = &exp->help.exp_irc_info;
u_int32_t dcc_ip;
u_int16_t dcc_port;
int i;
char *addr_beg_p, *addr_end_p;
- struct ip_ct_irc *info = &ct->help.ct_irc_info;
-
- mask = ((struct ip_conntrack_tuple)
- { { 0, { 0 } },
- { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }});
-
DEBUGP("entered\n");
- /* Can't track connections formed before we registered */
- if (!info)
- return NF_ACCEPT;
/* If packet is coming from IRC server */
if (dir == IP_CT_DIR_REPLY)
@@ -189,33 +193,37 @@
continue;
}
+
+ memset(&expect, 0, sizeof(expect));
LOCK_BH(&ip_irc_lock);
/* save position of address in dcc string,
* neccessary for NAT */
- info->is_irc = IP_CONNTR_IRC;
DEBUGP("tcph->seq = %u\n", tcph->seq);
- info->seq = ntohl(tcph->seq) + (addr_beg_p - _data);
- info->len = (addr_end_p - addr_beg_p);
- info->port = dcc_port;
+ exp->seq = ntohl(tcph->seq) + (addr_beg_p - _data);
+ exp_irc_info->len = (addr_end_p - addr_beg_p);
+ exp_irc_info->port = dcc_port;
DEBUGP("wrote info seq=%u (ofs=%u), len=%d\n",
- info->seq, (addr_end_p - _data), info->len);
+ exp->seq, (addr_end_p - _data), exp_irc_info->len);
- memset(&t, 0, sizeof(t));
- t.src.ip = 0;
- t.src.u.tcp.port = 0;
- t.dst.ip = htonl(dcc_ip);
- t.dst.u.tcp.port = htons(info->port);
- t.dst.protonum = IPPROTO_TCP;
+ exp->tuple = ((struct ip_conntrack_tuple)
+ { { 0, { 0 } },
+ { htonl(dcc_ip), { htons(dcc_port) },
+ IPPROTO_TCP }});
+ exp->mask = ((struct ip_conntrack_tuple)
+ { { 0, { 0 } },
+ { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }});
+
+ exp->expectfn = NULL;
DEBUGP("expect_related %u.%u.%u.%u:%u-%u.%u.%u.%u:%u\n",
- NIPQUAD(t.src.ip),
- ntohs(t.src.u.tcp.port),
- NIPQUAD(t.dst.ip),
- ntohs(t.dst.u.tcp.port));
+ NIPQUAD(exp->tuple.src.ip),
+ ntohs(exp->tuple.src.u.tcp.port),
+ NIPQUAD(exp->tuple.dst.ip),
+ ntohs(exp->tuple.dst.u.tcp.port));
- ip_conntrack_expect_related(ct, &t, &mask, NULL);
+ ip_conntrack_expect_related(ct, &expect);
UNLOCK_BH(&ip_irc_lock);
return NF_ACCEPT;
@@ -226,29 +234,53 @@
}
static struct ip_conntrack_helper irc_helpers[MAX_PORTS];
+static char irc_names[MAX_PORTS][10];
static void fini(void);
static int __init init(void)
{
int i, ret;
+ struct ip_conntrack_helper *hlpr;
+ char *tmpname;
+ if (max_dcc_channels < 1) {
+ printk("ip_conntrack_irc: max_dcc_channels must be a positive integer\n");
+ return -EBUSY;
+ }
+ if (dcc_timeout < 0) {
+ printk("ip_conntrack_irc: dcc_timeout must be a positive integer\n");
+ return -EBUSY;
+ }
+
/* If no port given, default to standard irc port */
if (ports[0] == 0)
- ports[0] = 6667;
+ ports[0] = IRC_PORT;
for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
- memset(&irc_helpers[i], 0,
+ hlpr = &irc_helpers[i];
+ memset(hlpr, 0,
sizeof(struct ip_conntrack_helper));
- irc_helpers[i].tuple.src.u.tcp.port = htons(ports[i]);
- irc_helpers[i].tuple.dst.protonum = IPPROTO_TCP;
- irc_helpers[i].mask.src.u.tcp.port = 0xFFFF;
- irc_helpers[i].mask.dst.protonum = 0xFFFF;
- irc_helpers[i].help = help;
+ hlpr->tuple.src.u.tcp.port = htons(ports[i]);
+ hlpr->tuple.dst.protonum = IPPROTO_TCP;
+ hlpr->mask.src.u.tcp.port = 0xFFFF;
+ hlpr->mask.dst.protonum = 0xFFFF;
+ hlpr->max_expected = max_dcc_channels;
+ hlpr->timeout = dcc_timeout;
+ hlpr->flags = IP_CT_HELPER_F_REUSE_EXPECT;
+ hlpr->me = ip_conntrack_irc;
+ hlpr->help = help;
+
+ tmpname = &irc_names[i][0];
+ if (ports[i] == IRC_PORT)
+ sprintf(tmpname, "irc");
+ else
+ sprintf(tmpname, "irc-%d", i);
+ hlpr->name = tmpname;
DEBUGP("port #%d: %d\n", i, ports[i]);
- ret = ip_conntrack_helper_register(&irc_helpers[i]);
+ ret = ip_conntrack_helper_register(hlpr);
if (ret) {
printk("ip_conntrack_irc: ERROR registering port %d\n",
@@ -256,7 +288,7 @@
fini();
return -EBUSY;
}
- ports_n_c++;
+ ports_c++;
}
return 0;
}
@@ -266,12 +298,16 @@
static void fini(void)
{
int i;
- for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
+ for (i = 0; i < ports_c; i++) {
DEBUGP("unregistering port %d\n",
ports[i]);
ip_conntrack_helper_unregister(&irc_helpers[i]);
}
}
+#ifdef CONFIG_IP_NF_NAT_NEEDED
+EXPORT_SYMBOL(ip_irc_lock);
+#endif
+
module_init(init);
module_exit(fini);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)