+1391. [func] Add support for IPv6 scoped addresses in named.
+
1390. [func] host now supports ixfr.
1389. [bug] named could fail to rotate long log files. [RT #3666]
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: client.c,v 1.211 2002/09/10 04:45:52 marka Exp $ */
+/* $Id: client.c,v 1.212 2002/10/24 03:52:31 marka Exp $ */
#include <config.h>
* the address of the interface where the request was received.
*/
if (client->interface->addr.type.sa.sa_family == AF_INET6) {
- if ((client->attributes & NS_CLIENTATTR_PKTINFO) != 0)
- isc_netaddr_fromin6(&destaddr, &client->pktinfo.ipi6_addr);
- else
+ if ((client->attributes & NS_CLIENTATTR_PKTINFO) != 0) {
+ u_int32_t zone = 0;
+
+ /*
+ * XXXJT technically, we should convert the receiving
+ * interface ID to a proper scope zone ID. However,
+ * due to the fact there is no standard API for this,
+ * we only handle link-local addresses and use the
+ * interface index as link ID. Despite the assumption,
+ * it should cover most typical cases.
+ */
+ if (IN6_IS_ADDR_LINKLOCAL(&client->pktinfo.ipi6_addr))
+ zone = (u_int32_t)client->pktinfo.ipi6_ifindex;
+
+ isc_netaddr_fromin6(&destaddr,
+ &client->pktinfo.ipi6_addr);
+ isc_netaddr_setzone(&destaddr, zone);
+
+ } else
isc_netaddr_any6(&destaddr);
} else {
isc_netaddr_fromsockaddr(&destaddr, &client->interface->addr);
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: interfacemgr.c,v 1.71 2002/09/10 04:45:52 marka Exp $ */
+/* $Id: interfacemgr.c,v 1.72 2002/10/24 03:52:31 marka Exp $ */
#include <config.h>
} else {
isc_netaddr_fromin6(&listen_netaddr,
&interface.address.type.in6);
+ isc_netaddr_setzone(&listen_netaddr,
+ interface.address.zone);
}
isc_sockaddr_fromnetaddr(&listen_sockaddr,
&listen_netaddr,
esyscmd([sed "s/^/# /" COPYRIGHT])dnl
AC_DIVERT_POP()dnl
-AC_REVISION($Revision: 1.331 $)
+AC_REVISION($Revision: 1.332 $)
AC_INIT(lib/dns/name.c)
AC_PREREQ(2.13)
],
[struct sockaddr_in6 xyzzy; xyzzy.sin6_scope_id = 0; return (0);],
[AC_MSG_RESULT(yes)
+ ISC_PLATFORM_HAVESCOPEID="#define ISC_PLATFORM_HAVESCOPEID 1"
result="#define LWRES_HAVE_SIN6_SCOPE_ID 1"],
[AC_MSG_RESULT(no)
+ ISC_PLATFORM_HAVESCOPEID="#undef ISC_PLATFORM_HAVESCOPEID"
result="#undef LWRES_HAVE_SIN6_SCOPE_ID"])
LWRES_HAVE_SIN6_SCOPE_ID="$result"
LWRES_PLATFORM_NEEDIN6ADDRANY="#undef LWRES_PLATFORM_NEEDIN6ADDRANY"
ISC_PLATFORM_HAVEIN6PKTINFO="#undef ISC_PLATFORM_HAVEIN6PKTINFO"
LWRES_HAVE_SIN6_SCOPE_ID="#define LWRES_HAVE_SIN6_SCOPE_ID 1"
+ ISC_PLATFORM_HAVESCOPEID="#define ISC_PLATFORM_HAVESCOPEID 1"
ISC_IPV6_H="ipv6.h"
ISC_IPV6_O="ipv6.$O"
ISC_ISCIPV6_O="unix/ipv6.$O"
AC_SUBST(ISC_ISCIPV6_O)
AC_SUBST(ISC_IPV6_C)
AC_SUBST(LWRES_HAVE_SIN6_SCOPE_ID)
+AC_SUBST(ISC_PLATFORM_HAVESCOPEID)
AC_MSG_CHECKING([for struct if_laddrreq])
AC_TRY_LINK([
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.0//EN"
"http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd">
-<!-- File: $Id: Bv9ARM-book.xml,v 1.205 2002/08/17 03:26:46 marka Exp $ -->
+<!-- File: $Id: Bv9ARM-book.xml,v 1.206 2002/10/24 03:52:32 marka Exp $ -->
<book>
<title>BIND 9 Administrator Reference Manual</title>
</row>
<row rowsep = "0">
<entry colname = "1"><para><varname>ip6_addr</varname></para></entry>
-<entry colname = "2"><para>An IPv6 address, such as <command>fe80::200:f8ff:fe01:9742</command>.</para></entry>
+<entry colname = "2"><para>An IPv6 address, such as <command>2001:ffff::200:f8ff:fe01:9742</command>.
+IPv6 scoped addresses that have ambiguity on their scope zones must be
+disambiguated by an appropriate zone ID with the percent character
+(`%') as delimiter.
+It is strongly recommended to use string zone names rather than
+numeric identifiers, in order to be robust against system
+configuration changes.
+However, since there is no standard mapping for such names and
+identifier values, currently only interface names as link identifiers
+are supported, assuming one-to-one mapping between interfaces and links.
+For example, a link-local address <command>fe80::1</command> on the
+link attached to the interface <command>ne0</command>
+can be specified as <command>fe80::1%ne0</command>.
+Note that on most systems link-local addresses always have the
+ambiguity, and need to be disambiguated.</para></entry>
</row>
<row rowsep = "0">
<entry colname = "1"><para><varname>ip_addr</varname></para></entry>
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.75 2002/02/20 03:35:20 marka Exp $
+# $Id: Makefile.in,v 1.76 2002/10/24 03:52:32 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
assertions.@O@ base64.@O@ bitstring.@O@ buffer.@O@ \
bufferlist.@O@ commandline.@O@ error.@O@ event.@O@ \
heap.@O@ hex.@O@ hmacmd5.@O@ \
- lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \
- md5.@O@ mem.@O@ mutexblock.@O@ netaddr.@O@ ondestroy.@O@ \
+ lex.@O@ lfsr.@O@ lib.@O@ log.@O@ md5.@O@ \
+ mem.@O@ mutexblock.@O@ netaddr.@O@ netscope.@O@ ondestroy.@O@ \
parseint.@O@ quota.@O@ random.@O@ \
ratelimiter.@O@ region.@O@ result.@O@ rwlock.@O@ \
serial.@O@ sha1.@O@ sockaddr.@O@ string.@O@ symtab.@O@ \
bufferlist.c commandline.c error.c event.c \
heap.c hex.c hmacmd5.c \
lex.c lfsr.c lib.c log.c \
- md5.c mem.c mutexblock.c netaddr.c ondestroy.c \
+ md5.c mem.c mutexblock.c netaddr.c netscope.c ondestroy.c \
parseint.c quota.c random.c \
ratelimiter.c result.c rwlock.c \
serial.c sha1.c sockaddr.c string.c symtab.c \
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: netaddr.h,v 1.21 2002/04/03 06:38:35 marka Exp $ */
+/* $Id: netaddr.h,v 1.22 2002/10/24 03:52:34 marka Exp $ */
#ifndef ISC_NETADDR_H
#define ISC_NETADDR_H 1
struct in_addr in;
struct in6_addr in6;
} type;
+ u_int32_t zone;
};
isc_boolean_t
void
isc_netaddr_fromin6(isc_netaddr_t *netaddr, const struct in6_addr *ina6);
+void
+isc_netaddr_setzone(isc_netaddr_t *netaddr, u_int32_t zone);
+
+u_int32_t
+isc_netaddr_getzone(const isc_netaddr_t *netaddr);
+
void
isc_netaddr_any(isc_netaddr_t *netaddr);
/*
--- /dev/null
+/*
+ * Copyright (C) 2002 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.
+ */
+
+/* $Id: netscope.h,v 1.2 2002/10/24 03:52:34 marka Exp $ */
+
+#ifndef ISC_NETSCOPE_H
+#define ISC_NETSCOPE_H 1
+
+ISC_LANG_BEGINDECLS
+
+/*
+ * Convert a string of an IPv6 scope zone to zone index. If the conversion
+ * succeeds, 'zoneid' will store the index value.
+ * XXXJT: when a standard interface for this purpose is defined,
+ * we should use it.
+ *
+ * Returns:
+ * ISC_R_SUCCESS: conversion succeeds
+ * ISC_R_FAILURE: conversion fails
+ */
+isc_result_t
+isc_netscope_pton(int af, char *scopename, char *addr, u_int32_t *zoneid);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_NETADDR_H */
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: platform.h.in,v 1.28 2001/11/19 03:08:26 mayer Exp $ */
+/* $Id: platform.h.in,v 1.29 2002/10/24 03:52:34 marka Exp $ */
#ifndef ISC_PLATFORM_H
#define ISC_PLATFORM_H 1
*/
@ISC_PLATFORM_HAVEINADDR6@
+/*
+ * If this system has sin6_scope_id, ISC_PLATFORM_HAVESCOPEID will be defined.
+ */
+@ISC_PLATFORM_HAVESCOPEID@
+
/*
* If this system needs inet_ntop(), ISC_PLATFORM_NEEDNTOP will be defined.
*/
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: netaddr.c,v 1.22 2002/04/03 06:38:31 marka Exp $ */
+/* $Id: netaddr.c,v 1.23 2002/10/24 03:52:32 marka Exp $ */
#include <config.h>
if (a->family != b->family)
return (ISC_FALSE);
+ if (a->zone != b->zone)
+ return (ISC_FALSE);
+
switch (a->family) {
case AF_INET:
if (a->type.in.s_addr != b->type.in.s_addr)
return (ISC_FALSE);
break;
case AF_INET6:
- if (memcmp(&a->type.in6, &b->type.in6, sizeof(a->type.in6))
- != 0)
+ if (memcmp(&a->type.in6, &b->type.in6,
+ sizeof(a->type.in6)) != 0)
return (ISC_FALSE);
break;
default:
if (a->family != b->family)
return (ISC_FALSE);
+ if (a->zone != b->zone)
+ return (ISC_FALSE);
+
switch (a->family) {
case AF_INET:
pa = (const unsigned char *) &a->type.in;
isc_result_t
isc_netaddr_totext(const isc_netaddr_t *netaddr, isc_buffer_t *target) {
char abuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
+ char zbuf[sizeof("%4294967295")];
unsigned int alen;
+ int zlen;
const char *r;
+ const void *type;
REQUIRE(netaddr != NULL);
- r = inet_ntop(netaddr->family, &netaddr->type, abuf, sizeof(abuf));
+ switch (netaddr->family) {
+ case AF_INET:
+ type = &netaddr->type.in;
+ break;
+ case AF_INET6:
+ type = &netaddr->type.in6;
+ break;
+ default:
+ return (ISC_R_FAILURE);
+ }
+ r = inet_ntop(netaddr->family, type, abuf, sizeof(abuf));
if (r == NULL)
return (ISC_R_FAILURE);
alen = strlen(abuf);
INSIST(alen < sizeof(abuf));
- if (alen > isc_buffer_availablelength(target))
+ zlen = 0;
+ if (netaddr->family == AF_INET6 && netaddr->zone != 0) {
+ zlen = snprintf(zbuf, sizeof(zbuf), "%%%u", netaddr->zone);
+ if (zlen < 0)
+ return (ISC_R_FAILURE);
+ INSIST((unsigned int)zlen < sizeof(zbuf));
+ }
+
+ if (alen + zlen > isc_buffer_availablelength(target))
return (ISC_R_NOSPACE);
isc_buffer_putmem(target, (unsigned char *)abuf, alen);
+ isc_buffer_putmem(target, (unsigned char *)zbuf, zlen);
return (ISC_R_SUCCESS);
}
netaddr->type.in6 = *ina6;
}
+void
+isc_netaddr_setzone(isc_netaddr_t *netaddr, u_int32_t zone) {
+ /* we currently only support AF_INET6. */
+ REQUIRE(netaddr->family == AF_INET6);
+
+ netaddr->zone = zone;
+}
+
+u_int32_t
+isc_netaddr_getzone(const isc_netaddr_t *netaddr) {
+ return (netaddr->zone);
+}
+
void
isc_netaddr_fromsockaddr(isc_netaddr_t *t, const isc_sockaddr_t *s) {
int family = s->type.sa.sa_family;
t->family = family;
switch (family) {
- case AF_INET:
+ case AF_INET:
t->type.in = s->type.sin.sin_addr;
- break;
- case AF_INET6:
+ break;
+ case AF_INET6:
memcpy(&t->type.in6, &s->type.sin6.sin6_addr, 16);
- break;
- default:
- INSIST(0);
- }
+#ifdef ISC_PLATFORM_HAVESCOPEID
+ t->zone = s->type.sin6.sin6_scope_id;
+#else
+ t->zone = 0;
+#endif
+ break;
+ default:
+ INSIST(0);
+ }
}
void
--- /dev/null
+/*
+ * Copyright (C) 1996-2001 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: netscope.c,v 1.2 2002/10/24 03:52:33 marka Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <isc/string.h>
+#include <isc/net.h>
+#include <isc/netscope.h>
+#include <isc/result.h>
+
+isc_result_t
+isc_netscope_pton(int af, char *scopename, char *addr, u_int32_t *zoneid) {
+ char *ep;
+ unsigned int ifid;
+ struct in6_addr *in6;
+ u_int32_t zone;
+ isc_uint64_t llz;
+
+ /* at this moment, we only support AF_INET6 */
+ if (af != AF_INET6)
+ return (ISC_R_FAILURE);
+
+ in6 = (struct in6_addr *)addr;
+
+ /*
+ * Basically, "names" are more stable than numeric IDs in terms of
+ * renumbering, and are more preferred. However, since there is no
+ * standard naming convention and APIs to deal with the names. Thus,
+ * we only handle the case of link-local addresses, for which we use
+ * interface names as link names, assuming one to one mapping between
+ * interfaces and links.
+ */
+ if (IN6_IS_ADDR_LINKLOCAL(in6) &&
+ (ifid = if_nametoindex((const char *)scopename)) != 0)
+ zone = (u_int32_t)ifid;
+ else {
+ llz = isc_string_touint64(scopename, &ep, 10);
+ if (ep == scopename)
+ return (ISC_R_FAILURE);
+
+ /* check overflow */
+ zone = (u_int32_t)(llz & 0xffffffffUL);
+ if (zone != llz)
+ return (ISC_R_FAILURE);
+ }
+
+ *zoneid = zone;
+ return (ISC_R_SUCCESS);
+}
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sockaddr.c,v 1.54 2002/04/03 06:38:32 marka Exp $ */
+/* $Id: sockaddr.c,v 1.55 2002/10/24 03:52:33 marka Exp $ */
#include <config.h>
sockaddr->type.sin6.sin6_len = sizeof(sockaddr->type.sin6);
#endif
memcpy(&sockaddr->type.sin6.sin6_addr, &na->type.in6, 16);
+#ifdef ISC_PLATFORM_HAVESCOPEID
+ sockaddr->type.sin6.sin6_scope_id = isc_netaddr_getzone(na);
+#endif
sockaddr->type.sin6.sin6_port = htons(port);
break;
default:
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: net.h,v 1.34 2002/04/03 06:38:38 marka Exp $ */
+/* $Id: net.h,v 1.35 2002/10/24 03:52:35 marka Exp $ */
#ifndef ISC_NET_H
#define ISC_NET_H 1
#include <sys/types.h>
#include <sys/socket.h> /* Contractual promise. */
+#include <net/if.h>
+
#include <netinet/in.h> /* Contractual promise. */
#include <arpa/inet.h> /* Contractual promise. */
#ifdef ISC_PLATFORM_NEEDNETINETIN6H
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: interfaceiter.c,v 1.27 2002/07/02 05:51:43 marka Exp $ */
+/* $Id: interfaceiter.c,v 1.28 2002/10/24 03:52:34 marka Exp $ */
#include <config.h>
/*
* Extract the network address part from a "struct sockaddr".
*
- * The address family is given explicity
+ * The address family is given explicitly
* instead of using src->sa_family, because the latter does not work
* for copying a network mask obtained by SIOCGIFNETMASK (it does
* not have a valid address family).
static void
get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src) {
+ struct sockaddr_in6 *sa6;
+
dst->family = family;
switch (family) {
case AF_INET:
sizeof(struct in_addr));
break;
case AF_INET6:
- memcpy(&dst->type.in6,
- &((struct sockaddr_in6 *) src)->sin6_addr,
+ sa6 = (struct sockaddr_in6 *)src;
+ memcpy(&dst->type.in6, &sa6->sin6_addr,
sizeof(struct in6_addr));
+#ifdef ISC_PLATFORM_HAVESCOPEID
+ if (sa6->sin6_scope_id != 0)
+ isc_netaddr_setzone(dst, sa6->sin6_scope_id);
+ else
+#endif
+ {
+ /*
+ * BSD variants embed scope zone IDs in the 128bit
+ * address as a kernel internal form. Unfortunately,
+ * the embedded IDs are not hidden from applications
+ * when getting access to them by sysctl or ioctl.
+ * We convert the internal format to the pure address
+ * part and the zone ID part.
+ * Since multicast addresses should not appear here
+ * and they cannot be distinguished from netmasks,
+ * we only consider unicast link-local addresses.
+ */
+ if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
+ u_int16_t zone;
+
+ memcpy(&zone, &sa6->sin6_addr.s6_addr[2],
+ sizeof(zone));
+ zone = ntohs(zone);
+ if (zone != 0) { /* the zone ID is embedded */
+ isc_netaddr_setzone(dst,
+ (u_int32_t)zone);
+ dst->type.in6.s6_addr[2] = 0;
+ dst->type.in6.s6_addr[3] = 0;
+ }
+ }
+ }
break;
default:
INSIST(0);
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: parser.c,v 1.102 2002/02/20 03:35:49 marka Exp $ */
+/* $Id: parser.c,v 1.103 2002/10/24 03:52:35 marka Exp $ */
#include <config.h>
}
}
}
- if (flags & CFG_ADDR_V6OK) {
- if (inet_pton(AF_INET6, s, &in6a) == 1) {
+ if ((flags & CFG_ADDR_V6OK) != 0 &&
+ strlen(s) <= 127) {
+ char buf[128];
+ char *d; /* zone delimiter */
+ u_int32_t zone = 0; /* scope zone ID */
+
+ strcpy(buf, s);
+ d = strchr(buf, '%');
+ if (d != NULL)
+ *d = '\0';
+
+ if (inet_pton(AF_INET6, buf, &in6a) == 1) {
+ if (d != NULL) {
+ isc_result_t result;
+
+ result = isc_netscope_pton(AF_INET6,
+ d + 1,
+ &in6a,
+ &zone);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ }
+
isc_netaddr_fromin6(na, &in6a);
+ isc_netaddr_setzone(na, zone);
return (ISC_R_SUCCESS);
}
}