On Mon, May 30, 2011 at 12:02:23AM +0300, Julian Anastasov wrote: > > 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: Julian Anastasov <ja@xxxxxx> > --- > > As this is not exactly a fix, it can be applied to > ipvs-next-2.6 after the merge window. Thanks, will do. > diff -urp v2.6.39/linux/net/netfilter/ipvs/ip_vs_ftp.c linux/net/netfilter/ipvs/ip_vs_ftp.c > --- v2.6.39/linux/net/netfilter/ipvs/ip_vs_ftp.c 2011-05-20 10:38:08.000000000 +0300 > +++ linux/net/netfilter/ipvs/ip_vs_ftp.c 2011-05-29 11:51:50.630247073 +0300 > @@ -44,8 +44,8 @@ > #include <net/ip_vs.h> > > > -#define SERVER_STRING "227 Entering Passive Mode (" > -#define CLIENT_STRING "PORT " > +#define SERVER_STRING "227 " > +#define CLIENT_STRING "PORT" > > > /* > @@ -79,14 +79,17 @@ ip_vs_ftp_done_conn(struct ip_vs_app *ap > > /* > * 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. > */ > 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, > char **start, char **end) > { > + char *s, c; > unsigned char p[6]; > int i = 0; > > @@ -101,19 +104,38 @@ static int ip_vs_ftp_get_addrport(char * > if (strnicmp(data, pattern, plen) != 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) > return -1; > + if (*data == term) > + break; > } > *end = data; > > memset(p, 0, sizeof(p)); > - for (data = *start; data != *end; data++) { > - if (*data >= '0' && *data <= '9') { > - p[i] = p[i]*10 + *data - '0'; > - } else if (*data == ',' && i < 5) { > + for (data = s; ; data++) { > + c = *data; > + if (c == term) > + break; > + if (c >= '0' && c <= '9') { > + p[i] = p[i]*10 + c - '0'; > + } else if (c == ',' && i < 5) { > i++; > } else { > /* unexpected character */ > @@ -124,8 +146,9 @@ static int ip_vs_ftp_get_addrport(char * > if (i != 5) > return -1; > > - *addr = get_unaligned((__be32 *)p); > - *port = get_unaligned((__be16 *)(p + 4)); > + *start = s; > + *addr = get_unaligned((__be32 *) p); > + *port = get_unaligned((__be16 *) (p + 4)); > return 1; > } > > @@ -185,7 +208,8 @@ static int ip_vs_ftp_out(struct ip_vs_ap > > if (ip_vs_ftp_get_addrport(data, data_limit, > SERVER_STRING, > - sizeof(SERVER_STRING)-1, ')', > + sizeof(SERVER_STRING)-1, > + '(', ')', > &from.ip, &port, > &start, &end) != 1) > return 1; > @@ -345,7 +369,7 @@ static int ip_vs_ftp_in(struct ip_vs_app > */ > if (ip_vs_ftp_get_addrport(data_start, data_limit, > CLIENT_STRING, sizeof(CLIENT_STRING)-1, > - '\r', &to.ip, &port, > + ' ', '\r', &to.ip, &port, > &start, &end) != 1) > return 1; > > -- To unsubscribe from this list: send the line "unsubscribe lvs-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html