diff options
Diffstat (limited to 'lib/libc/inet')
| -rw-r--r-- | lib/libc/inet/inet_net_ntop.c | 206 | ||||
| -rw-r--r-- | lib/libc/inet/inet_net_pton.c | 363 | 
2 files changed, 157 insertions, 412 deletions
| diff --git a/lib/libc/inet/inet_net_ntop.c b/lib/libc/inet/inet_net_ntop.c index 9d98dbb5ca99..30dd5c0571f2 100644 --- a/lib/libc/inet/inet_net_ntop.c +++ b/lib/libc/inet/inet_net_ntop.c @@ -1,20 +1,23 @@ -/*- - * SPDX-License-Identifier: ISC +/*	$OpenBSD: inet_net_ntop.c,v 1.9 2019/07/03 03:24:04 deraadt Exp $	*/ + +/* + * Copyright (c) 2012 by Gilles Chehade <gilles@openbsd.org> + * Copyright (c) 1996 by Internet Software Consortium.   * - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1996,1999 by Internet Software Consortium. + * SPDX-License-Identifier: ISC   *   * Permission to use, copy, modify, and distribute this software for any   * purpose with or without fee is hereby granted, provided that the above   * copyright notice and this permission notice appear in all copies.   * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE.   */  #include "port_before.h" @@ -31,18 +34,10 @@  #include "port_after.h" -#ifdef SPRINTF_CHAR -# define SPRINTF(x) strlen(sprintf/**/x) -#else -# define SPRINTF(x) ((size_t)sprintf x) -#endif - -static char *	inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, -		    size_t size); -static char *	inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, -		    size_t size); +static char *inet_net_ntop_ipv4(const u_char *, int, char *, size_t); +static char *inet_net_ntop_ipv6(const u_char *, int, char *, size_t); -/*% +/*   * char *   * inet_net_ntop(af, src, bits, dst, size)   *	convert network number from network to presentation format. @@ -66,7 +61,7 @@ inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size)  	}  } -/*% +/*   * static char *   * inet_net_ntop_ipv4(src, bits, dst, size)   *	convert IPv4 network number from network to presentation format. @@ -83,53 +78,63 @@ static char *  inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)  {  	char *odst = dst; -	char *t;  	u_int m;  	int b; +	char *ep; +	int advance; + +	ep = dst + size; +	if (ep <= dst) +		goto emsgsize;  	if (bits < 0 || bits > 32) {  		errno = EINVAL;  		return (NULL);  	} -  	if (bits == 0) { -		if (size < sizeof "0") +		if (ep - dst < sizeof "0")  			goto emsgsize;  		*dst++ = '0'; -		size--;  		*dst = '\0';  	}  	/* Format whole octets. */  	for (b = bits / 8; b > 0; b--) { -		if (size <= sizeof "255.") +		if (ep - dst < sizeof "255.") +			goto emsgsize; +		advance = snprintf(dst, ep - dst, "%u", *src++); +		if (advance <= 0 || advance >= ep - dst)  			goto emsgsize; -		t = dst; -		dst += SPRINTF((dst, "%u", *src++)); +		dst += advance;  		if (b > 1) { +			if (dst + 1 >= ep) +				goto emsgsize;  			*dst++ = '.';  			*dst = '\0';  		} -		size -= (size_t)(dst - t);  	}  	/* Format partial octet. */  	b = bits % 8;  	if (b > 0) { -		if (size <= sizeof ".255") +		if (ep - dst < sizeof ".255")  			goto emsgsize; -		t = dst;  		if (dst != odst)  			*dst++ = '.';  		m = ((1 << b) - 1) << (8 - b); -		dst += SPRINTF((dst, "%u", *src & m)); -		size -= (size_t)(dst - t); +		advance = snprintf(dst, ep - dst, "%u", *src & m); +		if (advance <= 0 || advance >= ep - dst) +			goto emsgsize; +		dst += advance;  	}  	/* Format CIDR /width. */ -	if (size <= sizeof "/32") +	if (ep - dst < sizeof "/32") +		goto emsgsize; +	advance = snprintf(dst, ep - dst, "/%u", bits); +	if (advance <= 0 || advance >= ep - dst)  		goto emsgsize; -	dst += SPRINTF((dst, "/%u", bits)); +	dst += advance;  	return (odst);   emsgsize: @@ -137,132 +142,27 @@ inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)  	return (NULL);  } -/*% - * static char * - * inet_net_ntop_ipv6(src, bits, fakebits, dst, size) - *	convert IPv6 network number from network to presentation format. - *	generates CIDR style result always. Picks the shortest representation - *	unless the IP is really IPv4. - *	always prints specified number of bits (bits). - * return: - *	pointer to dst, or NULL if an error occurred (check errno). - * note: - *	network byte order assumed.  this means 192.5.5.240/28 has - *	0b11110000 in its fourth octet. - * author: - *	Vadim Kogan (UCB), June 2001 - *  Original version (IPv4) by Paul Vixie (ISC), July 1996 - */ -  static char * -inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) { -	u_int	m; -	int	b; -	int	p; -	int	zero_s, zero_l, tmp_zero_s, tmp_zero_l; -	int	i; -	int	is_ipv4 = 0; -	unsigned char inbuf[16]; -	char outbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")]; -	char	*cp; -	int	words; -	u_char	*s; +inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) +{ +	int	ret; +	char	buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255:255:255:255/128")];  	if (bits < 0 || bits > 128) {  		errno = EINVAL;  		return (NULL);  	} -	cp = outbuf; - -	if (bits == 0) { -		*cp++ = ':'; -		*cp++ = ':'; -		*cp = '\0'; -	} else { -		/* Copy src to private buffer.  Zero host part. */ -		p = (bits + 7) / 8; -		memcpy(inbuf, src, p); -		memset(inbuf + p, 0, 16 - p); -		b = bits % 8; -		if (b != 0) { -			m = ~0 << (8 - b); -			inbuf[p-1] &= m; -		} - -		s = inbuf; - -		/* how many words need to be displayed in output */ -		words = (bits + 15) / 16; -		if (words == 1) -			words = 2; - -		/* Find the longest substring of zero's */ -		zero_s = zero_l = tmp_zero_s = tmp_zero_l = 0; -		for (i = 0; i < (words * 2); i += 2) { -			if ((s[i] | s[i+1]) == 0) { -				if (tmp_zero_l == 0) -					tmp_zero_s = i / 2; -				tmp_zero_l++; -			} else { -				if (tmp_zero_l && zero_l < tmp_zero_l) { -					zero_s = tmp_zero_s; -					zero_l = tmp_zero_l; -					tmp_zero_l = 0; -				} -			} -		} - -		if (tmp_zero_l && zero_l < tmp_zero_l) { -			zero_s = tmp_zero_s; -			zero_l = tmp_zero_l; -		} - -		if (zero_l != words && zero_s == 0 && ((zero_l == 6) || -		    ((zero_l == 5 && s[10] == 0xff && s[11] == 0xff) || -		    ((zero_l == 7 && s[14] != 0 && s[15] != 1))))) -			is_ipv4 = 1; - -		/* Format whole words. */ -		for (p = 0; p < words; p++) { -			if (zero_l != 0 && p >= zero_s && p < zero_s + zero_l) { -				/* Time to skip some zeros */ -				if (p == zero_s) -					*cp++ = ':'; -				if (p == words - 1) -					*cp++ = ':'; -				s++; -				s++; -				continue; -			} +	if (inet_ntop(AF_INET6, src, buf, size) == NULL) +		return (NULL); -			if (is_ipv4 && p > 5 ) { -				*cp++ = (p == 6) ? ':' : '.'; -				cp += SPRINTF((cp, "%u", *s++)); -				/* we can potentially drop the last octet */ -				if (p != 7 || bits > 120) { -					*cp++ = '.'; -					cp += SPRINTF((cp, "%u", *s++)); -				} -			} else { -				if (cp != outbuf) -					*cp++ = ':'; -				cp += SPRINTF((cp, "%x", *s * 256 + s[1])); -				s += 2; -			} -		} +	ret = snprintf(dst, size, "%s/%d", buf, bits); +	if (ret < 0 || ret >= size) { +		errno = EMSGSIZE; +		return (NULL);  	} -	/* Format CIDR /width. */ -	sprintf(cp, "/%u", bits); -	if (strlen(outbuf) + 1 > size) -		goto emsgsize; -	strcpy(dst, outbuf);  	return (dst); - -emsgsize: -	errno = EMSGSIZE; -	return (NULL);  }  /* @@ -271,5 +171,3 @@ emsgsize:   */  #undef inet_net_ntop  __weak_reference(__inet_net_ntop, inet_net_ntop); - -/*! \file */ diff --git a/lib/libc/inet/inet_net_pton.c b/lib/libc/inet/inet_net_pton.c index d566a0e1d3c3..14c88eb72014 100644 --- a/lib/libc/inet/inet_net_pton.c +++ b/lib/libc/inet/inet_net_pton.c @@ -1,20 +1,23 @@ -/*- - * SPDX-License-Identifier: ISC +/*	$OpenBSD: inet_net_pton.c,v 1.14 2022/12/27 17:10:06 jmc Exp $	*/ + +/* + * Copyright (c) 2012 by Gilles Chehade <gilles@openbsd.org> + * Copyright (c) 1996,1999 by Internet Software Consortium.   * - * Copyright (C) 2004, 2005, 2008  Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1996, 1998, 1999, 2001, 2003  Internet Software Consortium. + * SPDX-License-Identifier: ISC   * - * Permission to use, copy, modify, and/or distribute this software for any + * Permission to use, copy, modify, and distribute this software for any   * purpose with or without fee is hereby granted, provided that the above   * copyright notice and this permission notice appear in all copies.   * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE.   */  #include "port_before.h" @@ -22,7 +25,6 @@  #include <sys/types.h>  #include <sys/socket.h>  #include <netinet/in.h> -#include <arpa/nameser.h>  #include <arpa/inet.h>  #include <assert.h> @@ -34,13 +36,37 @@  #include "port_after.h" -#ifdef SPRINTF_CHAR -# define SPRINTF(x) strlen(sprintf/**/x) -#else -# define SPRINTF(x) ((size_t)sprintf x) -#endif +static int	inet_net_pton_ipv4(const char *, u_char *, size_t); +static int	inet_net_pton_ipv6(const char *, u_char *, size_t); -/*% +/* + * static int + * inet_net_pton(af, src, dst, size) + *	convert network number from presentation to network format. + *	accepts hex octets, hex strings, decimal octets, and /CIDR. + *	"size" is in bytes and describes "dst". + * return: + *	number of bits, either imputed classfully or specified with /CIDR, + *	or -1 if some failure occurred (check errno).  ENOENT means it was + *	not a valid network specification. + * author: + *	Paul Vixie (ISC), June 1996 + */ +int +inet_net_pton(int af, const char *src, void *dst, size_t size) +{ +	switch (af) { +	case AF_INET: +		return (inet_net_pton_ipv4(src, dst, size)); +	case AF_INET6: +		return (inet_net_pton_ipv6(src, dst, size)); +	default: +		errno = EAFNOSUPPORT; +		return (-1); +	} +} + +/*   * static int   * inet_net_pton_ipv4(src, dst, size)   *	convert IPv4 network number from presentation to network format. @@ -57,22 +83,24 @@   *	Paul Vixie (ISC), June 1996   */  static int -inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) { -	static const char xdigits[] = "0123456789abcdef"; -	static const char digits[] = "0123456789"; -	int n, ch, tmp = 0, dirty, bits; +inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) +{ +	static const char +		xdigits[] = "0123456789abcdef", +		digits[] = "0123456789"; +	int n, ch, tmp, dirty, bits;  	const u_char *odst = dst; -	ch = *src++; +	ch = (unsigned char)*src++;  	if (ch == '0' && (src[0] == 'x' || src[0] == 'X') -	    && isascii((unsigned char)(src[1])) -	    && isxdigit((unsigned char)(src[1]))) { +	    && isascii((unsigned char)src[1]) && isxdigit((unsigned char)src[1])) {  		/* Hexadecimal: Eat nybble string. */ -		if (size <= 0U) +		if (size == 0)  			goto emsgsize; -		dirty = 0; -		src++;	/*%< skip x or X. */ -		while ((ch = *src++) != '\0' && isascii(ch) && isxdigit(ch)) { +		tmp = 0, dirty = 0; +		src++;	/* skip x or X. */ +		while ((ch = (unsigned char)*src++) != '\0' && +		    isascii(ch) && isxdigit(ch)) {  			if (isupper(ch))  				ch = tolower(ch);  			n = strchr(xdigits, ch) - xdigits; @@ -82,14 +110,14 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {  			else  				tmp = (tmp << 4) | n;  			if (++dirty == 2) { -				if (size-- <= 0U) +				if (size-- == 0)  					goto emsgsize;  				*dst++ = (u_char) tmp;  				dirty = 0;  			}  		} -		if (dirty) {  /*%< Odd trailing nybble? */ -			if (size-- <= 0U) +		if (dirty) {  /* Odd trailing nybble? */ +			if (size-- == 0)  				goto emsgsize;  			*dst++ = (u_char) (tmp << 4);  		} @@ -104,16 +132,16 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {  				tmp += n;  				if (tmp > 255)  					goto enoent; -			} while ((ch = *src++) != '\0' && +			} while ((ch = (unsigned char)*src++) != '\0' &&  				 isascii(ch) && isdigit(ch)); -			if (size-- <= 0U) +			if (size-- == 0)  				goto emsgsize;  			*dst++ = (u_char) tmp;  			if (ch == '\0' || ch == '/')  				break;  			if (ch != '.')  				goto enoent; -			ch = *src++; +			ch = (unsigned char)*src++;  			if (!isascii(ch) || !isdigit(ch))  				goto enoent;  		} @@ -121,10 +149,10 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {  		goto enoent;  	bits = -1; -	if (ch == '/' && isascii((unsigned char)(src[0])) && -	    isdigit((unsigned char)(src[0])) && dst > odst) { +	if (ch == '/' && isascii((unsigned char)src[0]) && +	    isdigit((unsigned char)src[0]) && dst > odst) {  		/* CIDR width specifier.  Nothing can follow it. */ -		ch = *src++;	/*%< Skip over the /. */ +		ch = (unsigned char)*src++;	/* Skip over the /. */  		bits = 0;  		do {  			n = strchr(digits, ch) - digits; @@ -132,8 +160,9 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {  			bits *= 10;  			bits += n;  			if (bits > 32) -				goto enoent; -		} while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch)); +				goto emsgsize; +		} while ((ch = (unsigned char)*src++) != '\0' && +			 isascii(ch) && isdigit(ch));  		if (ch != '\0')  			goto enoent;  	} @@ -147,29 +176,23 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {  		goto enoent;  	/* If no CIDR spec was given, infer width from net class. */  	if (bits == -1) { -		if (*odst >= 240)	/*%< Class E */ +		if (*odst >= 240)	/* Class E */  			bits = 32; -		else if (*odst >= 224)	/*%< Class D */ -			bits = 8; -		else if (*odst >= 192)	/*%< Class C */ +		else if (*odst >= 224)	/* Class D */ +			bits = 4; +		else if (*odst >= 192)	/* Class C */  			bits = 24; -		else if (*odst >= 128)	/*%< Class B */ +		else if (*odst >= 128)	/* Class B */  			bits = 16; -		else			/*%< Class A */ +		else			/* Class A */  			bits = 8;  		/* If imputed mask is narrower than specified octets, widen. */  		if (bits < ((dst - odst) * 8))  			bits = (dst - odst) * 8; -		/* -		 * If there are no additional bits specified for a class D -		 * address adjust bits to 4. -		 */ -		if (bits == 8 && *odst == 224) -			bits = 4;  	}  	/* Extend network to cover the actual mask. */  	while (bits > ((dst - odst) * 8)) { -		if (size-- <= 0U) +		if (size-- == 0)  			goto emsgsize;  		*dst++ = '\0';  	} @@ -184,222 +207,48 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {  	return (-1);  } -static int -getbits(const char *src, int *bitsp) { -	static const char digits[] = "0123456789"; -	int n; -	int val; -	char ch; - -	val = 0; -	n = 0; -	while ((ch = *src++) != '\0') { -		const char *pch; - -		pch = strchr(digits, ch); -		if (pch != NULL) { -			if (n++ != 0 && val == 0)	/*%< no leading zeros */ -				return (0); -			val *= 10; -			val += (pch - digits); -			if (val > 128)			/*%< range */ -				return (0); -			continue; -		} -		return (0); -	} -	if (n == 0) -		return (0); -	*bitsp = val; -	return (1); -}  static int -getv4(const char *src, u_char *dst, int *bitsp) { -	static const char digits[] = "0123456789"; -	u_char *odst = dst; -	int n; -	u_int val; -	char ch; - -	val = 0; -	n = 0; -	while ((ch = *src++) != '\0') { -		const char *pch; +inet_net_pton_ipv6(const char *src, u_char *dst, size_t size) +{ +	struct in6_addr	 in6; +	int		 ret; +	int		 bits; +	size_t		 bytes; +	char		 buf[INET6_ADDRSTRLEN + sizeof("/128")]; +	char		*sep; +	const char	*errstr; -		pch = strchr(digits, ch); -		if (pch != NULL) { -			if (n++ != 0 && val == 0)	/*%< no leading zeros */ -				return (0); -			val *= 10; -			val += (pch - digits); -			if (val > 255)			/*%< range */ -				return (0); -			continue; -		} -		if (ch == '.' || ch == '/') { -			if (dst - odst > 3)		/*%< too many octets? */ -				return (0); -			*dst++ = val; -			if (ch == '/') -				return (getbits(src, bitsp)); -			val = 0; -			n = 0; -			continue; -		} -		return (0); +	if (strlcpy(buf, src, sizeof buf) >= sizeof buf) { +		errno = EMSGSIZE; +		return (-1);  	} -	if (n == 0) -		return (0); -	if (dst - odst > 3)		/*%< too many octets? */ -		return (0); -	*dst++ = val; -	return (1); -} -static int -inet_net_pton_ipv6(const char *src, u_char *dst, size_t size) { -	static const char xdigits_l[] = "0123456789abcdef", -			  xdigits_u[] = "0123456789ABCDEF"; -	u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; -	const char *xdigits, *curtok; -	int ch, saw_xdigit; -	u_int val; -	int digits; -	int bits; -	size_t bytes; -	int words; -	int ipv4; +	sep = strchr(buf, '/'); +	if (sep != NULL) +		*sep++ = '\0'; -	memset((tp = tmp), '\0', NS_IN6ADDRSZ); -	endp = tp + NS_IN6ADDRSZ; -	colonp = NULL; -	/* Leading :: requires some special handling. */ -	if (*src == ':') -		if (*++src != ':') -			goto enoent; -	curtok = src; -	saw_xdigit = 0; -	val = 0; -	digits = 0; -	bits = -1; -	ipv4 = 0; -	while ((ch = *src++) != '\0') { -		const char *pch; +	ret = inet_pton(AF_INET6, buf, &in6); +	if (ret != 1) +		return (-1); -		if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) -			pch = strchr((xdigits = xdigits_u), ch); -		if (pch != NULL) { -			val <<= 4; -			val |= (pch - xdigits); -			if (++digits > 4) -				goto enoent; -			saw_xdigit = 1; -			continue; -		} -		if (ch == ':') { -			curtok = src; -			if (!saw_xdigit) { -				if (colonp) -					goto enoent; -				colonp = tp; -				continue; -			} else if (*src == '\0') -				goto enoent; -			if (tp + NS_INT16SZ > endp) -				return (0); -			*tp++ = (u_char) (val >> 8) & 0xff; -			*tp++ = (u_char) val & 0xff; -			saw_xdigit = 0; -			digits = 0; -			val = 0; -			continue; -		} -		if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && -		     getv4(curtok, tp, &bits) > 0) { -			tp += NS_INADDRSZ; -			saw_xdigit = 0; -			ipv4 = 1; -			break;	/*%< '\\0' was seen by inet_pton4(). */ -		} -		if (ch == '/' && getbits(src, &bits) > 0) -			break; -		goto enoent; -	} -	if (saw_xdigit) { -		if (tp + NS_INT16SZ > endp) -			goto enoent; -		*tp++ = (u_char) (val >> 8) & 0xff; -		*tp++ = (u_char) val & 0xff; -	} -	if (bits == -1) +	if (sep == NULL)  		bits = 128; - -	words = (bits + 15) / 16; -	if (words < 2) -		words = 2; -	if (ipv4) -		words = 8; -	endp =  tmp + 2 * words; - -	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) -			goto enoent; -		for (i = 1; i <= n; i++) { -			endp[- i] = colonp[n - i]; -			colonp[n - i] = 0; +	else { +		bits = strtonum(sep, 0, 128, &errstr); +		if (errstr) { +			errno = EINVAL; +			return (-1);  		} -		tp = endp;  	} -	if (tp != endp) -		goto enoent;  	bytes = (bits + 7) / 8; -	if (bytes > size) -		goto emsgsize; -	memcpy(dst, tmp, bytes); -	return (bits); - - enoent: -	errno = ENOENT; -	return (-1); - - emsgsize: -	errno = EMSGSIZE; -	return (-1); -} - -/*% - * int - * inet_net_pton(af, src, dst, size) - *	convert network number from presentation to network format. - *	accepts hex octets, hex strings, decimal octets, and /CIDR. - *	"size" is in bytes and describes "dst". - * return: - *	number of bits, either imputed classfully or specified with /CIDR, - *	or -1 if some failure occurred (check errno).  ENOENT means it was - *	not a valid network specification. - * author: - *	Paul Vixie (ISC), June 1996 - */ -int -inet_net_pton(int af, const char *src, void *dst, size_t size) { -	switch (af) { -	case AF_INET: -		return (inet_net_pton_ipv4(src, dst, size)); -	case AF_INET6: -		return (inet_net_pton_ipv6(src, dst, size)); -	default: -		errno = EAFNOSUPPORT; +	if (bytes > size) { +		errno = EMSGSIZE;  		return (-1);  	} +	memcpy(dst, &in6.s6_addr, bytes); +	return (bits);  }  /* @@ -408,5 +257,3 @@ inet_net_pton(int af, const char *src, void *dst, size_t size) {   */  #undef inet_net_pton  __weak_reference(__inet_net_pton, inet_net_pton); - -/*! \file */ | 
