Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1884f78c authored by YOSHIFUJI Hideaki's avatar YOSHIFUJI Hideaki Committed by David S. Miller
Browse files

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

parent 1aaec67f
Loading
Loading
Loading
Loading
+4 −92
Original line number Diff line number Diff line
@@ -111,102 +111,14 @@ 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");
	int ret = in6_pton(src, min_t(size_t, dlen, 0xffff), dst, term, &end);
	if (ret > 0)
		return (int)(end - src);
	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[],
                      int array_size, char sep, char term)