mirror of https://gitee.com/openkylin/linux.git
[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:
parent
1aaec67f93
commit
1884f78c7a
|
@ -111,102 +111,14 @@ static struct ftp_search {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This code is based on inet_pton() in glibc-2.2.4 */
|
|
||||||
static int
|
static int
|
||||||
get_ipv6_addr(const char *src, size_t dlen, struct in6_addr *dst, u_int8_t term)
|
get_ipv6_addr(const char *src, size_t dlen, struct in6_addr *dst, u_int8_t term)
|
||||||
{
|
{
|
||||||
static const char xdigits[] = "0123456789abcdef";
|
int ret = in6_pton(src, min_t(size_t, dlen, 0xffff), dst, term, &end);
|
||||||
u_int8_t tmp[16], *tp, *endp, *colonp;
|
if (ret > 0)
|
||||||
int ch, saw_xdigit;
|
return (int)(end - src);
|
||||||
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;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int try_number(const char *data, size_t dlen, u_int32_t array[],
|
static int try_number(const char *data, size_t dlen, u_int32_t array[],
|
||||||
int array_size, char sep, char term)
|
int array_size, char sep, char term)
|
||||||
|
|
Loading…
Reference in New Issue