1630. [contrib] queryperf: add support for IPv6 transport.
-1629. [placeholder] rt8753
+1629. [func] dig now supports IPv6 scoped addresses with the
+ extended format in the local-server part. [RT #8753]
1628. [bug] Typo in Compaq Trucluster support. [RT# 11264]
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: getaddresses.c,v 1.15 2004/03/05 05:09:04 marka Exp $ */
+/* $Id: getaddresses.c,v 1.16 2004/05/15 03:37:33 jinmei Exp $ */
#include <config.h>
#include <string.h>
#include <isc/net.h>
#include <isc/netaddr.h>
#include <isc/netdb.h>
+#include <isc/netscope.h>
#include <isc/result.h>
#include <isc/sockaddr.h>
#include <isc/util.h>
have_ipv4 = (isc_net_probeipv4() == ISC_R_SUCCESS);
have_ipv6 = (isc_net_probeipv6() == ISC_R_SUCCESS);
- if (inet_pton(AF_INET6, hostname, &in6) == 1) {
- if (!have_ipv6)
- return (ISC_R_FAMILYNOSUPPORT);
- isc_sockaddr_fromin6(&addrs[0], &in6, port);
- *addrcount = 1;
- return (ISC_R_SUCCESS);
- } else if (inet_pton(AF_INET, hostname, &in4) == 1) {
+ /*
+ * Try IPv4, then IPv6. In order to handle the extended format
+ * for IPv6 scoped addresses (address%scope_ID), we'll use a local
+ * working buffer of 128 bytes. The length is an ad-hoc value, but
+ * should be enough for this purpose; the buffer can contain a string
+ * of at least 80 bytes for scope_ID in addition to any IPv6 numeric
+ * addresses (up to 46 bytes), the delimiter character and the
+ * terminating NULL character.
+ */
+ if (inet_pton(AF_INET, hostname, &in4) == 1) {
if (have_ipv4)
isc_sockaddr_fromin(&addrs[0], &in4, port);
else
isc_sockaddr_v6fromin(&addrs[0], &in4, port);
*addrcount = 1;
return (ISC_R_SUCCESS);
+ } else if (strlen(hostname) <= 127) {
+ char tmpbuf[128], *d;
+ isc_uint32_t zone = 0;
+
+ strcpy(tmpbuf, hostname);
+ d = strchr(tmpbuf, '%');
+ if (d != NULL)
+ *d = '\0';
+
+ if (inet_pton(AF_INET6, tmpbuf, &in6) == 1) {
+ isc_netaddr_t na;
+
+ if (!have_ipv6)
+ return (ISC_R_FAMILYNOSUPPORT);
+
+ if (d != NULL) {
+#ifdef ISC_PLATFORM_HAVESCOPEID
+ isc_result_t result;
+
+ result = isc_netscope_pton(AF_INET6, d + 1,
+ &in6, &zone);
+
+ if (result != ISC_R_SUCCESS)
+ return (result);
+#else
+ /*
+ * The extended format is specified while the
+ * system does not provide the ability to use
+ * it. Throw an explicit error instead of
+ * ignoring the specified value.
+ */
+ return (ISC_R_BADADDRESSFORM);
+#endif
+ }
+
+ isc_netaddr_fromin6(&na, &in6);
+ isc_netaddr_setzone(&na, zone);
+ isc_sockaddr_fromnetaddr(&addrs[0],
+ (const isc_netaddr_t *)&na,
+ port);
+
+ *addrcount = 1;
+ return (ISC_R_SUCCESS);
+
+ }
}
#ifdef USE_GETADDRINFO
memset(&hints, 0, sizeof(hints));
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: result.h,v 1.62 2004/03/05 05:11:00 marka Exp $ */
+/* $Id: result.h,v 1.63 2004/05/15 03:37:34 jinmei Exp $ */
#ifndef ISC_RESULT_H
#define ISC_RESULT_H 1
#define ISC_R_BADNUMBER 56 /* not a valid number */
#define ISC_R_DISABLED 57 /* disabled */
#define ISC_R_MAXSIZE 58 /* max size */
+#define ISC_R_BADADDRESSFORM 59 /* invalid address format */
/*
* Not a result code: the number of results.
*/
-#define ISC_R_NRESULTS 59
+#define ISC_R_NRESULTS 60
ISC_LANG_BEGINDECLS
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: netaddr.c,v 1.27 2004/03/05 05:10:47 marka Exp $ */
+/* $Id: netaddr.c,v 1.28 2004/05/15 03:37:33 jinmei Exp $ */
#include <config.h>
break;
case AF_INET6:
if (memcmp(&a->type.in6, &b->type.in6,
- sizeof(a->type.in6)) != 0)
+ sizeof(a->type.in6)) != 0 ||
+ a->zone != b->zone)
return (ISC_FALSE);
break;
default:
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: result.c,v 1.62 2004/03/05 05:10:48 marka Exp $ */
+/* $Id: result.c,v 1.63 2004/05/15 03:37:33 jinmei Exp $ */
#include <config.h>
"soft quota reached", /* 55 */
"not a valid number", /* 56 */
"disabled", /* 57 */
- "max size" /* 58 */
+ "max size", /* 58 */
+ "invalid address format" /* 59 */
};
#define ISC_RESULT_RESULTSET 2
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sockaddr.c,v 1.59 2004/03/05 05:10:49 marka Exp $ */
+/* $Id: sockaddr.c,v 1.60 2004/05/15 03:37:33 jinmei Exp $ */
#include <config.h>
if (memcmp(&a->type.sin6.sin6_addr, &b->type.sin6.sin6_addr,
sizeof(a->type.sin6.sin6_addr)) != 0)
return (ISC_FALSE);
+#ifdef ISC_PLATFORM_HAVESCOPEID
+ if (a->type.sin6.sin6_scope_id != b->type.sin6.sin6_scope_id)
+ return (ISC_FALSE);
+#endif
if (a->type.sin6.sin6_port != b->type.sin6.sin6_port)
return (ISC_FALSE);
break;
if (memcmp(&a->type.sin6.sin6_addr, &b->type.sin6.sin6_addr,
sizeof(a->type.sin6.sin6_addr)) != 0)
return (ISC_FALSE);
+#ifdef ISC_PLATFORM_HAVESCOPEID
+ if (a->type.sin6.sin6_scope_id != b->type.sin6.sin6_scope_id)
+ return (ISC_FALSE);
+#endif
break;
default:
if (memcmp(&a->type, &b->type, a->length) != 0)
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: parser.c,v 1.112 2004/03/18 02:58:07 marka Exp $ */
+/* $Id: parser.c,v 1.113 2004/05/15 03:37:34 jinmei Exp $ */
#include <config.h>
}
if ((flags & CFG_ADDR_V6OK) != 0 &&
strlen(s) <= 127U) {
- char buf[128];
+ char buf[128]; /* see lib/bind9/getaddresses.c */
char *d; /* zone delimiter */
isc_uint32_t zone = 0; /* scope zone ID */
if (inet_pton(AF_INET6, buf, &in6a) == 1) {
if (d != NULL) {
+#ifdef ISC_PLATFORM_HAVESCOPEID
isc_result_t result;
result = isc_netscope_pton(AF_INET6,
&zone);
if (result != ISC_R_SUCCESS)
return (result);
+#else
+ return (ISC_R_BADADDRESSFORM);
+#endif
}
isc_netaddr_fromin6(na, &in6a);