Commit c3aa1bd3 authored by Julian Anastasov's avatar Julian Anastasov Committed by Simon Horman

ipvs: support more FTP PASV responses

	Change the parsing of FTP commands and responses to
support skip character. It allows to detect variations in
the 227 PASV response.
Signed-off-by: default avatarJulian Anastasov <ja@ssi.bg>
Signed-off-by: default avatarSimon Horman <horms@verge.net.au>
parent 8f0ea0fe
...@@ -44,8 +44,8 @@ ...@@ -44,8 +44,8 @@
#include <net/ip_vs.h> #include <net/ip_vs.h>
#define SERVER_STRING "227 Entering Passive Mode (" #define SERVER_STRING "227 "
#define CLIENT_STRING "PORT " #define CLIENT_STRING "PORT"
/* /*
...@@ -79,14 +79,17 @@ ip_vs_ftp_done_conn(struct ip_vs_app *app, struct ip_vs_conn *cp) ...@@ -79,14 +79,17 @@ ip_vs_ftp_done_conn(struct ip_vs_app *app, struct ip_vs_conn *cp)
/* /*
* Get <addr,port> from the string "xxx.xxx.xxx.xxx,ppp,ppp", started * Get <addr,port> from the string "xxx.xxx.xxx.xxx,ppp,ppp", started
* with the "pattern" and terminated with the "term" character. * with the "pattern", ignoring before "skip" and terminated with
* the "term" character.
* <addr,port> is in network order. * <addr,port> is in network order.
*/ */
static int ip_vs_ftp_get_addrport(char *data, char *data_limit, static int ip_vs_ftp_get_addrport(char *data, char *data_limit,
const char *pattern, size_t plen, char term, const char *pattern, size_t plen,
char skip, char term,
__be32 *addr, __be16 *port, __be32 *addr, __be16 *port,
char **start, char **end) char **start, char **end)
{ {
char *s, c;
unsigned char p[6]; unsigned char p[6];
int i = 0; int i = 0;
...@@ -101,19 +104,38 @@ static int ip_vs_ftp_get_addrport(char *data, char *data_limit, ...@@ -101,19 +104,38 @@ static int ip_vs_ftp_get_addrport(char *data, char *data_limit,
if (strnicmp(data, pattern, plen) != 0) { if (strnicmp(data, pattern, plen) != 0) {
return 0; return 0;
} }
*start = data + plen; s = data + plen;
if (skip) {
int found = 0;
for (;; s++) {
if (s == data_limit)
return -1;
if (!found) {
if (*s == skip)
found = 1;
} else if (*s != skip) {
break;
}
}
}
for (data = *start; *data != term; data++) { for (data = s; ; data++) {
if (data == data_limit) if (data == data_limit)
return -1; return -1;
if (*data == term)
break;
} }
*end = data; *end = data;
memset(p, 0, sizeof(p)); memset(p, 0, sizeof(p));
for (data = *start; data != *end; data++) { for (data = s; ; data++) {
if (*data >= '0' && *data <= '9') { c = *data;
p[i] = p[i]*10 + *data - '0'; if (c == term)
} else if (*data == ',' && i < 5) { break;
if (c >= '0' && c <= '9') {
p[i] = p[i]*10 + c - '0';
} else if (c == ',' && i < 5) {
i++; i++;
} else { } else {
/* unexpected character */ /* unexpected character */
...@@ -124,8 +146,9 @@ static int ip_vs_ftp_get_addrport(char *data, char *data_limit, ...@@ -124,8 +146,9 @@ static int ip_vs_ftp_get_addrport(char *data, char *data_limit,
if (i != 5) if (i != 5)
return -1; return -1;
*addr = get_unaligned((__be32 *)p); *start = s;
*port = get_unaligned((__be16 *)(p + 4)); *addr = get_unaligned((__be32 *) p);
*port = get_unaligned((__be16 *) (p + 4));
return 1; return 1;
} }
...@@ -185,7 +208,8 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, ...@@ -185,7 +208,8 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
if (ip_vs_ftp_get_addrport(data, data_limit, if (ip_vs_ftp_get_addrport(data, data_limit,
SERVER_STRING, SERVER_STRING,
sizeof(SERVER_STRING)-1, ')', sizeof(SERVER_STRING)-1,
'(', ')',
&from.ip, &port, &from.ip, &port,
&start, &end) != 1) &start, &end) != 1)
return 1; return 1;
...@@ -345,7 +369,7 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, ...@@ -345,7 +369,7 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
*/ */
if (ip_vs_ftp_get_addrport(data_start, data_limit, if (ip_vs_ftp_get_addrport(data_start, data_limit,
CLIENT_STRING, sizeof(CLIENT_STRING)-1, CLIENT_STRING, sizeof(CLIENT_STRING)-1,
'\r', &to.ip, &port, ' ', '\r', &to.ip, &port,
&start, &end) != 1) &start, &end) != 1)
return 1; return 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment