25 #define KMSG_COMPONENT "IPVS"
26 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
28 #include <linux/module.h>
30 #include <linux/kernel.h>
34 #include <linux/netfilter.h>
42 #include <asm/unaligned.h>
47 #define SERVER_STRING "227 "
48 #define CLIENT_STRING "PORT"
55 static unsigned int ports_count = 1;
62 static int ip_vs_ftp_pasv;
87 static int ip_vs_ftp_get_addrport(
char *
data,
char *data_limit,
97 if (data_limit - data < plen) {
99 if (
strnicmp(data, pattern, data_limit - data) == 0)
105 if (
strnicmp(data, pattern, plen) != 0) {
118 }
else if (*s != skip) {
124 for (data = s; ; data++) {
125 if (data == data_limit)
133 for (data = s; ; data++) {
137 if (c >=
'0' && c <=
'9') {
138 p[
i] = p[
i]*10 + c -
'0';
139 }
else if (c ==
',' && i < 5) {
174 char *
data, *data_limit;
180 unsigned int buf_len;
186 #ifdef CONFIG_IP_VS_IPV6
204 if (cp->
app_data == &ip_vs_ftp_pasv) {
206 th = (
struct tcphdr *)&(((
char *)iph)[iph->ihl*4]);
207 data = (
char *)th + (th->doff << 2);
208 data_limit = skb_tail_pointer(skb);
210 if (ip_vs_ftp_get_addrport(data, data_limit,
218 IP_VS_DBG(7,
"PASV response (%pI4:%d) -> %pI4:%d detected\n",
226 ip_vs_conn_fill_param(ip_vs_conn_net(cp),
AF_INET,
233 ip_vs_conn_fill_param(ip_vs_conn_net(cp),
235 0, &cp->
vaddr, port, &p);
244 ip_vs_control_add(n_cp, cp);
252 snprintf(buf,
sizeof(buf),
"%u,%u,%u,%u,%u,%u",
253 ((
unsigned char *)&
from.ip)[0],
254 ((
unsigned char *)&
from.ip)[1],
255 ((
unsigned char *)&
from.ip)[2],
256 ((
unsigned char *)&
from.ip)[3],
262 ct = nf_ct_get(skb, &ctinfo);
263 if (ct && !nf_ct_is_untracked(ct) && nfct_nat(ct)) {
270 ret = nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
272 start-data, end-start,
311 struct sk_buff *skb,
int *diff)
322 #ifdef CONFIG_IP_VS_IPV6
345 th = (
struct tcphdr *)&(((
char *)iph)[iph->ihl*4]);
350 data = data_start = (
char *)th + (th->doff << 2);
351 data_limit = skb_tail_pointer(skb);
353 while (data <= data_limit - 6) {
354 if (
strnicmp(data,
"PASV\r\n", 6) == 0) {
358 data_limit - data_start);
372 if (ip_vs_ftp_get_addrport(data_start, data_limit,
374 ' ',
'\r', &to.ip, &port,
386 IP_VS_DBG(7,
"protocol %s %pI4:%d %pI4:%d\n",
392 ip_vs_conn_fill_param(ip_vs_conn_net(cp),
AF_INET,
405 ip_vs_control_add(n_cp, cp);
426 .init_conn = ip_vs_ftp_init_conn,
427 .done_conn = ip_vs_ftp_done_conn,
430 .pkt_out = ip_vs_ftp_out,
431 .pkt_in = ip_vs_ftp_in,
437 static int __net_init __ip_vs_ftp_init(
struct net *net)
450 for (i = 0; i < ports_count; i++) {
456 pr_info(
"%s: loaded support on port[%d] = %d\n",
457 app->
name, i, ports[i]);
468 static void __ip_vs_ftp_exit(
struct net *net)
474 .init = __ip_vs_ftp_init,
475 .exit = __ip_vs_ftp_exit,
478 static int __init ip_vs_ftp_init(
void)
489 static void __exit ip_vs_ftp_exit(
void)