summaryrefslogtreecommitdiffstats
path: root/contrib/bind/lib/inet
diff options
context:
space:
mode:
authornectar <nectar@FreeBSD.org>2002-02-04 19:12:46 +0000
committernectar <nectar@FreeBSD.org>2002-02-04 19:12:46 +0000
commitebeabb1ba32f14e308ae9aff9a2a7151265259cf (patch)
tree71ba64d0a82be4894e23f6d65f36b61203ec3875 /contrib/bind/lib/inet
parent1385a0dca8f9199ece158336f4c6a9f1e2e03c3e (diff)
downloadFreeBSD-src-ebeabb1ba32f14e308ae9aff9a2a7151265259cf.zip
FreeBSD-src-ebeabb1ba32f14e308ae9aff9a2a7151265259cf.tar.gz
Import of ISC BIND 8.3.1-REL.
Diffstat (limited to 'contrib/bind/lib/inet')
-rw-r--r--contrib/bind/lib/inet/Makefile10
-rw-r--r--contrib/bind/lib/inet/inet_addr.c13
-rw-r--r--contrib/bind/lib/inet/inet_cidr_ntop.c166
-rw-r--r--contrib/bind/lib/inet/inet_cidr_pton.c167
-rw-r--r--contrib/bind/lib/inet/inet_data.c44
-rw-r--r--contrib/bind/lib/inet/inet_net_ntop.c135
-rw-r--r--contrib/bind/lib/inet/inet_net_pton.c272
-rw-r--r--contrib/bind/lib/inet/inet_network.c9
-rw-r--r--contrib/bind/lib/inet/inet_ntop.c7
-rw-r--r--contrib/bind/lib/inet/inet_pton.c6
-rw-r--r--contrib/bind/lib/inet/nsap_addr.c7
11 files changed, 728 insertions, 108 deletions
diff --git a/contrib/bind/lib/inet/Makefile b/contrib/bind/lib/inet/Makefile
index 1876bb6..a448e61 100644
--- a/contrib/bind/lib/inet/Makefile
+++ b/contrib/bind/lib/inet/Makefile
@@ -13,7 +13,7 @@
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
# SOFTWARE.
-# $Id: Makefile,v 8.21 2000/12/23 08:02:59 vixie Exp $
+# $Id: Makefile,v 8.23 2001/08/14 05:58:05 marka Exp $
# these are only appropriate for BSD 4.4 or derivatives, and are used in
# development. normal builds will be done in the top level directory and
@@ -45,12 +45,14 @@ THREADED= threaded
SRCS= nsap_addr.c inet_addr.c inet_ntop.c inet_pton.c \
inet_ntoa.c inet_neta.c inet_net_ntop.c inet_net_pton.c \
inet_cidr_ntop.c inet_cidr_pton.c \
- inet_lnaof.c inet_makeaddr.c inet_netof.c inet_network.c
+ inet_lnaof.c inet_makeaddr.c inet_netof.c inet_network.c \
+ inet_data.c
OBJS= nsap_addr.${O} inet_addr.${O} inet_ntop.${O} inet_pton.${O} \
inet_ntoa.${O} inet_neta.${O} inet_net_ntop.${O} inet_net_pton.${O} \
inet_cidr_ntop.${O} inet_cidr_pton.${O} \
- inet_lnaof.${O} inet_makeaddr.${O} inet_netof.${O} inet_network.${O}
+ inet_lnaof.${O} inet_makeaddr.${O} inet_netof.${O} inet_network.${O} \
+ inet_data.${O}
all: ${LIBBIND}
@@ -62,7 +64,7 @@ ${LIBBIND}: ${OBJS}
${RANLIB} ${LIBBIND}
.c.${O}:
- if test ! -d ${THREADED} ; then mkdir ${THREADED} ; else true ; fi
+ mkdir ${THREADED} 2> /dev/null || test -d ${THREADED} -a -w ${THREADED}
${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} ${REENTRANT} -c $*.c \
-o ${THREADED}/$*.${O}
-${LDS} ${LD} ${LD_LIBFLAGS} ${THREADED}/$*.${O} \
diff --git a/contrib/bind/lib/inet/inet_addr.c b/contrib/bind/lib/inet/inet_addr.c
index 3b54aa8..b68190c 100644
--- a/contrib/bind/lib/inet/inet_addr.c
+++ b/contrib/bind/lib/inet/inet_addr.c
@@ -70,7 +70,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static const char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
-static const char rcsid[] = "$Id: inet_addr.c,v 8.11 1999/10/13 16:39:25 vixie Exp $";
+static const char rcsid[] = "$Id: inet_addr.c,v 8.12 2001/05/29 05:48:18 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include "port_before.h"
@@ -121,7 +121,7 @@ inet_aton(const char *cp, struct in_addr *addr) {
* Values are specified as for C:
* 0x=hex, 0=octal, isdigit=decimal.
*/
- if (!isdigit(c))
+ if (!isdigit((unsigned char)c))
return (0);
val = 0; base = 10; digit = 0;
if (c == '0') {
@@ -134,15 +134,16 @@ inet_aton(const char *cp, struct in_addr *addr) {
}
}
for (;;) {
- if (isascii(c) && isdigit(c)) {
+ if (isascii(c) && isdigit((unsigned char)c)) {
if (base == 8 && (c == '8' || c == '9'))
return (0);
val = (val * base) + (c - '0');
c = *++cp;
digit = 1;
- } else if (base == 16 && isascii(c) && isxdigit(c)) {
+ } else if (base == 16 && isascii(c) &&
+ isxdigit((unsigned char)c)) {
val = (val << 4) |
- (c + 10 - (islower(c) ? 'a' : 'A'));
+ (c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
c = *++cp;
digit = 1;
} else
@@ -165,7 +166,7 @@ inet_aton(const char *cp, struct in_addr *addr) {
/*
* Check for trailing characters.
*/
- if (c != '\0' && (!isascii(c) || !isspace(c)))
+ if (c != '\0' && (!isascii(c) || !isspace((unsigned char)c)))
return (0);
/*
* Did we get a valid digit?
diff --git a/contrib/bind/lib/inet/inet_cidr_ntop.c b/contrib/bind/lib/inet/inet_cidr_ntop.c
index 08352ab..0acff76 100644
--- a/contrib/bind/lib/inet/inet_cidr_ntop.c
+++ b/contrib/bind/lib/inet/inet_cidr_ntop.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: inet_cidr_ntop.c,v 8.4 1999/10/07 20:44:02 vixie Exp $";
+static const char rcsid[] = "$Id: inet_cidr_ntop.c,v 8.7 2001/09/28 05:19:36 marka Exp $";
#endif
#include "port_before.h"
@@ -24,6 +24,7 @@ static const char rcsid[] = "$Id: inet_cidr_ntop.c,v 8.4 1999/10/07 20:44:02 vix
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include <arpa/nameser.h>
#include <arpa/inet.h>
#include <errno.h>
@@ -41,6 +42,8 @@ static const char rcsid[] = "$Id: inet_cidr_ntop.c,v 8.4 1999/10/07 20:44:02 vix
static char * inet_cidr_ntop_ipv4 __P((const u_char *src, int bits,
char *dst, size_t size));
+static char * inet_cidr_ntop_ipv6 __P((const u_char *src, int bits,
+ char *dst, size_t size));
/*
* char *
@@ -61,12 +64,34 @@ inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size) {
switch (af) {
case AF_INET:
return (inet_cidr_ntop_ipv4(src, bits, dst, size));
+ case AF_INET6:
+ return (inet_cidr_ntop_ipv6(src, bits, dst, size));
default:
errno = EAFNOSUPPORT;
return (NULL);
}
}
+static int
+decoct(const u_char *src, int bytes, char *dst, size_t size) {
+ char *odst = dst;
+ char *t;
+ int b;
+
+ for (b = 1; b <= bytes; b++) {
+ if (size < sizeof "255.")
+ return (0);
+ t = dst;
+ dst += SPRINTF((dst, "%u", *src++));
+ if (b != bytes) {
+ *dst++ = '.';
+ *dst = '\0';
+ }
+ size -= (size_t)(dst - t);
+ }
+ return (dst - odst);
+}
+
/*
* static char *
* inet_cidr_ntop_ipv4(src, bits, dst, size)
@@ -83,9 +108,9 @@ inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size) {
static char *
inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) {
char *odst = dst;
- char *t;
size_t len = 4;
- int b, tb;
+ size_t b;
+ size_t bytes;
if ((bits < -1) || (bits > 32)) {
errno = EINVAL;
@@ -94,25 +119,21 @@ inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) {
/* Find number of significant bytes in address. */
if (bits == -1)
- len = 3;
+ len = 4;
else
- for (len = 0,b = 1 ; b < 4; b++)
+ for (len = 1, b = 1 ; b < 4; b++)
if (*(src + b))
- len = b;
+ len = b + 1;
/* Format whole octets plus nonzero trailing octets. */
- tb = (bits <= 0) ? 1 : (bits - 1);
- for (b = 0; b <= (tb / 8) || (b <= len); b++) {
- if (size < sizeof "255.")
- goto emsgsize;
- t = dst;
- dst += SPRINTF((dst, "%u", *src++));
- if (b + 1 <= (tb / 8) || (b + 1 <= len)) {
- *dst++ = '.';
- *dst = '\0';
- }
- size -= (size_t)(dst - t);
- }
+ bytes = (((bits <= 0) ? 1 : bits) + 7) / 8;
+ if (len > bytes)
+ bytes = len;
+ b = decoct(src, bytes, dst, size);
+ if (b == 0)
+ goto emsgsize;
+ dst += b;
+ size -= b;
if (bits != -1) {
/* Format CIDR /width. */
@@ -127,3 +148,112 @@ inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) {
errno = EMSGSIZE;
return (NULL);
}
+
+static char *
+inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) {
+ /*
+ * Note that int32_t and int16_t need only be "at least" large enough
+ * to contain a value of the specified size. On some systems, like
+ * Crays, there is no such thing as an integer variable with 16 bits.
+ * Keep this in mind if you think this function should have been coded
+ * to use pointer overlays. All the world's not a VAX.
+ */
+ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255/128"];
+ char *tp;
+ struct { int base, len; } best, cur;
+ u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
+ int i;
+
+ if ((bits < -1) || (bits > 128)) {
+ errno = EINVAL;
+ return (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++)
+ words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+ best.base = -1;
+ cur.base = -1;
+ for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+ if (words[i] == 0) {
+ if (cur.base == -1)
+ cur.base = i, cur.len = 1;
+ else
+ cur.len++;
+ } else {
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ cur.base = -1;
+ }
+ }
+ }
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ }
+ if (best.base != -1 && best.len < 2)
+ best.base = -1;
+
+ /*
+ * Format the result.
+ */
+ tp = tmp;
+ for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); 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)
+ *tp++ = ':';
+ continue;
+ }
+ /* Are we following an initial run of 0x00s or any real hex? */
+ if (i != 0)
+ *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))) {
+ int n;
+
+ if (src[15] || bits == -1 || bits > 120)
+ n = 4;
+ else if (src[14] || bits > 112)
+ n = 3;
+ else
+ n = 2;
+ n = decoct(src+12, n, tp, sizeof tmp - (tp - tmp));
+ if (n == 0) {
+ errno = EMSGSIZE;
+ return (NULL);
+ }
+ tp += strlen(tp);
+ break;
+ }
+ tp += SPRINTF((tp, "%x", words[i]));
+ }
+
+ /* Was it a trailing run of 0x00's? */
+ if (best.base != -1 && (best.base + best.len) ==
+ (NS_IN6ADDRSZ / NS_INT16SZ))
+ *tp++ = ':';
+ *tp = '\0';
+
+ if (bits != -1)
+ tp += SPRINTF((tp, "/%u", bits));
+
+ /*
+ * Check for overflow, copy, and we're done.
+ */
+ if ((size_t)(tp - tmp) > size) {
+ errno = EMSGSIZE;
+ return (NULL);
+ }
+ strcpy(dst, tmp);
+ return (dst);
+}
diff --git a/contrib/bind/lib/inet/inet_cidr_pton.c b/contrib/bind/lib/inet/inet_cidr_pton.c
index 9ead90b..b8a7226 100644
--- a/contrib/bind/lib/inet/inet_cidr_pton.c
+++ b/contrib/bind/lib/inet/inet_cidr_pton.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: inet_cidr_pton.c,v 8.4 2000/12/23 08:14:53 vixie Exp $";
+static const char rcsid[] = "$Id: inet_cidr_pton.c,v 8.7 2001/09/28 04:21:28 marka Exp $";
#endif
#include "port_before.h"
@@ -24,6 +24,7 @@ static const char rcsid[] = "$Id: inet_cidr_pton.c,v 8.4 2000/12/23 08:14:53 vix
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include <arpa/nameser.h>
#include <arpa/inet.h>
#include <isc/assertions.h>
@@ -42,8 +43,12 @@ static const char rcsid[] = "$Id: inet_cidr_pton.c,v 8.4 2000/12/23 08:14:53 vix
#endif
static int inet_cidr_pton_ipv4 __P((const char *src, u_char *dst,
+ int *bits, int ipv6));
+static int inet_cidr_pton_ipv6 __P((const char *src, u_char *dst,
int *bits));
+static int getbits(const char *, int ipv6);
+
/*
* int
* inet_cidr_pton(af, src, dst, *bits)
@@ -65,16 +70,19 @@ int
inet_cidr_pton(int af, const char *src, void *dst, int *bits) {
switch (af) {
case AF_INET:
- return (inet_cidr_pton_ipv4(src, dst, bits));
+ return (inet_cidr_pton_ipv4(src, dst, bits, 0));
+ case AF_INET6:
+ return (inet_cidr_pton_ipv6(src, dst, bits));
default:
errno = EAFNOSUPPORT;
return (-1);
}
}
+static const char digits[] = "0123456789";
+
static int
-inet_cidr_pton_ipv4(const char *src, u_char *dst, int *pbits) {
- static const char digits[] = "0123456789";
+inet_cidr_pton_ipv4(const char *src, u_char *dst, int *pbits, int ipv6) {
const u_char *odst = dst;
int n, ch, tmp, bits;
size_t size = 4;
@@ -101,30 +109,17 @@ inet_cidr_pton_ipv4(const char *src, u_char *dst, int *pbits) {
/* Get the prefix length if any. */
bits = -1;
- if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) {
- /* CIDR width specifier. Nothing can follow it. */
- ch = *src++; /* Skip over the /. */
- bits = 0;
- do {
- n = strchr(digits, ch) - digits;
- INSIST(n >= 0 && n <= 9);
- bits *= 10;
- bits += n;
- } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));
- if (ch != '\0')
+ if (ch == '/' && dst > odst) {
+ bits = getbits(src, ipv6);
+ if (bits == -2)
goto enoent;
- if (bits > 32)
- goto emsgsize;
- }
-
- /* Firey death and destruction unless we prefetched EOS. */
- if (ch != '\0')
+ } else if (ch != '\0')
goto enoent;
/* Prefix length can default to /32 only if all four octets spec'd. */
if (bits == -1) {
if (dst - odst == 4)
- bits = 32;
+ bits = ipv6 ? 128 : 32;
else
goto enoent;
}
@@ -134,7 +129,7 @@ inet_cidr_pton_ipv4(const char *src, u_char *dst, int *pbits) {
goto enoent;
/* If prefix length overspecifies mantissa, life is bad. */
- if ((bits / 8) > (dst - odst))
+ if (((bits - (ipv6 ? 96 : 0)) / 8) > (dst - odst))
goto enoent;
/* Extend address to four octets. */
@@ -152,3 +147,129 @@ inet_cidr_pton_ipv4(const char *src, u_char *dst, int *pbits) {
errno = EMSGSIZE;
return (-1);
}
+
+static int
+inet_cidr_pton_ipv6(const char *src, u_char *dst, int *pbits) {
+ 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 bits;
+
+ 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;
+ saw_xdigit = 0;
+ val = 0;
+ bits = -1;
+ 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 (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_cidr_pton_ipv4(curtok, tp, &bits, 1) == 0) {
+ tp += NS_INADDRSZ;
+ saw_xdigit = 0;
+ break; /* '\0' was seen by inet_pton4(). */
+ }
+ if (ch == '/') {
+ bits = getbits(src, 1);
+ if (bits == -2)
+ goto enoent;
+ break;
+ }
+ goto enoent;
+ }
+ if (saw_xdigit) {
+ if (tp + NS_INT16SZ > endp)
+ goto emsgsize;
+ *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)
+ goto enoent;
+ for (i = 1; i <= n; i++) {
+ endp[- i] = colonp[n - i];
+ colonp[n - i] = 0;
+ }
+ tp = endp;
+ }
+
+ memcpy(dst, tmp, NS_IN6ADDRSZ);
+
+ *pbits = bits;
+ return (0);
+
+ enoent:
+ errno = ENOENT;
+ return (-1);
+
+ emsgsize:
+ errno = EMSGSIZE;
+ return (-1);
+}
+
+int
+getbits(const char *src, int ipv6) {
+ int bits = 0;
+ char *cp, ch;
+
+ if (*src == '\0') /* syntax */
+ return (-2);
+ do {
+ ch = *src++;
+ cp = strchr(digits, ch);
+ if (cp == NULL) /* syntax */
+ return (-2);
+ bits *= 10;
+ bits += cp - digits;
+ if (bits == 0 && *src != '\0') /* no leading zeros */
+ return (-2);
+ if (bits > (ipv6 ? 128 : 32)) /* range error */
+ return (-2);
+ } while (*src != '\0');
+
+ return (bits);
+}
diff --git a/contrib/bind/lib/inet/inet_data.c b/contrib/bind/lib/inet/inet_data.c
new file mode 100644
index 0000000..47b6d9b
--- /dev/null
+++ b/contrib/bind/lib/inet/inet_data.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1995-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 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id: inet_data.c,v 1.2 2001/06/20 22:06:36 marka Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include "port_before.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <ctype.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "port_after.h"
+
+const struct in6_addr isc_in6addr_any = IN6ADDR_ANY_INIT;
+const struct in6_addr isc_in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
diff --git a/contrib/bind/lib/inet/inet_net_ntop.c b/contrib/bind/lib/inet/inet_net_ntop.c
index d8b8377..b38a6ca 100644
--- a/contrib/bind/lib/inet/inet_net_ntop.c
+++ b/contrib/bind/lib/inet/inet_net_ntop.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.7 2001/01/25 19:55:59 vixie Exp $";
+static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.8 2001/09/27 15:08:36 marka Exp $";
#endif
#include "port_before.h"
@@ -41,6 +41,8 @@ static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.7 2001/01/25 19:55:59 vixi
static char * inet_net_ntop_ipv4 __P((const u_char *src, int bits,
char *dst, size_t size));
+static char * inet_net_ntop_ipv6 __P((const u_char *src, int bits,
+ char *dst, size_t size));
/*
* char *
@@ -63,6 +65,8 @@ inet_net_ntop(af, src, bits, dst, size)
switch (af) {
case AF_INET:
return (inet_net_ntop_ipv4(src, bits, dst, size));
+ case AF_INET6:
+ return (inet_net_ntop_ipv6(src, bits, dst, size));
default:
errno = EAFNOSUPPORT;
return (NULL);
@@ -98,6 +102,7 @@ inet_net_ntop_ipv4(src, bits, dst, size)
errno = EINVAL;
return (NULL);
}
+
if (bits == 0) {
if (size < sizeof "0")
goto emsgsize;
@@ -142,3 +147,131 @@ inet_net_ntop_ipv4(src, bits, dst, size)
errno = EMSGSIZE;
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
+ * 0x11110000 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;
+
+ 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 (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;
+ }
+ }
+ }
+ /* Format CIDR /width. */
+ SPRINTF((cp, "/%u", bits));
+ if (strlen(outbuf) + 1 > size)
+ goto emsgsize;
+ strcpy(dst, outbuf);
+
+ return (dst);
+
+emsgsize:
+ errno = EMSGSIZE;
+ return (NULL);
+}
diff --git a/contrib/bind/lib/inet/inet_net_pton.c b/contrib/bind/lib/inet/inet_net_pton.c
index 4d265b2..ff62a8b 100644
--- a/contrib/bind/lib/inet/inet_net_pton.c
+++ b/contrib/bind/lib/inet/inet_net_pton.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: inet_net_pton.c,v 1.11 1999/01/08 19:23:44 vixie Exp $";
+static const char rcsid[] = "$Id: inet_net_pton.c,v 1.13 2001/09/27 15:08:38 marka Exp $";
#endif
#include "port_before.h"
@@ -24,6 +24,7 @@ static const char rcsid[] = "$Id: inet_net_pton.c,v 1.11 1999/01/08 19:23:44 vix
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include <arpa/nameser.h>
#include <arpa/inet.h>
#include <isc/assertions.h>
@@ -41,38 +42,6 @@ static const char rcsid[] = "$Id: inet_net_pton.c,v 1.11 1999/01/08 19:23:44 vix
# define SPRINTF(x) ((size_t)sprintf x)
#endif
-static int inet_net_pton_ipv4 __P((const char *src, u_char *dst,
- size_t size));
-
-/*
- * 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(af, src, dst, size)
- int af;
- const char *src;
- void *dst;
- size_t size;
-{
- switch (af) {
- case AF_INET:
- return (inet_net_pton_ipv4(src, dst, size));
- default:
- errno = EAFNOSUPPORT;
- return (-1);
- }
-}
-
/*
* static int
* inet_net_pton_ipv4(src, dst, size)
@@ -90,20 +59,16 @@ inet_net_pton(af, src, dst, size)
* Paul Vixie (ISC), June 1996
*/
static int
-inet_net_pton_ipv4(src, dst, size)
- const char *src;
- u_char *dst;
- size_t size;
-{
- static const char
- xdigits[] = "0123456789abcdef",
- digits[] = "0123456789";
- int n, ch, tmp, dirty, bits;
+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;
const u_char *odst = dst;
ch = *src++;
if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
- && isascii(src[1]) && isxdigit(src[1])) {
+ && isascii((unsigned char)(src[1]))
+ && isxdigit((unsigned char)(src[1]))) {
/* Hexadecimal: Eat nybble string. */
if (size <= 0)
goto emsgsize;
@@ -158,7 +123,8 @@ inet_net_pton_ipv4(src, dst, size)
goto enoent;
bits = -1;
- if (ch == '/' && isascii(src[0]) && isdigit(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 /. */
bits = 0;
@@ -213,3 +179,221 @@ inet_net_pton_ipv4(src, dst, size)
errno = EMSGSIZE;
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;
+
+ 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 (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;
+
+ 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;
+
+ 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)
+ 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;
+ }
+ 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;
+ return (-1);
+ }
+}
diff --git a/contrib/bind/lib/inet/inet_network.c b/contrib/bind/lib/inet/inet_network.c
index d26369c..9090d13 100644
--- a/contrib/bind/lib/inet/inet_network.c
+++ b/contrib/bind/lib/inet/inet_network.c
@@ -65,7 +65,7 @@ again:
if (*cp == 'x' || *cp == 'X')
base = 16, cp++;
while ((c = *cp) != 0) {
- if (isdigit(c)) {
+ if (isdigit((unsigned char)c)) {
if (base == 8 && (c == '8' || c == '9'))
return (INADDR_NONE);
val = (val * base) + (c - '0');
@@ -73,8 +73,9 @@ again:
digit = 1;
continue;
}
- if (base == 16 && isxdigit(c)) {
- val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
+ if (base == 16 && isxdigit((unsigned char)c)) {
+ val = (val << 4) +
+ (c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
cp++;
digit = 1;
continue;
@@ -89,7 +90,7 @@ again:
*pp++ = val, cp++;
goto again;
}
- if (*cp && !isspace(*cp))
+ if (*cp && !isspace(*cp&0xff))
return (INADDR_NONE);
*pp++ = val;
n = pp - parts;
diff --git a/contrib/bind/lib/inet/inet_ntop.c b/contrib/bind/lib/inet/inet_ntop.c
index d588e9f..e05812e 100644
--- a/contrib/bind/lib/inet/inet_ntop.c
+++ b/contrib/bind/lib/inet/inet_ntop.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: inet_ntop.c,v 1.10 2001/01/25 20:21:10 vixie Exp $";
+static const char rcsid[] = "$Id: inet_ntop.c,v 1.11 2001/09/27 15:12:57 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include "port_before.h"
@@ -175,8 +175,9 @@ inet_ntop6(src, dst, size)
if (i != 0)
*tp++ = ':';
/* Is this address an encapsulated IPv4? */
- if (i == 6 && best.base == 0 &&
- (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
+ 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, sizeof tmp - (tp - tmp)))
return (NULL);
tp += strlen(tp);
diff --git a/contrib/bind/lib/inet/inet_pton.c b/contrib/bind/lib/inet/inet_pton.c
index 0a2927d..a6b0a71 100644
--- a/contrib/bind/lib/inet/inet_pton.c
+++ b/contrib/bind/lib/inet/inet_pton.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: inet_pton.c,v 1.7 1999/10/13 16:39:28 vixie Exp $";
+static const char rcsid[] = "$Id: inet_pton.c,v 1.8 2001/07/16 03:22:24 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include "port_before.h"
@@ -95,10 +95,12 @@ inet_pton4(src, dst)
if ((pch = strchr(digits, ch)) != NULL) {
u_int new = *tp * 10 + (pch - digits);
+ if (saw_digit && *tp == 0)
+ return (0);
if (new > 255)
return (0);
*tp = new;
- if (! saw_digit) {
+ if (!saw_digit) {
if (++octets > 4)
return (0);
saw_digit = 1;
diff --git a/contrib/bind/lib/inet/nsap_addr.c b/contrib/bind/lib/inet/nsap_addr.c
index da388dc..7198b9d 100644
--- a/contrib/bind/lib/inet/nsap_addr.c
+++ b/contrib/bind/lib/inet/nsap_addr.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: nsap_addr.c,v 8.11 2001/03/26 07:04:30 marka Exp $";
+static const char rcsid[] = "$Id: nsap_addr.c,v 8.12 2001/05/28 07:37:46 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include "port_before.h"
@@ -46,6 +46,7 @@ inet_nsap_addr(const char *ascii, u_char *binary, int maxlen) {
if (ascii[0] != '0' || (ascii[1] != 'x' && ascii[1] != 'X'))
return (0);
+ ascii += 2;
while ((c = *ascii++) != '\0' && len < (u_int)maxlen) {
if (c == '.' || c == '+' || c == '/')
@@ -88,8 +89,8 @@ inet_nsap_ntoa(int binlen, const u_char *binary, char *ascii) {
start = tmpbuf;
}
- *ascii = '0';
- *ascii = 'x';
+ *ascii++ = '0';
+ *ascii++ = 'x';
if (binlen > 255)
binlen = 255;
OpenPOWER on IntegriCloud