X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv4%2Fnetfilter%2Fip_conntrack_irc.c;h=d007bc9950cf0a667d8d1413db15d19adc290134;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=31ff05349c96aa54d476427c01e2ab51b8229f2c;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c index 31ff05349..d007bc995 100644 --- a/net/ipv4/netfilter/ip_conntrack_irc.c +++ b/net/ipv4/netfilter/ip_conntrack_irc.c @@ -32,6 +32,7 @@ #include #include #include +#include #define MAX_PORTS 8 static int ports[MAX_PORTS]; @@ -40,23 +41,21 @@ static int max_dcc_channels = 8; static unsigned int dcc_timeout = 300; /* This is slow, but it's simple. --RR */ static char irc_buffer[65536]; +static DECLARE_LOCK(irc_buffer_lock); MODULE_AUTHOR("Harald Welte "); MODULE_DESCRIPTION("IRC (DCC) connection tracking helper"); MODULE_LICENSE("GPL"); -#ifdef MODULE_PARM -MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i"); +module_param_array(ports, int, ports_c, 0400); MODULE_PARM_DESC(ports, "port numbers of IRC servers"); -MODULE_PARM(max_dcc_channels, "i"); +module_param(max_dcc_channels, int, 0400); MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC session"); -MODULE_PARM(dcc_timeout, "i"); +module_param(dcc_timeout, int, 0400); MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels"); -#endif static char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " }; #define MINMATCHLEN 5 -DECLARE_LOCK(ip_irc_lock); struct module *ip_conntrack_irc = THIS_MODULE; #if 0 @@ -103,8 +102,8 @@ static int help(struct sk_buff *skb, struct ip_conntrack *ct, enum ip_conntrack_info ctinfo) { unsigned int dataoff; - struct tcphdr tcph; - char *data, *data_limit; + struct tcphdr _tcph, *th; + char *data, *data_limit, *ib_ptr; int dir = CTINFO2DIR(ctinfo); struct ip_conntrack_expect *exp; struct ip_ct_irc_expect *exp_irc_info = NULL; @@ -128,19 +127,23 @@ static int help(struct sk_buff *skb, } /* Not a full tcp header? */ - if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) != 0) + th = skb_header_pointer(skb, skb->nh.iph->ihl*4, + sizeof(_tcph), &_tcph); + if (th == NULL) return NF_ACCEPT; /* No data? */ - dataoff = skb->nh.iph->ihl*4 + tcph.doff*4; + dataoff = skb->nh.iph->ihl*4 + th->doff*4; if (dataoff >= skb->len) return NF_ACCEPT; - LOCK_BH(&ip_irc_lock); - skb_copy_bits(skb, dataoff, irc_buffer, skb->len - dataoff); + LOCK_BH(&irc_buffer_lock); + ib_ptr = skb_header_pointer(skb, dataoff, + skb->len - dataoff, irc_buffer); + BUG_ON(ib_ptr == NULL); - data = irc_buffer; - data_limit = irc_buffer + skb->len - dataoff; + data = ib_ptr; + data_limit = ib_ptr + skb->len - dataoff; /* strlen("\1DCC SENT t AAAAAAAA P\1\n")=24 * 5+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=14 */ @@ -154,8 +157,8 @@ static int help(struct sk_buff *skb, /* we have at least (19+MINMATCHLEN)-5 bytes valid data left */ DEBUGP("DCC found in master %u.%u.%u.%u:%u %u.%u.%u.%u:%u...\n", - NIPQUAD(iph->saddr), ntohs(tcph.source), - NIPQUAD(iph->daddr), ntohs(tcph.dest)); + NIPQUAD(iph->saddr), ntohs(th->source), + NIPQUAD(iph->daddr), ntohs(th->dest)); for (i = 0; i < ARRAY_SIZE(dccprotos); i++) { if (memcmp(data, dccprotos[i], strlen(dccprotos[i]))) { @@ -199,8 +202,8 @@ static int help(struct sk_buff *skb, /* save position of address in dcc string, * necessary for NAT */ - DEBUGP("tcph->seq = %u\n", tcph.seq); - exp->seq = ntohl(tcph.seq) + (addr_beg_p - irc_buffer); + DEBUGP("tcph->seq = %u\n", th->seq); + exp->seq = ntohl(th->seq) + (addr_beg_p - ib_ptr); 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", @@ -229,7 +232,7 @@ static int help(struct sk_buff *skb, } /* while data < ... */ out: - UNLOCK_BH(&ip_irc_lock); + UNLOCK_BH(&irc_buffer_lock); return NF_ACCEPT; } @@ -254,10 +257,10 @@ static int __init init(void) } /* If no port given, default to standard irc port */ - if (ports[0] == 0) - ports[0] = IRC_PORT; + if (ports_c == 0) + ports[ports_c++] = IRC_PORT; - for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { + for (i = 0; i < ports_c; i++) { hlpr = &irc_helpers[i]; hlpr->tuple.src.u.tcp.port = htons(ports[i]); hlpr->tuple.dst.protonum = IPPROTO_TCP; @@ -286,7 +289,6 @@ static int __init init(void) fini(); return -EBUSY; } - ports_c++; } return 0; } @@ -304,7 +306,6 @@ static void fini(void) } PROVIDES_CONNTRACK(irc); -EXPORT_SYMBOL(ip_irc_lock); module_init(init); module_exit(fini);