patch-2.4.20 linux-2.4.20/net/ipv4/netfilter/ip_nat_irc.c
Next file: linux-2.4.20/net/ipv4/netfilter/ip_nat_proto_tcp.c
Previous file: linux-2.4.20/net/ipv4/netfilter/ip_nat_helper.c
Back to the patch index
Back to the overall index
- Lines: 299
- Date:
Thu Nov 28 15:53:15 2002
- Orig file:
linux-2.4.19/net/ipv4/netfilter/ip_nat_irc.c
- Orig date:
Fri Dec 21 09:42:05 2001
diff -urN linux-2.4.19/net/ipv4/netfilter/ip_nat_irc.c linux-2.4.20/net/ipv4/netfilter/ip_nat_irc.c
@@ -51,42 +51,29 @@
/* FIXME: Time out? --RR */
-static int
+static unsigned int
irc_nat_expected(struct sk_buff **pskb,
unsigned int hooknum,
struct ip_conntrack *ct,
- struct ip_nat_info *info,
- struct ip_conntrack *master,
- struct ip_nat_info *masterinfo, unsigned int *verdict)
+ struct ip_nat_info *info)
{
struct ip_nat_multi_range mr;
u_int32_t newdstip, newsrcip, newip;
- struct ip_ct_irc *ircinfo;
+
+ struct ip_conntrack *master = master_ct(ct);
IP_NF_ASSERT(info);
IP_NF_ASSERT(master);
- IP_NF_ASSERT(masterinfo);
IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
DEBUGP("nat_expected: We have a connection!\n");
- /* Master must be an irc connection */
- ircinfo = &master->help.ct_irc_info;
- LOCK_BH(&ip_irc_lock);
- if (ircinfo->is_irc != IP_CONNTR_IRC) {
- UNLOCK_BH(&ip_irc_lock);
- DEBUGP("nat_expected: master not irc\n");
- return 0;
- }
-
newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
newsrcip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
DEBUGP("nat_expected: DCC cmd. %u.%u.%u.%u->%u.%u.%u.%u\n",
NIPQUAD(newsrcip), NIPQUAD(newdstip));
- UNLOCK_BH(&ip_irc_lock);
-
if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC)
newip = newsrcip;
else
@@ -99,16 +86,14 @@
mr.range[0].flags = IP_NAT_RANGE_MAP_IPS;
mr.range[0].min_ip = mr.range[0].max_ip = newip;
- *verdict = ip_nat_setup_info(ct, &mr, hooknum);
-
- return 1;
+ return ip_nat_setup_info(ct, &mr, hooknum);
}
-static int irc_data_fixup(const struct ip_ct_irc *ct_irc_info,
+static int irc_data_fixup(const struct ip_ct_irc_expect *ct_irc_info,
struct ip_conntrack *ct,
- unsigned int datalen,
struct sk_buff **pskb,
- enum ip_conntrack_info ctinfo)
+ enum ip_conntrack_info ctinfo,
+ struct ip_conntrack_expect *expect)
{
u_int32_t newip;
struct ip_conntrack_tuple t;
@@ -121,9 +106,9 @@
MUST_BE_LOCKED(&ip_irc_lock);
- DEBUGP("IRC_NAT: info (seq %u + %u) packet(seq %u + %u)\n",
- ct_irc_info->seq, ct_irc_info->len,
- ntohl(tcph->seq), datalen);
+ DEBUGP("IRC_NAT: info (seq %u + %u) in %u\n",
+ expect->seq, ct_irc_info->len,
+ ntohl(tcph->seq));
newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
@@ -133,13 +118,11 @@
only set in ip_conntrack_irc, with ip_irc_lock held
writable */
- t = ct->expected.tuple;
+ t = expect->tuple;
t.dst.ip = newip;
for (port = ct_irc_info->port; port != 0; port++) {
t.dst.u.tcp.port = htons(port);
- if (ip_conntrack_expect_related(ct, &t,
- &ct->expected.mask,
- NULL) == 0) {
+ if (ip_conntrack_change_expect(expect, &t) == 0) {
DEBUGP("using port %d", port);
break;
}
@@ -166,26 +149,28 @@
buffer, NIPQUAD(newip), port);
return ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
- ct_irc_info->seq - ntohl(tcph->seq),
+ expect->seq - ntohl(tcph->seq),
ct_irc_info->len, buffer,
strlen(buffer));
}
static unsigned int 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)
+ unsigned int hooknum,
+ struct sk_buff **pskb)
{
struct iphdr *iph = (*pskb)->nh.iph;
struct tcphdr *tcph = (void *) iph + iph->ihl * 4;
unsigned int datalen;
int dir;
- int score;
- struct ip_ct_irc *ct_irc_info = &ct->help.ct_irc_info;
+ struct ip_ct_irc_expect *ct_irc_info;
- /* Delete SACK_OK on initial TCP SYNs. */
- if (tcph->syn && !tcph->ack)
- ip_nat_delete_sack(*pskb, tcph);
+ if (!exp)
+ DEBUGP("ip_nat_irc: no exp!!");
+
+ ct_irc_info = &exp->help.exp_irc_info;
/* Only mangle things once: original direction in POST_ROUTING
and reply direction on PRE_ROUTING. */
@@ -202,55 +187,35 @@
DEBUGP("got beyond not touching\n");
datalen = (*pskb)->len - iph->ihl * 4 - tcph->doff * 4;
- score = 0;
LOCK_BH(&ip_irc_lock);
- if (ct_irc_info->len) {
- DEBUGP("got beyond ct_irc_info->len\n");
-
- /* If it's in the right range... */
- score += between(ct_irc_info->seq, ntohl(tcph->seq),
- ntohl(tcph->seq) + datalen);
- score += between(ct_irc_info->seq + ct_irc_info->len,
- ntohl(tcph->seq),
- ntohl(tcph->seq) + datalen);
- if (score == 1) {
- /* Half a match? This means a partial retransmisison.
- It's a cracker being funky. */
- if (net_ratelimit()) {
- printk
- ("IRC_NAT: partial packet %u/%u in %u/%u\n",
- ct_irc_info->seq, ct_irc_info->len,
- ntohl(tcph->seq),
- ntohl(tcph->seq) + datalen);
- }
+ /* Check wether the whole IP/address pattern is carried in the payload */
+ if (between(exp->seq + ct_irc_info->len,
+ ntohl(tcph->seq),
+ ntohl(tcph->seq) + datalen)) {
+ if (!irc_data_fixup(ct_irc_info, ct, pskb, ctinfo, exp)) {
UNLOCK_BH(&ip_irc_lock);
return NF_DROP;
- } else if (score == 2) {
- DEBUGP("IRC_NAT: score=2, calling fixup\n");
- if (!irc_data_fixup(ct_irc_info, ct, datalen,
- pskb, ctinfo)) {
- UNLOCK_BH(&ip_irc_lock);
- return NF_DROP;
- }
- /* skb may have been reallocated */
- iph = (*pskb)->nh.iph;
- tcph = (void *) iph + iph->ihl * 4;
}
+ } else {
+ /* Half a match? This means a partial retransmisison.
+ It's a cracker being funky. */
+ if (net_ratelimit()) {
+ printk
+ ("IRC_NAT: partial packet %u/%u in %u/%u\n",
+ exp->seq, ct_irc_info->len,
+ ntohl(tcph->seq),
+ ntohl(tcph->seq) + datalen);
+ }
+ UNLOCK_BH(&ip_irc_lock);
+ return NF_DROP;
}
-
UNLOCK_BH(&ip_irc_lock);
- ip_nat_seq_adjust(*pskb, ct, ctinfo);
-
return NF_ACCEPT;
}
static struct ip_nat_helper ip_nat_irc_helpers[MAX_PORTS];
-static char ip_nih_names[MAX_PORTS][6];
-
-static struct ip_nat_expect irc_expect
- = { {NULL, NULL}, irc_nat_expected };
-
+static char irc_names[MAX_PORTS][10];
/* This function is intentionally _NOT_ defined as __exit, because
* it is needed by init() */
@@ -262,52 +227,54 @@
DEBUGP("ip_nat_irc: unregistering helper for port %d\n",
ports[i]);
ip_nat_helper_unregister(&ip_nat_irc_helpers[i]);
- }
- ip_nat_expect_unregister(&irc_expect);
+ }
}
+
static int __init init(void)
{
- int ret;
+ int ret = 0;
int i;
struct ip_nat_helper *hlpr;
char *tmpname;
- ret = ip_nat_expect_register(&irc_expect);
- if (ret == 0) {
-
- if (ports[0] == 0) {
- ports[0] = 6667;
- }
+ if (ports[0] == 0) {
+ ports[0] = IRC_PORT;
+ }
- for (i = 0; (i < MAX_PORTS) && ports[i] != 0; i++) {
- hlpr = &ip_nat_irc_helpers[i];
- memset(hlpr, 0,
- sizeof(struct ip_nat_helper));
-
- hlpr->tuple.dst.protonum = IPPROTO_TCP;
- hlpr->tuple.src.u.tcp.port = htons(ports[i]);
- hlpr->mask.src.u.tcp.port = 0xFFFF;
- hlpr->mask.dst.protonum = 0xFFFF;
- hlpr->help = help;
-
- tmpname = &ip_nih_names[i][0];
- sprintf(tmpname, "irc%2.2d", i);
-
- hlpr->name = tmpname;
- DEBUGP
- ("ip_nat_irc: Trying to register helper for port %d: name %s\n",
- ports[i], hlpr->name);
- ret = ip_nat_helper_register(hlpr);
-
- if (ret) {
- printk
- ("ip_nat_irc: error registering helper for port %d\n",
- ports[i]);
- fini();
- return 1;
- }
- ports_c++;
+ for (i = 0; (i < MAX_PORTS) && ports[i] != 0; i++) {
+ hlpr = &ip_nat_irc_helpers[i];
+ memset(hlpr, 0,
+ sizeof(struct ip_nat_helper));
+
+ hlpr->tuple.dst.protonum = IPPROTO_TCP;
+ hlpr->tuple.src.u.tcp.port = htons(ports[i]);
+ hlpr->mask.src.u.tcp.port = 0xFFFF;
+ hlpr->mask.dst.protonum = 0xFFFF;
+ hlpr->help = help;
+ hlpr->flags = 0;
+ hlpr->me = THIS_MODULE;
+ hlpr->expect = irc_nat_expected;
+
+ tmpname = &irc_names[i][0];
+ if (ports[i] == IRC_PORT)
+ sprintf(tmpname, "irc");
+ else
+ sprintf(tmpname, "irc-%d", i);
+ hlpr->name = tmpname;
+
+ DEBUGP
+ ("ip_nat_irc: Trying to register helper for port %d: name %s\n",
+ ports[i], hlpr->name);
+ ret = ip_nat_helper_register(hlpr);
+
+ if (ret) {
+ printk
+ ("ip_nat_irc: error registering helper for port %d\n",
+ ports[i]);
+ fini();
+ return 1;
}
+ ports_c++;
}
return ret;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)