X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv4%2Fnetfilter%2Fip_nat_ftp.c;h=be00284f8a1d2aa397e1fef5136e6813ba2ed1cf;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=946ca05bb90f7014097a51c7cd983ad412a51738;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/net/ipv4/netfilter/ip_nat_ftp.c b/net/ipv4/netfilter/ip_nat_ftp.c index 946ca05bb..be00284f8 100644 --- a/net/ipv4/netfilter/ip_nat_ftp.c +++ b/net/ipv4/netfilter/ip_nat_ftp.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -33,9 +34,7 @@ MODULE_DESCRIPTION("ftp NAT helper"); static int ports[MAX_PORTS]; static int ports_c; -MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i"); - -DECLARE_LOCK_EXTERN(ip_ftp_lock); +module_param_array(ports, int, ports_c, 0400); /* FIXME: Time out? --RR */ @@ -59,8 +58,6 @@ ftp_nat_expected(struct sk_buff **pskb, DEBUGP("nat_expected: We have a connection!\n"); exp_ftp_info = &ct->master->help.exp_ftp_info; - LOCK_BH(&ip_ftp_lock); - if (exp_ftp_info->ftptype == IP_CT_FTP_PORT || exp_ftp_info->ftptype == IP_CT_FTP_EPRT) { /* PORT command: make connection go to the client. */ @@ -75,7 +72,6 @@ ftp_nat_expected(struct sk_buff **pskb, DEBUGP("nat_expected: PASV cmd. %u.%u.%u.%u->%u.%u.%u.%u\n", NIPQUAD(newsrcip), NIPQUAD(newdstip)); } - UNLOCK_BH(&ip_ftp_lock); if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) newip = newsrcip; @@ -111,8 +107,6 @@ mangle_rfc959_packet(struct sk_buff **pskb, { char buffer[sizeof("nnn,nnn,nnn,nnn,nnn,nnn")]; - MUST_BE_LOCKED(&ip_ftp_lock); - sprintf(buffer, "%u,%u,%u,%u,%u,%u", NIPQUAD(newip), port>>8, port&0xFF); @@ -134,8 +128,6 @@ mangle_eprt_packet(struct sk_buff **pskb, { char buffer[sizeof("|1|255.255.255.255|65535|")]; - MUST_BE_LOCKED(&ip_ftp_lock); - sprintf(buffer, "|1|%u.%u.%u.%u|%u|", NIPQUAD(newip), port); DEBUGP("calling ip_nat_mangle_tcp_packet\n"); @@ -156,8 +148,6 @@ mangle_epsv_packet(struct sk_buff **pskb, { char buffer[sizeof("|||65535|")]; - MUST_BE_LOCKED(&ip_ftp_lock); - sprintf(buffer, "|||%u|", port); DEBUGP("calling ip_nat_mangle_tcp_packet\n"); @@ -177,7 +167,7 @@ static int (*mangle[])(struct sk_buff **, u_int32_t, u_int16_t, [IP_CT_FTP_EPSV] = mangle_epsv_packet }; -static int ftp_data_fixup(const struct ip_ct_ftp_expect *ct_ftp_info, +static int ftp_data_fixup(const struct ip_ct_ftp_expect *exp_ftp_info, struct ip_conntrack *ct, struct sk_buff **pskb, enum ip_conntrack_info ctinfo, @@ -189,15 +179,14 @@ static int ftp_data_fixup(const struct ip_ct_ftp_expect *ct_ftp_info, u_int16_t port; struct ip_conntrack_tuple newtuple; - MUST_BE_LOCKED(&ip_ftp_lock); DEBUGP("FTP_NAT: seq %u + %u in %u\n", - expect->seq, ct_ftp_info->len, + expect->seq, exp_ftp_info->len, ntohl(tcph->seq)); /* Change address inside packet to match way we're mapping this connection. */ - if (ct_ftp_info->ftptype == IP_CT_FTP_PASV - || ct_ftp_info->ftptype == IP_CT_FTP_EPSV) { + if (exp_ftp_info->ftptype == IP_CT_FTP_PASV + || exp_ftp_info->ftptype == IP_CT_FTP_EPSV) { /* PASV/EPSV response: must be where client thinks server is */ newip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; @@ -219,7 +208,7 @@ static int ftp_data_fixup(const struct ip_ct_ftp_expect *ct_ftp_info, newtuple.src.u.tcp.port = expect->tuple.src.u.tcp.port; /* Try to get same port: if not, try to change it. */ - for (port = ct_ftp_info->port; port != 0; port++) { + for (port = exp_ftp_info->port; port != 0; port++) { newtuple.dst.u.tcp.port = htons(port); if (ip_conntrack_change_expect(expect, &newtuple) == 0) @@ -228,9 +217,9 @@ static int ftp_data_fixup(const struct ip_ct_ftp_expect *ct_ftp_info, if (port == 0) return 0; - if (!mangle[ct_ftp_info->ftptype](pskb, newip, port, + if (!mangle[exp_ftp_info->ftptype](pskb, newip, port, expect->seq - ntohl(tcph->seq), - ct_ftp_info->len, ct, ctinfo)) + exp_ftp_info->len, ct, ctinfo)) return 0; return 1; @@ -247,12 +236,12 @@ static unsigned int help(struct ip_conntrack *ct, struct tcphdr *tcph = (void *)iph + iph->ihl*4; unsigned int datalen; int dir; - struct ip_ct_ftp_expect *ct_ftp_info; + struct ip_ct_ftp_expect *exp_ftp_info; if (!exp) DEBUGP("ip_nat_ftp: no exp!!"); - ct_ftp_info = &exp->help.exp_ftp_info; + exp_ftp_info = &exp->help.exp_ftp_info; /* Only mangle things once: original direction in POST_ROUTING and reply direction on PRE_ROUTING. */ @@ -268,29 +257,23 @@ static unsigned int help(struct ip_conntrack *ct, } datalen = (*pskb)->len - iph->ihl * 4 - tcph->doff * 4; - LOCK_BH(&ip_ftp_lock); /* If it's in the right range... */ - if (between(exp->seq + ct_ftp_info->len, + if (between(exp->seq + exp_ftp_info->len, ntohl(tcph->seq), ntohl(tcph->seq) + datalen)) { - if (!ftp_data_fixup(ct_ftp_info, ct, pskb, ctinfo, exp)) { - UNLOCK_BH(&ip_ftp_lock); + if (!ftp_data_fixup(exp_ftp_info, ct, pskb, ctinfo, exp)) return NF_DROP; - } } else { /* Half a match? This means a partial retransmisison. It's a cracker being funky. */ if (net_ratelimit()) { printk("FTP_NAT: partial packet %u/%u in %u/%u\n", - exp->seq, ct_ftp_info->len, + exp->seq, exp_ftp_info->len, ntohl(tcph->seq), ntohl(tcph->seq) + datalen); } - UNLOCK_BH(&ip_ftp_lock); return NF_DROP; } - UNLOCK_BH(&ip_ftp_lock); - return NF_ACCEPT; } @@ -313,10 +296,10 @@ static int __init init(void) int i, ret = 0; char *tmpname; - if (ports[0] == 0) - ports[0] = FTP_PORT; + if (ports_c == 0) + ports[ports_c++] = FTP_PORT; - for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { + for (i = 0; i < ports_c; i++) { ftp[i].tuple.dst.protonum = IPPROTO_TCP; ftp[i].tuple.src.u.tcp.port = htons(ports[i]); ftp[i].mask.dst.protonum = 0xFFFF; @@ -343,7 +326,6 @@ static int __init init(void) fini(); return ret; } - ports_c++; } return ret;