From b407c7256674c12c3d81fa11b01b5739eccd43dd Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Thu, 22 Feb 2018 09:01:23 +0000 Subject: win32: import inet_pton.c from ISC BIND The copy of inet_pton.c imported from gnulib was licensed under GPL3 which is incompatible with the GPL2-only licence of BusyBox. Import an MPL2-licensed version of this file from ISC BIND git master as of this date. --- win32/inet_pton.c | 413 ++++++++++++++++++++++++------------------------------ 1 file changed, 182 insertions(+), 231 deletions(-) (limited to 'win32') diff --git a/win32/inet_pton.c b/win32/inet_pton.c index ec87abec5..ba8770d2c 100644 --- a/win32/inet_pton.c +++ b/win32/inet_pton.c @@ -1,255 +1,206 @@ -/* inet_pton.c -- convert IPv4 and IPv6 addresses from text to binary form - - Copyright (C) 2006, 2008-2015 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - /* - * Copyright (c) 1996,1999 by Internet Software Consortium. + * Copyright (C) 1996-2005, 2007, 2013, 2014, 2016, 2017 Internet Systems Consortium, Inc. ("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 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. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "libbb.h" +/*! \file */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = + "$Id: inet_pton.c,v 1.19 2007/06/19 23:47:17 tbox Exp $"; +#endif /* LIBC_SCCS and not lint */ -/* Specification. */ -#include +#include -# include -# include -# include +#include +#include -# define NS_INADDRSZ 4 -# define NS_IN6ADDRSZ 16 -# define NS_INT16SZ 2 -# define HAVE_IPV6 1 +#include + +/*% INT16 Size */ +#define NS_INT16SZ 2 +/*% IPv4 Address Size */ +#define NS_INADDRSZ 4 +/*% IPv6 Address Size */ +#define NS_IN6ADDRSZ 16 /* * 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, unsigned char *dst); -# if HAVE_IPV6 -static int inet_pton6 (const char *src, unsigned char *dst); -# endif - -/* 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. +static int inet_pton4(const char *src, unsigned char *dst); +static int inet_pton6(const char *src, unsigned char *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 *restrict src, void *restrict dst) -{ - switch (af) - { - case AF_INET: - return (inet_pton4 (src, dst)); - -# if HAVE_IPV6 - case AF_INET6: - return (inet_pton6 (src, dst)); -# endif - - default: - errno = EAFNOSUPPORT; - return (-1); - } - /* NOTREACHED */ +isc_net_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, octal (with the - * exception of 0) 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. +/*!\fn static int inet_pton4(const char *src, unsigned char *dst) + * \brief + * like inet_aton() but without all the hexadecimal and shorthand. + * \return + * 1 if `src' is a valid dotted quad, else 0. + * \note + * does not touch `dst' unless it's returning 1. + * \author + * Paul Vixie, 1996. */ static int -inet_pton4 (const char *restrict src, unsigned char *restrict dst) -{ - int saw_digit, octets, ch; - unsigned char tmp[NS_INADDRSZ], *tp; - - saw_digit = 0; - octets = 0; - *(tp = tmp) = 0; - while ((ch = *src++) != '\0') - { - - if (ch >= '0' && ch <= '9') - { - unsigned new = *tp * 10 + (ch - '0'); - - if (saw_digit && *tp == 0) - return (0); - if (new > 255) - return (0); - *tp = new; - if (!saw_digit) - { - if (++octets > 4) - return (0); - saw_digit = 1; - } - } - 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, NS_INADDRSZ); - return (1); +inet_pton4(const char *src, unsigned char *dst) { + static const char digits[] = "0123456789"; + int saw_digit, octets, ch; + unsigned char tmp[NS_INADDRSZ], *tp; + + saw_digit = 0; + octets = 0; + *(tp = tmp) = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr(digits, ch)) != NULL) { + unsigned int byte = *tp * 10; + + byte += (int)(pch - digits); + if (saw_digit && *tp == 0) + return (0); + if (byte > 255) + return (0); + *tp = byte; + if (!saw_digit) { + if (++octets > 4) + return (0); + saw_digit = 1; + } + } else if (ch == '.' && saw_digit) { + if (octets == 4) + return (0); + *++tp = 0; + saw_digit = 0; + } else + return (0); + } + if (octets < 4) + return (0); + memmove(dst, tmp, NS_INADDRSZ); + return (1); } -# if HAVE_IPV6 - -/* 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. +/*% + * convert presentation level address to network order binary form. + * \return + * 1 if `src' is a valid [RFC1884 2.2] address, else 0. + * \note + * (1) does not touch `dst' unless it's returning 1. + * \note + * (2) :: in a full address is silently ignored. + * \author + * inspired by Mark Andrews. + * \author + * Paul Vixie, 1996. */ static int -inet_pton6 (const char *restrict src, unsigned char *restrict dst) -{ - static const char xdigits[] = "0123456789abcdef"; - unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; - const char *curtok; - int ch, saw_xdigit; - unsigned val; - - tp = memset (tmp, '\0', NS_IN6ADDRSZ); - endp = tp + NS_IN6ADDRSZ; - colonp = NULL; - /* Leading :: requires some special handling. */ - if (*src == ':') - if (*++src != ':') - return (0); - curtok = src; - saw_xdigit = 0; - val = 0; - while ((ch = tolower (*src++)) != '\0') - { - const char *pch; - - pch = strchr (xdigits, ch); - if (pch != NULL) - { - val <<= 4; - val |= (pch - xdigits); - if (val > 0xffff) - return (0); - saw_xdigit = 1; - continue; - } - if (ch == ':') - { - curtok = src; - if (!saw_xdigit) - { - 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; - saw_xdigit = 0; - val = 0; - continue; - } - if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && - inet_pton4 (curtok, tp) > 0) - { - tp += NS_INADDRSZ; - saw_xdigit = 0; - break; /* '\0' was seen by inet_pton4(). */ - } - return (0); - } - if (saw_xdigit) - { - 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 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, NS_IN6ADDRSZ); - return (1); +inet_pton6(const char *src, unsigned char *dst) { + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; + const char *xdigits, *curtok; + int ch, seen_xdigits; + unsigned int val; + + 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 |= (pch - xdigits); + if (++seen_xdigits > 4) + return (0); + continue; + } + if (ch == ':') { + curtok = src; + if (!seen_xdigits) { + if (colonp) + return (0); + colonp = tp; + continue; + } + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (unsigned char) (val >> 8) & 0xff; + *tp++ = (unsigned char) val & 0xff; + seen_xdigits = 0; + val = 0; + continue; + } + if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && + inet_pton4(curtok, tp) > 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++ = (unsigned char) (val >> 8) & 0xff; + *tp++ = (unsigned 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 = (int)(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); + memmove(dst, tmp, NS_IN6ADDRSZ); + return (1); } - -# endif -- cgit v1.2.3-55-g6feb