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,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[],
|
||||
|
|
Loading…
Reference in New Issue