[NETFILTER] NF_CONNTRACK_FTP: Use in6_pton() to convert address string.

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
This commit is contained in:
YOSHIFUJI Hideaki 2006-06-19 03:20:32 +09:00 committed by David S. Miller
parent 1aaec67f93
commit 1884f78c7a
1 changed files with 4 additions and 92 deletions

View File

@ -111,101 +111,13 @@ static struct ftp_search {
},
};
/* This code is based on inet_pton() in glibc-2.2.4 */
static int
get_ipv6_addr(const char *src, size_t dlen, struct in6_addr *dst, u_int8_t term)
{
static const char xdigits[] = "0123456789abcdef";
u_int8_t tmp[16], *tp, *endp, *colonp;
int ch, saw_xdigit;
u_int32_t val;
size_t clen = 0;
tp = memset(tmp, '\0', sizeof(tmp));
endp = tp + sizeof(tmp);
colonp = NULL;
/* Leading :: requires some special handling. */
if (*src == ':'){
if (*++src != ':') {
DEBUGP("invalid \":\" at the head of addr\n");
return 0;
}
clen++;
}
saw_xdigit = 0;
val = 0;
while ((clen < dlen) && (*src != term)) {
const char *pch;
ch = tolower(*src++);
clen++;
pch = strchr(xdigits, ch);
if (pch != NULL) {
val <<= 4;
val |= (pch - xdigits);
if (val > 0xffff)
return 0;
saw_xdigit = 1;
continue;
}
if (ch != ':') {
DEBUGP("get_ipv6_addr: invalid char. \'%c\'\n", ch);
return 0;
}
if (!saw_xdigit) {
if (colonp) {
DEBUGP("invalid location of \"::\".\n");
return 0;
}
colonp = tp;
continue;
} else if (*src == term) {
DEBUGP("trancated IPv6 addr\n");
return 0;
}
if (tp + 2 > endp)
return 0;
*tp++ = (u_int8_t) (val >> 8) & 0xff;
*tp++ = (u_int8_t) val & 0xff;
saw_xdigit = 0;
val = 0;
continue;
}
if (saw_xdigit) {
if (tp + 2 > endp)
return 0;
*tp++ = (u_int8_t) (val >> 8) & 0xff;
*tp++ = (u_int8_t) val & 0xff;
}
if (colonp != NULL) {
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
const int n = tp - colonp;
int i;
if (tp == endp)
return 0;
for (i = 1; i <= n; i++) {
endp[- i] = colonp[n - i];
colonp[n - i] = 0;
}
tp = endp;
}
if (tp != endp || (*src != term))
return 0;
memcpy(dst->s6_addr, tmp, sizeof(dst->s6_addr));
return clen;
int ret = in6_pton(src, min_t(size_t, dlen, 0xffff), dst, term, &end);
if (ret > 0)
return (int)(end - src);
return 0;
}
static int try_number(const char *data, size_t dlen, u_int32_t array[],