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
|