From 6a41b0fb0e589c4afc4ecbcf7c425f0aa40eaea4 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Tue, 13 May 2014 16:05:51 -0700 Subject: [PATCH] Flesh out . Use the upstream OpenBSD implementations of these functions. Also ensure we have symbols for htonl, htons, ntohl, and ntohs. gtest doesn't like us using the macro versions in ASSERT_EQ. Bug: 14840760 Change-Id: I68720e9aca14838df457d2bb27b999d5818ac2b5 --- libc/Android.mk | 16 +- libc/include/arpa/inet.h | 23 +- libc/include/sys/endian.h | 14 +- .../upstream-netbsd/lib/libc/inet/inet_pton.c | 310 ------------------ libc/upstream-openbsd/lib/libc/net/htonl.c | 21 ++ libc/upstream-openbsd/lib/libc/net/htons.c | 21 ++ .../lib/libc/net}/inet_addr.c | 119 ++----- .../lib/libc/net/inet_lnaof.c | 51 +++ .../lib/libc/net/inet_makeaddr.c | 54 +++ .../lib/libc/net/inet_netof.c | 50 +++ .../lib/libc/net/inet_network.c | 84 +++++ .../lib/libc/net}/inet_ntoa.c | 45 +-- .../lib/libc/net}/inet_ntop.c | 123 +++---- .../upstream-openbsd/lib/libc/net/inet_pton.c | 213 ++++++++++++ libc/upstream-openbsd/lib/libc/net/ntohl.c | 21 ++ libc/upstream-openbsd/lib/libc/net/ntohs.c | 21 ++ tests/Android.mk | 1 + tests/arpa_inet_test.cpp | 61 ++++ 18 files changed, 731 insertions(+), 517 deletions(-) delete mode 100644 libc/upstream-netbsd/lib/libc/inet/inet_pton.c create mode 100644 libc/upstream-openbsd/lib/libc/net/htonl.c create mode 100644 libc/upstream-openbsd/lib/libc/net/htons.c rename libc/{upstream-netbsd/common/lib/libc/inet => upstream-openbsd/lib/libc/net}/inet_addr.c (62%) create mode 100644 libc/upstream-openbsd/lib/libc/net/inet_lnaof.c create mode 100644 libc/upstream-openbsd/lib/libc/net/inet_makeaddr.c create mode 100644 libc/upstream-openbsd/lib/libc/net/inet_netof.c create mode 100644 libc/upstream-openbsd/lib/libc/net/inet_network.c rename libc/{upstream-netbsd/lib/libc/inet => upstream-openbsd/lib/libc/net}/inet_ntoa.c (73%) rename libc/{upstream-netbsd/lib/libc/inet => upstream-openbsd/lib/libc/net}/inet_ntop.c (58%) create mode 100644 libc/upstream-openbsd/lib/libc/net/inet_pton.c create mode 100644 libc/upstream-openbsd/lib/libc/net/ntohl.c create mode 100644 libc/upstream-openbsd/lib/libc/net/ntohs.c create mode 100644 tests/arpa_inet_test.cpp diff --git a/libc/Android.mk b/libc/Android.mk index 5befacf51..6d1bcf8dc 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -257,7 +257,6 @@ libc_upstream_freebsd_src_files := \ libc_upstream_netbsd_src_files := \ upstream-netbsd/common/lib/libc/hash/sha1/sha1.c \ - upstream-netbsd/common/lib/libc/inet/inet_addr.c \ upstream-netbsd/lib/libc/gen/ftw.c \ upstream-netbsd/lib/libc/gen/nftw.c \ upstream-netbsd/lib/libc/gen/nice.c \ @@ -266,9 +265,6 @@ libc_upstream_netbsd_src_files := \ upstream-netbsd/lib/libc/gen/setjmperr.c \ upstream-netbsd/lib/libc/gen/utime.c \ upstream-netbsd/lib/libc/gen/utmp.c \ - upstream-netbsd/lib/libc/inet/inet_ntoa.c \ - upstream-netbsd/lib/libc/inet/inet_ntop.c \ - upstream-netbsd/lib/libc/inet/inet_pton.c \ upstream-netbsd/lib/libc/isc/ev_streams.c \ upstream-netbsd/lib/libc/isc/ev_timers.c \ upstream-netbsd/lib/libc/regex/regcomp.c \ @@ -357,6 +353,18 @@ libc_upstream_openbsd_src_files := \ upstream-openbsd/lib/libc/locale/wcsxfrm.c \ upstream-openbsd/lib/libc/locale/wctob.c \ upstream-openbsd/lib/libc/locale/wctomb.c \ + upstream-openbsd/lib/libc/net/htonl.c \ + upstream-openbsd/lib/libc/net/htons.c \ + upstream-openbsd/lib/libc/net/inet_addr.c \ + upstream-openbsd/lib/libc/net/inet_lnaof.c \ + upstream-openbsd/lib/libc/net/inet_makeaddr.c \ + upstream-openbsd/lib/libc/net/inet_netof.c \ + upstream-openbsd/lib/libc/net/inet_network.c \ + upstream-openbsd/lib/libc/net/inet_ntoa.c \ + upstream-openbsd/lib/libc/net/inet_ntop.c \ + upstream-openbsd/lib/libc/net/inet_pton.c \ + upstream-openbsd/lib/libc/net/ntohl.c \ + upstream-openbsd/lib/libc/net/ntohs.c \ upstream-openbsd/lib/libc/stdio/asprintf.c \ upstream-openbsd/lib/libc/stdio/clrerr.c \ upstream-openbsd/lib/libc/stdio/fdopen.c \ diff --git a/libc/include/arpa/inet.h b/libc/include/arpa/inet.h index b0088129c..067be1fe9 100644 --- a/libc/include/arpa/inet.h +++ b/libc/include/arpa/inet.h @@ -36,19 +36,18 @@ __BEGIN_DECLS typedef uint32_t in_addr_t; -extern uint32_t inet_addr(const char *); - -extern int inet_aton(const char *, struct in_addr *); -extern char* inet_ntoa(struct in_addr); - -extern int inet_pton(int, const char *, void *); -extern const char* inet_ntop(int, const void *, char *, socklen_t); - -extern unsigned int inet_nsap_addr(const char *, unsigned char *, int); -extern char* inet_nsap_ntoa(int, const unsigned char *, char *); +in_addr_t inet_addr(const char*); +int inet_aton(const char*, struct in_addr*); +in_addr_t inet_lnaof(struct in_addr); +struct in_addr inet_makeaddr(in_addr_t, in_addr_t); +in_addr_t inet_netof(struct in_addr); +in_addr_t inet_network(const char*); +char* inet_ntoa(struct in_addr); +const char* inet_ntop(int, const void*, char*, socklen_t); +unsigned int inet_nsap_addr(const char*, unsigned char*, int); +char* inet_nsap_ntoa(int, const unsigned char*, char*); +int inet_pton(int, const char*, void*); __END_DECLS #endif /* _ARPA_INET_H_ */ - - diff --git a/libc/include/sys/endian.h b/libc/include/sys/endian.h index cbde12110..11865404f 100644 --- a/libc/include/sys/endian.h +++ b/libc/include/sys/endian.h @@ -186,14 +186,22 @@ #define letoh64(x) (x) #endif /* __BSD_VISIBLE */ -#define htons(x) __swap16(x) +/* glibc compatibility. */ +__BEGIN_DECLS +uint32_t htonl(uint32_t) __pure2; +uint16_t htons(uint16_t) __pure2; +uint32_t ntohl(uint32_t) __pure2; +uint16_t ntohs(uint16_t) __pure2; +__END_DECLS + #define htonl(x) __swap32(x) -#define ntohs(x) __swap16(x) +#define htons(x) __swap16(x) #define ntohl(x) __swap32(x) +#define ntohs(x) __swap16(x) /* Bionic additions */ -#define ntohq(x) __swap64(x) #define htonq(x) __swap64(x) +#define ntohq(x) __swap64(x) #define __LITTLE_ENDIAN_BITFIELD diff --git a/libc/upstream-netbsd/lib/libc/inet/inet_pton.c b/libc/upstream-netbsd/lib/libc/inet/inet_pton.c deleted file mode 100644 index c1e9a698a..000000000 --- a/libc/upstream-netbsd/lib/libc/inet/inet_pton.c +++ /dev/null @@ -1,310 +0,0 @@ -/* $NetBSD: inet_pton.c,v 1.8 2012/03/13 21:13:38 christos Exp $ */ - -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1996,1999 by Internet Software Consortium. - * - * 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. - */ - -#include -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static const char rcsid[] = "Id: inet_pton.c,v 1.5 2005/07/28 06:51:47 marka Exp"; -#else -__RCSID("$NetBSD: inet_pton.c,v 1.8 2012/03/13 21:13:38 christos Exp $"); -#endif -#endif /* LIBC_SCCS and not lint */ - -#include "port_before.h" - -#include "namespace.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "port_after.h" - -#ifdef __weak_alias -__weak_alias(inet_pton,_inet_pton) -#endif - -/*% - * WARNING: Don't even consider trying to compile this on a system where - * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. - */ - -static int inet_pton4(const char *src, u_char *dst, int pton); -static int inet_pton6(const char *src, u_char *dst); - -/* int - * inet_pton(af, src, dst) - * convert from presentation format (which usually means ASCII printable) - * to network format (which is usually some kind of binary format). - * return: - * 1 if the address was valid for the specified address family - * 0 if the address wasn't valid (`dst' is untouched in this case) - * -1 if some other error occurred (`dst' is untouched in this case, too) - * author: - * Paul Vixie, 1996. - */ -int -inet_pton(int af, const char *src, void *dst) -{ - - _DIAGASSERT(src != NULL); - _DIAGASSERT(dst != NULL); - - switch (af) { - case AF_INET: - return (inet_pton4(src, dst, 1)); - case AF_INET6: - return (inet_pton6(src, dst)); - default: - errno = EAFNOSUPPORT; - return (-1); - } - /* NOTREACHED */ -} - -/* int - * inet_pton4(src, dst, pton) - * when last arg is 0: inet_aton(). with hexadecimal, octal and shorthand. - * when last arg is 1: inet_pton(). decimal dotted-quad only. - * return: - * 1 if `src' is a valid input, else 0. - * notice: - * does not touch `dst' unless it's returning 1. - * author: - * Paul Vixie, 1996. - */ -static int -inet_pton4(const char *src, u_char *dst, int pton) -{ - u_int32_t val; - u_int digit, base; - ptrdiff_t n; - unsigned char c; - u_int parts[4]; - u_int *pp = parts; - - _DIAGASSERT(src != NULL); - _DIAGASSERT(dst != NULL); - - c = *src; - for (;;) { - /* - * Collect number up to ``.''. - * Values are specified as for C: - * 0x=hex, 0=octal, isdigit=decimal. - */ - if (!isdigit(c)) - return (0); - val = 0; base = 10; - if (c == '0') { - c = *++src; - if (c == 'x' || c == 'X') - base = 16, c = *++src; - else if (isdigit(c) && c != '9') - base = 8; - } - /* inet_pton() takes decimal only */ - if (pton && base != 10) - return (0); - for (;;) { - if (isdigit(c)) { - digit = c - '0'; - if (digit >= base) - break; - val = (val * base) + digit; - c = *++src; - } else if (base == 16 && isxdigit(c)) { - digit = c + 10 - (islower(c) ? 'a' : 'A'); - if (digit >= 16) - break; - val = (val << 4) | digit; - c = *++src; - } else - break; - } - if (c == '.') { - /* - * Internet format: - * a.b.c.d - * a.b.c (with c treated as 16 bits) - * a.b (with b treated as 24 bits) - * a (with a treated as 32 bits) - */ - if (pp >= parts + 3) - return (0); - *pp++ = val; - c = *++src; - } else - break; - } - /* - * Check for trailing characters. - */ - if (c != '\0' && !isspace(c)) - return (0); - /* - * Concoct the address according to - * the number of parts specified. - */ - n = pp - parts + 1; - /* inet_pton() takes dotted-quad only. it does not take shorthand. */ - if (pton && n != 4) - return (0); - switch (n) { - - case 0: - return (0); /* initial nondigit */ - - case 1: /* a -- 32 bits */ - break; - - case 2: /* a.b -- 8.24 bits */ - if (parts[0] > 0xff || val > 0xffffff) - return (0); - val |= parts[0] << 24; - break; - - case 3: /* a.b.c -- 8.8.16 bits */ - if ((parts[0] | parts[1]) > 0xff || val > 0xffff) - return (0); - val |= (parts[0] << 24) | (parts[1] << 16); - break; - - case 4: /* a.b.c.d -- 8.8.8.8 bits */ - if ((parts[0] | parts[1] | parts[2] | val) > 0xff) - return (0); - val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); - break; - } - if (dst) { - val = htonl(val); - memcpy(dst, &val, NS_INADDRSZ); - } - return (1); -} - -/* int - * inet_pton6(src, dst) - * convert presentation level address to network order binary form. - * return: - * 1 if `src' is a valid [RFC1884 2.2] address, else 0. - * notice: - * (1) does not touch `dst' unless it's returning 1. - * (2) :: in a full address is silently ignored. - * credit: - * inspired by Mark Andrews. - * author: - * Paul Vixie, 1996. - */ -static int -inet_pton6(const char *src, u_char *dst) -{ - static const char xdigits_l[] = "0123456789abcdef", - xdigits_u[] = "0123456789ABCDEF"; - u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; - const char *xdigits, *curtok; - int ch, seen_xdigits; - u_int val; - - _DIAGASSERT(src != NULL); - _DIAGASSERT(dst != NULL); - - memset((tp = tmp), '\0', NS_IN6ADDRSZ); - endp = tp + NS_IN6ADDRSZ; - colonp = NULL; - /* Leading :: requires some special handling. */ - if (*src == ':') - if (*++src != ':') - return (0); - curtok = src; - seen_xdigits = 0; - val = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) - pch = strchr((xdigits = xdigits_u), ch); - if (pch != NULL) { - val <<= 4; - val |= (int)(pch - xdigits); - if (++seen_xdigits > 4) - return (0); - continue; - } - if (ch == ':') { - curtok = src; - if (!seen_xdigits) { - if (colonp) - return (0); - colonp = tp; - continue; - } else if (*src == '\0') - return (0); - if (tp + NS_INT16SZ > endp) - return (0); - *tp++ = (u_char) (val >> 8) & 0xff; - *tp++ = (u_char) val & 0xff; - seen_xdigits = 0; - val = 0; - continue; - } - if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && - inet_pton4(curtok, tp, 1) > 0) { - tp += NS_INADDRSZ; - seen_xdigits = 0; - break; /*%< '\\0' was seen by inet_pton4(). */ - } - return (0); - } - if (seen_xdigits) { - if (tp + NS_INT16SZ > endp) - return (0); - *tp++ = (u_char) (val >> 8) & 0xff; - *tp++ = (u_char) val & 0xff; - } - if (colonp != NULL) { - /* - * Since some memmove()'s erroneously fail to handle - * overlapping regions, we'll do the shift by hand. - */ - const ptrdiff_t 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) - return (0); - memcpy(dst, tmp, NS_IN6ADDRSZ); - return (1); -} - -/*! \file */ diff --git a/libc/upstream-openbsd/lib/libc/net/htonl.c b/libc/upstream-openbsd/lib/libc/net/htonl.c new file mode 100644 index 000000000..5ab418959 --- /dev/null +++ b/libc/upstream-openbsd/lib/libc/net/htonl.c @@ -0,0 +1,21 @@ +/* $OpenBSD: htonl.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */ +/* + * Written by J.T. Conklin . + * Public domain. + */ + +#include +#include + +#undef htonl + +u_int32_t +htonl(u_int32_t x) +{ +#if BYTE_ORDER == LITTLE_ENDIAN + u_char *s = (u_char *)&x; + return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]); +#else + return x; +#endif +} diff --git a/libc/upstream-openbsd/lib/libc/net/htons.c b/libc/upstream-openbsd/lib/libc/net/htons.c new file mode 100644 index 000000000..c8b73fdbb --- /dev/null +++ b/libc/upstream-openbsd/lib/libc/net/htons.c @@ -0,0 +1,21 @@ +/* $OpenBSD: htons.c,v 1.8 2005/08/06 20:30:03 espie Exp $ */ +/* + * Written by J.T. Conklin . + * Public domain. + */ + +#include +#include + +#undef htons + +u_int16_t +htons(u_int16_t x) +{ +#if BYTE_ORDER == LITTLE_ENDIAN + u_char *s = (u_char *) &x; + return (u_int16_t)(s[0] << 8 | s[1]); +#else + return x; +#endif +} diff --git a/libc/upstream-netbsd/common/lib/libc/inet/inet_addr.c b/libc/upstream-openbsd/lib/libc/net/inet_addr.c similarity index 62% rename from libc/upstream-netbsd/common/lib/libc/inet/inet_addr.c rename to libc/upstream-openbsd/lib/libc/net/inet_addr.c index 1360ce970..18762ab52 100644 --- a/libc/upstream-netbsd/common/lib/libc/inet/inet_addr.c +++ b/libc/upstream-openbsd/lib/libc/net/inet_addr.c @@ -1,6 +1,8 @@ -/* $NetBSD: inet_addr.c,v 1.3 2012/03/09 15:41:16 christos Exp $ */ +/* $OpenBSD: inet_addr.c,v 1.10 2013/11/24 23:51:28 deraadt Exp $ */ /* + * ++Copyright++ 1983, 1990, 1993 + * - * Copyright (c) 1983, 1990, 1993 * The Regents of the University of California. All rights reserved. * @@ -12,11 +14,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -31,9 +29,7 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - */ - -/* + * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any @@ -51,63 +47,23 @@ * 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. + * - + * --Copyright-- */ -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. - * - * 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. - */ - -#if !defined(_KERNEL) && !defined(_STANDALONE) -#include -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static const char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; -static const char rcsid[] = "Id: inet_addr.c,v 1.2.206.2 2004/03/17 00:29:45 marka Exp"; -#else -__RCSID("$NetBSD: inet_addr.c,v 1.3 2012/03/09 15:41:16 christos Exp $"); -#endif -#endif /* LIBC_SCCS and not lint */ - -#include "port_before.h" - -#include "namespace.h" #include #include - #include #include - #include -#include "port_after.h" - -#ifdef __weak_alias -__weak_alias(inet_aton,_inet_aton) -#endif -#else -#include -#include -#endif - /* * Ascii internet address interpretation routine. * The value returned is in network order. */ -uint32_t -inet_addr(const char *cp) { +in_addr_t +inet_addr(const char *cp) +{ struct in_addr val; if (inet_aton(cp, &val)) @@ -123,14 +79,13 @@ inet_addr(const char *cp) { * cannot distinguish between failure and a local broadcast address. */ int -inet_aton(const char *cp, struct in_addr *addr) { - uint32_t val; - int base; - size_t n; +inet_aton(const char *cp, struct in_addr *addr) +{ + in_addr_t val; + int base, n; char c; - uint8_t parts[4]; - uint8_t *pp = parts; - int digit; + u_int parts[4]; + u_int *pp = parts; c = *cp; for (;;) { @@ -141,29 +96,25 @@ inet_aton(const char *cp, struct in_addr *addr) { */ if (!isdigit((unsigned char)c)) return (0); - val = 0; base = 10; digit = 0; + val = 0; base = 10; if (c == '0') { c = *++cp; if (c == 'x' || c == 'X') base = 16, c = *++cp; - else { + else base = 8; - digit = 1 ; - } } for (;;) { - if (isascii(c) && isdigit((unsigned char)c)) { - if (base == 8 && (c == '8' || c == '9')) - return (0); + if (isascii((unsigned char)c) && + isdigit((unsigned char)c)) { val = (val * base) + (c - '0'); c = *++cp; - digit = 1; - } else if (base == 16 && isascii(c) && - isxdigit((unsigned char)c)) { + } else if (base == 16 && + isascii((unsigned char)c) && + isxdigit((unsigned char)c)) { val = (val << 4) | - (c + 10 - (islower((unsigned char)c) ? 'a' : 'A')); + (c + 10 - (islower((unsigned char)c) ? 'a' : 'A')); c = *++cp; - digit = 1; } else break; } @@ -174,7 +125,7 @@ inet_aton(const char *cp, struct in_addr *addr) { * a.b.c (with c treated as 16 bits) * a.b (with b treated as 24 bits) */ - if (pp >= parts + 3 || val > 0xffU) + if (pp >= parts + 3) return (0); *pp++ = val; c = *++cp; @@ -184,12 +135,8 @@ inet_aton(const char *cp, struct in_addr *addr) { /* * Check for trailing characters. */ - if (c != '\0' && (!isascii(c) || !isspace((unsigned char)c))) - return (0); - /* - * Did we get a valid digit? - */ - if (!digit) + if (c != '\0' && + (!isascii((unsigned char)c) || !isspace((unsigned char)c))) return (0); /* * Concoct the address according to @@ -197,28 +144,32 @@ inet_aton(const char *cp, struct in_addr *addr) { */ n = pp - parts + 1; switch (n) { + + case 0: + return (0); /* initial nondigit */ + case 1: /* a -- 32 bits */ break; case 2: /* a.b -- 8.24 bits */ - if (val > 0xffffffU) + if ((val > 0xffffff) || (parts[0] > 0xff)) return (0); val |= parts[0] << 24; break; case 3: /* a.b.c -- 8.8.16 bits */ - if (val > 0xffffU) + if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff)) return (0); val |= (parts[0] << 24) | (parts[1] << 16); break; case 4: /* a.b.c.d -- 8.8.8.8 bits */ - if (val > 0xffU) + if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) return (0); val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); break; } - if (addr != NULL) + if (addr) addr->s_addr = htonl(val); return (1); } diff --git a/libc/upstream-openbsd/lib/libc/net/inet_lnaof.c b/libc/upstream-openbsd/lib/libc/net/inet_lnaof.c new file mode 100644 index 000000000..b1a58cd2c --- /dev/null +++ b/libc/upstream-openbsd/lib/libc/net/inet_lnaof.c @@ -0,0 +1,51 @@ +/* $OpenBSD: inet_lnaof.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +/* + * Return the local network address portion of an + * internet address; handles class a/b/c network + * number formats. + */ +in_addr_t +inet_lnaof(struct in_addr in) +{ + in_addr_t i = ntohl(in.s_addr); + + if (IN_CLASSA(i)) + return ((i)&IN_CLASSA_HOST); + else if (IN_CLASSB(i)) + return ((i)&IN_CLASSB_HOST); + else + return ((i)&IN_CLASSC_HOST); +} diff --git a/libc/upstream-openbsd/lib/libc/net/inet_makeaddr.c b/libc/upstream-openbsd/lib/libc/net/inet_makeaddr.c new file mode 100644 index 000000000..87d932523 --- /dev/null +++ b/libc/upstream-openbsd/lib/libc/net/inet_makeaddr.c @@ -0,0 +1,54 @@ +/* $OpenBSD: inet_makeaddr.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +/* + * Formulate an Internet address from network + host. Used in + * building addresses stored in the ifnet structure. + */ +struct in_addr +inet_makeaddr(in_addr_t net, in_addr_t host) +{ + in_addr_t addr; + + if (net < 128) + addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST); + else if (net < 65536) + addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST); + else if (net < 16777216L) + addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST); + else + addr = net | host; + addr = htonl(addr); + return (*(struct in_addr *)&addr); +} diff --git a/libc/upstream-openbsd/lib/libc/net/inet_netof.c b/libc/upstream-openbsd/lib/libc/net/inet_netof.c new file mode 100644 index 000000000..2f468c3ac --- /dev/null +++ b/libc/upstream-openbsd/lib/libc/net/inet_netof.c @@ -0,0 +1,50 @@ +/* $OpenBSD: inet_netof.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +/* + * Return the network number from an internet + * address; handles class a/b/c network #'s. + */ +in_addr_t +inet_netof(struct in_addr in) +{ + in_addr_t i = ntohl(in.s_addr); + + if (IN_CLASSA(i)) + return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT); + else if (IN_CLASSB(i)) + return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT); + else + return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT); +} diff --git a/libc/upstream-openbsd/lib/libc/net/inet_network.c b/libc/upstream-openbsd/lib/libc/net/inet_network.c new file mode 100644 index 000000000..ecf554e4f --- /dev/null +++ b/libc/upstream-openbsd/lib/libc/net/inet_network.c @@ -0,0 +1,84 @@ +/* $OpenBSD: inet_network.c,v 1.11 2013/11/25 17:29:19 deraadt Exp $ */ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +/* + * Internet network address interpretation routine. + * The library routines call this routine to interpret + * network numbers. + */ +in_addr_t +inet_network(const char *cp) +{ + in_addr_t val, base, n; + u_char c; + in_addr_t parts[4], *pp = parts; + int i; + +again: + val = 0; base = 10; + if (*cp == '0') + base = 8, cp++; + if (*cp == 'x' || *cp == 'X') + base = 16, cp++; + while ((c = *cp)) { + if (isdigit(c)) { + val = (val * base) + (c - '0'); + cp++; + continue; + } + if (base == 16 && isxdigit(c)) { + val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A')); + cp++; + continue; + } + break; + } + if (*cp == '.') { + if (pp >= parts + 3) + return (INADDR_NONE); + *pp++ = val, cp++; + goto again; + } + if (*cp && !isspace(*cp)) + return (INADDR_NONE); + *pp++ = val; + n = pp - parts; + for (val = 0, i = 0; i < 4; i++) { + val <<= 8; + if (i < n) + val |= parts[i] & 0xff; + } + return (val); +} diff --git a/libc/upstream-netbsd/lib/libc/inet/inet_ntoa.c b/libc/upstream-openbsd/lib/libc/net/inet_ntoa.c similarity index 73% rename from libc/upstream-netbsd/lib/libc/inet/inet_ntoa.c rename to libc/upstream-openbsd/lib/libc/net/inet_ntoa.c index 6ed023b41..ff5d93ded 100644 --- a/libc/upstream-netbsd/lib/libc/inet/inet_ntoa.c +++ b/libc/upstream-openbsd/lib/libc/net/inet_ntoa.c @@ -1,5 +1,4 @@ -/* $NetBSD: inet_ntoa.c,v 1.2 2012/03/13 21:13:38 christos Exp $ */ - +/* $OpenBSD: inet_ntoa.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */ /* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. @@ -29,36 +28,24 @@ * SUCH DAMAGE. */ -#include -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: inet_ntoa.c,v 1.2 2012/03/13 21:13:38 christos Exp $"); -#endif -#endif /* LIBC_SCCS and not lint */ - -#include "namespace.h" -#include -#include -#include -#include -#include -#include - -#ifdef __weak_alias -__weak_alias(inet_ntoa,_inet_ntoa) -#endif - /* * Convert network-format internet address * to base 256 d.d.d.d representation. */ -/*const*/ char * -inet_ntoa(struct in_addr in) { - static char ret[18]; +#include +#include +#include +#include - strlcpy(ret, "[inet_ntoa error]", sizeof(ret)); - (void) inet_ntop(AF_INET, &in, ret, (socklen_t)sizeof ret); - return ret; +char * +inet_ntoa(struct in_addr in) +{ + static char b[18]; + char *p; + + p = (char *)∈ +#define UC(b) (((int)b)&0xff) + (void)snprintf(b, sizeof(b), + "%u.%u.%u.%u", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); + return (b); } diff --git a/libc/upstream-netbsd/lib/libc/inet/inet_ntop.c b/libc/upstream-openbsd/lib/libc/net/inet_ntop.c similarity index 58% rename from libc/upstream-netbsd/lib/libc/inet/inet_ntop.c rename to libc/upstream-openbsd/lib/libc/net/inet_ntop.c index 00c55a8cc..359acd8cd 100644 --- a/libc/upstream-netbsd/lib/libc/inet/inet_ntop.c +++ b/libc/upstream-openbsd/lib/libc/net/inet_ntop.c @@ -1,63 +1,40 @@ -/* $NetBSD: inet_ntop.c,v 1.9 2012/03/20 17:08:13 matt Exp $ */ +/* $OpenBSD: inet_ntop.c,v 1.9 2014/02/05 14:20:43 millert Exp $ */ -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1996-1999 by Internet Software Consortium. +/* Copyright (c) 1996 by Internet Software Consortium. * * 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 -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static const char rcsid[] = "Id: inet_ntop.c,v 1.5 2005/11/03 22:59:52 marka Exp"; -#else -__RCSID("$NetBSD: inet_ntop.c,v 1.9 2012/03/20 17:08:13 matt Exp $"); -#endif -#endif /* LIBC_SCCS and not lint */ - -#include "port_before.h" - -#include "namespace.h" #include #include #include - #include #include #include - -#include +#include #include #include -#include -#include -#include "port_after.h" - -#ifdef __weak_alias -__weak_alias(inet_ntop,_inet_ntop) -#endif - -/*% +/* * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ -static const char *inet_ntop4(const u_char *src, char *dst, socklen_t size); -static const char *inet_ntop6(const u_char *src, char *dst, socklen_t size); +static const char *inet_ntop4(const u_char *src, char *dst, size_t size); +static const char *inet_ntop6(const u_char *src, char *dst, size_t size); -/* char * +/* const char * * inet_ntop(af, src, dst, size) * convert a network format address to presentation format. * return: @@ -68,15 +45,11 @@ static const char *inet_ntop6(const u_char *src, char *dst, socklen_t size); const char * inet_ntop(int af, const void *src, char *dst, socklen_t size) { - - _DIAGASSERT(src != NULL); - _DIAGASSERT(dst != NULL); - switch (af) { case AF_INET: - return (inet_ntop4(src, dst, size)); + return (inet_ntop4(src, dst, (size_t)size)); case AF_INET6: - return (inet_ntop6(src, dst, size)); + return (inet_ntop6(src, dst, (size_t)size)); default: errno = EAFNOSUPPORT; return (NULL); @@ -96,17 +69,14 @@ inet_ntop(int af, const void *src, char *dst, socklen_t size) * Paul Vixie, 1996. */ static const char * -inet_ntop4(const u_char *src, char *dst, socklen_t size) +inet_ntop4(const u_char *src, char *dst, size_t size) { + static const char fmt[] = "%u.%u.%u.%u"; char tmp[sizeof "255.255.255.255"]; int l; - _DIAGASSERT(src != NULL); - _DIAGASSERT(dst != NULL); - - l = snprintf(tmp, sizeof(tmp), "%u.%u.%u.%u", - src[0], src[1], src[2], src[3]); - if (l <= 0 || (socklen_t) l >= size) { + l = snprintf(tmp, size, fmt, src[0], src[1], src[2], src[3]); + if (l <= 0 || l >= size) { errno = ENOSPC; return (NULL); } @@ -121,7 +91,7 @@ inet_ntop4(const u_char *src, char *dst, socklen_t size) * Paul Vixie, 1996. */ static const char * -inet_ntop6(const u_char *src, char *dst, socklen_t size) +inet_ntop6(const u_char *src, char *dst, size_t size) { /* * Note that int32_t and int16_t need only be "at least" large enough @@ -133,26 +103,21 @@ inet_ntop6(const u_char *src, char *dst, socklen_t size) char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; char *tp, *ep; struct { int base, len; } best, cur; - u_int words[NS_IN6ADDRSZ / NS_INT16SZ]; + u_int words[IN6ADDRSZ / INT16SZ]; int i; int advance; - _DIAGASSERT(src != NULL); - _DIAGASSERT(dst != NULL); - /* * Preprocess: * Copy the input (bytewise) array into a wordwise array. * Find the longest run of 0x00's in src[] for :: shorthanding. */ memset(words, '\0', sizeof words); - for (i = 0; i < NS_IN6ADDRSZ; i++) + for (i = 0; i < IN6ADDRSZ; i++) words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); best.base = -1; - best.len = 0; cur.base = -1; - cur.len = 0; - for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { if (words[i] == 0) { if (cur.base == -1) cur.base = i, cur.len = 1; @@ -178,44 +143,54 @@ inet_ntop6(const u_char *src, char *dst, socklen_t size) */ tp = tmp; ep = tmp + sizeof(tmp); - for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { + for (i = 0; i < (IN6ADDRSZ / INT16SZ) && tp < ep; i++) { /* Are we inside the best run of 0x00's? */ if (best.base != -1 && i >= best.base && i < (best.base + best.len)) { - if (i == best.base) + if (i == best.base) { + if (tp + 1 >= ep) { + errno = ENOSPC; + return (NULL); + } *tp++ = ':'; + } continue; } /* Are we following an initial run of 0x00s or any real hex? */ if (i != 0) { - if (tp + 1 >= ep) + if (tp + 1 >= ep) { + errno = ENOSPC; return (NULL); + } *tp++ = ':'; } /* Is this address an encapsulated IPv4? */ if (i == 6 && best.base == 0 && - (best.len == 6 || - (best.len == 7 && words[7] != 0x0001) || - (best.len == 5 && words[5] == 0xffff))) { - if (!inet_ntop4(src+12, tp, (socklen_t)(ep - tp))) + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { + if (!inet_ntop4(src+12, tp, (size_t)(ep - tp))) return (NULL); tp += strlen(tp); break; } - advance = snprintf(tp, (size_t)(ep - tp), "%x", words[i]); - if (advance <= 0 || advance >= ep - tp) + advance = snprintf(tp, ep - tp, "%x", words[i]); + if (advance <= 0 || advance >= ep - tp) { + errno = ENOSPC; return (NULL); + } tp += advance; } /* Was it a trailing run of 0x00's? */ - if (best.base != -1 && (best.base + best.len) == - (NS_IN6ADDRSZ / NS_INT16SZ)) { - if (tp + 1 >= ep) + if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) { + if (tp + 1 >= ep) { + errno = ENOSPC; return (NULL); + } *tp++ = ':'; } - if (tp + 1 >= ep) + if (tp + 1 >= ep) { + errno = ENOSPC; return (NULL); + } *tp++ = '\0'; /* @@ -228,5 +203,3 @@ inet_ntop6(const u_char *src, char *dst, socklen_t size) strlcpy(dst, tmp, size); return (dst); } - -/*! \file */ diff --git a/libc/upstream-openbsd/lib/libc/net/inet_pton.c b/libc/upstream-openbsd/lib/libc/net/inet_pton.c new file mode 100644 index 000000000..7e521c328 --- /dev/null +++ b/libc/upstream-openbsd/lib/libc/net/inet_pton.c @@ -0,0 +1,213 @@ +/* $OpenBSD: inet_pton.c,v 1.8 2010/05/06 15:47:14 claudio Exp $ */ + +/* Copyright (c) 1996 by Internet Software Consortium. + * + * 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 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 +#include +#include +#include +#include +#include +#include +#include + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static int inet_pton4(const char *src, u_char *dst); +static int inet_pton6(const char *src, u_char *dst); + +/* int + * inet_pton(af, src, dst) + * convert from presentation format (which usually means ASCII printable) + * to network format (which is usually some kind of binary format). + * return: + * 1 if the address was valid for the specified address family + * 0 if the address wasn't valid (`dst' is untouched in this case) + * -1 if some other error occurred (`dst' is untouched in this case, too) + * author: + * Paul Vixie, 1996. + */ +int +inet_pton(int af, const char *src, void *dst) +{ + switch (af) { + case AF_INET: + return (inet_pton4(src, dst)); + case AF_INET6: + return (inet_pton6(src, dst)); + default: + errno = EAFNOSUPPORT; + return (-1); + } + /* NOTREACHED */ +} + +/* int + * inet_pton4(src, dst) + * like inet_aton() but without all the hexadecimal and shorthand. + * return: + * 1 if `src' is a valid dotted quad, else 0. + * notice: + * does not touch `dst' unless it's returning 1. + * author: + * Paul Vixie, 1996. + */ +static int +inet_pton4(const char *src, u_char *dst) +{ + static const char digits[] = "0123456789"; + int saw_digit, octets, ch; + u_char tmp[INADDRSZ], *tp; + + saw_digit = 0; + octets = 0; + *(tp = tmp) = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr(digits, ch)) != NULL) { + u_int new = *tp * 10 + (pch - digits); + + if (new > 255) + return (0); + if (! saw_digit) { + if (++octets > 4) + return (0); + saw_digit = 1; + } + *tp = new; + } else if (ch == '.' && saw_digit) { + if (octets == 4) + return (0); + *++tp = 0; + saw_digit = 0; + } else + return (0); + } + if (octets < 4) + return (0); + + memcpy(dst, tmp, INADDRSZ); + return (1); +} + +/* int + * inet_pton6(src, dst) + * convert presentation level address to network order binary form. + * return: + * 1 if `src' is a valid [RFC1884 2.2] address, else 0. + * notice: + * does not touch `dst' unless it's returning 1. + * credit: + * inspired by Mark Andrews. + * author: + * Paul Vixie, 1996. + */ +static int +inet_pton6(const char *src, u_char *dst) +{ + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp; + const char *xdigits, *curtok; + int ch, saw_xdigit, count_xdigit; + u_int val; + + memset((tp = tmp), '\0', IN6ADDRSZ); + endp = tp + IN6ADDRSZ; + colonp = NULL; + /* Leading :: requires some special handling. */ + if (*src == ':') + if (*++src != ':') + return (0); + curtok = src; + saw_xdigit = count_xdigit = 0; + val = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) + pch = strchr((xdigits = xdigits_u), ch); + if (pch != NULL) { + if (count_xdigit >= 4) + return (0); + val <<= 4; + val |= (pch - xdigits); + if (val > 0xffff) + return (0); + saw_xdigit = 1; + count_xdigit++; + continue; + } + if (ch == ':') { + curtok = src; + if (!saw_xdigit) { + if (colonp) + return (0); + colonp = tp; + continue; + } else if (*src == '\0') { + return (0); + } + if (tp + INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + saw_xdigit = 0; + count_xdigit = 0; + val = 0; + continue; + } + if (ch == '.' && ((tp + INADDRSZ) <= endp) && + inet_pton4(curtok, tp) > 0) { + tp += INADDRSZ; + saw_xdigit = 0; + count_xdigit = 0; + break; /* '\0' was seen by inet_pton4(). */ + } + return (0); + } + if (saw_xdigit) { + if (tp + INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) 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) + return (0); + memcpy(dst, tmp, IN6ADDRSZ); + return (1); +} diff --git a/libc/upstream-openbsd/lib/libc/net/ntohl.c b/libc/upstream-openbsd/lib/libc/net/ntohl.c new file mode 100644 index 000000000..36414b7a1 --- /dev/null +++ b/libc/upstream-openbsd/lib/libc/net/ntohl.c @@ -0,0 +1,21 @@ +/* $OpenBSD: ntohl.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */ +/* + * Written by J.T. Conklin . + * Public domain. + */ + +#include +#include + +#undef ntohl + +u_int32_t +ntohl(u_int32_t x) +{ +#if BYTE_ORDER == LITTLE_ENDIAN + u_char *s = (u_char *)&x; + return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]); +#else + return x; +#endif +} diff --git a/libc/upstream-openbsd/lib/libc/net/ntohs.c b/libc/upstream-openbsd/lib/libc/net/ntohs.c new file mode 100644 index 000000000..8f345e84a --- /dev/null +++ b/libc/upstream-openbsd/lib/libc/net/ntohs.c @@ -0,0 +1,21 @@ +/* $OpenBSD: ntohs.c,v 1.8 2005/08/06 20:30:03 espie Exp $ */ +/* + * Written by J.T. Conklin . + * Public domain. + */ + +#include +#include + +#undef ntohs + +u_int16_t +ntohs(u_int16_t x) +{ +#if BYTE_ORDER == LITTLE_ENDIAN + u_char *s = (u_char *) &x; + return (u_int16_t)(s[0] << 8 | s[1]); +#else + return x; +#endif +} diff --git a/tests/Android.mk b/tests/Android.mk index b17492a7c..4ad07ba64 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -44,6 +44,7 @@ test_cppflags = \ -std=gnu++11 \ libBionicStandardTests_src_files := \ + arpa_inet_test.cpp \ buffer_tests.cpp \ ctype_test.cpp \ dirent_test.cpp \ diff --git a/tests/arpa_inet_test.cpp b/tests/arpa_inet_test.cpp new file mode 100644 index 000000000..cee9f362d --- /dev/null +++ b/tests/arpa_inet_test.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +TEST(arpa_inet, inet_addr) { + ASSERT_EQ((htonl)(0x7f000001), inet_addr("127.0.0.1")); +} + +TEST(arpa_inet, inet_aton) { + in_addr a; + ASSERT_EQ(1, inet_aton("127.0.0.1", &a)); + ASSERT_EQ((htonl)(0x7f000001), a.s_addr); +} + +TEST(arpa_inet, inet_lnaof) { + in_addr a = { htonl(0x12345678) }; + ASSERT_EQ(0x00345678U, inet_lnaof(a)); +} + +TEST(arpa_inet, inet_makeaddr) { + in_addr a = inet_makeaddr(0x12U, 0x345678); + ASSERT_EQ((htonl)(0x12345678), a.s_addr); +} + +TEST(arpa_inet, inet_netof) { + in_addr a = { htonl(0x12345678) }; + ASSERT_EQ(0x12U, inet_netof(a)); +} + +TEST(arpa_inet, inet_network) { + ASSERT_EQ(0x7f000001U, inet_network("127.0.0.1")); +} + +TEST(arpa_inet, inet_ntoa) { + in_addr a = { (htonl)(0x7f000001) }; + ASSERT_STREQ("127.0.0.1", inet_ntoa(a)); +} + +TEST(arpa_inet, inet_pton__inet_ntop) { + sockaddr_storage ss; + ASSERT_EQ(1, inet_pton(AF_INET, "127.0.0.1", &ss)); + + char s[INET_ADDRSTRLEN]; + ASSERT_STREQ("127.0.0.1", inet_ntop(AF_INET, &ss, s, INET_ADDRSTRLEN)); +}