Imported Upstream version 2.82 68/251668/1 upstream/2.82
authorSeonah Moon <seonah1.moon@samsung.com>
Mon, 18 Jan 2021 09:17:41 +0000 (18:17 +0900)
committerSeonah Moon <seonah1.moon@samsung.com>
Mon, 18 Jan 2021 09:18:15 +0000 (18:18 +0900)
Change-Id: If6c75c812a79ed39237a4cb4af71ce73d665de75

75 files changed:
CHANGELOG
Makefile
VERSION
bld/Android.mk
bld/pkg-wrapper
contrib/lease-tools/dhcp_lease_time.c
contrib/lease-tools/dhcp_release.c
contrib/lease-tools/dhcp_release6.c
contrib/reverse-dns/README
contrib/reverse-dns/reverse_replace.sh
contrib/systemd/dbus_activation
contrib/systemd/dnsmasq.service
dbus/DBus-interface
dnsmasq.conf.example
man/dnsmasq.8
man/es/dnsmasq.8
man/fr/dnsmasq.8
po/de.po
po/es.po
po/fi.po
po/fr.po
po/id.po
po/it.po
po/no.po
po/pl.po
po/pt_BR.po
po/ro.po
src/arp.c
src/auth.c
src/blockdata.c
src/bpf.c
src/cache.c
src/config.h
src/conntrack.c
src/crypto.c
src/dbus.c
src/dhcp-common.c
src/dhcp-protocol.h
src/dhcp.c
src/dhcp6-protocol.h
src/dhcp6.c
src/dns-protocol.h
src/dnsmasq.c
src/dnsmasq.h
src/dnssec.c
src/domain.c
src/dump.c [new file with mode: 0644]
src/edns0.c
src/forward.c
src/helper.c
src/inotify.c
src/ip6addr.h
src/ipset.c
src/lease.c
src/log.c
src/loop.c
src/metrics.c [new file with mode: 0644]
src/metrics.h [new file with mode: 0644]
src/netlink.c
src/network.c
src/option.c
src/outpacket.c
src/poll.c
src/radv-protocol.h
src/radv.c
src/rfc1035.c
src/rfc2131.c
src/rfc3315.c
src/rrfilter.c
src/slaac.c
src/tables.c
src/tftp.c
src/ubus.c [new file with mode: 0644]
src/util.c
trust-anchors.conf

index b32d95d..e6a2231 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,186 @@
+version 2.82
+       Improve behaviour in the face of network interfaces which come
+       and go and change index. Thanks to Petr Mensik for the patch.
+
+       Convert hard startup failure on NETLINK_NO_ENOBUFS under qemu-user
+       to a warning.
+
+       Allow IPv6 addresses ofthe form [::ffff:1.2.3.4] in --dhcp-option.
+
+       Fix crash under heavy TCP connection load introduced in 2.81.
+       Thanks to Frank for good work chasing this down.
+
+       Change default lease time for DHCPv6 to one day.
+
+       Alter calculation of preferred and valid times in router
+       advertisements, so that these do not have a floor applied
+       of the lease time in the dhcp-range if this is not explicitly
+       specified and is merely the default.
+       Thanks to Martin-Éric Racine for suggestions on this.
+
+       
+version 2.81
+       Improve cache behaviour for TCP connections. For ease of
+       implementation, dnsmasq has always forked a new process to handle
+       each incoming TCP connection. A side-effect of this is that
+       any DNS queries answered from TCP connections are not cached:
+       when TCP connections were rare, this was not a problem.
+       With the coming of DNSSEC, it is now the case that some
+       DNSSEC queries have answers which spill to TCP, and if,
+       for instance, this applies to the keys for the root, then
+       those never get cached, and performance is very bad.
+       This fix passes cache entries back from the TCP child process to
+       the main server process, and fixes the problem.
+
+       Remove the NO_FORK compile-time option, and support for uclinux.
+       In an era where everything has an MMU, this looks like
+       an anachronism, and it adds to (Ok, multiplies!) the
+       combinatorial explosion of compile-time options. Thanks to
+       Kevin Darbyshire-Bryant for the patch.
+
+       Fix line-counting when reading /etc/hosts and friends; for
+       correct error messages. Thanks to Christian Rosentreter
+       for reporting this.
+
+       Fix bug in DNS non-terminal code, added in 2.80, which could
+       sometimes cause a NODATA rather than an NXDOMAIN reply.
+       Thanks to Norman Rasmussen, Sven Mueller and Maciej Żenczykowski
+       for spotting and diagnosing the bug and providing patches.
+
+       Support TCP-fastopen (RFC-7413) on both incoming and
+       outgoing TCP connections, if supported and enabled in the OS.
+
+       Improve kernel-capability manipulation code under Linux. Dnsmasq
+       now fails early if a required capability is not available, and
+       tries not to request capabilities not required by its
+       configuration.
+
+       Add --shared-network config. This enables allocation of addresses
+       by the DHCP server in subnets where the server (or relay) does not
+       have an interface on the network in that subnet. Many thanks to
+       kamp.de for sponsoring this feature.
+       
+       Fix broken contrib/lease_tools/dhcp_lease_time.c. A packet
+       validation check got borked in commit 2b38e382 and release 2.80.
+       Thanks to Tomasz Szajner for spotting this.
+
+       Fix compilation against nettle version 3.5 and later.
+
+       Fix spurious DNSSEC validation failures when the auth section
+       of a reply contains unsigned RRs from a signed zone, 
+       with the exception that NSEC and NSEC3 RRs must always be signed.
+        Thanks to Tore Anderson for spotting and diagnosing the bug.
+
+       Add --dhcp-ignore-clid. This disables reading of DHCP client
+       identifier option (option 61), so clients are only identified by
+       MAC addresses.
+
+       Fix a bug which stopped --dhcp-name-match from working when a hostname
+       is supplied in --dhcp-host. Thanks to James Feeney for spotting this.
+
+       Fix bug which caused very rarely caused zero-length DHCPv6 packets.
+       Thanks to Dereck Higgins for spotting this.
+
+       Add --tftp-single-port option.
+
+       Enhance --conf-dir to load files in a deterministic order. Thanks to
+       Evgenii Seliavka for the suggestion and initial patch.
+
+       In the router advert code, handle case where we have two
+       different interfaces on the same IPv6 net, and we are doing
+       RA/DHCP service on only one of them. Thanks to NIIBE Yutaka
+       for spotting this case and making the initial patch.
+
+       Support prefixed ranges of ipv6 addresses in dhcp-host.
+       This eases problems chain-netbooting, where each link in the
+       chain requests an address using a different UID. With a single
+       address, only one gets the "static" address, but with this
+       fix, enough addresses can be reserved for all the stages of the
+       boot. Many thanks to Harald Jensås for his work on this idea and
+       earlier patches.
+
+       Add filtering by tag of --dhcp-host directives. Based on a patch
+       by Harald Jensås.
+
+       Allow empty server spec in --rev-server, to match --server.
+       
+       Remove DSA signature verification from DNSSEC, as specified in
+       RFC 8624. Thanks to Loganaden Velvindron for the original patch.
+
+       Add --script-on-renewal option.
+
+       
+version 2.80
+       Add support for RFC 4039 DHCP rapid commit. Thanks to Ashram Method
+       for the initial patch and motivation.
+
+       Alter the default for dnssec-check-unsigned. Versions of
+       dnsmasq prior to 2.80 defaulted to not checking unsigned
+       replies, and used --dnssec-check-unsigned to switch
+        this on. Such configurations will continue to work as before,
+        but those which used the default of no checking will need to be
+        altered to explicitly select no checking. The new default is
+        because switching off checking for unsigned replies is
+       inherently dangerous. Not only does it open the possiblity of forged
+        replies, but it allows everything to appear to be working even
+        when the upstream namesevers do not support DNSSEC, and in this
+        case no DNSSEC validation at all is occuring.
+
+        Fix DHCP broken-ness when --no-ping AND --dhcp-sequential-ip
+       are set. Thanks to Daniel Miess for help with this.
+
+       Add a facilty to store DNS packets sent/recieved in a
+       pcap-format file for later debugging. The file location
+       is given by the --dumpfile option, and a bitmap controlling
+       which packets should be dumped is given by the --dumpmask
+       option.
+
+       Handle the case of both standard and constructed dhcp-ranges on the
+       same interface better. We don't now contruct a dhcp-range if there's
+       already one specified. This allows the specified interface to
+       have different parameters and avoids advertising the same
+       prefix twice. Thanks to Luis Marsano for spotting this case.
+
+       Allow zone transfer in authoritative mode if auth-peer is specified,
+       even if auth-sec-servers is not. Thanks to Raphaël Halimi for
+       the suggestion.
+
+       Fix bug which sometimes caused dnsmasq to wrongly return answers
+       without DNSSEC RRs to queries with the do-bit set, but only when
+       DNSSEC validation was not enabled.
+       Thanks to Petr Menšík for spotting this.
+
+       Fix missing fatal errors with some malformed options
+       (server, local, address, rebind-domain-ok, ipset, alias).
+       Thanks to Eugene Lozovoy for spotting the problem.
+
+       Fix crash on startup with a --synth-domain which has no prefix.
+       Introduced in 2.79. Thanks to Andreas Engel for the bug report.
+
+       Fix missing EDNS0 section in some replies generated by local
+       DNS configuration which confused systemd-resolvd. Thanks to
+       Steve Dodd for characterising the problem.
+
+       Add --dhcp-name-match config option. 
+
+       Add --caa-record config option.
+
+       Implement --address=/example.com/# as (more efficient) syntactic
+       sugar for --address=/example.com/0.0.0.0 and
+       --address=/example.com/::
+       Returning null addresses is a useful technique for ad-blocking.
+       Thanks to Peter Russell for the suggestion.
+       
+       Change anti cache-snooping behaviour with queries with the
+       recursion-desired bit unset. Instead to returning SERVFAIL, we
+       now always forward, and never answer from the cache. This
+       allows "dig +trace" command to work. 
+       
+       Include in the example config file a formulation which
+       stops DHCP clients from claiming the DNS name "wpad".
+       This is a fix for the CERT Vulnerability VU#598349.
+
+       
 version 2.79
        Fix parsing of CNAME arguments, which are confused by extra spaces.
        Thanks to Diego Aguirre for spotting the bug.
index 98ec760..78e25f0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -53,6 +53,7 @@ top?=$(CURDIR)
 
 dbus_cflags =   `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG) --cflags dbus-1` 
 dbus_libs =     `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG) --libs dbus-1` 
+ubus_libs =     `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_UBUS "" --copy -lubox -lubus`
 idn_cflags =    `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) --cflags libidn` 
 idn_libs =      `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) --libs libidn` 
 idn2_cflags =   `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LIBIDN2 $(PKG_CONFIG) --cflags libidn2`
@@ -76,16 +77,16 @@ objs = cache.o rfc1035.o util.o option.o forward.o network.o \
        helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \
        dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o \
        domain.o dnssec.o blockdata.o tables.o loop.o inotify.o \
-       poll.o rrfilter.o edns0.o arp.o crypto.o
+       poll.o rrfilter.o edns0.o arp.o crypto.o dump.o ubus.o metrics.o
 
 hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
-       dns-protocol.h radv-protocol.h ip6addr.h
+       dns-protocol.h radv-protocol.h ip6addr.h metrics.h
 
 all : $(BUILDDIR)
        @cd $(BUILDDIR) && $(MAKE) \
  top="$(top)" \
  build_cflags="$(version) $(dbus_cflags) $(idn2_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \
- build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs)" \
+ build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs) $(ubus_libs)" \
  -f $(top)/Makefile dnsmasq 
 
 mostly_clean :
@@ -100,7 +101,8 @@ clean : mostly_clean
 install : all install-common
 
 install-common :
-       $(INSTALL) -d $(DESTDIR)$(BINDIR) -d $(DESTDIR)$(MANDIR)/man8
+       $(INSTALL) -d $(DESTDIR)$(BINDIR)
+       $(INSTALL) -d $(DESTDIR)$(MANDIR)/man8
        $(INSTALL) -m 644 $(MAN)/dnsmasq.8 $(DESTDIR)$(MANDIR)/man8 
        $(INSTALL) -m 755 $(BUILDDIR)/dnsmasq $(DESTDIR)$(BINDIR)
 
@@ -109,7 +111,7 @@ all-i18n : $(BUILDDIR)
  top="$(top)" \
  i18n=-DLOCALEDIR=\'\"$(LOCALEDIR)\"\' \
  build_cflags="$(version) $(dbus_cflags) $(idn2_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \
- build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs)"  \
+ build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs) $(ubus_libs)"  \
  -f $(top)/Makefile dnsmasq
        for f in `cd $(PO); echo *.po`; do \
                cd $(top) && cd $(BUILDDIR) && $(MAKE) top="$(top)" -f $(top)/Makefile $${f%.po}.mo; \
diff --git a/VERSION b/VERSION
index 5ec247c..bfe3ec9 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
- (HEAD -> master, tag: v2.79, origin/master, origin/HEAD)
+ (HEAD -> master, tag: v2.82, origin/master, origin/HEAD)
index 80ec842..080a615 100644 (file)
@@ -10,7 +10,8 @@ LOCAL_SRC_FILES :=  bpf.c cache.c dbus.c dhcp.c dnsmasq.c \
                    dhcp6.c rfc3315.c dhcp-common.c outpacket.c \
                    radv.c slaac.c auth.c ipset.c domain.c \
                    dnssec.c dnssec-openssl.c blockdata.c tables.c \
-                   loop.c inotify.c poll.c rrfilter.c edns0.c arp.c crypto.c
+                   loop.c inotify.c poll.c rrfilter.c edns0.c arp.c \
+                   crypto.c dump.c ubus.c
 
 LOCAL_MODULE := dnsmasq
 
index 0ddb678..704bdd3 100755 (executable)
@@ -11,23 +11,25 @@ in=`cat`
 
 if grep "^\#[[:space:]]*define[[:space:]]*$search" config.h >/dev/null 2>&1 || \
     echo $in | grep $search >/dev/null 2>&1; then
-# Nasty, nasty, in --copy, arg 2 is another config to search for, use with NO_GMP
+# Nasty, nasty, in --copy, arg 2 (if non-empty) is another config to search for, used with NO_GMP
     if [ $op = "--copy" ]; then
-       if grep "^\#[[:space:]]*define[[:space:]]*$pkg" config.h >/dev/null 2>&1 || \
-            echo $in | grep $pkg >/dev/null 2>&1; then
+       if [ -z "$pkg" ]; then
+           pkg="$*"
+       elif grep "^\#[[:space:]]*define[[:space:]]*$pkg" config.h >/dev/null 2>&1 || \
+                echo $in | grep $pkg >/dev/null 2>&1; then
            pkg=""
        else 
            pkg="$*"
        fi
     elif grep "^\#[[:space:]]*define[[:space:]]*${search}_STATIC" config.h >/dev/null 2>&1 || \
-             echo $in | grep ${search}_STATIC >/dev/null 2>&1; then
+            echo $in | grep ${search}_STATIC >/dev/null 2>&1; then
        pkg=`$pkg  --static $op $*`
     else
        pkg=`$pkg $op $*`
     fi
-
+    
     if grep "^\#[[:space:]]*define[[:space:]]*${search}_STATIC" config.h >/dev/null 2>&1 || \
-       echo $in | grep ${search}_STATIC >/dev/null 2>&1; then
+          echo $in | grep ${search}_STATIC >/dev/null 2>&1; then
        if [ $op = "--libs" ] || [ $op = "--copy" ]; then
            echo "-Wl,-Bstatic $pkg -Wl,-Bdynamic"
        else
index f9d7a85..91edbfa 100644 (file)
@@ -83,7 +83,7 @@ static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt
           if (p >= end - 2)
             return NULL; /* malformed packet */
           opt_len = option_len(p);
-          if (p >= end - (2 + opt_len))
+          if (end - p < (2 + opt_len))
             return NULL; /* malformed packet */
           if (*p == opt && opt_len >= minsize)
             return p;
index 201fcd3..30e77c6 100644 (file)
@@ -178,7 +178,7 @@ static int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask)
   return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr);
 }
 
-static struct in_addr find_interface(struct in_addr client, int fd, unsigned int index)
+static struct in_addr find_interface(struct in_addr client, int fd, unsigned int index, int ifrfd, struct ifreq *ifr)
 {
   struct sockaddr_nl addr;
   struct nlmsghdr *h;
@@ -218,7 +218,17 @@ static struct in_addr find_interface(struct in_addr client, int fd, unsigned int
 
       for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
        if (h->nlmsg_type == NLMSG_DONE)
-         exit(0);
+          {
+           /* No match found, return first address as src/dhcp.c code does */
+           ifr->ifr_addr.sa_family = AF_INET;
+           if (ioctl(ifrfd, SIOCGIFADDR, ifr) != -1)
+             return ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
+           else
+             {
+               fprintf(stderr, "error: local IPv4 address not found\n");
+               exit(1);
+             }
+          }
        else if (h->nlmsg_type == RTM_NEWADDR)
           {
             struct ifaddrmsg *ifa = NLMSG_DATA(h);  
@@ -270,7 +280,8 @@ int main(int argc, char **argv)
   
   /* This voodoo fakes up a packet coming from the correct interface, which really matters for 
      a DHCP server */
-  strcpy(ifr.ifr_name, argv[1]);
+  strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name)-1);
+  ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
   if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == -1)
     {
       perror("cannot setup interface");
@@ -284,7 +295,7 @@ int main(int argc, char **argv)
     }
   
   lease.s_addr = inet_addr(argv[2]);
-  server = find_interface(lease, nl, if_nametoindex(argv[1]));
+  server = find_interface(lease, nl, if_nametoindex(argv[1]), fd, &ifr);
   
   memset(&packet, 0, sizeof(packet));
  
index 7f79fa7..d680222 100644 (file)
@@ -376,9 +376,12 @@ int send_release_packet(const char* iface, struct dhcp6_packet* packet)
             sleep(1);
             continue;
          }
+
+        close(sock);
         return result;
       }
-    
+
+    close(sock);
     fprintf(stderr, "Response timed out\n");
     return -1;   
 }
index 62af669..db9ca77 100644 (file)
@@ -1,18 +1,18 @@
-The script reads stdin and replaces all IP addresses with names before
-outputting it again. IPs from private networks are reverse looked  up
-via dns. Other IP addresses are searched for in the dnsmasq query log.
-This gives names (CNAMEs if I understand DNS correctly) that are closer
-to the name the client originally asked for then the names obtained by
-reverse lookup. Just run
-
-netstat -n -4 | ./reverse_replace.sh 
-
-to see what it does. It needs 
-
-log-queries
-log-facility=/var/log/dnsmasq.log
-
-in the dnsmasq configuration.
-
-The script runs on debian (with ash installed) and on busybox.
-
+The script reads stdin and replaces all IP addresses with names before\r
+outputting it again. IPs from private networks are reverse looked  up\r
+via dns. Other IP addresses are searched for in the dnsmasq query log.\r
+This gives names (CNAMEs if I understand DNS correctly) that are closer\r
+to the name the client originally asked for then the names obtained by\r
+reverse lookup. Just run\r
+\r
+netstat -n -4 | ./reverse_replace.sh \r
+\r
+to see what it does. It needs \r
+\r
+log-queries\r
+log-facility=/var/log/dnsmasq.log\r
+\r
+in the dnsmasq configuration.\r
+\r
+The script runs on debian (with dash installed) and on busybox.\r
+\r
index c6401fb..dfdc1bf 100644 (file)
@@ -1,4 +1,4 @@
-#!/bin/ash
+#!/bin/dash
 # $Id: reverse_replace.sh 18 2015-03-01 16:12:35Z jo $
 #
 # Usage e.g.: netstat -n -4 | reverse_replace.sh 
index 94a8820..38f0822 100644 (file)
@@ -1,57 +1,57 @@
-To: dnsmasq-discuss@lists.thekelleys.org.uk
-From: Alex Elsayed <eternaleye+usenet@gmail.com>
-Date: Tue, 15 May 2012 01:53:54 -0700
-Subject: [Dnsmasq-discuss] [PATCH] Support dbus activation
-
-Introduce dbus service file and turn dbus on in the systemd
-unit.
-
-Note to packagers:
-To add support for dbus activation, you must install the dbus
-service file (dbus/uk.org.thekelleys.dnsmasq.service) into
-$DATADIR/dbus-1/system-services.
-
----
- contrib/systemd/dnsmasq.service        |    2 +-
- dbus/uk.org.thekelleys.dnsmasq.service |    7 +++++++
- 2 files changed, 8 insertions(+), 1 deletion(-)
- create mode 100644 dbus/uk.org.thekelleys.dnsmasq.service
-
-diff --git a/contrib/systemd/dnsmasq.service 
-b/contrib/systemd/dnsmasq.service
-index a27fe6d..4a784d3 100644
---- a/contrib/systemd/dnsmasq.service
-+++ b/contrib/systemd/dnsmasq.service
-@@ -5,7 +5,7 @@ Description=A lightweight DHCP and caching DNS server
- Type=dbus
- BusName=uk.org.thekelleys.dnsmasq
- ExecStartPre=/usr/sbin/dnsmasq --test
--ExecStart=/usr/sbin/dnsmasq -k
-+ExecStart=/usr/sbin/dnsmasq -k -1
- ExecReload=/bin/kill -HUP $MAINPID
- [Install]
-diff --git a/dbus/uk.org.thekelleys.dnsmasq.service 
-b/dbus/uk.org.thekelleys.dnsmasq.service
-new file mode 100644
-index 0000000..f5fe98d
---- /dev/null
-+++ b/dbus/uk.org.thekelleys.dnsmasq.service
-@@ -0,0 +1,7 @@
-+[D-BUS Service]
-+Name=uk.org.thekelleys.dnsmasq
-+Exec=/usr/sbin/dnsmasq -k -1
-+User=root
-+SystemdService=dnsmasq.service
-+
-+
--- 
-1.7.10.2
-
-
-
-_______________________________________________
-Dnsmasq-discuss mailing list
-Dnsmasq-discuss@lists.thekelleys.org.uk
-http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
-
+To: dnsmasq-discuss@lists.thekelleys.org.uk\r
+From: Alex Elsayed <eternaleye+usenet@gmail.com>\r
+Date: Tue, 15 May 2012 01:53:54 -0700\r
+Subject: [Dnsmasq-discuss] [PATCH] Support dbus activation\r
+\r
+Introduce dbus service file and turn dbus on in the systemd\r
+unit.\r
+\r
+Note to packagers:\r
+To add support for dbus activation, you must install the dbus\r
+service file (dbus/uk.org.thekelleys.dnsmasq.service) into\r
+$DATADIR/dbus-1/system-services.\r
+\r
+---\r
+ contrib/systemd/dnsmasq.service        |    2 +-\r
+ dbus/uk.org.thekelleys.dnsmasq.service |    7 +++++++\r
+ 2 files changed, 8 insertions(+), 1 deletion(-)\r
+ create mode 100644 dbus/uk.org.thekelleys.dnsmasq.service\r
+\r
+diff --git a/contrib/systemd/dnsmasq.service \r
+b/contrib/systemd/dnsmasq.service\r
+index a27fe6d..4a784d3 100644\r
+--- a/contrib/systemd/dnsmasq.service\r
++++ b/contrib/systemd/dnsmasq.service\r
+@@ -5,7 +5,7 @@ Description=A lightweight DHCP and caching DNS server\r
+ Type=dbus\r
+ BusName=uk.org.thekelleys.dnsmasq\r
+ ExecStartPre=/usr/sbin/dnsmasq --test\r
+-ExecStart=/usr/sbin/dnsmasq -k\r
++ExecStart=/usr/sbin/dnsmasq -k -1\r
+ ExecReload=/bin/kill -HUP $MAINPID\r
\r
+ [Install]\r
+diff --git a/dbus/uk.org.thekelleys.dnsmasq.service \r
+b/dbus/uk.org.thekelleys.dnsmasq.service\r
+new file mode 100644\r
+index 0000000..f5fe98d\r
+--- /dev/null\r
++++ b/dbus/uk.org.thekelleys.dnsmasq.service\r
+@@ -0,0 +1,7 @@\r
++[D-BUS Service]\r
++Name=uk.org.thekelleys.dnsmasq\r
++Exec=/usr/sbin/dnsmasq -k -1\r
++User=root\r
++SystemdService=dnsmasq.service\r
++\r
++\r
+-- \r
+1.7.10.2\r
+\r
+\r
+\r
+_______________________________________________\r
+Dnsmasq-discuss mailing list\r
+Dnsmasq-discuss@lists.thekelleys.org.uk\r
+http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss\r
+\r
index c70b144..ff0ed08 100644 (file)
@@ -1,5 +1,8 @@
 [Unit]
 Description=dnsmasq - A lightweight DHCP and caching DNS server
+After=network.target
+Before=network-online.target nss-lookup.target
+Wants=nss-lookup.target
 
 [Service]
 Type=dbus
index 2db5c30..954c5b9 100644 (file)
@@ -243,6 +243,10 @@ IPv4 or IPv6 address of the lease to remove.
 Note that this function will trigger the DhcpLeaseRemoved signal and the
 configured DHCP lease script will be run with the "del" action.
 
+GetMetrics
+----------
+
+Returns an array with various metrics for DNS and DHCP.
 
 
 2. SIGNALS
index 574b053..bf19424 100644 (file)
 # http://www.isc.org/files/auth.html
 #dhcp-authoritative
 
+# Set the DHCP server to enable DHCPv4 Rapid Commit Option per RFC 4039.
+# In this mode it will respond to a DHCPDISCOVER message including a Rapid Commit
+# option with a DHCPACK including a Rapid Commit option and fully committed address
+# and configuration information. This must only be enabled if either the server is 
+# the only server for the subnet, or multiple servers are present and they each
+# commit a binding for all clients.
+#dhcp-rapid-commit
+
 # Run an executable when a DHCP lease is created or destroyed.
 # The arguments sent to the script are "add" or "del",
 # then the MAC address, the IP address and finally the hostname
 
 # Include all files in a directory which end in .conf
 #conf-dir=/etc/dnsmasq.d/,*.conf
+
+# If a DHCP client claims that its name is "wpad", ignore that.
+# This fixes a security hole. see CERT Vulnerability VU#598349
+#dhcp-name-match=set:wpad-ignore,wpad
+#dhcp-ignore-names=tag:wpad-ignore
index bd99b48..7b0e106 100644 (file)
@@ -1,4 +1,4 @@
-.TH DNSMASQ 8
+.TH DNSMASQ 8 2020-04-05
 .SH NAME
 dnsmasq \- A lightweight DHCP and caching DNS server.
 .SH SYNOPSIS
@@ -27,7 +27,7 @@ TFTP server to allow net/PXE boot of DHCP hosts and also supports BOOTP. The PXE
 .PP
 The dnsmasq DHCPv6 server provides the same set of features as the
 DHCPv4 server, and in addition, it includes router advertisements and
-a neat feature which allows nameing for clients which use DHCPv4 and
+a neat feature which allows naming for clients which use DHCPv4 and
 stateless autoconfiguration only for IPv6 configuration. There is support for doing address allocation (both DHCPv6 and RA) from subnets which are dynamically delegated via DHCPv6 prefix delegation.
 .PP
 Dnsmasq is coded with small embedded systems in mind. It aims for the smallest possible memory footprint compatible with the supported functions,  and allows unneeded functions to be omitted from the compiled binary.  
@@ -53,13 +53,13 @@ will display DHCPv6 options.
 Don't read the hostnames in /etc/hosts.
 .TP
 .B \-H, --addn-hosts=<file>
-Additional hosts file. Read the specified file as well as /etc/hosts. If -h is given, read
+Additional hosts file. Read the specified file as well as /etc/hosts. If \fB--no-hosts\fP is given, read
 only the specified file. This option may be repeated for more than one
 additional hosts file. If a directory is given, then read all the files contained in that directory. 
 .TP
 .B --hostsdir=<path>
 Read all the hosts files contained in the directory. New or changed files
-are read automatically. See --dhcp-hostsdir for details.
+are read automatically. See \fB--dhcp-hostsdir\fP for details.
 .TP
 .B \-E, --expand-hosts
 Add the domain to simple names (without a period) in /etc/hosts
@@ -76,7 +76,7 @@ reduce the load on the server at the expense of clients using stale
 data under some circumstances.
 .TP
 .B --dhcp-ttl=<time>
-As for --local-ttl, but affects only replies with information from DHCP leases. If both are given, --dhcp-ttl applies for DHCP information, and --local-ttl for others. Setting this to zero eliminates the effect of --local-ttl for DHCP.
+As for \fB--local-ttl\fP, but affects only replies with information from DHCP leases. If both are given, \fB--dhcp-ttl\fP applies for DHCP information, and \fB--local-ttl\fP for others. Setting this to zero eliminates the effect of \fB--local-ttl\fP for DHCP.
 .TP
 .B --neg-ttl=<time>
 Negative replies from upstream servers normally contain time-to-live
@@ -115,7 +115,7 @@ don't change user id, generate a complete cache dump on receipt on
 SIGUSR1, log to stderr as well as syslog, don't fork new processes
 to handle TCP queries. Note that this option is for use in debugging
 only, to stop dnsmasq daemonising in production, use 
-.B -k.
+.B --keep-in-foreground.
 .TP
 .B \-q, --log-queries
 Log the results of DNS queries handled by dnsmasq. Enable a full cache dump on receipt of SIGUSR1. If the argument "extra" is supplied, ie
@@ -156,7 +156,7 @@ can be over-ridden with this switch.
 .TP
 .B \-g, --group=<groupname> 
 Specify the group which dnsmasq will run
-as. The defaults to "dip", if available, to facilitate access to
+as. The default is "dip", if available, to facilitate access to
 /etc/ppp/resolv.conf which is not normally world readable.
 .TP
 .B \-v, --version
@@ -191,7 +191,6 @@ Dnsmasq picks random ports as source for outbound queries:
 when this option is given, the ports used will always be lower
 than that specified. Useful for systems behind firewalls.
 .TP
-
 .B \-i, --interface=<interface name>
 Listen only on the specified interface(s). Dnsmasq automatically adds
 the loopback (local) interface to the list of interfaces to use when
@@ -232,7 +231,7 @@ options always override the others. The comments about interface labels for
 .B --listen-address
 apply here.
 .TP
-.B --auth-server=<domain>,<interface>|<ip-address>
+.B --auth-server=<domain>,[<interface>|<ip-address>...]
 Enable DNS authoritative mode for queries arriving at an interface or address. Note that the interface or address
 need not be mentioned in 
 .B --interface
@@ -245,13 +244,13 @@ specified interface. The <domain> is the "glue record". It should
 resolve in the global DNS to an A and/or AAAA record which points to
 the address dnsmasq is listening on. When an interface is specified,
 it may be qualified with "/4" or "/6" to specify only the IPv4 or IPv6
-addresses associated with the interface.
+addresses associated with the interface. Since any defined authoritative zones are also available as part of the normal recusive DNS service supplied by dnsmasq, it can make sense to have an --auth-server declaration with no interfaces or address, but simply specifying the primary external nameserver.
 .TP
 .B --local-service
 Accept DNS queries only from hosts whose address is on a local subnet,
 ie a subnet for which an interface exists on the server. This option
-only has effect if there are no --interface --except-interface,
---listen-address or --auth-server options. It is intended to be set as
+only has effect if there are no \fB--interface\fP, \fB--except-interface\fP,
+\fB--listen-address\fP or \fB--auth-server\fP options. It is intended to be set as
 a default on installation, to allow unconfigured installations to be
 useful but also safe from being used for DNS amplification attacks.
 .TP 
@@ -294,10 +293,10 @@ addresses appear, it automatically listens on those (subject to any
 access-control configuration). This makes dynamically created
 interfaces work in the same way as the default. Implementing this
 option requires non-standard networking APIs and it is only available
-under Linux. On other platforms it falls-back to --bind-interfaces mode.
+under Linux. On other platforms it falls-back to \fB--bind-interfaces\fP mode.
 .TP
 .B \-y, --localise-queries
-Return answers to DNS queries from /etc/hosts and --interface-name which depend on the interface over which the query was
+Return answers to DNS queries from /etc/hosts and \fB--interface-name\fP which depend on the interface over which the query was
 received. If a name has more than one address associated with
 it, and at least one of those addresses is on the same subnet as the
 interface to which the query was sent, then return only the
@@ -367,6 +366,14 @@ been built with DBus support. If the service name is given, dnsmasq
 provides service at that name, rather than the default which is 
 .B uk.org.thekelleys.dnsmasq
 .TP 
+.B --enable-ubus[=<service-name>]
+Enable dnsmasq UBus interface. It sends notifications via UBus on
+DHCPACK and DHCPRELEASE events. Furthermore it offers metrics.
+Requires that dnsmasq has been built with UBus support. If the service
+name is given, dnsmasq provides service at that namespace, rather than
+the default which is
+.B dnsmasq
+.TP
 .B \-o, --strict-order
 By default, dnsmasq will send queries to any of the upstream servers
 it knows about and tries to favour servers that are known to
@@ -391,18 +398,20 @@ were previously disabled.
 .TP
 .B --stop-dns-rebind
 Reject (and log) addresses from upstream nameservers which are in the
-private IP ranges. This blocks an attack where a browser behind a
-firewall is used to probe machines on the local network.
+private ranges. This blocks an attack where a browser behind a
+firewall is used to probe machines on the local network. For IPv6, the
+private range covers the IPv4-mapped addresses in private space plus
+all link-local (LL) and site-local (ULA) addresses.
 .TP
 .B --rebind-localhost-ok
-Exempt 127.0.0.0/8 from rebinding checks. This address range is
+Exempt 127.0.0.0/8 and ::1 from rebinding checks. This address range is
 returned by realtime black hole servers, so blocking it may disable
 these services.
 .TP 
 .B  --rebind-domain-ok=[<domain>]|[[/<domain>/[<domain>/]
 Do not detect and block dns-rebind on queries to these domains. The
 argument may be either a single domain, or multiple domains surrounded
-by '/', like the --server syntax, eg. 
+by '/', like the \fB--server\fP syntax, eg.
 .B  --rebind-domain-ok=/domain1/domain2/domain3/
 .TP
 .B \-n, --no-poll
@@ -419,16 +428,15 @@ Tells dnsmasq to never forward A or AAAA queries for plain names, without dots
 or domain parts, to upstream nameservers. If the name is not known
 from /etc/hosts or DHCP then a "not found" answer is returned.
 .TP
-.B \-S, --local, --server=[/[<domain>]/[domain/]][<ipaddr>[#<port>][@<source-ip>|<interface>[#<port>]]
+.B \-S, --local, --server=[/[<domain>]/[domain/]][<ipaddr>[#<port>]][@<source-ip>|<interface>[#<port>]]
 Specify IP address of upstream servers directly. Setting this flag does
-not suppress reading of /etc/resolv.conf, use -R to do that. If one or
-more 
+not suppress reading of /etc/resolv.conf, use \fB--no-resolv\fP to do that. If one or more
 optional domains are given, that server is used only for those domains
 and they are queried only using the specified server. This is
 intended for private nameservers: if you have a nameserver on your
 network which deals with names of the form
 xxx.internal.thekelleys.org.uk at 192.168.1.1 then giving  the flag 
-.B -S /internal.thekelleys.org.uk/192.168.1.1 
+.B --server=/internal.thekelleys.org.uk/192.168.1.1
 will send all queries for
 internal machines to that nameserver, everything else will go to the
 servers in /etc/resolv.conf. DNSSEC validation is turned off for such
@@ -440,7 +448,7 @@ has the special meaning of "unqualified names only" ie names without any
 dots in them. A non-standard port may be specified as 
 part of the IP
 address using a # character.
-More than one -S flag is allowed, with
+More than one \fB--server\fP flag is allowed, with
 repeated domain or ipaddr parts as required.
 
 More specific domains take precedence over less specific domains, so:
@@ -460,9 +468,9 @@ flag which gives a domain but no IP address; this tells dnsmasq that
 a domain is local and it may answer queries from /etc/hosts or DHCP
 but should never forward queries on that domain to any upstream
 servers.
-.B local
+.B --local
 is a synonym for
-.B server
+.B --server
 to make configuration files clearer in this case.
 
 IPv6 addresses may include an %interface scope-id, eg
@@ -481,7 +489,7 @@ source address specified but the port may be specified directly as
 part of the source address. Forcing queries to an interface is not
 implemented on all platforms supported by dnsmasq.
 .TP
-.B --rev-server=<ip-address>/<prefix-len>,<ipaddr>[#<port>][@<source-ip>|<interface>[#<port>]]
+.B --rev-server=<ip-address>/<prefix-len>[,<ipaddr>][#<port>][@<source-ip>|<interface>[#<port>]]
 This is functionally the same as 
 .B --server, 
 but provides some syntactic sugar to make specifying address-to-name queries easier. For example
@@ -493,7 +501,7 @@ is exactly equivalent to
 Specify an IP address to return for any host in the given domains.
 Queries in the domains are never forwarded and always replied to
 with the specified IP address which may be IPv4 or IPv6. To give
-both IPv4 and IPv6 addresses for a domain, use repeated \fB-A\fP flags.
+both IPv4 and IPv6 addresses for a domain, use repeated \fB--address\fP flags.
 To include multiple IP addresses for a single query, use
 \fB--addn-hosts=<path>\fP instead.
 Note that /etc/hosts and DHCP leases override this for individual
@@ -507,7 +515,12 @@ upstream nameserver by a more specific \fB--server\fP directive. As for
 \fB--server\fP, one or more domains with no address returns a
 no-such-domain answer, so \fB--address=/example.com/\fP is equivalent to
 \fB--server=/example.com/\fP and returns NXDOMAIN for example.com and
-all its subdomains.
+all its subdomains. An address specified as '#' translates to the NULL
+address of 0.0.0.0 and its IPv6 equivalent of :: so
+\fB--address=/example.com/#\fP will return NULL addresses for example.com and
+its subdomains. This is partly syntactic sugar for \fB--address=/example.com/0.0.0.0\fP
+and \fB--address=/example.com/::\fP but is also more efficient than including both
+as separate configuration lines. Note that NULL addresses normally work in the same way as localhost, so beware that clients looking up these names are likely to end up talking to themselves.
 .TP
 .B --ipset=/<domain>[/<domain>...]/<ipset>[,<ipset>...]
 Places the resolved IP addresses of queries for one or more domains in
@@ -523,7 +536,7 @@ for more details.
 .B \-m, --mx-host=<mx name>[[,<hostname>],<preference>]
 Return an MX record named <mx name> pointing to the given hostname (if
 given), or
-the host specified in the --mx-target switch
+the host specified in the \fB--mx-target\fP switch
 or, if that switch is not given, the host on which dnsmasq 
 is running. The default is useful for directing mail from systems on a LAN
 to a central server. The preference value is optional, and defaults to
@@ -531,7 +544,7 @@ to a central server. The preference value is optional, and defaults to
 .TP 
 .B \-t, --mx-target=<hostname>
 Specify the default target for the MX record returned by dnsmasq. See
---mx-host.  If --mx-target is given, but not --mx-host, then dnsmasq
+\fB--mx-host\fP.  If \fB--mx-target\fP is given, but not \fB--mx-host\fP, then dnsmasq
 returns a MX record containing the MX target for MX queries on the 
 hostname of the machine on which dnsmasq is running.
 .TP
@@ -540,7 +553,7 @@ Return an MX record pointing to itself for each local
 machine. Local machines are those in /etc/hosts or with DHCP leases.
 .TP 
 .B \-L, --localmx
-Return an MX record pointing to the host given by mx-target (or the
+Return an MX record pointing to the host given by \fB--mx-target\fP (or the
 machine on which dnsmasq is running) for each
 local machine. Local machines are those in /etc/hosts or with DHCP
 leases.
@@ -560,22 +573,22 @@ all that match are returned.
 Add A, AAAA and PTR records to the DNS. This adds one or more names to
 the DNS with associated IPv4 (A) and IPv6 (AAAA) records. A name may
 appear in more than one 
-.B host-record
+.B --host-record
 and therefore be assigned more than one address. Only the first
 address creates a PTR record linking the address to the name. This is
 the same rule as is used reading hosts-files. 
-.B host-record
+.B --host-record
 options are considered to be read before host-files, so a name
 appearing there inhibits PTR-record creation if it appears in
 hosts-file also. Unlike hosts-files, names are not expanded, even when
-.B expand-hosts
+.B --expand-hosts
 is in effect. Short and long names may appear in the same 
-.B host-record,
+.B --host-record,
 eg. 
 .B --host-record=laptop,laptop.thekelleys.org,192.168.0.1,1234::100
 
 If the time-to-live is given, it overrides the default, which is zero
-or the value of --local-ttl. The value is a positive integer and gives 
+or the value of \fB--local-ttl\fP. The value is a positive integer and gives
 the time-to-live in seconds.
 .TP
 .B \-Y, --txt-record=<name>[[,<text>],<text>]
@@ -590,20 +603,20 @@ Return a PTR DNS record.
 .B --naptr-record=<name>,<order>,<preference>,<flags>,<service>,<regexp>[,<replacement>]
 Return an NAPTR DNS record, as specified in RFC3403.
 .TP
+.B --caa-record=<name>,<flags>,<tag>,<value>
+Return a CAA DNS record, as specified in RFC6844.
+.TP
 .B --cname=<cname>,[<cname>,]<target>[,<TTL>]
 Return a CNAME record which indicates that <cname> is really
-<target>. There are significant limitations on the target; it must be a
-DNS name which is known to dnsmasq from /etc/hosts (or additional
-hosts files), from DHCP, from --interface-name or from another 
-.B --cname.
-If the target does not satisfy this
-criteria, the whole cname is ignored. The cname must be unique, but it
+<target>. There is a significant limitation on the target; it must be a
+DNS record which is known to dnsmasq and NOT a DNS record which comes from
+an upstream server. The cname must be unique, but it
 is permissible to have more than one cname pointing to the same target. Indeed
 it's possible to declare multiple cnames to a target in a single line, like so:
 .B --cname=cname1,cname2,target
 
 If the time-to-live is given, it overrides the default, which is zero
-or the value of -local-ttl. The value is a positive integer and gives 
+or the value of \fB--local-ttl\fP. The value is a positive integer and gives
 the time-to-live in seconds.
 .TP
 .B --dns-rr=<name>,<RR-number>,[<hex data>]
@@ -624,7 +637,7 @@ matching PTR record is also created, mapping the interface address to
 the name. More than one name may be associated with an interface
 address by repeating the flag; in that case the first instance is used
 for the reverse address-to-name mapping. Note that a name used in 
---interface-name may not appear in /etc/hosts.
+\fB--interface-name\fP may not appear in /etc/hosts.
 .TP
 .B --synth-domain=<domain>,<address range>[,<prefix>[*]]
 Create artificial A/AAAA and PTR records for an address range. The
@@ -647,6 +660,13 @@ V4 mapped IPv6 addresses, which have a representation like ::ffff:1.2.3.4 are ha
 The address range can be of the form
 <ip address>,<ip address> or <ip address>/<netmask> in both forms of the option.
 .TP
+.B --dumpfile=<path/to/file>
+Specify the location of a pcap-format file which dnsmasq uses to dump copies of network packets for debugging purposes. If the file exists when dnsmasq starts, it is not deleted; new packets are added to the end.
+.TP
+.B --dumpmask=<mask>
+Specify which types of packets should be added to the dumpfile. The argument should be the OR of the bitmasks for each type of packet to be dumped: it can be specified in hex by preceding the number with 0x in  the normal way. Each time a packet is written to the dumpfile, dnsmasq logs the packet sequence and the mask
+representing its type. The current types are: 0x0001 - DNS queries from clients 0x0002 DNS replies to clients 0x0004 - DNS queries to upstream 0x0008 - DNS replies from upstream 0x0010 - queries send upstream for DNSSEC validation 0x0020 - replies to queries for DNSSEC validation 0x0040 - replies to client queries which fail DNSSEC validation 0x0080 replies to queries for DNSSEC validation which fail validation.
+.TP
 .B --add-mac[=base64|text]
 Add the MAC address of the requestor to DNS queries which are
 forwarded upstream. This may be used to DNS filtering by the upstream
@@ -655,11 +675,11 @@ subnet as the dnsmasq server. Note that the mechanism used to achieve this (an E
 is not yet standardised, so this should be considered
 experimental. Also note that exposing MAC addresses in this way may
 have security and privacy implications. The warning about caching
-given for --add-subnet applies to --add-mac too. An alternative encoding of the 
+given for \fB--add-subnet\fP applies to \fB--add-mac\fP too. An alternative encoding of the
 MAC, as base64, is enabled by adding the "base64" parameter and a human-readable encoding of hex-and-colons is enabled by added the "text" parameter.
 .TP
 .B --add-cpe-id=<string>
-Add an arbitrary identifying string to DNS queries which are
+Add an arbitrary identifying string to DNS queries which are
 forwarded upstream.
 .TP 
 .B --add-subnet[[=[<IPv4 address>/]<IPv4 prefix length>][,[<IPv6 address>/]<IPv6 prefix length>]]
@@ -685,7 +705,7 @@ will add 1.2.3.0/24 for both IPv4 and IPv6 requestors.
 
 .TP
 .B \-c, --cache-size=<cachesize>
-Set the size of dnsmasq's cache. The default is 150 names. Setting the cache size to zero disables caching.
+Set the size of dnsmasq's cache. The default is 150 names. Setting the cache size to zero disables caching. Note: huge cache size impacts performance.
 .TP
 .B \-N, --no-negcache
 Disable negative caching. Negative caching allows dnsmasq to remember
@@ -712,10 +732,7 @@ permitted to reduce the cache size below the default when DNSSEC is
 enabled. The nameservers upstream of dnsmasq must be DNSSEC-capable,
 ie capable of returning DNSSEC records with data. If they are not,
 then dnsmasq will not be able to determine the trusted status of
-answers. In the default mode, this means that all replies will be
-marked as untrusted. If 
-.B --dnssec-check-unsigned
-is set and the upstream servers don't support DNSSEC, then DNS service will be entirely broken.
+answers and this means that DNS service will be entirely broken.
 .TP
 .B --trust-anchor=[<class>],<domain>,<key-tag>,<algorithm>,<digest-type>,<digest>
 Provide DS records to act a trust anchors for DNSSEC
@@ -724,17 +741,19 @@ key(s) (KSK) of the root zone,
 but trust anchors for limited domains are also possible. The current
 root-zone trust anchors may be downloaded from https://data.iana.org/root-anchors/root-anchors.xml 
 .TP
-.B --dnssec-check-unsigned
-As a default, dnsmasq does not check that unsigned DNS replies are
-legitimate: they are assumed to be valid and passed on (without the
+.B --dnssec-check-unsigned[=no]
+As a default, dnsmasq checks that unsigned DNS replies are
+legitimate: this entails possible extra queries even for the majority of DNS
+zones which are not, at the moment, signed. If
+.B --dnssec-check-unsigned=no
+appears in the configuration, then such replies they are assumed to be valid and passed on (without the
 "authentic data" bit set, of course). This does not protect against an
 attacker forging unsigned replies for signed DNS zones, but it is
-fast. If this flag is set, dnsmasq will check the zones of unsigned
-replies, to ensure that unsigned replies are allowed in those
-zones. The cost of this is more upstream queries and slower
-performance. See also the warning about upstream servers in the
-section on 
-.B --dnssec
+fast.
+
+Versions of dnsmasq prior to 2.80 defaulted to not checking unsigned replies, and used 
+.B --dnssec-check-unsigned
+to switch this on. Such configurations will continue to work as before, but those which used the default of no checking will need to be altered to explicitly select no checking. The new default is because switching off checking for unsigned replies is inherently dangerous. Not only does it open the possiblity of forged replies, but it allows everything to appear to be working even when the upstream namesevers do not support DNSSEC, and in this case no DNSSEC validation at all is occurring.
 .TP
 .B --dnssec-no-timecheck
 DNSSEC signatures are only valid for specified time windows, and should be rejected outside those windows. This generates an
@@ -747,19 +766,22 @@ which have not been thoroughly checked.
 
 Earlier versions of dnsmasq overloaded SIGHUP (which re-reads much configuration) to also enable time validation.
 
-If dnsmasq is run in debug mode (-d flag) then SIGINT retains its usual meaning of terminating the dnsmasq process.
+If dnsmasq is run in debug mode (\fB--no-daemon\fP flag) then SIGINT retains its usual meaning of terminating the dnsmasq process.
 .TP
 .B --dnssec-timestamp=<path>
-Enables an alternative way of checking the validity of the system time for DNSSEC (see --dnssec-no-timecheck). In this case, the 
+Enables an alternative way of checking the validity of the system time for DNSSEC (see \fB--dnssec-no-timecheck\fP). In this case, the
 system time is considered to be valid once it becomes later than the timestamp on the specified file. The file is created and 
 its timestamp set automatically by dnsmasq. The file must be stored on a persistent filesystem, so that it and its mtime are carried 
 over system restarts. The timestamp file is created after dnsmasq has dropped root, so it must be in a location writable by the 
 unprivileged user that dnsmasq runs as.
 .TP
 .B --proxy-dnssec
-Copy the DNSSEC Authenticated Data bit from upstream servers to downstream clients and cache it.  This is an 
+Copy the DNSSEC Authenticated Data bit from upstream servers to downstream clients.  This is an 
 alternative to having dnsmasq validate DNSSEC, but it depends on the security of the network between 
-dnsmasq and the upstream servers, and the trustworthiness of the upstream servers.
+dnsmasq and the upstream servers, and the trustworthiness of the upstream servers. Note that caching the
+Authenticated Data bit correctly in all cases is not technically possible. If the AD bit is to be relied upon
+when using this option, then the cache should be disabled using --cache-size=0. In most cases, enabling DNSSEC validation
+within dnsmasq is a better option. See --dnssec for details.
 .TP
 .B --dnssec-debug
 Set debugging mode for the DNSSEC validation, set the Checking Disabled bit on upstream queries, 
@@ -783,7 +805,7 @@ interface addresses may be confined to only IPv6 addresses using
 an interface has dynamically determined global IPv6 addresses which should
 appear in the zone, but RFC1918 IPv4 addresses which should not.
 Interface-name and address-literal subnet specifications may be used
-freely in the same --auth-zone declaration.
+freely in the same \fB--auth-zone\fP declaration.
 
 It's possible to exclude certain IP addresses from responses. It can be
 used, to make sure that answers contain only global routeable IP
@@ -810,8 +832,13 @@ authoritative zones as dnsmasq.
 .B --auth-peer=<ip-address>[,<ip-address>[,<ip-address>...]]
 Specify the addresses of secondary servers which are allowed to
 initiate zone transfer (AXFR) requests for zones for which dnsmasq is
-authoritative. If this option is not given, then AXFR requests will be
-accepted from any secondary. 
+authoritative. If this option is not given but --auth-sec-servers is,
+then AXFR requests will be
+accepted from any secondary. Specifying
+.B --auth-peer
+without
+.B --auth-sec-servers
+enables zone transfer but does not advertise the secondary in NS records returned by dnsmasq.
 .TP 
 .B --conntrack
 Read the Linux connection track mark associated with incoming DNS
@@ -821,7 +848,7 @@ associated with the queries which cause it, useful for bandwidth
 accounting and firewalling. Dnsmasq must have conntrack support
 compiled in and the kernel must have conntrack support
 included and configured. This option cannot be combined with
---query-port. 
+.B --query-port.
 .TP
 .B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-addr>[,<end-addr>|<mode>][,<netmask>[,<broadcast>]][,<lease time>]
 .TP
@@ -830,11 +857,11 @@ included and configured. This option cannot be combined with
 Enable the DHCP server. Addresses will be given out from the range
 <start-addr> to <end-addr> and from statically defined addresses given
 in 
-.B dhcp-host
+.B --dhcp-host
 options. If the lease time is given, then leases
 will be given for that length of time. The lease time is in seconds,
 or minutes (eg 45m) or hours (eg 1h) or "infinite". If not given,
-the default lease time is one hour. The
+the default lease time is one hour for IPv4 and one day for IPv6. The
 minimum lease time is two minutes. For IPv6 ranges, the lease time
 maybe "deprecated"; this sets the preferred lifetime sent in a DHCP
 lease or router advertisement to zero, which causes clients to use
@@ -849,7 +876,7 @@ agent, dnsmasq cannot determine the netmask itself, so it should be
 specified, otherwise dnsmasq will have to guess, based on the class (A, B or
 C) of the network address. The broadcast address is
 always optional. It is always
-allowed to have more than one dhcp-range in a single subnet. 
+allowed to have more than one \fB--dhcp-range\fP in a single subnet.
 
 For IPv6, the parameters are slightly different: instead of netmask
 and broadcast address, there is an optional prefix length which must
@@ -873,7 +900,7 @@ then deleted. The interface name may have a final "*" wildcard. Note
 that just any address on eth0 will not do: it must not be an
 autoconfigured or privacy address, or be deprecated.
 
-If a dhcp-range is only being used for stateless DHCP and/or SLAAC,
+If a \fB--dhcp-range\fP is only being used for stateless DHCP and/or SLAAC,
 then the address can be simply ::
 
 .B --dhcp-range=::,constructor:eth0
@@ -882,7 +909,7 @@ then the address can be simply ::
 The optional 
 .B set:<tag> 
 sets an alphanumeric label which marks this network so that
-dhcp options may be specified on a per-network basis. 
+DHCP options may be specified on a per-network basis.
 When it is prefixed with 'tag:' instead, then its meaning changes from setting
 a tag to matching it. Only one tag may be set, but more than one tag
 may be matched.
@@ -892,7 +919,7 @@ The optional <mode> keyword may be
 which tells dnsmasq to enable DHCP for the network specified, but not
 to dynamically allocate IP addresses: only hosts which have static
 addresses given via 
-.B dhcp-host
+.B --dhcp-host
 or from /etc/ethers will be served. A static-only subnet with address
 all zeros may be used as a "catch-all" address to enable replies to all
 Information-request packets on a subnet which is provided with
@@ -903,9 +930,9 @@ For IPv4, the <mode> may be
 .B proxy
 in which case dnsmasq will provide proxy-DHCP on the specified
 subnet. (See 
-.B pxe-prompt
+.B --pxe-prompt
 and 
-.B pxe-service
+.B --pxe-service
 for details.)
 
 For IPv6, the mode may be some combination of
@@ -953,7 +980,7 @@ is also included, as described in RFC-3775 section 7.3.
 tells dnsmasq to advertise the prefix without the on-link (aka L) bit set.
 
 .TP
-.B \-G, --dhcp-host=[<hwaddr>][,id:<client_id>|*][,set:<tag>][,<ipaddr>][,<hostname>][,<lease_time>][,ignore]
+.B \-G, --dhcp-host=[<hwaddr>][,id:<client_id>|*][,set:<tag>][tag:<tag>][,<ipaddr>][,<hostname>][,<lease_time>][,ignore]
 Specify per host parameters for the DHCP server. This allows a machine
 with a particular hardware address to be always allocated the same
 hostname, IP address and lease time. A hostname specified like this
@@ -971,10 +998,10 @@ dnsmasq to always allocate the machine lap the IP address
 192.168.0.199. 
 
 Addresses allocated like this are not constrained to be
-in the range given by the --dhcp-range option, but they must be in
+in the range given by the \fB--dhcp-range\fP option, but they must be in
 the same subnet as some valid dhcp-range.  For
 subnets which don't need a pool of dynamically allocated addresses,
-use the "static" keyword in the dhcp-range declaration.
+use the "static" keyword in the \fB--dhcp-range\fP declaration.
 
 It is allowed to use client identifiers (called client
 DUID in IPv6-land) rather than
@@ -985,13 +1012,20 @@ allowed to specify the client ID as text, like this:
 .B --dhcp-host=id:clientidastext,..... 
 
 A single
-.B dhcp-host 
-may contain an IPv4 address or an IPv6 address, or both. IPv6 addresses must be bracketed by square brackets thus:
+.B --dhcp-host
+may contain an IPv4 address or one or more IPv6 addresses, or both. IPv6 addresses must be bracketed by square brackets thus:
 .B --dhcp-host=laptop,[1234::56]
 IPv6 addresses may contain only the host-identifier part:
 .B --dhcp-host=laptop,[::56]
-in which case they act as wildcards in constructed dhcp ranges, with
-the appropriate network part inserted. 
+in which case they act as wildcards in constructed DHCP ranges, with
+the appropriate network part inserted. For IPv6, an address may include a prefix length:
+.B --dhcp-host=laptop,[1234:50/126]
+which (in this case) specifies four addresses, 1234::50 to 1234::53. This (an the ability
+to specify multiple addresses) is useful
+when a host presents either a consistent name or hardware-ID, but varying DUIDs, since it allows
+dnsmasq to honour the static address allocation but assign a different adddress for each DUID. This
+typically occurs when chain netbooting, as each stage of the chain gets in turn allocates an address.
+
 Note that in IPv6 DHCP, the hardware address may not be
 available, though it normally is for direct-connected clients, or
 clients using DHCP relays which support RFC 6939.
@@ -1006,7 +1040,7 @@ allocated to a DHCP lease, but only if a
 .B --dhcp-host
 option specifying the name also exists. Only one hostname can be
 given in a 
-.B dhcp-host
+.B --dhcp-host
 option, but aliases are possible by using CNAMEs. (See 
 .B --cname
 ).
@@ -1021,16 +1055,19 @@ useful when there is another DHCP server on the network which should
 be used by some machines.
 
 The set:<tag> construct sets the tag
-whenever this dhcp-host directive is in use. This can be used to 
+whenever this \fB--dhcp-host\fP directive is in use. This can be used to
 selectively send DHCP options just for this host. More than one tag
-can be set in a dhcp-host directive (but not in other places where
+can be set in a \fB--dhcp-host\fP directive (but not in other places where
 "set:<tag>" is allowed). When a host matches any
-dhcp-host directive (or one implied by /etc/ethers) then the special
+\fB--dhcp-host\fP directive (or one implied by /etc/ethers) then the special
 tag "known" is set. This allows dnsmasq to be configured to
 ignore requests from unknown machines using
 .B --dhcp-ignore=tag:!known
-If the host matches only a dhcp-host directive which cannot
+If the host matches only a \fB--dhcp-host\fP directive which cannot
 be used because it specifies an address on different subnet, the tag "known-othernet" is set.
+
+The tag:<tag> construct filters which dhcp-host directives are used. Tagged directives are used in preference to untagged ones.
+
 Ethernet addresses (but not client-ids) may have
 wildcard bytes, so for example 
 .B --dhcp-host=00:20:e0:3b:13:*,ignore 
@@ -1062,23 +1099,23 @@ has both wired and wireless interfaces.
 Read DHCP host information from the specified file. If a directory
 is given, then read all the files contained in that directory. The file contains 
 information about one host per line. The format of a line is the same
-as text to the right of '=' in --dhcp-host. The advantage of storing DHCP host information
+as text to the right of '=' in \fB--dhcp-host\fP. The advantage of storing DHCP host information
 in this file is that it can be changed without re-starting dnsmasq:
 the file will be re-read when dnsmasq receives SIGHUP.
 .TP
 .B --dhcp-optsfile=<path>
 Read DHCP option information from the specified file.  If a directory
 is given, then read all the files contained in that directory. The advantage of 
-using this option is the same as for --dhcp-hostsfile: the
-dhcp-optsfile will be re-read when dnsmasq receives SIGHUP. Note that
+using this option is the same as for \fB--dhcp-hostsfile\fP: the
+\fB--dhcp-optsfile\fP will be re-read when dnsmasq receives SIGHUP. Note that
 it is possible to encode the information in a
 .B --dhcp-boot
 flag as DHCP options, using the options names bootfile-name,
 server-ip-address and tftp-server. This allows these to be included
-in a dhcp-optsfile.
+in a \fB--dhcp-optsfile\fP.
 .TP
 .B --dhcp-hostsdir=<path>
-This is equivalent to dhcp-hostsfile, except for the following. The path MUST be a
+This is equivalent to \fB--dhcp-hostsfile\fP, except for the following. The path MUST be a
 directory, and not an individual file. Changed or new files within
 the directory are read automatically, without the need to send SIGHUP.
 If a file is deleted or changed after it has been read by dnsmasq, then the
@@ -1086,7 +1123,7 @@ host record it contained will remain until dnsmasq receives a SIGHUP, or
 is restarted; ie host records are only added dynamically.
 .TP
 .B --dhcp-optsdir=<path>
-This is equivalent to dhcp-optsfile, with the differences noted for --dhcp-hostsdir.
+This is equivalent to \fB--dhcp-optsfile\fP, with the differences noted for \fB--dhcp-hostsdir\fP.
 .TP 
 .B \-Z, --read-ethers
 Read /etc/ethers for information about hosts for the DHCP server. The
@@ -1157,12 +1194,12 @@ a literal IP address as TFTP server name, it is necessary to do
 .B --dhcp-option=66,"1.2.3.4"
 
 Encapsulated Vendor-class options may also be specified (IPv4 only) using
---dhcp-option: for instance 
+\fB--dhcp-option\fP: for instance
 .B --dhcp-option=vendor:PXEClient,1,0.0.0.0 
 sends the encapsulated vendor
 class-specific option "mftp-address=0.0.0.0" to any client whose
 vendor-class matches "PXEClient". The vendor-class matching is
-substring based (see --dhcp-vendorclass for details). If a
+substring based (see \fB--dhcp-vendorclass\fP for details). If a
 vendor-class option (number 60) is sent by dnsmasq, then that is used 
 for selecting encapsulated options in preference to any sent by the
 client. It is
@@ -1175,7 +1212,7 @@ Options may be encapsulated (IPv4 only) within other options: for instance
 will send option 175, within which is the option 190. If multiple
 options are given which are encapsulated with the same option number
 then they will be correctly combined into one encapsulated option.
-encap: and vendor: are may not both be set in the same dhcp-option.
+encap: and vendor: are may not both be set in the same \fB--dhcp-option\fP.
 
 The final variant on encapsulated options is "Vendor-Identifying
 Vendor Options" as specified by RFC3925. These are denoted like this: 
@@ -1197,7 +1234,7 @@ needed, for example when sending options to PXELinux.
 .B --dhcp-no-override
 (IPv4 only) Disable re-use of the DHCP servername and filename fields as extra
 option space. If it can, dnsmasq moves the boot server and filename
-information (from dhcp-boot) out of their dedicated fields into
+information (from \fB--dhcp-boot\fP) out of their dedicated fields into
 DHCP options. This make extra space available in the DHCP packet for
 options but can, rarely, confuse old or broken clients. This flag
 forces "simple and safe" behaviour to avoid problems in such a case.
@@ -1207,7 +1244,7 @@ Configure dnsmasq to do DHCP relay. The local address is an address
 allocated to an interface on the host running dnsmasq. All DHCP
 requests arriving on that interface will we relayed to a remote DHCP
 server at the server address. It is possible to relay from a single local
-address to multiple remote servers by using multiple dhcp-relay
+address to multiple remote servers by using multiple \fB--dhcp-relay\fP
 configs with the same local address and different server
 addresses. A server address must be an IP literal address, not a
 domain name. In the case of DHCPv6, the server address may be the
@@ -1216,8 +1253,8 @@ must be given, not be wildcard, and is used to direct the multicast to the
 correct interface to reach the DHCP server. 
 
 Access control for DHCP clients has the same rules as for the DHCP
-server, see --interface, --except-interface, etc. The optional
-interface name in the dhcp-relay config has a different function: it
+server, see \fB--interface\fP, \fB--except-interface\fP, etc. The optional
+interface name in the \fB--dhcp-relay\fP config has a different function: it
 controls on which interface DHCP replies from the server will be
 accepted. This is intended for configurations which have three
 interfaces: one being relayed from, a second connecting the DHCP
@@ -1239,7 +1276,7 @@ Map from a vendor-class string to a tag. Most DHCP clients provide a
 "vendor class" which represents, in some sense, the type of host. This option 
 maps vendor classes to tags, so that DHCP options may be selectively delivered
 to different classes of hosts. For example 
-.B dhcp-vendorclass=set:printers,Hewlett-Packard JetDirect
+.B --dhcp-vendorclass=set:printers,Hewlett-Packard JetDirect
 will allow options to be set only for HP printers like so:
 .B --dhcp-option=tag:printers,3,192.168.4.4 
 The vendor-class string is
@@ -1274,8 +1311,8 @@ normally given as colon-separated hex, but is also allowed to be a
 simple string. If an exact match is achieved between the circuit or
 agent ID and one provided by a relay agent, the tag is set. 
 
-.B dhcp-remoteid
-(but not dhcp-circuitid) is supported in IPv6. 
+.B --dhcp-remoteid
+(but not \fB--dhcp-circuitid\fP) is supported in IPv6.
 .TP
 .B --dhcp-subscrid=set:<tag>,<subscriber-id>
 (IPv4 and IPv6) Map from RFC3993 subscriber-id relay agent options to tags.
@@ -1286,9 +1323,9 @@ a DHCP interaction to the DHCP server. Once a client is configured, it
 communicates directly with the server. This is undesirable if the
 relay agent is adding extra information to the DHCP packets, such as
 that used by
-.B dhcp-circuitid
+.B --dhcp-circuitid
 and
-.B dhcp-remoteid.
+.B --dhcp-remoteid.
 A full relay implementation can use the RFC 5107 serverid-override
 option to force the DHCP server to use the relay as a full proxy, with all
 packets passing through it. This flag provides an alternative method
@@ -1304,12 +1341,10 @@ the option is sent and matches the value. The value may be of the form
 "01:ff:*:02" in which case the value must match (apart from wildcards)
 but the option sent may have unmatched data past the end of the
 value. The value may also be of the same form as in 
-.B dhcp-option
+.B --dhcp-option
 in which case the option sent is treated as an array, and one element
 must match, so
-
---dhcp-match=set:efi-ia32,option:client-arch,6
-
+.B --dhcp-match=set:efi-ia32,option:client-arch,6
 will set the tag "efi-ia32" if the the number 6 appears in the list of
 architectures sent by the client in option 93. (See RFC 4578 for
 details.)  If the value is a string, substring matching is used.
@@ -1318,14 +1353,17 @@ The special form with vi-encap:<enterprise number> matches against
 vendor-identifying vendor classes for the specified enterprise. Please
 see RFC 3925 for more details of these rare and interesting beasts.
 .TP
+.B --dhcp-name-match=set:<tag>,<name>[*]
+Set the tag if the given name is supplied by a DHCP client. There may be a single trailing wildcard *, which has the usual meaning. Combined with dhcp-ignore or dhcp-ignore-names this gives the ability to ignore certain clients by name, or disallow certain hostnames from being claimed by a client.
+.TP
 .B --tag-if=set:<tag>[,set:<tag>[,tag:<tag>[,tag:<tag>]]]
 Perform boolean operations on tags. Any tag appearing as set:<tag> is set if
 all the tags which appear as tag:<tag> are set, (or unset when tag:!<tag> is used)
 If no tag:<tag> appears set:<tag> tags are set unconditionally.
 Any number of set: and tag: forms may appear, in any order. 
-Tag-if lines are executed in order, so if the tag in tag:<tag> is a
+\fB--tag-if\fP lines are executed in order, so if the tag in tag:<tag> is a
 tag set by another
-.B tag-if,
+.B --tag-if,
 the line which sets the tag must precede the one which tests it.
 .TP
 .B \-J, --dhcp-ignore=tag:<tag>[,tag:<tag>]
@@ -1334,10 +1372,10 @@ not allocate it a DHCP lease.
 .TP
 .B --dhcp-ignore-names[=tag:<tag>[,tag:<tag>]]
 When all the given tags appear in the tag set, ignore any hostname
-provided by the host. Note that, unlike dhcp-ignore, it is permissible
+provided by the host. Note that, unlike \fB--dhcp-ignore\fP, it is permissible
 to supply no tags, in which case DHCP-client supplied hostnames
 are always ignored, and DHCP hosts are added to the DNS using only
-dhcp-host configuration in dnsmasq and the contents of /etc/hosts and
+\fB--dhcp-host\fP configuration in dnsmasq and the contents of /etc/hosts and
 /etc/ethers.
 .TP
 .B --dhcp-generate-names=tag:<tag>[,tag:<tag>]
@@ -1382,10 +1420,16 @@ address, and setting this flag enables this mode. Note that in the
 sequential mode, clients which allow a lease to expire are much more
 likely to move IP address; for this reason it should not be generally used.
 .TP
+.B --dhcp-ignore-clid
+Dnsmasq is reading 'client identifier' (RFC 2131) option sent by clients
+(if available) to identify clients. This allow to serve same IP address
+for a host using several interfaces. Use this option to disable 'client identifier'
+reading, i.e. to always identify a host using the MAC address.
+.TP
 .B --pxe-service=[tag:<tag>,]<CSA>,<menu text>[,<basename>|<bootservicetype>][,<server address>|<server_name>]
 Most uses of PXE boot-ROMS simply allow the PXE
 system to obtain an IP address and then download the file specified by
-.B dhcp-boot
+.B --dhcp-boot
 and execute it. However the PXE system is capable of more complex
 functions when supported by a suitable DHCP server.
 
@@ -1397,7 +1441,7 @@ integer may be used for other types. The
 parameter after the menu text may be a file name, in which case dnsmasq acts as a
 boot server and directs the PXE client to download the file by TFTP,
 either from itself (
-.B enable-tftp 
+.B --enable-tftp
 must be set for this to work) or another TFTP server if the final server
 address/name is given.
 Note that the "layer"
@@ -1419,23 +1463,23 @@ timeout is given then after the
 timeout has elapsed with no keyboard input, the first available menu
 option will be automatically executed. If the timeout is zero then the first available menu
 item will be executed immediately. If 
-.B pxe-prompt
+.B --pxe-prompt
 is omitted the system will wait for user input if there are multiple
 items in the menu, but boot immediately if
 there is only one. See
-.B pxe-service 
+.B --pxe-service
 for details of menu items.
 
 Dnsmasq supports PXE "proxy-DHCP", in this case another DHCP server on
 the network is responsible for allocating IP addresses, and dnsmasq
 simply provides the information given in 
-.B pxe-prompt
+.B --pxe-prompt
 and
-.B pxe-service
+.B --pxe-service
 to allow netbooting. This mode is enabled using the
 .B proxy
 keyword in
-.B dhcp-range.
+.B --dhcp-range.
 .TP  
 .B \-X, --dhcp-lease-max=<number>
 Limits dnsmasq to the specified maximum number of DHCP leases. The
@@ -1452,6 +1496,13 @@ allows dnsmasq to rebuild its lease database without each client needing to
 reacquire a lease, if the database is lost. For DHCPv6 it sets the
 priority in replies to 255 (the maximum) instead of 0 (the minimum).
 .TP
+.B --dhcp-rapid-commit
+Enable DHCPv4 Rapid Commit Option specified in RFC 4039. When enabled, dnsmasq
+will respond to a DHCPDISCOVER message including a Rapid Commit
+option with a DHCPACK including a Rapid Commit option and fully committed
+address and configuration information. Should only be enabled if either the
+server is  the only server for the subnet, or multiple servers are present and they each commit a binding for all clients.
+.TP
 .B --dhcp-alternate-port[=<server port>[,<client port>]]
 (IPv4 only) Change the ports used for DHCP from the default. If this option is
 given alone, without arguments, it changes the ports used for DHCP
@@ -1481,8 +1532,8 @@ the tags used to determine them.
 .TP
 .B --quiet-dhcp, --quiet-dhcp6, --quiet-ra
 Suppress logging of the routine operation of these protocols. Errors and
-problems will still be logged. --quiet-dhcp and quiet-dhcp6 are
-over-ridden by --log-dhcp.
+problems will still be logged. \fB--quiet-dhcp\fP and quiet-dhcp6 are
+over-ridden by \fB--log-dhcp\fP.
 .TP
 .B \-l, --dhcp-leasefile=<path>
 Use the specified file to store DHCP lease information.
@@ -1508,7 +1559,8 @@ address of the host (or DUID for IPv6) , the IP address, and the hostname,
 if known. "add" means a lease has been created, "del" means it has
 been destroyed, "old" is a notification of an existing lease when
 dnsmasq starts or a change to MAC address or hostname of an existing
-lease (also, lease length or expiry and client-id, if leasefile-ro is set).
+lease (also, lease length or expiry and client-id, if \fB--leasefile-ro\fP is set
+and lease expiry if \fB--script-on-renewal\fP is set).
 If the MAC address is from a network type other than ethernet,
 it will have the network type prepended, eg "06-01:23:45:67:89:ab" for
 token ring. The process is run as root (assuming that dnsmasq was originally run as
@@ -1682,7 +1734,7 @@ and
 Specify the user as which to run the lease-change script or Lua script. This defaults to root, but can be changed to another user using this flag. 
 .TP
 .B --script-arp
-Enable the "arp" and "arp-old" functions in the dhcp-script and dhcp-luascript.
+Enable the "arp" and "arp-old" functions in the \fB--dhcp-script\fP and \fB--dhcp-luascript\fP.
 .TP
 .B \-9, --leasefile-ro
 Completely suppress use of the lease database file. The file will not
@@ -1698,6 +1750,10 @@ stdout and exit with zero exit code. Setting this
 option also forces the leasechange script to be called on changes
 to the client-id and lease length and expiry time.
 .TP
+.B --script-on-renewal
+Call the DHCP script when the lease expiry time changes, for instance when the
+lease is renewed.
+.TP
 .B --bridge-interface=<interface>,<alias>[,<alias>]
 Treat DHCP (v4 and v6) requests and IPv6 Router Solicit packets
 arriving at any of the <alias> interfaces as if they had arrived at
@@ -1707,9 +1763,39 @@ OpenStack compute host where each such interface is a TAP interface to
 a VM, or as in "old style bridging" on BSD platforms.  A trailing '*'
 wildcard can be used in each <alias>.
 
-It is permissible to add more than one alias using more than one --bridge-interface option since 
---bridge-interface=int1,alias1,alias2 is exactly equivalent to
---bridge-interface=int1,alias1 --bridge-interface=int1,alias2
+It is permissible to add more than one alias using more than one \fB--bridge-interface\fP option since
+\fB--bridge-interface=int1,alias1,alias2\fP is exactly equivalent to
+\fB--bridge-interface=int1,alias1 --bridge-interface=int1,alias2\fP
+.TP
+.B --shared-network=<interface>,<addr>
+.PD 0
+.TP
+.B --shared-network=<addr>,<addr>
+.PD 1v
+The DHCP server determines which DHCP ranges are useable for allocating an
+address to a DHCP client based on the network from which the DHCP request arrives,
+and the IP configuration of the server's interface on that network. The shared-network
+option extends the available subnets (and therefore DHCP ranges) beyond the
+subnets configured on the arrival interface.
+
+The first argument is either the
+name of an interface, or an address that is configured on a local interface, and the
+second argument is an address which defines another subnet on which addresses can be allocated.
+
+To be useful, there must be a suitable dhcp-range which allows address allocation on this subnet
+and this dhcp-range MUST include the netmask.
+
+Using shared-network also needs extra
+consideration of routing. Dnsmasq does not have the usual information that it uses to
+determine the default route, so the default route option (or other routing) MUST be
+configured manually. The client must have a route to the server: if the two-address form
+of shared-network is used, this needs to be to the first specified address. If the interface,address
+form is used, there must be a route to all of the addresses configured on the interface.
+
+The two-address form of shared-network is also usable with a DHCP relay: the first address
+is the address of the relay and the second, as before, specifies an extra subnet which
+addresses may be allocated from.
+
 .TP
 .B \-s, --domain=<domain>[,<address range>[,local]]
 Specifies DNS domains for the DHCP server. Domains may be be given 
@@ -1718,7 +1804,7 @@ firstly it causes the DHCP server to return the domain to any hosts
 which request it, and secondly it sets the domain which it is legal
 for DHCP-configured hosts to claim. The intention is to constrain
 hostnames so that an untrusted host on the LAN cannot advertise 
-its name via dhcp as e.g. "microsoft.com" and capture traffic not 
+its name via DHCP as e.g. "microsoft.com" and capture traffic not 
 meant for it. If no domain suffix is specified, then any DHCP
 hostname with a domain part (ie with a period) will be disallowed 
 and logged. If suffix is specified, then hostnames with a domain 
@@ -1740,11 +1826,11 @@ which can change the behaviour of dnsmasq with domains.
 
 If the address range is given as ip-address/network-size, then a
 additional flag "local" may be supplied which has the effect of adding
---local declarations for forward and reverse DNS queries. Eg.
+\fB--local\fP declarations for forward and reverse DNS queries. Eg.
 .B --domain=thekelleys.org.uk,192.168.0.0/24,local
 is identical to
 .B --domain=thekelleys.org.uk,192.168.0.0/24
---local=/thekelleys.org.uk/ --local=/0.168.192.in-addr.arpa/
+.B --local=/thekelleys.org.uk/ --local=/0.168.192.in-addr.arpa/
 The network size must be 8, 16 or 24 for this to be legal.
 .TP
 .B --dhcp-fqdn
@@ -1779,7 +1865,7 @@ discovery and (possibly) prefix discovery for autonomous address
 creation are handled by a different protocol. When DHCP is in use,
 only a subset of this is needed, and dnsmasq can handle it, using
 existing DHCP configuration to provide most data. When RA is enabled,
-dnsmasq will advertise a prefix for each dhcp-range, with default
+dnsmasq will advertise a prefix for each \fB--dhcp-range\fP, with default
 router  as the relevant link-local address on 
 the machine running dnsmasq. By default, the "managed address" bits are set, and
 the "use SLAAC" bit is reset. This can be changed for individual
@@ -1799,7 +1885,7 @@ The interval between router advertisements may be set (in seconds) with
 .B --ra-param=eth0,60.
 The lifetime of the route may be changed or set to zero, which allows
 a router to advertise prefixes but not a route via itself. 
-.B --ra-parm=eth0,0,0
+.B --ra-param=eth0,0,0
 (A value of zero for the interval means the default value.) All four parameters may be set at once.
 .B --ra-param=eth0,mtu:1280,low,60,1200
 
@@ -1809,7 +1895,7 @@ The mtu: parameter may be an arbitrary interface name, in which case the MTU val
 for (eg) advertising the MTU of a WAN interface on the other interfaces of a router.
 .TP
 .B --dhcp-reply-delay=[tag:<tag>,]<integer>
-Delays sending DHCPOFFER and proxydhcp replies for at least the specified number of seconds.
+Delays sending DHCPOFFER and PROXYDHCP replies for at least the specified number of seconds.
 This can be used as workaround for bugs in PXE boot firmware that does not function properly when
 receiving an instant reply.
 This option takes into account the time already spent waiting (e.g. performing ping check) if any.
@@ -1834,9 +1920,9 @@ Do not abort startup if specified tftp root directories are inaccessible.
 .TP
 .B --tftp-unique-root[=ip|mac]
 Add the IP or hardware address of the TFTP client as a path component on the end
-of the TFTP-root. Only valid if a tftp-root is set and the directory exists.
+of the TFTP-root. Only valid if a \fB--tftp-root\fP is set and the directory exists.
 Defaults to adding IP address (in standard dotted-quad format).
-For instance, if tftp-root is "/tftp" and client 1.2.3.4 requests file "myfile"
+For instance, if \fB--tftp-root\fP is "/tftp" and client 1.2.3.4 requests file "myfile"
 then the effective path will be "/tftp/1.2.3.4/myfile" if /tftp/1.2.3.4 exists or /tftp/myfile otherwise.
 When "=mac" is specified it will append the MAC address instead, using lowercase zero padded digits
 separated by dashes, e.g.: 01-02-03-04-aa-bb
@@ -1846,12 +1932,12 @@ a DHCP lease from us.
 .B --tftp-secure
 Enable TFTP secure mode: without this, any file which is readable by
 the dnsmasq process under normal unix access-control rules is
-available via TFTP. When the --tftp-secure flag is given, only files
+available via TFTP. When the \fB--tftp-secure\fP flag is given, only files
 owned by the user running the dnsmasq process are accessible. If
-dnsmasq is being run as root, different rules apply: --tftp-secure
+dnsmasq is being run as root, different rules apply: \fB--tftp-secure\fP
 has no effect, but only files which have the world-readable bit set
 are accessible. It is not recommended to run dnsmasq as root with TFTP
-enabled, and certainly not without specifying --tftp-root. Doing so
+enabled, and certainly not without specifying \fB--tftp-root\fP. Doing so
 can expose any world-readable file on the server to any host on the net. 
 .TP
 .B --tftp-lowercase
@@ -1889,10 +1975,16 @@ specifies a range of ports for use by TFTP transfers. This can be
 useful when TFTP has to traverse a firewall. The start of the range
 cannot be lower than 1025 unless dnsmasq is running as root. The number
 of concurrent TFTP connections is limited by the size of the port range. 
-.TP  
+.TP
+.B --tftp-single-port
+Run in a mode where the TFTP server uses ONLY the well-known port (69) for its end
+of the TFTP transfer. This allows TFTP to work when there in NAT is the path between client and server. Note that
+this is not strictly compliant with the RFCs specifying the TFTP protocol: use at your own risk.
+.TP
 .B \-C, --conf-file=<file>
-Specify a different configuration file. The conf-file option is also allowed in
-configuration files, to include multiple configuration files. A
+Specify a configuration file. The presence of this option stops dnsmasq from reading the default configuration
+file (normally /etc/dnsmasq.conf). Multiple files may be specified by repeating the option
+either on the command line or in configuration files. A
 filename of "-" causes dnsmasq to read configuration from stdin.
 .TP
 .B \-7, --conf-dir=<directory>[,<file-extension>......],
@@ -1904,12 +1996,12 @@ which have that extension are loaded. So
 .B --conf-dir=/path/to/dir,*.conf
 loads all files with the suffix .conf in /path/to/dir. This flag may be given on the command
 line or in a configuration file. If giving it on the command line, be sure to
-escape * characters.
+escape * characters. Files are loaded in alphabetical order of filename.
 .TP
 .B --servers-file=<file>
 A special case of 
 .B --conf-file
-which differs in two respects. Firstly, only --server and --rev-server are allowed 
+which differs in two respects. Firstly, only \fB--server\fP and \fB--rev-server\fP are allowed
 in the configuration file included. Secondly, the file is re-read and the configuration
 therein is updated when dnsmasq receives SIGHUP.
 .SH CONFIG FILE
@@ -1919,9 +2011,9 @@ if it exists. (On
 FreeBSD, the file is 
 .I /usr/local/etc/dnsmasq.conf
 ) (but see the 
-.B \-C
+.B \--conf-file
 and
-.B \-7
+.B \--conf-dir
 options.) The format of this
 file consists of one option per line, exactly as the long options detailed 
 in the OPTIONS section but without the leading "--". Lines starting with # are comments and ignored. For
@@ -1937,9 +2029,9 @@ clears its cache and then re-loads
 .I /etc/hosts
 and 
 .I /etc/ethers 
-and any file given by --dhcp-hostsfile, --dhcp-hostsdir, --dhcp-optsfile, 
---dhcp-optsdir, --addn-hosts or --hostsdir.
-The dhcp lease change script is called for all
+and any file given by \fB--dhcp-hostsfile\fP, \fB--dhcp-hostsdir\fP, \fB--dhcp-optsfile\fP,
+\fB--dhcp-optsdir\fP, \fB--addn-hosts\fP or \fB--hostsdir\fP.
+The DHCP lease change script is called for all
 existing DHCP leases. If 
 .B
 --no-poll
@@ -1958,7 +2050,7 @@ misses and the number of authoritative queries answered are also given. For each
 server it gives the number of queries sent, and the number which
 resulted in an error. In 
 .B --no-daemon
-mode or when full logging is enabled (-q), a complete dump of the
+mode or when full logging is enabled (\fB--log-queries\fP), a complete dump of the
 contents of the cache is made. 
 
 The cache statistics are also available in the DNS as answers to 
@@ -2039,7 +2131,7 @@ using
 options or put their addresses real in another file, say
 .I /etc/resolv.dnsmasq
 and run dnsmasq with the 
-.B \-r /etc/resolv.dnsmasq
+.B \--resolv-file /etc/resolv.dnsmasq
 option. This second technique allows for dynamic update of the server
 addresses by PPP or DHCP.
 .PP
@@ -2057,67 +2149,66 @@ the CNAME is shadowed too.
 The tag system works as follows: For each DHCP request, dnsmasq
 collects a set of valid tags from active configuration lines which
 include set:<tag>, including one from the 
-.B dhcp-range
+.B --dhcp-range
 used to allocate the address, one from any matching 
-.B dhcp-host
-(and "known" or "known-othernet" if a dhcp-host matches) 
+.B --dhcp-host
+(and "known" or "known-othernet" if a \fB--dhcp-host\fP matches)
 The tag "bootp" is set for BOOTP requests, and a tag whose name is the 
 name of the interface on which the request arrived is also set.
 
 Any configuration lines which include one or more tag:<tag> constructs
 will only be valid if all that tags are matched in the set derived
-above. Typically this is dhcp-option.
-.B dhcp-option 
+above. Typically this is \fB--dhcp-option\fP.
+.B --dhcp-option
 which has tags will be used in preference  to an untagged 
-.B dhcp-option,
+.B --dhcp-option,
 provided that _all_ the tags match somewhere in the
 set collected as described above. The prefix '!' on a tag means 'not'
-so --dhcp-option=tag:!purple,3,1.2.3.4 sends the option when the
+so \fB--dhcp-option=tag:!purple,3,1.2.3.4\fP sends the option when the
 tag purple is not in the set of valid tags. (If using this in a
 command line rather than a configuration file, be sure to escape !,
 which is a shell metacharacter)
 
-When selecting dhcp-options, a tag from dhcp-range is second class
+When selecting \fB--dhcp-options\fP, a tag from \fB--dhcp-range\fP is second class
 relative to other tags, to make it easy to override options for
 individual hosts, so 
-.B dhcp-range=set:interface1,......
-.B dhcp-host=set:myhost,.....
-.B dhcp-option=tag:interface1,option:nis-domain,"domain1"
-.B dhcp-option=tag:myhost,option:nis-domain,"domain2"
+.B --dhcp-range=set:interface1,......
+.B --dhcp-host=set:myhost,.....
+.B --dhcp-option=tag:interface1,option:nis-domain,"domain1"
+.B --dhcp-option=tag:myhost,option:nis-domain,"domain2"
 will set the NIS-domain to domain1 for hosts in the range, but
 override that to domain2 for a particular host.
 
 .PP
 Note that for 
-.B dhcp-range 
+.B --dhcp-range
 both tag:<tag> and set:<tag> are allowed, to both select the range in
-use based on (eg) dhcp-host, and to affect the options sent, based on
+use based on (eg) \fB--dhcp-host\fP, and to affect the options sent, based on
 the range selected.
 
 This system evolved from an earlier, more limited one and for backward
 compatibility "net:" may be used instead of "tag:" and "set:" may be
 omitted. (Except in 
-.B dhcp-host,
+.B --dhcp-host,
 where "net:" may be used instead of "set:".) For the same reason, '#'
 may be used instead of '!' to indicate NOT.
 .PP 
 The DHCP server in dnsmasq will function as a BOOTP server also,
 provided that the MAC address and IP address for clients are given,
 either using 
-.B dhcp-host 
+.B --dhcp-host
 configurations or in
 .I /etc/ethers
 , and a
-.B dhcp-range 
+.B --dhcp-range
 configuration option is present to activate the DHCP server
-on a particular network. (Setting --bootp-dynamic removes the need for
+on a particular network. (Setting \fB--bootp-dynamic\fP removes the need for
 static address mappings.) The filename
 parameter in a BOOTP request is used as a tag,
 as is the tag "bootp", allowing some control over the options returned to
 different classes of hosts.
 
 .SH AUTHORITATIVE CONFIGURATION
-.PP 
 Configuring dnsmasq to act as an authoritative DNS server is
 complicated by the fact that it involves configuration of external DNS
 servers to provide delegation. We will walk through three scenarios of
@@ -2131,8 +2222,8 @@ for which dnsmasq is authoritative our.zone.com.
 The simplest configuration consists of two lines of dnsmasq configuration; something like
 
 .nf
-.B auth-server=server.example.com,eth0
-.B auth-zone=our.zone.com,1.2.3.0/24
+.B --auth-server=server.example.com,eth0
+.B --auth-zone=our.zone.com,1.2.3.0/24
 .fi
 
 and two records in the external DNS
@@ -2155,8 +2246,8 @@ authoritative zone which dnsmasq is serving, typically at the root. Now
 we have
 
 .nf
-.B auth-server=our.zone.com,eth0
-.B auth-zone=our.zone.com,1.2.3.0/24
+.B --auth-server=our.zone.com,eth0
+.B --auth-zone=our.zone.com,1.2.3.0/24
 .fi
 
 .nf
@@ -2175,25 +2266,25 @@ entry or
 .B --host-record.
 
 .nf
-.B auth-server=our.zone.com,eth0
-.B host-record=our.zone.com,1.2.3.4
-.B auth-zone=our.zone.com,1.2.3.0/24
+.B --auth-server=our.zone.com,eth0
+.B --host-record=our.zone.com,1.2.3.4
+.B --auth-zone=our.zone.com,1.2.3.0/24
 .fi
 
 If the external address is dynamic, the address
 associated with our.zone.com must be derived from the address of the
 relevant interface. This is done using 
-.B interface-name
+.B --interface-name
 Something like:
 
 .nf
-.B auth-server=our.zone.com,eth0
-.B interface-name=our.zone.com,eth0
-.B auth-zone=our.zone.com,1.2.3.0/24,eth0
+.B --auth-server=our.zone.com,eth0
+.B --interface-name=our.zone.com,eth0
+.B --auth-zone=our.zone.com,1.2.3.0/24,eth0
 .fi
 
-(The "eth0" argument in auth-zone adds the subnet containing eth0's
-dynamic address to the zone, so that the interface-name returns the
+(The "eth0" argument in \fB--auth-zone\fP adds the subnet containing eth0's
+dynamic address to the zone, so that the \fB--interface-name\fP returns the
 address in outside queries.)
 
 Our final configuration builds on that above, but also adds a
@@ -2204,7 +2295,7 @@ secondary is beyond the scope of this man-page, but the extra
 configuration of dnsmasq is simple:
 
 .nf
-.B auth-sec-servers=secondary.myisp.com
+.B --auth-sec-servers=secondary.myisp.com
 .fi
 
 and
@@ -2218,13 +2309,13 @@ secondary to collect the DNS data. If you wish to restrict this data
 to particular hosts then
 
 .nf
-.B auth-peer=<IP address of secondary>
+.B --auth-peer=<IP address of secondary>
 .fi
 
 will do so.
 
 Dnsmasq acts as an authoritative server for  in-addr.arpa and
-ip6.arpa domains associated with the subnets given in auth-zone
+ip6.arpa domains associated with the subnets given in \fB--auth-zone\fP
 declarations, so reverse (address to name) lookups can be simply
 configured with a suitable NS record, for instance in this example,
 where we allow 1.2.3.0/24 addresses.
@@ -2241,8 +2332,8 @@ secondary servers for reverse lookups.
 When dnsmasq is configured to act as an authoritative server, the
 following data is used to populate the authoritative zone.
 .PP
-.B --mx-host, --srv-host, --dns-rr, --txt-record, --naptr-record
-as long as the record names are in the authoritative domain.
+.B --mx-host, --srv-host, --dns-rr, --txt-record, --naptr-record, --caa-record,
+as long as the record names are in the authoritative domain.
 .PP
 .B --cname
 as long as the record name is in  the authoritative domain. If the
@@ -2250,7 +2341,7 @@ target of the CNAME is unqualified, then it  is qualified with the
 authoritative zone name. CNAME used in this way (only) may be wildcards, as in
 
 .nf
-.B cname=*.example.com,default.example.com
+.B --cname=*.example.com,default.example.com
 .fi
 
 .PP
@@ -2287,7 +2378,6 @@ used, and must match the zone's domain.
 
 
 .SH EXIT CODES
-.PP
 0 - Dnsmasq successfully forked into the background, or terminated
 normally if backgrounding is not enabled.
 .PP
index 81c745a..4a70a4f 100644 (file)
@@ -478,7 +478,8 @@ la traza reversa direcci
 .TP
 .B \-c, --cache-size=<tamaño de caché>
 Fijar el tamaño del caché de dnsmasq. El predeterminado es 150 nombres.
-Fijar el tamaño a cero deshabilita el caché.
+Fijar el tamaño a cero deshabilita el caché. Nota: el gran tamaño de
+caché afecta el rendimiento.
 .TP
 .B \-N, --no-negcache
 Deshabilitar caché negativo. El caché negativo le permite a dnsmasq
index 80cef39..dc2fdc0 100644 (file)
@@ -10,7 +10,7 @@ est un serveur à faible empreinte mémoire faisant DNS, TFTP, PXE, annonces de
 routeurs et DHCP. Il offre à la fois les services DNS et DHCP pour un réseau
 local (LAN).
 .PP
-Dnsmasq accepte les requêtes DNS et y réponds soit en utilisant un petit cache
+Dnsmasq accepte les requêtes DNS et y répond soit en utilisant un petit cache
 local, soit en effectuant une requête à un serveur DNS récursif externe (par
 exemple celui de votre fournisseur d'accès internet). Il charge le contenu du
 fichier /etc/hosts afin que les noms locaux n'apparaissant pas dans les DNS
@@ -19,25 +19,25 @@ pour les hôtes présents dans le service DHCP. Il peut aussi agir en temps que
 serveur DNS faisant autorité pour un ou plusieurs domaines, permettant à des
 noms locaux d'apparaitre dans le DNS global.
 .PP
-Le serveur DHCP Dnsmasq DHCP supporte les définitions d'adresses statiques et les
+Le serveur DHCP de Dnsmasq supporte les définitions d'adresses statiques et les
 réseaux multiples. Il fournit par défaut un jeu raisonnable de paramètres DHCP,
 et peut être configuré pour fournir n'importe quelle option DHCP.
 Il inclut un serveur TFTP sécurisé en lecture seule permettant le démarrage via
 le réseau/PXE de clients DHCP et supporte également le protocole BOOTP. Le
 support PXE est complet, et comprend un mode proxy permettant de fournir des
-informations PXE aux clients alors que l'allocation DHCP est effectuée par un
-autre serveur.
+informations PXE aux clients alors que l'allocation d'adresse via DHCP est
+effectuée par un autre serveur.
 .PP
-Le serveur DHCPv6 de dnsmasq possède non seulement les mêmes fonctionalités
+Le serveur DHCPv6 de dnsmasq possède non seulement les mêmes fonctionnalités
 que le serveur DHCPv4, mais aussi le support des annonces de routeurs ainsi
-qu'une fonctionalité permettant l'addition de ressources AAAA pour des
+qu'une fonctionnalité permettant l'addition de ressources AAAA pour des
 clients utilisant DHCPv4 et la configuration IPv6 sans état (stateless
 autoconfiguration).
 Il inclut le support d'allocations d'adresses (à la fois en DHCPv6 et en
 annonces de routeurs - RA) pour des sous-réseaux dynamiquement délégués via
 une délégation de préfixe DHCPv6.
 .PP
-Dnsmasq est developpé pour de petits systèmes embarqués. It tends à avoir
+Dnsmasq est développé pour de petits systèmes embarqués. Il tend à avoir
 l'empreinte mémoire la plus faible possible pour les fonctions supportées,
 et permet d'exclure les fonctions inutiles du binaire compilé.
 .SH OPTIONS
@@ -46,16 +46,23 @@ Dans ce cas, la fonction correspondante sera désactivée. Par exemple
 .B --pid-file=
 (sans paramètre après le =) désactive l'écriture du fichier PID.
 Sur BSD, à moins que le logiciel ne soit compilé avec la bibliothèque GNU
-getopt, la forme longue des options ne fonctionne pas en ligne de commande; Elle
+getopt, la forme longue des options ne fonctionne pas en ligne de commande; elle
 est toujours supportée dans le fichier de configuration.
 .TP
 .B --test
-Vérifie la syntaxe du ou des fichiers de configurations. Se termine avec le
+Vérifie la syntaxe du ou des fichiers de configuration. Se termine avec le
 code de retour 0 si tout est OK, ou un code différent de 0 dans le cas
 contraire. Ne démarre pas Dnsmasq.
 .TP
+.B \-w, --help
+Affiche toutes les options de ligne de commande.
+.B --help dhcp
+affiche les options de configuration connues pour DHCPv4, et
+.B --help dhcp6
+affiche les options de configuration connues pour DHCPv6.
+.TP
 .B \-h, --no-hosts
-Ne pas charger les noms du fichier /etc/hosts.
+Ne pas charger les noms d'hôtes du fichier /etc/hosts.
 .TP
 .B \-H, --addn-hosts=<fichier>
 Fichiers d'hôtes additionnels. Lire le fichier spécifié en plus de /etc/hosts.
@@ -68,7 +75,7 @@ fichiers contenus dans ce répertoire.
 .B \-E, --expand-hosts
 Ajoute le nom de domaine aux noms simples (ne contenant pas de point dans le
 nom) contenus dans le fichier /etc/hosts, de la même façon que pour le service
-DHCP. Notez que cela ne s'applique pas au nom de domaine dans les CNAME, les
+DHCP. Notez que cela ne s'applique pas aux noms de domaine dans les CNAME, les
 enregistrements PTR, TXT, etc...
 .TP
 .B \-T, --local-ttl=<durée>
@@ -86,7 +93,7 @@ Les réponses négatives provenant des serveurs amonts contiennent normalement
 une information de durée de vie (time-to-live) dans les enregistrements SOA,
 information dont dnsmasq se sert pour mettre la réponse en cache. Si la réponse
 du serveur amont omet cette information, dnsmasq ne cache pas la réponse. Cette
-option permet de doner une valeur de durée de vie par défaut (en secondes) que
+option permet de donner une valeur de durée de vie par défaut (en secondes) que
 dnsmasq utilise pour mettre les réponses négatives dans son cache, même en
 l'absence d'enregistrement SOA.
 .TP
@@ -194,7 +201,7 @@ au dessus de la valeur spécifiée. Utile pour des systèmes derrière des dispo
 garde-barrières ("firewalls").
 .TP
 .B \-i, --interface=<nom d'interface>
-N'écouter que sur l'interface réseau spécifiée. Dnsmasq aujoute automatiquement
+N'écouter que sur l'interface réseau spécifiée. Dnsmasq ajoute automatiquement
 l'interface locale ("loopback") à la liste des interfaces lorsque l'option
 .B --interface
 est utilisée.
@@ -205,13 +212,13 @@ ou
 n'est donnée, Dnsmasq écoutera sur toutes les interfaces disponibles sauf
 celle(s) spécifiée(s) par l'option
 .B --except-interface.
-Les alias d'interfaces IP (e-g "eth1:0") ne peuvent être utilisés ni avec
+Les alias d'interfaces IP (par exemple "eth1:0") ne peuvent être utilisés ni avec
 .B --interface
 ni
 .B \--except-interface.
 Utiliser l'option 
 .B --listen-address
-à la place. Un simple joker, consistant d'un '*' final, peut-être utilisé dans
+à la place. Un simple joker, consistant en un '*' final, peut être utilisé dans
 les options
 .B \--interface 
 et
@@ -229,10 +236,10 @@ sont fournies n'importe pas, et que l'option
 .B --except-interface
 l'emporte toujours sur les autres.
 .TP
-.B --auth-server=<domaine>,<interface>|<addresse IP>
+.B --auth-server=<domaine>,<interface>|<adresse IP>
 Active le mode DNS faisant autorité pour les requêtes arrivant sur cette
 interface ou sur cette adresse. Noter que l'interface ou l'adresse n'ont
-pas besoin d'être mentionées ni dans
+pas besoin d'être mentionnées ni dans
 .B --interface
 ni dans
 .B --listen-address
@@ -253,7 +260,7 @@ Ecouter sur la ou les adresse(s) IP spécifiée(s). Les options
 .B \--interface
 et
 .B \--listen-address
-peuvent-être spécifiées simultanément, auquel cas un jeu d'interfaces et
+peuvent être spécifiées simultanément, auquel cas un jeu d'interfaces et
 d'adresses seront utilisées. Notez que si
 aucune option
 .B \--interface
@@ -265,7 +272,7 @@ nécessaire de fournir explicitement son adresse IP, 127.0.0.1 via l'option
 .B \--listen-address.
 .TP
 .B \-z, --bind-interfaces
-Sur les systèmes qui le supporte, Dnsmasq s'associe avec l'interface joker
+Sur les systèmes qui le supportent, Dnsmasq s'associe avec l'interface joker
 ("wildcard"), même lorsqu'il ne doit écouter que sur certaines interfaces. Par
 la suite, il rejette les requêtes auxquelles il ne doit pas répondre. Cette
 situation présente l'avantage de fonctionner même lorsque les interfaces vont
@@ -302,7 +309,7 @@ le réseau auquel ils sont attachés). Cette possibilité est actuellement limit
 .TP
 .B \-b, --bogus-priv
 Fausse résolution inverse pour les réseaux privés. Toutes les requêtes DNS
-inverses pour des adresses IP privées (ie 192.168.x.x, etc...) qui ne sont pas
+inverses pour des adresses IP privées (192.168.x.x, etc...) qui ne sont pas
 trouvées dans /etc/hosts ou dans le fichier de baux DHCP se voient retournées
 une réponse "pas de tel domaine" ("no such domain") au lieu d'être transmises
 aux serveurs de nom amont ("upstream server").
@@ -317,7 +324,7 @@ modifiera 1.2.3.56 en 6.7.8.56 et 1.2.3.67 en 6.7.8.67.
 Cette fonctionnalité correspond à ce que les routeurs Cisco PIX appellent
 "bidouillage DNS" ("DNS doctoring"). Si l'ancienne IP est donnée sous la forme
 d'une gamme d'adresses, alors seules les adresses dans cette gamme seront
-réecrites, et non le sous-réseau dans son ensemble. Ainsi,
+réécrites, et non le sous-réseau dans son ensemble. Ainsi,
 .B --alias=192.168.0.10-192.168.0.40,10.0.0.0,255.255.255.0
 fait correspondre 192.168.0.10->192.168.0.40 à 10.0.0.10->10.0.0.40
 .TP 
@@ -380,7 +387,7 @@ effectuer ses requêtes à tous les serveurs disponibles. Le résultat renvoyé
 au client sera celui fournit par le premier serveur ayant répondu.
 .TP
 .B --stop-dns-rebind
-Rejete (et enregistre dans le journal d'activité) les adresses dans la gamme
+Rejette (et enregistre dans le journal d'activité) les adresses dans la gamme
 d'adresses IP privée (au sens RFC1918) qui pourraient être renvoyées par les
 serveurs amonts suite à une résolution de nom. Cela bloque les attaques cherchant
 à détourner de leur usage les logiciels de navigation web ('browser') en s'en
@@ -389,13 +396,13 @@ servant pour découvrir les machines situées sur le réseau local.
 .B --rebind-localhost-ok
 Exclue 127.0.0/8 des vérifications de réassociation DNS. Cette gamme d'adresses
 est retournée par les serveurs Realtime Blackhole (RBL, utilisés dans la
-lutte contre le spam), la bloquer peut entraîner des disfonctionnements de ces
+lutte contre le spam), la bloquer peut entraîner des dysfonctionnements de ces
 services.
 .TP 
 .B  --rebind-domain-ok=[<domaine>]|[[/<domaine>/[<domaine>/]
 Ne pas détecter ni bloquer les actions de type dns-rebind pour ces domaines.
 Cette option peut prendre comme valeur soit un nom de domaine soit plusieurs
-noms de domains entourés par des '/', selon une syntaxe similaire à l'option
+noms de domaine entourés par des '/', selon une syntaxe similaire à l'option
 --server, c-à-d :
 .B  --rebind-domain-ok=/domaine1/domaine2/domaine3/
 .TP
@@ -474,7 +481,7 @@ serveur de nom. Il doit s'agir d'une des adresses IP appartenant à la machine s
 laquelle tourne Dnsmasq ou sinon la ligne sera ignorée et une erreur sera
 consignée dans le journal des événements, ou alors d'un nom d'interface. Si un nom
 d'interface est donné, alors les requêtes vers le serveur de nom seront envoyées
-depuis cette interface; si une adresse ip est donnée, alors l'adresse source de
+depuis cette interface; si une adresse IP est donnée, alors l'adresse source de
 la requête sera l'adresse en question. L'option query-port est ignorée pour tous
 les serveurs ayant une adresse source spécifiée, mais il est possible de la donner
 directement dans la spécification de l'adresse source. Forcer les requêtes à être
@@ -510,7 +517,7 @@ d'IP netfilter (ipset) indiqués. Domaines et sous-domaines sont résolus de la
 même façon que pour --address. Ces groupes d'IP doivent déjà exister. Voir
 ipset(8) pour plus de détails.
 .TP
-.B \-m, --mx-host=<nom de l'hôte>[[,<nom du MX>],<préference>]
+.B \-m, --mx-host=<nom de l'hôte>[[,<nom du MX>],<préférence>]
 Spécifie un enregistrement de type MX pour <nom de l'hôte> retournant le nom
 donné dans <nom du MX> (s'il est présent), ou sinon le nom spécifié dans
 l'option
@@ -612,7 +619,7 @@ l'enregistrement est donnée dans les données hexadécimales, qui peuvent
 être de la forme 01:23:45, 01 23 45,+012345 ou n'importe quelle combinaison.
 .TP
 .B --interface-name=<nom>,<interface>
-Définit un entregistrement DNS associant le nom avec l'adresse primaire sur
+Définit un enregistrement DNS associant le nom avec l'adresse primaire sur
 l'interface donnée en argument. Cette option spécifie un enregistrement de type
 A pour le nom donné en argument de la même façon que s'il était défini par une
 ligne de /etc/hosts, sauf que l'adresse n'est pas constante mais dépendante de
@@ -638,7 +645,7 @@ IPv6 pouvant commencer par '::', mais les noms DNS ne pouvant pas commencer
 par '-', si aucun préfixe n'est donné, un zéro est ajouté en début de nom.
 Ainsi, ::1 devient 0--1.
 
-La plage d'adresses peut-être de la forme
+La plage d'adresses peut être de la forme
 <adresse IP>,<adresse IP> ou <adresse IP>/<masque réseau>
 .TP
 .B --add-mac
@@ -647,7 +654,7 @@ amonts. Cela peut être utilisé dans un but de filtrage DNS par les serveurs
 amonts. L'adresse MAC peut uniquement être ajoutée si le requêteur est sur le
 même sous-réseau que le serveur dnsmasq. Veuillez noter que le mécanisme
 utilisé pour effectuer cela (une option EDNS0) n'est pas encore standardisée,
-aussi cette fonctionalité doit être considérée comme expérimentale. Notez
+aussi cette fonctionnalité doit être considérée comme expérimentale. Notez
 également qu'exposer les adresses MAC de la sorte peut avoir des implications
 en termes de sécurité et de vie privée. L'avertissement donné pour --add-subnet
 s'applique également ici.
@@ -659,19 +666,20 @@ longueur du préfixe : 32 (ou 128 dans le cas d'IPv6) transmet la totalité
 de l'adresse, 0 n'en transmet aucun mais marque néanmoins la requête ce qui
 fait qu'aucun serveur amont ne rajoutera d'adresse client. La valeur par
 défaut est zéro et pour IPv4 et pour IPv6. A noter que les serveurs amonts
-peuvent-être configurés pour retourner des valeurs différentes en fonction
+peuvent être configurés pour retourner des valeurs différentes en fonction
 de cette information mais que le cache de dnsmasq n'en tient pas compte.
-Si une instance de dnsmasq est configurée de telle maniêre que des valeurs
-différentes pourraient-être rencontrés, alors le cache devrait être désactivé.
+Si une instance de dnsmasq est configurée de telle manière que des valeurs
+différentes pourraient être rencontrées, alors le cache devrait être désactivé.
 .TP
 .B \-c, --cache-size=<taille>
 Définit la taille du cache de Dnsmasq. La valeur par défaut est de 150 noms.
-Définir une valeur de zéro désactive le cache.
+Définir une valeur de zéro désactive le cache. Remarque: la taille importante
+du cache a un impact sur les performances.
 .TP
 .B \-N, --no-negcache
 Désactive le "cache négatif". Le "cache négatif" permet à Dnsmasq de se souvenir
 des réponses de type "no such domain" fournies par les serveurs DNS en amont et
-de fournir les réponses sans avoir à re-transmettre les requêtes aux serveurs
+de fournir les réponses sans avoir à retransmettre les requêtes aux serveurs
 amont.
 .TP
 .B \-0, --dns-forward-max=<nombre de requêtes>
@@ -683,17 +691,17 @@ son journal des requêtes, ce qui peut générer un nombre important de requête
 simultanées.
 .TP
 .B --proxy-dnssec
-Un resolveur sur une machine cliente peut effectuer la validation DNSSEC de
+Un résolveur sur une machine cliente peut effectuer la validation DNSSEC de
 deux façons : il peut effectuer lui-même les opérations de chiffrements sur
 la réponse reçue, ou il peut laisser le serveur récursif amont faire la
 validation et positionner un drapeau dans la réponse au cas où celle-ci est
 correcte. Dnsmasq n'est pas un validateur DNSSEC, aussi il ne peut effectuer
 la validation comme un serveur de nom récursif, cependant il peut retransmettre
 les résultats de validation de ses serveurs amonts. Cette option permet
-l'activation de cette fonctionalité. Vous ne devriez utiliser cela que si vous
+l'activation de cette fonctionnalité. Vous ne devriez utiliser cela que si vous
 faites confiance aux serveurs amonts
 .I ainsi que le réseau entre vous et eux.
-Si vous utilisez le premier mode DNSSEC, la validation par le resolveur des
+Si vous utilisez le premier mode DNSSEC, la validation par le résolveur des
 clients, cette option n'est pas requise. Dnsmasq retourne toujours toutes les
 données nécessaires par un client pour effectuer la validation lui-même.
 .TP
@@ -703,12 +711,12 @@ Définie une zone DNS pour laquelle dnsmasq agit en temps que serveur faisant
 autorité. Les enregistrements DNS définis localement et correspondant à ce
 domaine seront fournis. Les enregistrements A et AAAA doivent se situer dans
 l'un des sous-réseaux définis, ou dans un réseau correspondant à une plage DHCP
-(ce comportement peut-être désactivé par
+(ce comportement peut être désactivé par
 .B constructor-noauth:
 ). Le ou les sous-réseaux sont également utilisé(s) pour définir les domaines
 in-addr.arpa et ip6.arpa servant à l'interrogation DNS inverse. Si la longueur
 de préfixe n'est pas spécifiée, elle sera par défaut de 24 pour IPv4 et 64 pour
-IPv6. Dans le cas d'IPv4, la longueur du masque de réseau devrait-être de 8, 16
+IPv6. Dans le cas d'IPv4, la longueur du masque de réseau devrait être de 8, 16
 ou 24, sauf si en cas de mise en place d'une délégation de la zone in-addr.arpa
 conforme au RFC 2317.
 .TP
@@ -719,7 +727,7 @@ optionnel, les valeurs par défaut devant convenir à la majorité des cas.
 .TP
 .B --auth-sec-servers=<domaine>[,<domaine>[,<domaine>...]]
 Spécifie un ou plusieurs serveur de nom secondaires pour une zone pour
-laquelle dnsmasq fait autorité. Ces serveurs doivent-être configurés pour
+laquelle dnsmasq fait autorité. Ces serveurs doivent être configurés pour
 récupérer auprès de dnsmasq les informations liées à la zone au travers d'un
 transfert de zone, et répondre aux requêtes pour toutes les zones pour
 lesquelles dnsmasq fait autorité.
@@ -733,7 +741,7 @@ seront acceptées pour tous les serveurs secondaires.
 .B --conntrack
 Lis le marquage de suivi de connexion Linux associé aux requêtes DNS entrantes
 et positionne la même marque au trafic amont utilisé pour répondre à ces
-requétes. Cela permet au trafic généré par Dnsmasq d'étre associé aux requêtes
+requêtes. Cela permet au trafic généré par Dnsmasq d'être associé aux requêtes
 l'ayant déclenché, ce qui est pratique pour la gestion de la bande passante
 (accounting) et le filtrage (firewall). Dnsmasq doit pour cela être compilé
 avec le support conntrack, le noyau doit également inclure conntrack et être
@@ -742,7 +750,7 @@ configuré pour cela. Cette option ne peut pas être combinée avec
 .TP
 .B \-F, --dhcp-range=[tag:<label>[,tag:<label>],][set:<label>],]<adresse de début>[,<adresse de fin>][,<mode>][,<masque de réseau>[,<broadcast>]][,<durée de bail>]
 .TP
-.B \-F, --dhcp-range=[tag:<label>[,tag:<label>],][set:<label>],]<addresse IPv6 de début>[,<adresse IPv6 de fin>|constructor:<interface>][,<mode>][,<longueur de préfixe>][,<durée de bail>]
+.B \-F, --dhcp-range=[tag:<label>[,tag:<label>],][set:<label>],]<adresse IPv6 de début>[,<adresse IPv6 de fin>|constructor:<interface>][,<mode>][,<longueur de préfixe>][,<durée de bail>]
 
 Active le serveur DHCP. Les adresses seront données dans la plage comprise entre
 <adresse de début> et <adresse de fin> et à partir des adresses définies
@@ -755,7 +763,7 @@ durée indéterminée. Si aucune valeur n'est donnée, une durée de bail par d
 de une heure est appliquée. La valeur minimum pour un bail DHCP est de 2
 minutes.
 
-Pour les plages IPv6, la durée de bail peut-être égale au mot-clef "deprecated"
+Pour les plages IPv6, la durée de bail peut être égale au mot-clef "deprecated"
 (obsolète); Cela positionne la durée de vie préférée envoyée dans les baux DHCP
 ou les annonces routeurs à zéro, ce qui incite les clients à utiliser d'autres
 adresses autant que possible, pour toute nouvelle connexion, en préalable à
@@ -795,7 +803,7 @@ adresses assignées à l'interface. Par exemple
 provoque la recherche d'adresses de la forme <réseau>::1 sur eth0 et crée une
 plage allant de <réseau>::1 à <réseau>:400. Si une interface est assignée à
 plus d'un réseau, les plages correspondantes seront automatiquement créées,
-rendues obsolètes puis supprimées lorsque l'adress est rendue obsolète puis
+rendues obsolètes puis supprimées lorsque l'adresse est rendue obsolète puis
 supprimée. Le nom de l'interface peut être spécifié avec un caractère joker '*'
 final.
 
@@ -809,7 +817,7 @@ obsolètes ne conviennent pas.
 
 Si une plage dhcp-range est uniquement utilisée pour du DHCP sans-état
 ("stateless") ou de l'autoconfiguration sans état ("SLAAC"), alors l'adresse
-peut-être indiquée sous la forme '::'
+peut être indiquée sous la forme '::'
 
 .B --dhcp-range=::,constructor:eth0
 
@@ -851,7 +859,7 @@ et
 .B pxe-service
 pour plus de détails).
 
-Pour IPv6, le mode peut-être une combinaison des valeurs
+Pour IPv6, le mode peut être une combinaison des valeurs
 .B ra-only, slaac, ra-names, ra-stateless, off-link.
 
 .B ra-only
@@ -883,7 +891,7 @@ connectés (et non ceux pour lesquels DHCP se fait via relai), et ne
 fonctionnera pas si un hôte utilise les "extensions de vie privée"
 ("privacy extensions").
 .B ra-names
-peut-être combiné avec
+peut être combiné avec
 .B ra-stateless
 et
 .B slaac.
@@ -914,7 +922,7 @@ sous-réseau qu'une plage dhcp-range valide. Pour les sous-réseaux qui n'ont pa
 besoin d'adresses dynamiquement allouées, utiliser le mot-clef "static" dans la
 déclaration de plage d'adresses dhcp-range.
 
-Il est possible d'utiliser des identifiants clients (appel "DUID client" dans
+Il est possible d'utiliser des identifiants clients (appelés "DUID client" dans
 le monde IPv6) plutôt que des adresses matérielles pour identifier les hôtes,
 en préfixant ceux-ci par 'id:'. Ainsi, 
 .B --dhcp-host=id:01:02:03:04,..... 
@@ -926,7 +934,7 @@ ceci :
 Un seul
 .B dhcp-host 
 peut contenir une adresse IPv4, une adresse IPv6, ou les deux en même temps.
-Les adresses IPv6 doivent-être mises entre crochets comme suit :
+Les adresses IPv6 doivent être mises entre crochets comme suit :
 .B --dhcp-host=laptop,[1234::56]
 Les adresses IPv6 peuvent ne contenir que la partie identifiant de client :
 .B --dhcp-host=laptop,[::56]
@@ -945,7 +953,7 @@ identifiant client mais pas les autres.
 Si un nom apparaît dans /etc/hosts, l'adresse associée peut être allouée à un
 bail DHCP mais seulement si une option
 .B --dhcp-host
-spécifiant le nom existe par ailleurs. Seul un nom d'hôte peut-être donné dans
+spécifiant le nom existe par ailleurs. Seul un nom d'hôte peut être donné dans
 une option
 .B dhcp-host
 , mais les alias sont possibles au travers de l'utilisation des CNAMEs. (Voir
@@ -973,7 +981,7 @@ Les adresses ethernet (mais pas les identifiants clients) peuvent être définie
 avec des octets joker, ainsi par exemple
 .B --dhcp-host=00:20:e0:3b:13:*,ignore 
 demande à Dnsmasq d'ignorer une gamme d'adresses matérielles. Il est  à noter
-que "*" doit-être précédé d'un caractère d'échappement ou mis entre guillemets
+que "*" doit être précédé d'un caractère d'échappement ou mis entre guillemets
 lorsque spécifié en option de ligne de commande, mais pas dans le fichier de
 configuration.
 
@@ -1059,14 +1067,14 @@ qu'aux réseaux dont tous les labels coïncident avec ceux de la requête.
 Un traitement spécial est effectué sur les chaînes de caractères fournies pour
 l'option 119, conformément à la RFC 3397. Les chaînes de caractères ou les
 adresses IP sous forme de 4 chiffres séparés par des points donnés en arguments
-de l'option 120 sont traités conforméments à la RFC 3361. Les adresses IP sous
+de l'option 120 sont traités conformément à la RFC 3361. Les adresses IP sous
 forme de 4 chiffres séparés par des points suivies par une barre montante "/",
-puis une taille de masque sont encodés conforméments à la RFC 3442.
+puis une taille de masque sont encodés conformément à la RFC 3442.
 
 Les options IPv6 sont fournies en utilisant le mot-clef
 .B option6:
 suivi par le numéro d'option ou le nom d'option. L'espace de nommage des options
-IPv6 est disjint de l'espace de nommage des options IPv4. Les adresses IPv6
+IPv6 est disjoint de l'espace de nommage des options IPv4. Les adresses IPv6
 en option doivent être entourées de crochets, comme par exemple :
 .B --dhcp-option=option6:ntp-server,[1234::56]
 
@@ -1075,7 +1083,7 @@ adéquat sont envoyées pour un numéro d'option donné, il est tout à fait pos
 de persuader Dnsmasq de générer des paquets DHCP illégaux par une utilisation
 incorrecte de cette option. Lorsque la valeur est un nombre décimal, Dnsmasq
 doit déterminer la taille des données. Cela est fait en examinant le numéro de
-l'option et/ou la valeur, mais peut-être évité en rajoutant un suffixe d'une
+l'option et/ou la valeur, mais peut être évité en rajoutant un suffixe d'une
 lettre comme suit :
 b = un octet, s = 2 octets, i = 4 octets. Cela sert essentiellement pour des
 options encapsulées de classes de vendeurs (voir plus bas), pour lesquelles 
@@ -1088,7 +1096,7 @@ d'une chaîne de caractères comme nom de serveur TFTP, il est nécessaire de fa
 comme suit :
 .B --dhcp-option=66,"1.2.3.4"
 
-Les options encapsulées de classes de vendeurs peuvent-être aussi spécifiées 
+Les options encapsulées de classes de vendeurs peuvent être aussi spécifiées
 (pour IPv4 seulement) en utilisant
 .B --dhcp-option
 : par exemple
@@ -1105,7 +1113,7 @@ par le client. Il est possible d'omettre complètement une classe de vendeur :
 .B --dhcp-option=vendor:,1,0.0.0.0
 Dans ce cas l'option encapsulée est toujours envoyée.
 
-En IPv4, les options peuvent-être encapsulées au sein d'autres options :
+En IPv4, les options peuvent être encapsulées au sein d'autres options :
 par exemple
 .B --dhcp-option=encap:175, 190, "iscsi-client0"
 enverra l'option 175, au sein de laquelle se trouve l'option 190.
@@ -1128,7 +1136,7 @@ une option encapsulée.
 Cela fonctionne exactement de la même façon que
 .B --dhcp-option
 sauf que cette option sera toujours envoyée, même si le client ne la demande pas
-dans la liste de paramêtres requis. Cela est parfois nécessaire, par exemple lors
+dans la liste de paramètres requis. Cela est parfois nécessaire, par exemple lors
 de la fourniture d'options à PXELinux.
 .TP
 .B --dhcp-no-override
@@ -1149,10 +1157,10 @@ Toutes les requêtes DHCP arrivant sur cette interface seront relayées au
 serveur DHCP distant correspondant à l'adresse de serveur indiquée. Il est
 possible de relayer depuis une unique adresse locale vers différents serveurs
 distant en spécifiant plusieurs fois l'option dhcp-relay avec la même adresse
-locale et différentes adresses de serveur. L'adresse de serveur doit-être
-sous forme numérique. Dans le cas de DHCPv6, l'adresse de serveur peut-être
+locale et différentes adresses de serveur. L'adresse de serveur doit être
+sous forme numérique. Dans le cas de DHCPv6, l'adresse de serveur peut être
 l'adresse de multicast ff05::1:3 correspondant à tous les serveurs DHCP. Dans
-ce cas, l'interface doittre spécifiée et ne peut comporter de caractère
+ce cas, l'interface doit être spécifiée et ne peut comporter de caractère
 joker. Elle sera utilisée pour indiquer l'interface à partir de laquelle le
 multicast pourra atteindre le serveur DHCP.
 
@@ -1181,14 +1189,14 @@ vice-versa.
 Associe une chaîne de classe de vendeur à un label. La plupart
 des clients DHCP fournissent une "classe de vendeur" ("vendor class") qui
 représente, d'une certaine façon, le type d'hôte. Cette option associe des
-classes de vendeur à des labels, de telle sorte que des options DHCP peuvent-être
-fournie de manière sélective aux différentes classes d'hôtes. Par exemple,
+classes de vendeur à des labels, de telle sorte que des options DHCP peuvent être
+fournies de manière sélective aux différentes classes d'hôtes. Par exemple,
 .B dhcp-vendorclass=set:printers,Hewlett-Packard JetDirect
 ou
 .B dhcp-vendorclass=printers,Hewlett-Packard JetDirect
 permet de n'allouer des options qu'aux imprimantes HP de la manière suivante :
 .B --dhcp-option=tag:printers,3,192.168.4.4
-La chaîne de caractères de la classe de vendeur founie en argument est cherchée
+La chaîne de caractères de la classe de vendeur fournie en argument est cherchée
 en temps que sous-chaîne de caractères au sein de la classe de vendeur fournie
 par le client, de façon à permettre la recherche d'un sous-ensemble de la chaîne
 de caractères ("fuzzy matching"). Le préfixe set: est optionnel mais autorisé
@@ -1218,7 +1226,7 @@ matérielle coïncide avec les critères définis.
 .TP
 .B --dhcp-circuitid=set:<label>,<identifiant de circuit>, --dhcp-remoteid=set:<label>,<identifiant distant>
 Associe des options de relais DHCP issus de la RFC3046 à des labels.
-Cette information peut-être fournie par des relais DHCP. L'identifiant
+Cette information peut être fournie par des relais DHCP. L'identifiant
 de circuit ou l'identifiant distant est normalement fourni sous la forme d'une
 chaîne de valeurs hexadécimales séparées par des ":", mais il est également
 possible qu'elle le soit sous la forme d'une simple chaîne de caractères. Si
@@ -1231,7 +1239,7 @@ est supporté en IPv6 (mais non dhcp-circuitid).
 (IPv4 et IPv6) Associe des options de relais DHCP issues de la RFC3993 à des
 labels.
 .TP
-.B --dhcp-proxy[=<adresse ip>]......
+.B --dhcp-proxy[=<adresse IP>]......
 (IPv4 seulement) Un agent relai DHCP normal est uniquement utilisé pour faire
 suivre les éléments initiaux de l'interaction avec le serveur DHCP. Une fois
 que le client est configuré, il communique directement avec le serveur. Cela
@@ -1252,7 +1260,7 @@ interactions avec les relais dont l'adresse est dans la liste seront affectées.
 Si aucune valeur n'est spécifiée, associe le label si le client
 envoie une option DHCP avec le numéro ou le nom spécifié. Lorsqu'une valeur est
 fournie, positionne le label seulement dans le cas où l'option est fournie et
-correspond à la valeur. La valeur peut-être de la forme "01:ff:*:02", auquel
+correspond à la valeur. La valeur peut être de la forme "01:ff:*:02", auquel
 cas le début de l'option doit correspondre (en respectant les jokers). La
 valeur peut aussi être de la même forme que dans
 .B dhcp-option
@@ -1262,14 +1270,14 @@ valeur peut aussi être de la même forme que dans
 --dhcp-match=set:efi-ia32,option:client-arch,6
 
 spécifie le label "efi-ia32" si le numéro 6 apparaît dnas la liste
-d'architectures envoyé par le client au sein de l'option 93. (se réferer
+d'architectures envoyé par le client au sein de l'option 93. (se référer
 au RFC 4578 pour plus de détails). Si la valeur est un chaine de caractères,
 celle-ci est recherchée (correspondance en temps que sous-chaîne).
 
 Pour la forme particulière vi-encap:<numéro d'entreprise>, la comparaison se
 fait avec les classes de vendeur "identifiant de vendeur" ("vendor-identifying
 vendor classes") pour l'entreprise dont le numéro est fourni en option.
-Veuillez vous réferer à la RFC 3925 pour plus de détail.
+Veuillez vous référer à la RFC 3925 pour plus de détails.
 .TP
 .B --tag-if=set:<label>[,set:<label>[,tag:<label>[,tag:<label>]]]
 Effectue une opération booléenne sur les labels. Si tous les labels
@@ -1280,7 +1288,7 @@ Si aucun tag:<label> n'est spécifié, alors tous les labels fournis par
 set:<label> sont positionnés.
 N'importe quel nombre de set: ou tag: peuvent être fournis, et l'ordre est sans
 importance.
-Les lignes tag-if sont executées dans l'ordre, ce qui fait que si un label dans
+Les lignes tag-if sont exécutées dans l'ordre, ce qui fait que si un label dans
 tag:<label> est un label positionné par une rêgle
 .B tag-if,
 la ligne qui positionne le label doit précéder celle qui le teste.
@@ -1320,17 +1328,17 @@ le cas de certains vieux clients BOOTP.
 (IPv4 seulement) Spécifie les options BOOTP devant être retournées par le
 serveur DHCP. Le nom de serveur ainsi que l'adresse sont optionnels : s'ils
 ne sont pas fournis, le nom est laissé vide et l'adresse fournie est celle de
-la machine sur laquelle s'exécute Dnsmasq. Si Dnsmasq founit un service TFTP (voir
+la machine sur laquelle s'exécute Dnsmasq. Si Dnsmasq fournit un service TFTP (voir
 .B --enable-tftp
 ), alors seul un nom de fichier est requis ici pour permettre un démarrage par
 le réseau.
 Si d'éventuels labels sont fournis, ils doivent coïncider avec
-ceux du client pour que cet élement de configuration lui soit envoyé.
+ceux du client pour que cet élément de configuration lui soit envoyé.
 Une adresse de serveur TFTP peut être spécifiée à la place de l'adresse IP,
 sous la forme d'un nom de domaine qui sera cherché dans le fichier /etc/hosts.
 Ce nom peut être associé dans /etc/hosts avec plusieurs adresses IP, auquel cas
 celles-ci seront utilisées tour à tour (algorithme round-robin).
-Cela peut-être utiliser pour équilibrer la charge tftp sur plusieurs serveurs.
+Cela peut être utilisé pour équilibrer la charge tftp sur plusieurs serveurs.
 .TP
 .B --dhcp-sequential-ip
 Dnsmasq est conçu pour choisir l'adresse IP des clients DHCP en utilisant
@@ -1346,6 +1354,13 @@ Veuillez noter que dans ce mode séquentiel, les clients qui laissent expirer
 leur bail ont beaucoup plus de chance de voir leur adresse IP changer, aussi
 cette option ne devrait pas être utilisée dans un cas général.
 .TP
+.B --dhcp-ignore-clid
+Dnsmasq lit l'option 'client identifier' (RFC 2131) envoyée par les clients
+(si disponible) afin d'identifier les clients. Cela permet de distribuer la
+même adresse IP à un client utilisant plusieurs interfaces. Activer cette option
+désactive la lecture du 'client identifier', afin de toujours identifier un client
+en utilisant l'adresse MAC.
+.TP
 .B --pxe-service=[tag:<label>,]<CSA>,<entrée de menu>[,<nom de fichier>|<type de service de démarrage>][,<adresse de serveur>|<nom de serveur>]
 La plupart des ROMS de démarrage PXE ne permettent au système PXE que la simple
 obtention d'une adresse IP, le téléchargement du fichier spécifié dans
@@ -1357,7 +1372,7 @@ Ceci spécifie l'option de démarrage qui apparaitra dans un menu de démarrage
 PXE. <CSA> est le type du système client. Seuls des types de services valides
 apparaitront dans un menu. Les types connus sont x86PC, PC98, IA64_EFI, Alpha,
 Arc_x86, Intel_Lean_Client, IA32_EFI, BC_EFI, Xscale_EFI et X86-64_EFI;
-D'autres types peuvent-être spécifiés sous la forme d'une valeur entière. Le
+D'autres types peuvent être spécifiés sous la forme d'une valeur entière. Le
 paramètre après le texte correspondant à l'entrée dans le menu peut être un nom
 de fichier, auquel cas Dnsmasq agit comme un serveur de démarrage et indique au
 client PXE qu'il faut télécharger ce fichier via TFTP, soit depuis ce serveur
@@ -1376,7 +1391,7 @@ démarrage n'est fournie (ou qu'une valeur de 0 est donnée pour le type de
 service), alors l'entrée de menu provoque l'interruption du démarrage par
 le réseau et la poursuite du démarrage sur un média local. L'adresse de serveur
 peut être donnée sous la forme de nom de domaine qui est recherché dans
-/etc/hosts. Ce nom peut-être associé à plusieurs adresses IP, qui dans ce cas
+/etc/hosts. Ce nom peut être associé à plusieurs adresses IP, qui dans ce cas
 sont utilisées à tour de rôle (en "round-robin").
 .TP
 .B --pxe-prompt=[tag:<label>,]<invite>[,<délai>]
@@ -1435,7 +1450,7 @@ Utiliser cette option avec précaution, une adresse allouée à un client BOOTP
 étant perpétuelle, et de fait n'est plus disponibles pour d'autres hôtes. Si
 aucun argument n'est donné, alors cette option permet une allocation dynamique
 dans tous les cas. Si des arguments sont spécifiés, alors l'allocation ne se
-fait que lorsque tous les identifiants coïncident. Il est possible de répeter
+fait que lorsque tous les identifiants coïncident. Il est possible de répéter
 cette option avec plusieurs jeux d'arguments.
 .TP
 .B \-5, --no-ping
@@ -1560,7 +1575,7 @@ Tous les descripteurs de fichiers sont fermés, sauf stdin, stdout et stderr qui
 sont ouverts sur /dev/null (sauf en mode déverminage).
 
 Le script n'est pas lancé de manière concurrente : au plus une instance du
-script est executée à la fois (dnsmasq attends qu'une instance de script se
+script est exécutée à la fois (dnsmasq attend qu'une instance de script se
 termine avant de lancer la suivante). Les changements dans la base des baux
 nécessitant le lancement du script sont placé en attente dans une queue jusqu'à
 terminaison d'une instance du script en cours. Si cette mise en queue fait que
@@ -1575,7 +1590,7 @@ le script sera invoqué avec une action "old" pour tous les baux existants.
 
 Il existe deux autres actions pouvant apparaître comme argument au script :
 "init" et "tftp". D'autres sont susceptibles d'être rajoutées dans le futur,
-aussi les scripts devraient-être écrits de sorte à ignorer les actions
+aussi les scripts devraient être écrits de sorte à ignorer les actions
 inconnues. "init" est décrite ci-dessous dans
 .B --leasefile-ro.
 L'action "tftp" est invoquée lorsqu'un transfert de fichier TFTP s'est
@@ -1588,7 +1603,7 @@ Spécifie un script écrit en Lua, devant être exécuté lorsque des baux sont
 créés, détruits ou modifiés. Pour utiliser cette option, dnsmasq doit être
 compilé avec avec le support de Lua. L'interpréteur Lua est initialisé une
 seule fois, lorsque dnsmasq démarre, ce qui fait que les variables globales
-persistent entre les Ã©vênements liés aux baux. Le code Lua doit définir une
+persistent entre les Ã©vénements liés aux baux. Le code Lua doit définir une
 fonction
 .B lease
 et peut fournir des fonctions
@@ -1637,7 +1652,7 @@ et
 .B --dhcp-scriptuser
 Spécifie l'utilisateur sous lequel le script shell lease-change ou le script
 doivent être exécutés. La valeur par défaut correspond à l'utilisateur root
-mais peut-être changée par le biais de cette option.
+mais peut être changée par le biais de cette option.
 .TP
 .B \-9, --leasefile-ro
 Supprimer complètement l'usage du fichier servant de base de donnée pour les
@@ -1649,8 +1664,8 @@ biais de l'option
 être complètement gérée par le script sur un stockage externe. En addition aux
 actions décrites dans 
 .B  --dhcp-script,
-le script de changement d'état de bail est appellé une fois, au lancement de
-Dnsmasq, avec pour seul argument "init". Lorsqu'appellé de la sorte, le script
+le script de changement d'état de bail est appelé une fois, au lancement de
+Dnsmasq, avec pour seul argument "init". Lorsqu'appelé de la sorte, le script
 doit fournir l'état de la base de baux, dans le format de fichier de baux de
 Dnsmasq, sur sa sortie standard (stdout) et retourner un code de retour de 0.
 Positionner cette option provoque également une invocation du script de
@@ -1692,20 +1707,20 @@ positionné à la première valeur de la directive "search" du fichier
 /etc/resolv.conf (ou équivalent).
 
 La gamme d'adresses peut être de la forme
-<adresse ip>,<adresse ip> ou <adresse ip>/<masque de réseau> voire une simple
-<adresse ip>. Voir
+<adresse IP>,<adresse IP> ou <adresse IP>/<masque de réseau> voire une simple
+<adresse IP>. Voir
 .B --dhcp-fqdn
 qui peut changer le comportement de dnsmasq relatif aux domaines.
 
 Si la gamme d'adresse est fournie sous la forme
-<adresse ip>/<taille de réseau>, alors le drapeau "local" peut-être rajouté
-qui a pour effect d'ajouter --local-declarations aux requêtes DNS directes et
+<adresse IP>/<taille de réseau>, alors le drapeau "local" peut être rajouté
+qui a pour effet d'ajouter --local-declarations aux requêtes DNS directes et
 inverses. C-à-d
 .B --domain=thekelleys.org.uk,192.168.0.0/24,local
 est identique à
 .B --domain=thekelleys.org.uk,192.168.0.0/24
 --local=/thekelleys.org.uk/ --local=/0.168.192.in-addr.arpa/
-La taille de réseau doit-être de 8, 16 ou 24 pour être valide.
+La taille de réseau doit être de 8, 16 ou 24 pour être valide.
 .TP
 .B --dhcp-fqdn
 Dans le mode par défaut, dnsmasq insère les noms non-qualifiés des clients
@@ -1717,8 +1732,8 @@ ce nom est transféré au nouveau client. Si
 est spécifié, ce comportement change : les noms non qualifiés ne sont plus
 rajoutés dans le DNS, seuls les noms qualifiés le sont. Deux clients DHCP
 avec le même nom peuvent tous les deux garder le nom, pour peu que la partie
-relative au domaine soit différente (c-à-d que les noms pleinements qualifiés
-diffèrent). Pour d'assurer que tous les noms ont une partie domaine, il doit-y
+relative au domaine soit différente (c-à-d que les noms pleinement qualifiés
+diffèrent). Pour s'assurer que tous les noms ont une partie domaine, il doit y
 avoir au moins un
 .B --domain
 sans gamme d'adresses de spécifié lorsque l'option
@@ -1735,7 +1750,7 @@ Windows de la mise à jour de serveurs Active Directory. Voir la RFC 4702 pour
 plus de détails.
 .TP
 .B --enable-ra
-Active la fonctionalité d'annonces routeurs IPv6 ("IPv6 Router Advertisement").
+Active la fonctionnalité d'annonces routeurs IPv6 ("IPv6 Router Advertisement").
 DHCPv6 ne gère pas la configuration complète du réseau de la même façon que
 DHCPv4. La découverte de routeurs et la découverte (éventuelle) de préfixes pour
 la création autonome d'adresse sont gérées par un protocole différent.
@@ -1747,7 +1762,7 @@ dhcp-range et, par défaut, fournir comme valeur de routeur et de DNS récursif
 la valeur d'adresse link-local appropriée parmi celles de la machine sur
 laquelle tourne dnsmasq.
 Par défaut, les bits "managed address" sont positionnés, et le bit "use SLAAC"
-("utiliser SLAAC") est réinitialisé. Cela peut-être changé pour des
+("utiliser SLAAC") est réinitialisé. Cela peut être changé pour des
 sous-réseaux donnés par le biais du mot clef de mode décris dans
 .B --dhcp-range.
 Les paramètres DNS du RFC6106 sont inclus dans les annonces. Par défaut,
@@ -1759,16 +1774,16 @@ DNSSL.
 .B --ra-param=<interface>,[mtu:<valeur>|<interface>|off,][high,|low,]<intervalle d'annonce routeur>[,<durée de vie route>]
 Configure pour une interface donnée des valeurs pour les annonces routeurs
 différentes des valeurs par défaut. La valeur par défaut du champ priorité
-pour le routeur peut-être changée de "medium" (moyen) à "high" (haute) ou
+pour le routeur peut être changée de "medium" (moyen) à "high" (haute) ou
 "low" (basse). Par exemple :
 .B --ra-param=eth0,high,0.
-Un intervalle (en secondes) entre les annonces routeur peut-être fourni par :
+Un intervalle (en secondes) entre les annonces routeur peut être fourni par :
 .B --ra-param=eth0,60.
-La durée de vie de la route peut-être changée ou mise à zéro, auquel cas 
+La durée de vie de la route peut être changée ou mise à zéro, auquel cas
 le routeur peut annoncer les préfixes mais pas de route :
-.B --ra-parm=eth0,0,0
+.B --ra-param=eth0,0,0
 (une valeur de zéro pour l'intervalle signifie qu'il garde la valeur par défaut).
-Ces quatre paramètres peuvent-être configurés en une fois :
+Ces quatre paramètres peuvent être configurés en une fois :
 .B --ra-param=eth0,mtu:1280,low,60,1200
 La valeur pour l'interface peut inclure un caractère joker.
 .TP
@@ -1776,7 +1791,7 @@ La valeur pour l'interface peut inclure un caractère joker.
 Active la fonction serveur TFTP. Celui-ci est de manière délibérée limité aux
 fonctions nécessaires au démarrage par le réseau ("net-boot") d'un client. Seul
 un accès en lecture est possible; les extensions tsize et blksize sont supportées
-(tsize est seulement supporté en mode octet). Sans argument optionel, le service
+(tsize est seulement supportée en mode octet). Sans argument optionnel, le service
 TFTP est fourni sur les mêmes interfaces que le service DHCP. Si une liste
 d'interfaces est fournie, cela définit les interfaces sur lesquelles le
 service TFTP sera activé.
@@ -1847,9 +1862,9 @@ Un serveur TFTP écoute sur le port prédéfini 69 ("well-known port") pour
 l'initiation de la connexion, mais utilise également un port dynamiquement
 alloué pour chaque connexion. Normalement, ces ports sont alloués par
 le système d'exploitation, mais cette option permet de spécifier une gamme
-de ports à utiliser pour les transferts TFTP. Cela peut-être utile si
+de ports à utiliser pour les transferts TFTP. Cela peut être utile si
 TFTP doit traverser un dispositif garde-barrière ("firewall"). La valeur
-de début pour la plage de port ne peut-être inférieure à 1025 sauf si
+de début pour la plage de port ne peut être inférieure à 1025 sauf si
 dnsmasq tourne en temps que super-utilisateur ("root"). Le nombre de
 connexions TFTP concurrentes est limitée par la taille de la gamme de
 ports ainsi spécifiée.
@@ -1859,8 +1874,8 @@ Un serveur TFTP écoute sur un numéro de port bien connu (69) pour l'initiation
 de la connexion, et alloue dynamiquement un port pour chaque connexion. Ces
 numéros de ports sont en principe alloués par le système d'exploitation, mais
 cette option permet de spécifier une gamme de ports à utiliser pour les
-transferts TFTP. Cela peut-être utile lorsque ceux-ci doivent traverser un
-dispositif garde-barrière ("firewall"). Le début de la plage ne peut-être
+transferts TFTP. Cela peut être utile lorsque ceux-ci doivent traverser un
+dispositif garde-barrière ("firewall"). Le début de la plage ne peut être
 inférieur à 1024 à moins que Dnsmasq ne fonctionne en temps que
 super-utilisateur ("root"). Le nombre maximal de connexions TFTP concurrentes
 est limitée par la taille de la plage de ports ainsi définie. 
@@ -1895,7 +1910,7 @@ par "--". Les lignes commençant par # sont des commentaires et sont ignorées.
 Pour les options qui ne peuvent-être spécifiées qu'une seule fois, celle du
 fichier de configuration prends le pas sur celle fournie en ligne de commande.
 Il est possible d'utiliser des guillemets afin d'éviter que les ",",":","." et
-"#" ne soit interprêtés, et il est possible d'utiliser les séquences
+"#" ne soient interprétés, et il est possible d'utiliser les séquences
 d'échappement suivantes : \\\\ \\" \\t \\e \\b \\r et \\n. Elles correspondent
 respectivement à la barre oblique descendante ("anti-slash"), guillemets doubles,
 tabulation, caractère d'échappement ("escape"), suppression ("backspace"), retour ("return") et
@@ -1940,8 +1955,8 @@ traces dans un fichier (voir
 .B --log-facility
 ), alors 
 .B Dnsmasq
-ferme et re-rouvre le fichier de traces. Il faut noter que pendant cette
-opération Dnsmasq ne s'exécute pas en temps que "root". Lorsqu'il créé un
+ferme et rouvre le fichier de traces. Il faut noter que pendant cette
+opération Dnsmasq ne s'exécute pas en tant que "root". Lorsqu'il créé un
 fichier de traces pour la première fois, Dnsmasq change le propriétaire du
 fichier afin de le faire appartenir à l'utilisateur non "root" sous lequel
 Dnsmasq s'exécute. Le logiciel de rotation de fichiers de trace logrotate doit
@@ -1983,7 +1998,7 @@ qu'une connexion PPP ne soit établie. Dans ce cas, Dnsmasq vérifie régulière
 pour voir si un fichier
 .I /etc/resolv.conf 
 est créé. Dnsmasq peut être configuré pour lire plus d'un fichier resolv.conf.
-Cela est utile sur un ordinateur portable où PPP et DHCP peuvent-être utilisés :
+Cela est utile sur un ordinateur portable où PPP et DHCP peuvent être utilisés :
 Dnsmasq peut alors être configuré pour lire à la fois
 .I /etc/ppp/resolv.conf 
 et
@@ -2007,7 +2022,7 @@ ou alors en mettant leurs adresses dans un autre fichier, par exemple
 .I /etc/resolv.dnsmasq
 et en lançant Dnsmasq avec l'option
 .B \-r /etc/resolv.dnsmasq.
-Cette deuxième technique permet la mise-à-jour dynamique des addresses de
+Cette deuxième technique permet la mise-à-jour dynamique des adresses de
 serveurs DNS amont par le biais de PPP ou DHCP.
 .PP
 Les adresses dans /etc/hosts prennent le dessus sur celles fournies par le
@@ -2067,10 +2082,10 @@ et pour affecter l'option envoyée, sur la base de la plage sélectionnée.
 
 Ce système a évolué d'un système plus ancien et aux possibilités plus limitées,
 et pour des raisons de compatibilité "net:" peut être utilisé à la place de
-"tag:" et "set:" peut-être omis (à l'exception de
+"tag:" et "set:" peut être omis (à l'exception de
 .B dhcp-host,
-où "net:" peut-être utilisé à la place de "set:"). Pour les mêmes raisons, '#'
-peut-être utilisé à la place de '!' pour indiquer la négation.
+où "net:" peut être utilisé à la place de "set:"). Pour les mêmes raisons, '#'
+peut être utilisé à la place de '!' pour indiquer la négation.
 .PP 
 Le serveur DHCP intégré dans Dnsmasq fonctionne également en temps que serveur
 BOOTP, pour peu que l'adresse MAC et l'adresse IP des clients soient fournies,
@@ -2097,7 +2112,7 @@ scénarios de complexité croissante. Le pré-requis pour chacun de ces scénari
 est l'existence d'une adresse IP globalement disponible, d'un enregistrement de
 type A ou AAAA pointant vers cette adresse, ainsi que d'un serveur DNS externe
 capable d'effectuer la délégation de la zone en question. Pour la première
-partie de ces explications, nous allons appeller serveur.exemple.com
+partie de ces explications, nous allons appeler serveur.exemple.com
 l'enregistrement A (ou AAAA) de l'adresse globalement accessible, et
 notre.zone.com la zone pour laquelle dnsmasq fait autorité.
 
@@ -2138,11 +2153,11 @@ notre.zone.com            NS    our.zone.com
 .fi
 
 L'enregistrement A pour notre.zone.com est dorénavant un enregistrement "colle"
-qui résoud le problème de poule et d'oeuf consistant à trouver l'adresse IP
+qui résout le problème de poule et d'oeuf consistant à trouver l'adresse IP
 du serveur de nom pour notre.zone.com lorsque l'enregistrement se trouve dans
 la zone en question. Il s'agit du seul rôle de cet enregistrement : comme dnsmasq
 fait désormais autorité pour notre.zone.com, il doit également fournir cet
-enregistrement. Si l'adresse externe est statique, cela peut-être réalisé par
+enregistrement. Si l'adresse externe est statique, cela peut être réalisé par
 le biais d'une entrée dans
 .B /etc/hosts 
 ou via un
@@ -2194,7 +2209,7 @@ spécifiques, vous pouvez le faire via :
 Dnsmasq joue le rôle de serveur faisant autorité pour les domaines in-addr.arpa
 et ip6.arpa associés aux sous-réseaux définis dans la déclaration de zone
 auth-zone, ce qui fait que les requêtes DNS inversées (de l'adresse vers
-le nom) peuvent-simplement être configurées avec un enregistrement NS
+le nom) peuvent simplement être configurées avec un enregistrement NS
 adéquat. Par exemple, comme nous définissons plus haut les adresses
 1.2.3.0/24 :
 .nf
@@ -2243,7 +2258,7 @@ celui fourni par
 .B --domain.
 Si l'option
 .B --dhcp-fqdn
-est fournie, alors les noms pleinemenet qualifiés associés aux baux DHCP
+est fournie, alors les noms pleinement qualifiés associés aux baux DHCP
 sont utilisés, dès lors qu'ils correspondent au nom de domaine associé
 à la zone.
 
@@ -2282,7 +2297,7 @@ Dnsmasq est capable de gérer le DNS et DHCP pour au moins un millier de clients
 Pour cela, la durée des bail ne doit pas être très courte (moins d'une heure).
 La valeur de
 .B --dns-forward-max 
-peut-être augmentée : commencer par la rendre égale au nombre de clients et
+peut être augmentée : commencer par la rendre égale au nombre de clients et
 l'augmenter si le DNS semble lent. Noter que la performance du DNS dépends
 également de la performance des serveurs amonts. La taille du cache DNS peut-
 être augmentée : la limite en dur est de 10000 entrées et la valeur par défaut
@@ -2306,7 +2321,7 @@ Il est possible d'utiliser Dnsmasq pour bloquer la publicité sur la toile
 en associant des serveurs de publicité bien connus à l'adresse 127.0.0.1 ou
 0.0.0.0 par le biais du fichier
 .B /etc/hosts 
-ou d'un fichier d'hôte additionnel. Cette liste peut-être très longue, Dnsmasq
+ou d'un fichier d'hôte additionnel. Cette liste peut être très longue, Dnsmasq
 ayant été testé avec succès avec un million de noms. Cette taille de fichier
 nécessite un processeur à 1 Ghz et environ 60 Mo de RAM.
 
index a8a83e0..6e80188 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -9,84 +9,84 @@
 # Simon Kelley <simon@thekelleys.org.uk>, 2005.
 msgid ""
 msgstr ""
-"Project-Id-Version: dnsmasq 2.77\n"
+"Project-Id-Version: dnsmasq 2.81\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2009-06-18 12:24+0100\n"
-"PO-Revision-Date: 2017-07-17 18:30+0100\n"
-"Last-Translator: Conrad Kostecki <ck@conrad-kostecki.de>\n"
+"PO-Revision-Date: 2020-03-08 20:25+0100\n"
+"Last-Translator: Conrad Kostecki <conrad@kostecki.com>\n"
 "Language-Team: German <de@li.org>\n"
 "Language: de\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.0.1\n"
+"X-Generator: Poedit 2.3\n"
 "X-Poedit-SourceCharset: UTF-8\n"
 
-#: cache.c:518
+#: cache.c:559
 msgid "Internal error in cache."
 msgstr "Interner Fehler im Cache."
 
-#: cache.c:928
+#: cache.c:1081
 #, c-format
 msgid "failed to load names from %s: %s"
 msgstr "Fehler beim Laden der Namen von %s: %s"
 
-#: cache.c:954 dhcp.c:867
+#: cache.c:1103 dhcp.c:927
 #, c-format
 msgid "bad address at %s line %d"
 msgstr "Fehlerhafte Adresse in %s Zeile %d"
 
-#: cache.c:1007 dhcp.c:883
+#: cache.c:1156 dhcp.c:943
 #, c-format
 msgid "bad name at %s line %d"
 msgstr "Fehlerhafter Name in %s Zeile %d"
 
-#: cache.c:1016 dhcp.c:958
+#: cache.c:1167 dhcp.c:1018
 #, c-format
 msgid "read %s - %d addresses"
 msgstr "%s gelesen - %d Adressen"
 
-#: cache.c:1129
+#: cache.c:1283
 msgid "cleared cache"
 msgstr "Cache geleert"
 
-#: cache.c:1158
+#: cache.c:1345
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr "Keine IPv4-Adresse für %s gefunden"
 
-#: cache.c:1237
+#: cache.c:1391
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr "%s ist ein CNAME, weise es der DHCP-Lease von %s nicht zu"
 
-#: cache.c:1261
+#: cache.c:1415
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr "Name %s wurde dem DHCP-Lease von %s nicht zugewiesen, da der Name in %s bereits mit Adresse %s existiert"
 
-#: cache.c:1418
+#: cache.c:1663
 #, c-format
 msgid "time %lu"
 msgstr "Zeit %lu"
 
-#: cache.c:1419
+#: cache.c:1664
 #, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr "Cache Größe %d, %d/%d Cache-Einfügungen verwendeten nicht abgelaufene Cache-Einträge wieder."
 
-#: cache.c:1421
+#: cache.c:1666
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr "%u weitergeleitete Anfragen, %u lokal beantwortete Anfragen"
 
-#: cache.c:1424
+#: cache.c:1669
 #, c-format
 msgid "queries for authoritative zones %u"
 msgstr "Anfragen nach autoritativen Zonen %u"
 
-#: cache.c:1450
+#: cache.c:1694
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr "Server %s#%d: %u Anfragen gesendet, %u erneut versucht oder fehlgeschlagen"
@@ -100,667 +100,700 @@ msgstr "Konnte den Zufallszahlengenerator nicht initialisieren: %s"
 msgid "failed to allocate memory"
 msgstr "Konnte Speicher nicht belegen"
 
-#: util.c:281 option.c:619
+#: util.c:281 option.c:641
 msgid "could not get memory"
 msgstr "Speicher nicht verfügbar"
 
-#: util.c:291
+#: util.c:302
 #, c-format
 msgid "cannot create pipe: %s"
 msgstr "Konnte Pipe nicht erzeugen: %s"
 
-#: util.c:299
+#: util.c:310
 #, c-format
 msgid "failed to allocate %d bytes"
 msgstr "Konnte %d Bytes nicht belegen"
 
 # @Simon: not perfect but I cannot get nearer right now.
-#: util.c:468
+#: util.c:506
 #, c-format
 msgid "infinite"
 msgstr "unendlich"
 
-#: option.c:344
+#: option.c:358
 msgid "Specify local address(es) to listen on."
 msgstr "Lokale abzuhörende Adresse(n) angeben."
 
-#: option.c:345
+#: option.c:359
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr "IP-Adresse für alle Hosts in angegebenen Domänen festlegen."
 
 # FIXME: the English test is not to the point. Just use a shortened description
 # from the manpage instead. -- MA
-#: option.c:346
+#: option.c:360
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr "Für private Adressbereiche nach RFC1918 \"keine solche Domain\" liefern."
 
-#: option.c:347
+#: option.c:361
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr "Diese IP-Adresse als NXDOMAIN interpretieren (wehrt \"Suchhilfen\" ab)."
 
-#: option.c:348
+#: option.c:362
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr "Größe des Caches (Zahl der Einträge) festlegen (Voreinstellung: %s)."
 
-#: option.c:349
+#: option.c:363
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr "Konfigurationsdatei festlegen (Voreinstellung: %s)."
 
-#: option.c:350
+#: option.c:364
 msgid "Do NOT fork into the background: run in debug mode."
-msgstr "NICHT in den Hintergrund gehen: Betrieb im Debug-Modus"
+msgstr "NICHT in den Hintergrund gehen: Betrieb im Debug-Modus."
 
-#: option.c:351
+#: option.c:365
 msgid "Do NOT forward queries with no domain part."
 msgstr "Anfragen ohne Domänen-Teil NICHT weiterschicken."
 
-#: option.c:352
+#: option.c:366
 msgid "Return self-pointing MX records for local hosts."
 msgstr "Für lokale Einträge MX-Einträge liefern, die auf sich selbst zeigen."
 
-#: option.c:353
+#: option.c:367
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr "Erweitere einfache Namen in /etc/hosts mit der Domänen-Endung."
 
-#: option.c:354
+#: option.c:368
 msgid "Don't forward spurious DNS requests from Windows hosts."
-msgstr "'unechte' DNS-Anfragen von Windows-Rechnern nicht weiterleiten"
+msgstr "'unechte' DNS-Anfragen von Windows-Rechnern nicht weiterleiten."
 
 # @Simon: I'm a bit unsure about "spurious"
-#: option.c:355
+#: option.c:369
 msgid "Enable DHCP in the range given with lease duration."
-msgstr "DHCP für angegebenen Bereich und Dauer einschalten"
+msgstr "DHCP für angegebenen Bereich und Dauer einschalten."
 
-#: option.c:356
+#: option.c:370
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr "Nach dem Start in diese Benutzergruppe wechseln (Voreinstellung %s)."
 
-#: option.c:357
+#: option.c:371
 msgid "Set address or hostname for a specified machine."
 msgstr "Adresse oder Hostnamen für einen angegebenen Computer setzen."
 
-#: option.c:358
+#: option.c:372
 msgid "Read DHCP host specs from file."
 msgstr "DHCP-Host-Angaben aus Datei lesen."
 
-#: option.c:359
+#: option.c:373
 msgid "Read DHCP option specs from file."
 msgstr "DHCP-Optionen aus Datei lesen."
 
-#: option.c:360
+#: option.c:374
 msgid "Read DHCP host specs from a directory."
 msgstr "DHCP-Host-Angaben aus einem Verzeichnis lesen."
 
-#: option.c:361
+#: option.c:375
 msgid "Read DHCP options from a directory."
 msgstr "DHCP-Optionen aus einem Verzeichnis lesen."
 
-#: option.c:362
+#: option.c:376
 msgid "Evaluate conditional tag expression."
 msgstr "Auswertung eines Ausdrucks bedingter Marken."
 
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Do NOT load %s file."
 msgstr "%s-Datei NICHT laden."
 
-#: option.c:364
+#: option.c:378
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr "Hosts-Datei festlegen, die zusätzlich zu %s gelesen wird."
 
-#: option.c:365
+#: option.c:379
 msgid "Read hosts files from a directory."
 msgstr "DHCP-Host-Dateien aus einem Verzeichnis lesen."
 
-#: option.c:366
+#: option.c:380
 msgid "Specify interface(s) to listen on."
 msgstr "Schnittstelle(n) zum Empfang festlegen."
 
-#: option.c:367
+#: option.c:381
 msgid "Specify interface(s) NOT to listen on."
 msgstr "Schnittstelle(n) festlegen, die NICHT empfangen sollen."
 
-#: option.c:368
+#: option.c:382
 msgid "Map DHCP user class to tag."
 msgstr "DHCP-Benutzerklasse auf Marke abbilden."
 
-#: option.c:369
+#: option.c:383
 msgid "Map RFC3046 circuit-id to tag."
 msgstr "RFC3046 \"circuit-id\" auf Marke abbilden."
 
-#: option.c:370
+#: option.c:384
 msgid "Map RFC3046 remote-id to tag."
 msgstr "RFC3046 \"remote-id\" auf Marke abbilden."
 
-#: option.c:371
+#: option.c:385
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr "RFC3993 \"subscriber-id\" auf Marke abbilden."
 
-#: option.c:372
+#: option.c:386
 msgid "Don't do DHCP for hosts with tag set."
 msgstr "Kein DHCP für Hosts mit gesetzter Marke verwenden."
 
-#: option.c:373
+#: option.c:387
 msgid "Force broadcast replies for hosts with tag set."
 msgstr "Rundsendung für Hosts mit gesetzter Marke erzwingen."
 
-#: option.c:374
+#: option.c:388
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr "NICHT in den Hintergrund wechseln, NICHT im Debug-Modus laufen."
 
-#: option.c:375
+#: option.c:389
 msgid "Assume we are the only DHCP server on the local network."
 msgstr "Voraussetzen, dass wir der einzige DHCP-Server im lokalen Netz sind."
 
-#: option.c:376
+#: option.c:390
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr "Festlegen, wo DHCP-Leases gespeichert werden (Voreinstellung %s)."
 
-#: option.c:377
+#: option.c:391
 msgid "Return MX records for local hosts."
 msgstr "MX-Einträge für lokale Hosts liefern."
 
-#: option.c:378
+#: option.c:392
 msgid "Specify an MX record."
 msgstr "Einen MX-Eintrag festlegen."
 
-#: option.c:379
+#: option.c:393
 msgid "Specify BOOTP options to DHCP server."
 msgstr "BOOTP-Optionen für DHCP-Server festlegen."
 
-#: option.c:380
+#: option.c:394
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr "%s-Datei NICHT abfragen, nur bei SIGHUP neu laden."
 
-#: option.c:381
+#: option.c:395
 msgid "Do NOT cache failed search results."
 msgstr "Fehlerhafte Suchergebnisse NICHT zwischenspeichern."
 
-#: option.c:382
+#: option.c:396
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr "Namensserver streng in der in %s angegebenen Reihenfolge verwenden."
 
-#: option.c:383
+#: option.c:397
 msgid "Specify options to be sent to DHCP clients."
 msgstr "Optionen festlegen, die an DHCP-Klienten gesendet werden."
 
-#: option.c:384
+#: option.c:398
 msgid "DHCP option sent even if the client does not request it."
 msgstr "DHCP-Option, die selbst ohne Klientenanfrage gesendet wird."
 
-#: option.c:385
+#: option.c:399
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr "Port zum Abhören der DNS-Anfragen festlegen (53 voreingestellt)."
 
-#: option.c:386
+#: option.c:400
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr "Maximale unterstützte UDP-Paketgröße für EDNS.0 (Voreinstellung %s)."
 
-#: option.c:387
+#: option.c:401
 msgid "Log DNS queries."
 msgstr "DNS-Anfragen protokollieren."
 
-#: option.c:388
+#: option.c:402
 msgid "Force the originating port for upstream DNS queries."
 msgstr "Ausgehenden Port erzwingen für DNS-Anfragen an vorgelagerte Server."
 
-#: option.c:389
+#: option.c:403
 msgid "Do NOT read resolv.conf."
-msgstr "resolv.conf NICHT lesen."
+msgstr "Die resolv.conf NICHT lesen."
 
-#: option.c:390
+#: option.c:404
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr "Pfad zu resolv.conf festlegen (%s voreingestellt)."
 
-#: option.c:391
+#: option.c:405
 msgid "Specify path to file with server= options"
-msgstr " Dateipfad mit der Option server= angeben"
+msgstr "Dateipfad mit der Option server= angeben"
 
-#: option.c:392
+#: option.c:406
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr "Adresse(n) vorgelagerter Server festlegen, optional mit Domänen."
 
-#: option.c:393
+#: option.c:407
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr "Adresse(n) vorgelagerter Server festlegen, für reverse Adressanfragen"
 
-#: option.c:394
+#: option.c:408
 msgid "Never forward queries to specified domains."
 msgstr "Anfragen für angegebene Domänen niemals weiterleiten."
 
-#: option.c:395
+#: option.c:409
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr "Domäne festlegen, die für DHCP-Leases zugewiesen wird."
 
-#: option.c:396
+#: option.c:410
 msgid "Specify default target in an MX record."
 msgstr "Voreingestelltes Ziel für MX-Einträge festlegen."
 
-#: option.c:397
+#: option.c:411
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr "Gültigkeitsdauer für Antworten aus /etc/hosts festlegen."
 
-#: option.c:398
+#: option.c:412
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr "Gültigkeitsdauer in Sekunden für Caching negativer Ergebnisse festlegen."
 
-#: option.c:399
+#: option.c:413
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr "Gültigkeitsdauer in Sekunden für Caching negativer Ergebnisse festlegen."
 
-#: option.c:400
+#: option.c:414
 msgid "Specify time-to-live ceiling for cache."
 msgstr "Spezifiziere time-to-live ceiling für Cache."
 
-#: option.c:401
+#: option.c:415
 msgid "Specify time-to-live floor for cache."
 msgstr "Spezifiziere time-to-live floor für Cache."
 
-#: option.c:402
+#: option.c:416
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr "Nach dem Start diese Benutzerrechte annehmen (%s voreingestellt)."
 
-#: option.c:403
+#: option.c:417
 msgid "Map DHCP vendor class to tag."
 msgstr "DHCP-\"vendor class\" auf Marke abbilden."
 
-#: option.c:404
+#: option.c:418
 msgid "Display dnsmasq version and copyright information."
-msgstr "dnsmasq-Version und Urheberrecht anzeigen."
+msgstr "DNSMasq-Version und Urheberrecht anzeigen."
 
-#: option.c:405
+#: option.c:419
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr "IPv4-Adressen von vorgelagerten Servern übersetzen."
 
-#: option.c:406
+#: option.c:420
 msgid "Specify a SRV record."
 msgstr "SRV-Eintrag festlegen."
 
-#: option.c:407
+#: option.c:421
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr "Diese Hilfe anzeigen. Benutzen Sie --help dhcp oder --help dhcp6 für bekannte DHCP-Optionen."
 
-#: option.c:408
+#: option.c:422
 #, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr "Dateipfad für Prozesskennung (PID) festlegen (Voreinstellung: %s)."
 
-#: option.c:409
+#: option.c:423
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr "Höchstzahl der DHCP-Leases festlegen (%s voreingestellt)."
 
-#: option.c:410
+#: option.c:424
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr "DNS-Anfragen abhängig der Emfpangsschnittstelle beantworten."
 
-#: option.c:411
+#: option.c:425
 msgid "Specify TXT DNS record."
 msgstr "DNS-TXT-Eintrag festlegen."
 
-#: option.c:412
+#: option.c:426
 msgid "Specify PTR DNS record."
 msgstr "DNS-PTR-Eintrag festlegen."
 
-#: option.c:413
+#: option.c:427
 msgid "Give DNS name to IPv4 address of interface."
 msgstr "Schnittstellennamen zur IPv4-Adresse des Interfaces auflösen."
 
-#: option.c:414
+#: option.c:428
 msgid "Bind only to interfaces in use."
 msgstr "Nur an verwendete Schnittstellen binden."
 
-#: option.c:415
+#: option.c:429
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr "Statische DHCP-Host-Information aus %s lesen."
 
-#: option.c:416
+#: option.c:430
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr "DBus-Schnittstelle zum Festlegen vorgelagerter Server usw. festlegen."
 
-#: option.c:417
+#: option.c:431
+msgid "Enable the UBus interface."
+msgstr "UBus-Schnittstelle aktivieren."
+
+#: option.c:432
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr "Auf dieser Schnittstelle kein DHCP anbieten, sondern nur DNS."
 
-#: option.c:418
+#: option.c:433
 msgid "Enable dynamic address allocation for bootp."
 msgstr "Dynamische Adressbelegung für bootp einschalten."
 
-#: option.c:419
+#: option.c:434
 msgid "Map MAC address (with wildcards) to option set."
 msgstr "MAC-Adresse (mit Jokerzeichen) auf Netzmarke abbilden."
 
-#: option.c:420
+#: option.c:435
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr "DHCP-Anfragen von Alias-Schnittstellen für die Hauptschnittstelle beantworten."
 
-#: option.c:421
+#: option.c:436
+msgid "Specify extra networks sharing a broadcast domain for DHCP"
+msgstr "Geben Sie zusätzliche Netzwerke an, die eine Broadcast-Domäne für DHCP gemeinsam nutzen"
+
+#: option.c:437
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr "ICMP-Echo-Adressprüfung im DHCP-Server abschalten."
 
-#: option.c:422
+#: option.c:438
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr "Skript, das bei Erzeugung/Löschung einer DHCP-Lease laufen soll."
 
-#: option.c:423
+#: option.c:439
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr "Lua-Skript, welches bei Erzeugung/Löschung eines DHCP-Leases laufen soll."
 
-#: option.c:424
+#: option.c:440
 msgid "Run lease-change scripts as this user."
 msgstr "Lease-Änderungs-Skript mit den Rechten dieses Nutzers ausführen."
 
-#: option.c:425
+#: option.c:441
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr "Rufe dhcp-script mit Änderungen an der lokalen ARP-Tabelle auf."
 
-#: option.c:426
+#: option.c:442
 msgid "Read configuration from all the files in this directory."
 msgstr "Konfiguration aus allen Dateien in diesem Verzeichnis lesen."
 
-#: option.c:427
+#: option.c:443
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr "Für diese Syslog-Anlage oder in Datei loggen (Voreinstellung DAEMON)."
 
-#: option.c:428
+#: option.c:444
 msgid "Do not use leasefile."
 msgstr "Keine Lease-Datei benützen."
 
-#: option.c:429
+#: option.c:445
 #, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr "Höchstzahl nebenläufiger DNS-Anfragen (%s voreingestellt)."
 
-#: option.c:430
+#: option.c:446
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr "DNS-Cache beim Neuladen von %s löschen."
 
-#: option.c:431
+#: option.c:447
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr "Von DHCP-Clients gelieferte Hostnamen ignorieren."
 
-#: option.c:432
+#: option.c:448
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr "Dateinamen und Server-Datenfehler für zusätzliche DHCP-Optionen NICHT wiederverwenden."
 
-#: option.c:433
+#: option.c:449
 msgid "Enable integrated read-only TFTP server."
 msgstr "Eingebauten Nur-Lese-TFTP-Server einschalten."
 
-#: option.c:434
+#: option.c:450
 msgid "Export files by TFTP only from the specified subtree."
 msgstr "Nur vom festgelegten Unterbaum Dateien per TFTP exportieren."
 
-#: option.c:435
-#, fuzzy
+#: option.c:451
 msgid "Add client IP or hardware address to tftp-root."
-msgstr "IP-Adresse des Klienten an tftp-root anhängen."
+msgstr "IP-Adresse oder Hardware-Adresse des Klienten an tftp-root anhängen."
 
-#: option.c:436
+#: option.c:452
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr "Zugriff nur auf Dateien gestatten, die dem dnsmasq aufrufenden Benutzer gehören."
 
-#: option.c:437
+#: option.c:453
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr "Der Dienst sollte nicht beendet werden, wenn die TFTP-Verzeichnisse nicht zugreifbar sind."
 
-#: option.c:438
-#, fuzzy, c-format
+#: option.c:454
+#, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
-msgstr "Höchstzahl nebenläufiger TFTP-Übertragungen (%s voreingestellt)."
+msgstr "Maximale Anzahl gleichzeitiger TFTP-Übertragungen (%s voreingestellt)."
 
-#: option.c:439
+#: option.c:455
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr "Maximale MTU für TFTP-Übertragungen erreicht."
 
-#: option.c:440
+#: option.c:456
 msgid "Disable the TFTP blocksize extension."
 msgstr "TFTP-Blockgrößen-Erweiterung abschalten."
 
-#: option.c:441
+#: option.c:457
 msgid "Convert TFTP filenames to lowercase"
 msgstr "Konvertiere TFTP Dateinamen in Kleinschreibung"
 
-#: option.c:442
+#: option.c:458
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr "Bereich für vorübergehende Ports für TFTP-Übertragungen."
 
-#: option.c:443
+#: option.c:459
+msgid "Use only one port for TFTP server."
+msgstr "Bitte nur einen Port für den TFTP-Server nutzen."
+
+#: option.c:460
 msgid "Extra logging for DHCP."
 msgstr "Erweiterte DHCP-Protokollierung."
 
-#: option.c:444
+#: option.c:461
 msgid "Enable async. logging; optionally set queue length."
 msgstr "Asynchrone Protokollierung einschalten, opt. Warteschlangenlänge festlegen."
 
-#: option.c:445
+#: option.c:462
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr "DNS-Rebinding unterbinden, private IP-Bereiche bei der Auflösung ausfiltern."
 
-#: option.c:446
+#: option.c:463
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr "Auflösung zu 127.0.0.0/8 erlauben, für RBL-Server."
 
-#: option.c:447
+#: option.c:464
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr "DNS-Rebind-Schutz für diese Domäne sperren."
 
-#: option.c:448
+#: option.c:465
 msgid "Always perform DNS queries to all servers."
 msgstr "DNS-Anfragen immer an alle Server weiterleiten."
 
-#: option.c:449
+#: option.c:466
 msgid "Set tag if client includes matching option in request."
 msgstr "Marke setzen, wenn Klient eine entsprechende Option anfragt."
 
-#: option.c:450
+#: option.c:467
+msgid "Set tag if client provides given name."
+msgstr "Setzt das Tag, wenn der Client diesen Namen anbietet."
+
+#: option.c:468
 msgid "Use alternative ports for DHCP."
 msgstr "Alternative Ports für DHCP verwenden."
 
-#: option.c:451
+#: option.c:469
 msgid "Specify NAPTR DNS record."
 msgstr "DNS-NAPTR-Eintrag festlegen."
 
-#: option.c:452
+#: option.c:470
 msgid "Specify lowest port available for DNS query transmission."
 msgstr "Niedrigsten verfügbaren Port für Übertragung von DNS-Anfragen festlegen."
 
-#: option.c:453
+#: option.c:471
 msgid "Specify highest port available for DNS query transmission."
 msgstr "Höchsten verfügbaren Port für Übertragung von DNS-Anfragen festlegen."
 
-#: option.c:454
+#: option.c:472
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr "Für DHCP-Klienten nur vollständig bestimmte Domänennamen benutzen."
 
 # FIXME: probably typo in original message. -- MA
-#: option.c:455
+#: option.c:473
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr "Generiere Hostnamen auf Basis der MAC-Adresse für namenlose Klienten."
 
-#: option.c:456
+#: option.c:474
 msgid "Use these DHCP relays as full proxies."
 msgstr "Diese DHCP-Relais als vollwertige Proxies verwenden."
 
-#: option.c:457
+#: option.c:475
 msgid "Relay DHCP requests to a remote server"
 msgstr "Leute DHCP Anfragen an entfernten Server weiter"
 
-#: option.c:458
+#: option.c:476
 msgid "Specify alias name for LOCAL DNS name."
 msgstr "Alias für LOKALEN DNS-Namen festlegen."
 
-#: option.c:459
+#: option.c:477
 msgid "Prompt to send to PXE clients."
 msgstr "Aufforderung, die an PXE-Klienten geschickt wird."
 
-#: option.c:460
+#: option.c:478
 msgid "Boot service for PXE menu."
 msgstr "Boot-Dienst für PXE-Menü."
 
-#: option.c:461
+#: option.c:479
 msgid "Check configuration syntax."
 msgstr "Konfigurationssyntax prüfen."
 
-#: option.c:462
+#: option.c:480
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr "Anfragende MAC-Adresse in die weiterleitende DNS-Anfrage einfügen."
 
-#: option.c:463
+#: option.c:481
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr "Füge spezifiziertes IP-Subnetz an weitergeleiteten DNS-Anfragen hinzu."
 
-#: option.c:464
+#: option.c:482
 msgid "Add client identification to forwarded DNS queries."
 msgstr "Füge Klient Identifikationan weitergeleiteten DNS-Anfragen hinzu."
 
-#: option.c:465
+#: option.c:483
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr "Proxy-DNSSEC-Validierung-Ergebnisse von Upstream-Namensservern."
 
-#: option.c:466
+#: option.c:484
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr "Versuche sequenzielle IP-Adressen an DHCP-Klienten zu vergeben."
 
-#: option.c:467
+#: option.c:485
+msgid "Ignore client identifier option sent by DHCP clients."
+msgstr "Ignorieren Sie die von DHCP-Clients gesendete Client-ID-Option."
+
+#: option.c:486
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr "Kopiere \"connection-track mark\" von Anfragen nach Upstream-Verbindungen."
 
-#: option.c:468
+#: option.c:487
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr "Erlaube DHCP-Klienten ihre eigenen DDNS-Updates durchzuführen."
 
-#: option.c:469
+#: option.c:488
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr "Sende \"Router-Advertisments\" für Netzwerkschnittstellen, welche DHCPv6 nutzen"
 
-#: option.c:470
+#: option.c:489
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr "Spezifiziere DUID_EN-type DHCPv6 Server DUID"
 
-#: option.c:471
+#: option.c:490
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr "Spezifiziere Host (A/AAAA und PTR) Einträge"
 
-#: option.c:472
+#: option.c:491
+msgid "Specify certification authority authorization record"
+msgstr "Geben Sie den Autorisierungsdatensatz der Zertifizierungsstelle an"
+
+#: option.c:492
 msgid "Specify arbitrary DNS resource record"
 msgstr "Spezifiziere einen beliebiegen DNS Eintrag"
 
-#: option.c:473
+#: option.c:493
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr "Bindung zu Schnittstellen in Benutzung - prüfe auf neue Schnittstellen"
 
-#: option.c:474
+#: option.c:494
 msgid "Export local names to global DNS"
 msgstr "Exportiere lokale Namen in das globale DNS"
 
-#: option.c:475
+#: option.c:495
 msgid "Domain to export to global DNS"
 msgstr "Domain für das Exportieren des globalen DNS"
 
-#: option.c:476
+#: option.c:496
 msgid "Set TTL for authoritative replies"
 msgstr "Setzte TTL für autoritative Antworten"
 
-#: option.c:477
-#, fuzzy
+#: option.c:497
 msgid "Set authoritative zone information"
 msgstr "Setze autoritative Zoneninformationen"
 
-#: option.c:478
+#: option.c:498
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr "Sekundärer autoritativer Nameserver für weitergeleitete Domains"
 
-#: option.c:479
+#: option.c:499
 msgid "Peers which are allowed to do zone transfer"
 msgstr "Peers welche einen Zonentransfer durchführen dürfen"
 
-#: option.c:480
+#: option.c:500
 msgid "Specify ipsets to which matching domains should be added"
 msgstr "Spezifiziere IPSets zu welcher passende Domains hinzugefügt werden sollen"
 
-#: option.c:481
+#: option.c:501
 msgid "Specify a domain and address range for synthesised names"
 msgstr "Spezifiziere eine Domain und Adressbereich für synthetisierte Namen"
 
-#: option.c:482
+#: option.c:502
 msgid "Activate DNSSEC validation"
 msgstr "Aktiviere DNSSEC-Validierung"
 
-#: option.c:483
+#: option.c:503
 msgid "Specify trust anchor key digest."
 msgstr "Spezifiziere Vertrauensursprung (Trust Anchor) der Schlüssel-Prüfdaten (Key Digest)."
 
-#: option.c:484
+#: option.c:504
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr "Deaktiviere die Überprüfung vorgelagerter Server für DNSSEC-Debugging."
 
-#: option.c:485
+#: option.c:505
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr "Stellt sicher, dass Antworten ohne DNSSEC sich in einer unsignierten Zone befinden."
 
-#: option.c:486
+#: option.c:506
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr "DNSSEC Signatur-Zeitstempel nicht prüfen, bis erstmalig der Cache neugeladen wird"
 
-#: option.c:487
+#: option.c:507
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr "Zeitstempel-Datei für die Verifizierung der Systemuhrzeit für DNSSEC"
 
-#: option.c:489
-msgid "Specify DHCPv6 prefix class"
-msgstr "Spezifiziere DHCPv6 Prefix Klasse"
-
-#: option.c:491
-#, fuzzy
+#: option.c:508
 msgid "Set MTU, priority, resend-interval and router-lifetime"
-msgstr "Setze Priorität, Intervall des erneuten Sendens und Router Lebenszeit"
+msgstr "Setze MTU, Priorität, Sendewiederholungsintervall und Router-Lebensdauer"
 
-#: option.c:492
+#: option.c:509
 msgid "Do not log routine DHCP."
 msgstr "Protokolliere kein DHCP."
 
-#: option.c:493
+#: option.c:510
 msgid "Do not log routine DHCPv6."
 msgstr "Protokolliere kein DHCPv6."
 
-#: option.c:494
+#: option.c:511
 msgid "Do not log RA."
 msgstr "RA nicht protokollieren."
 
-#: option.c:495
+#: option.c:512
 msgid "Accept queries only from directly-connected networks."
 msgstr "Akzeptiere nur Anfragen von direkt verbundenen Netzwerken."
 
-#: option.c:496
+#: option.c:513
 msgid "Detect and remove DNS forwarding loops."
 msgstr "Erkennen und Entfernen von DNS-Weiterleitungsschleifen."
 
-#: option.c:497
+#: option.c:514
 msgid "Ignore DNS responses containing ipaddr."
 msgstr "Ignoriere DNS-Antworten, welche ipaddr enthalten."
 
-#: option.c:498
+#: option.c:515
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr "Setzte TTL in DNS-Antworten mit DHCP-abgeleiteten Adressen."
 
-#: option.c:499
+#: option.c:516
 msgid "Delay DHCP replies for at least number of seconds."
-msgstr ""
+msgstr "Verzögere DHCP-Antworten für mindestens Anzahl von Sekunden."
+
+#: option.c:517
+msgid "Enables DHCPv4 Rapid Commit option."
+msgstr "Aktiviert die Option DHCPv4 Rapid Commit."
+
+#: option.c:518
+msgid "Path to debug packet dump file"
+msgstr "Pfad zur Debug-Paketdatei, wohin gedumpt werden soll"
+
+#: option.c:519
+msgid "Mask which packets to dump"
+msgstr "Maskiere Pakete, welche gedumpt werden sollen"
+
+#: option.c:520
+msgid "Call dhcp-script when lease expiry changes."
+msgstr "Rufe dhcp-script auf, wenn der Ablauf des Leases sich ändert."
 
-#: option.c:703
+#: option.c:725
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
@@ -769,320 +802,332 @@ msgstr ""
 "Verwendung: dnsmasq [Optionen]\n"
 "\n"
 
-#: option.c:705
+#: option.c:727
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr "Auf der Befehlszeile nur kurze Optionen verwenden!\n"
 
-#: option.c:707
+#: option.c:729
 #, c-format
 msgid "Valid options are:\n"
 msgstr "Gültige Optionen sind:\n"
 
-#: option.c:754 option.c:868
+#: option.c:776 option.c:884
 msgid "bad address"
-msgstr "Fehlerhafte Adresse."
+msgstr "Fehlerhafte Adresse"
 
-#: option.c:779 option.c:783
+#: option.c:799 option.c:803
 msgid "bad port"
 msgstr "unzulässiger Port"
 
-#: option.c:797 option.c:826 option.c:861
+#: option.c:815 option.c:844 option.c:878
 msgid "interface binding not supported"
 msgstr "Schnittstellenbindung nicht unterstützt"
 
-#: option.c:821 option.c:856
+#: option.c:839 option.c:873
 msgid "interface can only be specified once"
-msgstr ""
+msgstr "Schnittstelle kann nur einmal angegeben werden"
 
-#: option.c:835 option.c:3809
+#: option.c:852 option.c:4042
 msgid "bad interface name"
 msgstr "unzulässiger Schnittestellenname"
 
-#: option.c:1062
+#: option.c:1184
 msgid "unsupported encapsulation for IPv6 option"
 msgstr "Nicht unterstützte Verkapselung für eine IPv6-Option"
 
-#: option.c:1076
+#: option.c:1198
 msgid "bad dhcp-option"
 msgstr "Fehlerhafte DHCP-Option"
 
-#: option.c:1144
+#: option.c:1270
 msgid "bad IP address"
 msgstr "Fehlerhafte IP-Adresse"
 
-#: option.c:1147 option.c:1286 option.c:3079
+#: option.c:1273 option.c:1412 option.c:3297
 msgid "bad IPv6 address"
 msgstr "Fehlerhafte IPv6-Adresse"
 
-#: option.c:1240
+#: option.c:1366
 msgid "bad IPv4 address"
 msgstr "Fehlerhafte IPv4-Adresse"
 
-#: option.c:1313 option.c:1407
+#: option.c:1439 option.c:1533
 msgid "bad domain in dhcp-option"
 msgstr "Fehlerhafte Domäne in DHCP-Option"
 
-#: option.c:1445
+#: option.c:1571
 msgid "dhcp-option too long"
 msgstr "DHCP-Option zu lang"
 
-#: option.c:1452
+#: option.c:1578
 msgid "illegal dhcp-match"
 msgstr "Unzulässige dhcp-match-Option"
 
-#: option.c:1514
+#: option.c:1647
 msgid "illegal repeated flag"
 msgstr "unzulässig wiederholte Markierung"
 
-#: option.c:1522
+#: option.c:1655
 msgid "illegal repeated keyword"
 msgstr "unzulässig wiederholtes Schlüsselwort"
 
-#: option.c:1593 option.c:4443
+#: option.c:1726 option.c:4764
 #, c-format
 msgid "cannot access directory %s: %s"
 msgstr "Kann auf Verzeichnis %s nicht zugreifen: %s"
 
-#: option.c:1639 tftp.c:537
+#: option.c:1772 tftp.c:564 dump.c:68
 #, c-format
 msgid "cannot access %s: %s"
 msgstr "Kann auf %s nicht zugreifen: %s"
 
-#: option.c:1727
+#: option.c:1879
 msgid "setting log facility is not possible under Android"
 msgstr "Die Einstellung Protokolliereinrichtung kann unter Android nicht gesetzt werden"
 
-#: option.c:1736
+#: option.c:1888
 msgid "bad log facility"
 msgstr "Falsche Protokolliereinrichtung"
 
-#: option.c:1789
+#: option.c:1941
 msgid "bad MX preference"
 msgstr "unzulässige MX-Präferenz-Angabe"
 
-#: option.c:1794
+#: option.c:1946
 msgid "bad MX name"
 msgstr "unzulässiger MX-Name"
 
-#: option.c:1808
+#: option.c:1960
 msgid "bad MX target"
 msgstr "unzulässiges MX-Ziel"
 
-#: option.c:1820
-msgid "cannot run scripts under uClinux"
-msgstr "unter uClinux ist die Skriptausführung nicht möglich"
-
-#: option.c:1822
+#: option.c:1980
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr "Neuübersetzung mit HAVE_SCRIPT nötig, um Lease-Änderungs-Skripte auszuführen"
 
-#: option.c:1826
+#: option.c:1984
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr "Um Benutzerdefinierte Lua-Skripte zu ermöglichen, muss mit HAVE_LUASCRIPT neu kompiliert werden"
 
-#: option.c:2095 option.c:2106 option.c:2143 option.c:2199 option.c:2482
+#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
 msgid "bad prefix"
 msgstr "unzulässiger Präfix"
 
-#: option.c:2504
+#: option.c:2658
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr "Um IPSet-Direktiven zu aktivieren, muss mit HAVE_IPSET neu übersetzt werden"
 
-#: option.c:2713
+#: option.c:2871
 msgid "bad port range"
 msgstr "unzulässiger Portbereich"
 
-#: option.c:2739
+#: option.c:2897
 msgid "bad bridge-interface"
 msgstr "unzulässige Brücken-Schnittstelle"
 
-#: option.c:2807
+#: option.c:2941
+msgid "bad shared-network"
+msgstr "unzulässiger geteiltes Netz"
+
+#: option.c:2996
 msgid "only one tag allowed"
 msgstr "nur eine Marke zulässig"
 
-#: option.c:2827 option.c:2839 option.c:2948 option.c:2953 option.c:2992
+#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
 msgid "bad dhcp-range"
 msgstr "unzulässiger DHCP-Bereich"
 
-#: option.c:2854
+#: option.c:3050
 msgid "inconsistent DHCP range"
 msgstr "inkonsistenter DHCP-Bereich"
 
-#: option.c:2916
+#: option.c:3115
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr "Die Präfixlenge muss genau 64 für RA Subnetze sein"
 
-#: option.c:2918
+#: option.c:3117
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr "Die Präfixlenge muss genau 64 für Subnet Konstruktoren sein"
 
-#: option.c:2922
+#: option.c:3120
 msgid "prefix length must be at least 64"
 msgstr "Die Präfixlänge muss mindestens 64 sein"
 
-#: option.c:2925
+#: option.c:3123
 msgid "inconsistent DHCPv6 range"
 msgstr "Inkonsistenter DHCPv6-Bereich"
 
-#: option.c:2936
+#: option.c:3142
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr "Prefix muss mit dem \"constructor:\" Argument Null sein"
 
-#: option.c:3049 option.c:3097
+#: option.c:3262 option.c:3340
 msgid "bad hex constant"
 msgstr "Falscher Hexwert"
 
-#: option.c:3071
-msgid "cannot match tags in --dhcp-host"
-msgstr "Kann die Tags in --dhcp-host nicht abgleichen"
+#: option.c:3315
+msgid "bad IPv6 prefix"
+msgstr "unzulässiger IPv6-Präfix"
 
-#: option.c:3119
+#: option.c:3362
 #, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr "doppelte dhcp-host IP-Adresse %s"
 
-#: option.c:3177
+#: option.c:3422
 msgid "bad DHCP host name"
 msgstr "unzulässiger DHCP-Hostname"
 
-#: option.c:3259
+#: option.c:3508
 msgid "bad tag-if"
 msgstr "unzulässige bedingte Marke (tag-if)"
 
-#: option.c:3616 option.c:4039
+#: option.c:3851 option.c:4324
 msgid "invalid port number"
 msgstr "unzulässige Portnummer"
 
-#: option.c:3678
+#: option.c:3907
 msgid "bad dhcp-proxy address"
 msgstr "Fehlerhafte DHCP-Proxy-Adresse"
 
-#: option.c:3704
+#: option.c:3935
 msgid "Bad dhcp-relay"
-msgstr "unzulässiger dhcp-relay"
+msgstr "Uunzulässiger dhcp-relay"
 
-#: option.c:3745
+#: option.c:3979
 msgid "bad RA-params"
 msgstr "unzulässige RA-Parameter"
 
-#: option.c:3754
+#: option.c:3989
 msgid "bad DUID"
 msgstr "unzulässige DUID"
 
-#: option.c:3796
+#: option.c:4023
+msgid "missing address in alias"
+msgstr "Adresse fehlt in Alias"
+
+#: option.c:4029
 msgid "invalid alias range"
 msgstr "unzulässiger Alias-Bereich"
 
-#: option.c:3850 option.c:3862
+#: option.c:4081 option.c:4097
 msgid "bad CNAME"
 msgstr "unzulässiger CNAME"
 
-#: option.c:3866
+#: option.c:4105
 msgid "duplicate CNAME"
 msgstr "doppelter CNAME"
 
-#: option.c:3889
+#: option.c:4132
 msgid "bad PTR record"
 msgstr "unzulässiger PTR-Eintrag"
 
-#: option.c:3920
+#: option.c:4167
 msgid "bad NAPTR record"
 msgstr "unzulässiger NAPTR-Eintrag"
 
-#: option.c:3954
+#: option.c:4203
 msgid "bad RR record"
 msgstr "unzulässiger RR-Eintrag"
 
-#: option.c:3984
+#: option.c:4236
+msgid "bad CAA record"
+msgstr "unzulässiger CAA-Eintrag"
+
+#: option.c:4265
 msgid "bad TXT record"
 msgstr "unzulässiger TXT-Eintrag"
 
-#: option.c:4025
+#: option.c:4308
 msgid "bad SRV record"
 msgstr "unzulässiger SRV-Eintrag"
 
-#: option.c:4032
+#: option.c:4315
 msgid "bad SRV target"
 msgstr "unzulässiges SRV-Ziel"
 
-#: option.c:4046
+#: option.c:4334
 msgid "invalid priority"
 msgstr "unzulässige Priorität"
 
-#: option.c:4049
+#: option.c:4339
 msgid "invalid weight"
 msgstr "unzulässige Wichtung"
 
-#: option.c:4073
+#: option.c:4362
 msgid "Bad host-record"
-msgstr "unzulässiger host-record"
+msgstr "Unzulässiger host-record"
 
-#: option.c:4097
+#: option.c:4402
 msgid "Bad name in host-record"
 msgstr "Unzulässiger Name in host-record"
 
-#: option.c:4162
+#: option.c:4444
+msgid "bad value for dnssec-check-unsigned"
+msgstr "Ungültiger Wert für dnssec-check-unsigned"
+
+#: option.c:4480
 msgid "bad trust anchor"
 msgstr "unzulässiger Vertrauensursprung (Trust Anchor)"
 
-#: option.c:4176
+#: option.c:4496
 msgid "bad HEX in trust anchor"
 msgstr "unzulässiger Hexwert in Vertrauensursprung (Trust Anchor)"
 
-#: option.c:4186
+#: option.c:4507
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr "Nicht unterstützte Option (prüfen Sie, ob DNSMasq mit DHCP/TFTP/DNSSEC/DBus-Unterstützung übersetzt wurde)"
 
-#: option.c:4246
+#: option.c:4567
 msgid "missing \""
 msgstr "fehlende \\\""
 
-#: option.c:4303
+#: option.c:4624
 msgid "bad option"
 msgstr "unzulässige Option"
 
-#: option.c:4305
+#: option.c:4626
 msgid "extraneous parameter"
 msgstr "überschüssiger Parameter"
 
-#: option.c:4307
+#: option.c:4628
 msgid "missing parameter"
 msgstr "fehler Parameter"
 
-#: option.c:4309
+#: option.c:4630
 msgid "illegal option"
 msgstr "unzulässige Option"
 
-#: option.c:4316
+#: option.c:4637
 msgid "error"
 msgstr "Fehler"
 
-#: option.c:4318
+#: option.c:4639
 #, c-format
 msgid " at line %d of %s"
 msgstr " in Zeile %d von %s"
 
-#: option.c:4333 option.c:4580 option.c:4616
+#: option.c:4654 option.c:4939 option.c:4950
 #, c-format
 msgid "read %s"
 msgstr "%s gelesen"
 
-#: option.c:4396 option.c:4519 tftp.c:715
+#: option.c:4717 option.c:4840 tftp.c:754
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "kann %s nicht lesen: %s"
 
-#: option.c:4688
+#: option.c:5027
 msgid "junk found in command line"
 msgstr "Mist in der Kommandozeile gefunden"
 
-#: option.c:4729
+#: option.c:5067
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr "Dnsmasq Version %s  %s\n"
 
-#: option.c:4730
+#: option.c:5068
 #, c-format
 msgid ""
 "Compile time options: %s\n"
@@ -1091,505 +1136,550 @@ msgstr ""
 "Kompilierungs-Optionen %s\n"
 "\n"
 
-#: option.c:4731
+#: option.c:5069
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr "Für diese Software wird ABSOLUT KEINE GARANTIE gewährt.\n"
 
 # FIXME: this must be one long string! -- MA
-#: option.c:4732
+#: option.c:5070
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr "Dnsmasq ist freie Software, und du bist willkommen es weiter zu verteilen\n"
 
-#: option.c:4733
+#: option.c:5071
 #, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr "unter den Bedingungen der GNU General Public Lizenz, Version 2 oder 3.\n"
 
-#: option.c:4744
+#: option.c:5088
 msgid "try --help"
 msgstr "versuchen Sie --help"
 
-#: option.c:4746
+#: option.c:5090
 msgid "try -w"
 msgstr "versuchen Sie -w"
 
-#: option.c:4748
+#: option.c:5092
 #, c-format
 msgid "bad command line options: %s"
 msgstr "unzulässige Optionen auf der Befehlszeile: %s"
 
-#: option.c:4818
+#: option.c:5161
 #, c-format
 msgid "CNAME loop involving %s"
-msgstr ""
+msgstr "CNAME-Schleife mit %s"
 
-#: option.c:4854
+#: option.c:5195
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr "kann Hostnamen nicht ermitteln: %s"
 
-#: option.c:4882
+#: option.c:5223
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr "mit -n/--no-poll ist nur eine resolv.conf-Datei zulässig."
 
-#: option.c:4892
+#: option.c:5233
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr "Um die Domäne zu lesen, muss genau eine resolv.conf-Datei verwendet werden."
 
-#: option.c:4895 network.c:1623 dhcp.c:816
+#: option.c:5236 network.c:1594 dhcp.c:876
 #, c-format
 msgid "failed to read %s: %s"
 msgstr "konnte %s nicht lesen: %s"
 
-#: option.c:4912
+#: option.c:5253
 #, c-format
 msgid "no search directive found in %s"
 msgstr "keine \"search\"-Anweisung in %s gefunden"
 
-#: option.c:4933
+#: option.c:5274
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr "Es muss eine standard Domain gesetzt sein, wenn --dhcp-fqdn gesetzt ist"
 
-#: option.c:4942
+#: option.c:5283
 msgid "syntax check OK"
 msgstr "Syntaxprüfung OK"
 
-#: forward.c:102
+#: forward.c:99
 #, c-format
 msgid "failed to send packet: %s"
 msgstr "Fehlgeschlagen, folgendes Paket zu senden: %s"
 
-#: forward.c:598
+#: forward.c:614
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr "Verwerfe DNS Antwort: Subnetoption stimmt nicht überrein"
 
-#: forward.c:652
+#: forward.c:677
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr "Namensserver %s hat eine rekursive Anfrage verweigert"
 
-#: forward.c:684
+#: forward.c:709
 #, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr "möglichen DNS-Rebind-Angriff entdeckt: %s"
 
-#: forward.c:870
+#: forward.c:961
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
-msgstr ""
+msgstr "Reduziere der DNS-Paketgröße für Nameserver %s auf %d"
 
-#: forward.c:1266 forward.c:1704
+#: forward.c:1370 forward.c:1830
 msgid "Ignoring query from non-local network"
 msgstr "Ignoriere Anfragen vom nicht lokalen Netzwerk"
 
-#: forward.c:2184
+#: forward.c:2321
 #, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr "Maximale Anzahl an nebenläufiger DNS-Anfragen erreicht (Max: %d)"
 
-#: network.c:720
+#: network.c:698
 #, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr "Konnte Empfangs-Socket für %s: %s nicht erzeugen"
 
-#: network.c:1031
+#: network.c:1002
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr "LOUD WARNING: Das Abhören von %s kann die Anfragen auf der Schnittstelle akzeptieren anders als %s"
 
-#: network.c:1038
+#: network.c:1009
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr "LOUD WARNING: Es sollte --bind-dynamic anstatt --bind-interfaces benutzt werden, um DNS-Verstärkungsangriffe auf diesen Schnittstellen zu unterbinden"
 
-#: network.c:1047
-#, fuzzy, c-format
+#: network.c:1018
+#, c-format
 msgid "warning: using interface %s instead"
-msgstr "Warnung: %s nicht zugreifbar"
+msgstr "Warnung: Benutzer stattdessen Schnittstelle %s"
 
-#: network.c:1056
+#: network.c:1027
 #, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr "Warnung: Keine Adresse für die Schnittstelle %s gefunden"
 
-#: network.c:1114
+#: network.c:1085
 #, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr "Schnittstelle %s konnte DHCPv6-Multicast-Gruppe nicht beitreten: %s"
 
-#: network.c:1119
+#: network.c:1090
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr "Versuche /proc/sys/net/core/optmem_max zu erhöhen"
 
-#: network.c:1337
+#: network.c:1307
 #, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr "konnte nicht an Server-Socket für %s binden: %s"
 
-#: network.c:1528
+#: network.c:1499
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr "ignoriere Namensserver %s - lokale Schnittstelle"
 
-#: network.c:1539
+#: network.c:1510
 #, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr "ignoriere Namensserver %s - kann Socket nicht erzeugen/binden: %s"
 
-#: network.c:1559
+#: network.c:1530
 msgid "(no DNSSEC)"
 msgstr "(kein DNSSEC)"
 
 # FIXME: this isn't translatable - always provide full strings, do not assemble yourself! -- MA
-#: network.c:1562
+#: network.c:1533
 msgid "unqualified"
 msgstr "unqualifiziert"
 
-#: network.c:1562
+#: network.c:1533
 msgid "names"
 msgstr "Namen"
 
-#: network.c:1564
+#: network.c:1535
 msgid "default"
 msgstr "Standard"
 
-#: network.c:1566
+#: network.c:1537
 msgid "domain"
 msgstr "Domain"
 
-#: network.c:1572
+#: network.c:1543
 #, c-format
-msgid "using local addresses only for %s %s"
-msgstr "Benutze lokale Adressen nur für %s %s"
+msgid "using only locally-known addresses for %s %s"
+msgstr "Benutze nur lokal-bekannte Adressen für %s %s"
 
-#: network.c:1575
+#: network.c:1546
 #, c-format
 msgid "using standard nameservers for %s %s"
 msgstr "Benutze standard Namensserver für %s %s"
 
-#: network.c:1577
+#: network.c:1548
 #, c-format
 msgid "using nameserver %s#%d for %s %s %s"
 msgstr "Benutze Namensserver %s#%d für %s %s %s"
 
-#: network.c:1581
+#: network.c:1552
 #, c-format
 msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr "Benutze Namensserver %s#%d NICHT - Anfragenschleife festgetellt"
 
-#: network.c:1584
+#: network.c:1555
 #, c-format
 msgid "using nameserver %s#%d(via %s)"
 msgstr "Benutze Namensserver %s#%d(via %s)"
 
-#: network.c:1586
+#: network.c:1557
 #, c-format
 msgid "using nameserver %s#%d"
 msgstr "Benutze Namensserver %s#%d"
 
-#: network.c:1591
-#, fuzzy, c-format
+#: network.c:1562
+#, c-format
 msgid "using %d more local addresses"
-msgstr "Benutze %d mehr Namensserver"
+msgstr "Benutze %d mehr lokale Adressen"
 
-#: network.c:1593
+#: network.c:1564
 #, c-format
 msgid "using %d more nameservers"
 msgstr "Benutze %d mehr Namensserver"
 
-#: dnsmasq.c:171
+#: dnsmasq.c:173
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr "dhcp-hostsdir, dhcp-optsdir und hostsdir sind auf dieser Plattform nicht unterstüzt"
 
-#: dnsmasq.c:186
+#: dnsmasq.c:188
 msgid "no root trust anchor provided for DNSSEC"
 msgstr "Keine Root-Vertrauensursprünge (Root Trust Anchor) für DNSSEC verfügbar"
 
-#: dnsmasq.c:189
+#: dnsmasq.c:191
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr "Kann die Standard Cachegröße nicht verkleinern, wenn DNSSEC aktiviert ist"
 
-#: dnsmasq.c:191
+#: dnsmasq.c:193
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr "DNSSEC nicht verfügbar: setzen Sie HAVE_DNSSEC in src/config.h"
 
-#: dnsmasq.c:197
+#: dnsmasq.c:199
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr "TFTP-Server nicht verfügbar, setzen Sie HAVE_TFTP in src/config.h"
 
-#: dnsmasq.c:202
+#: dnsmasq.c:204
 msgid "cannot use --conntrack AND --query-port"
 msgstr "Kann nicht --conntrack UND --query-port einsetzen"
 
-#: dnsmasq.c:205
+#: dnsmasq.c:207
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr "Conntrack-Unterstützung nicht verfügbar: Aktiviere HAVE_CONNTRACK in src/config.h"
 
-#: dnsmasq.c:210
+#: dnsmasq.c:212
 msgid "asynchronous logging is not available under Solaris"
 msgstr "asynchrone Protokollierung unter Solaris nicht verfügbar"
 
-#: dnsmasq.c:215
+#: dnsmasq.c:217
 msgid "asynchronous logging is not available under Android"
 msgstr "Asynchrone Protokollierung unter Android nicht verfügbar"
 
-#: dnsmasq.c:220
+#: dnsmasq.c:222
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr "Authoritatives DNS nicht verfügbar: Es muss HAVE_AUTH in src/config.h gesetzt sein"
 
-#: dnsmasq.c:225
+#: dnsmasq.c:227
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr "Loop-Erkennung nicht verfügbar, Aktiviere HAVE_LOOP in src/config.h"
 
-#: dnsmasq.c:229
+#: dnsmasq.c:232
+msgid "Ubus not available: set HAVE_UBUS in src/config.h"
+msgstr "UBus nicht verfügbar: setzen Sie HAVE_UBUS in src/config.h"
+
+#: dnsmasq.c:236
 msgid "max_port cannot be smaller than min_port"
 msgstr "max_port darf nicht kleiner als min_port sein"
 
-#: dnsmasq.c:236
+#: dnsmasq.c:243
+msgid "--auth-server required when an auth zone is defined."
+msgstr "--Auth-Server ist notwendig, wenn eine Auth-Zone definiert ist."
+
+#: dnsmasq.c:248
 msgid "zone serial must be configured in --auth-soa"
 msgstr "Zonen Seriennummer muss mit --auth-soa konfiguriert werden"
 
-#: dnsmasq.c:254
+#: dnsmasq.c:268
 msgid "dhcp-range constructor not available on this platform"
 msgstr "dhcp-range Konstruktor ist auf dieser Plattform nicht verfübar"
 
-#: dnsmasq.c:300
+#: dnsmasq.c:332
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr "Kann nicht --bind-interfaces und --bind-dynamic setzen"
 
-#: dnsmasq.c:303
+#: dnsmasq.c:335
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr "konnte Schnitstellenliste nicht beziehen: %s"
 
-#: dnsmasq.c:312
+#: dnsmasq.c:344
 #, c-format
 msgid "unknown interface %s"
 msgstr "unbekannte Schnittstelle %s"
 
-#: dnsmasq.c:377 dnsmasq.c:1054
+#: dnsmasq.c:406
+msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
+msgstr "Paketdump nicht verfügbar: setzen Sie HAVE_DUMP in src/config.h"
+
+#: dnsmasq.c:416 dnsmasq.c:1171
 #, c-format
 msgid "DBus error: %s"
 msgstr "DBus-Fehler: %s"
 
-#: dnsmasq.c:380
+#: dnsmasq.c:419
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr "DBus nicht verfügbar: setzen Sie HAVE_DBUS in src/config.h"
 
-#: dnsmasq.c:410
+#: dnsmasq.c:429
+msgid "UBus not available: set HAVE_UBUS in src/config.h"
+msgstr "UBus nicht verfügbar: setzen Sie HAVE_UBUS in src/config.h"
+
+#: dnsmasq.c:459
 #, c-format
 msgid "unknown user or group: %s"
 msgstr "Unbekannter Benutzer oder Gruppe: %s"
 
-#: dnsmasq.c:465
+#: dnsmasq.c:535
+#, c-format
+msgid "process is missing required capability %s"
+msgstr "Prozess benötigt nicht vorhandene Fähigkeit %s"
+
+#: dnsmasq.c:567
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr "kann nicht ins Wurzelverzeichnis des Dateisystems wechseln: %s"
 
 # FIXME: this and the next would need commas after the version
-#: dnsmasq.c:730
+#: dnsmasq.c:815
 #, c-format
 msgid "started, version %s DNS disabled"
 msgstr "gestartet, Version %s, DNS abgeschaltet"
 
-#: dnsmasq.c:734
+#: dnsmasq.c:820
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr "gestartet, Version %s, Cachegröße %d"
 
-#: dnsmasq.c:736
+#: dnsmasq.c:822
+msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
+msgstr "Die Cachegröße größer als 10000 kann Performanceprobleme verursachen und der positive Nutzen ist zudem unwahrscheinlich."
+
+#: dnsmasq.c:825
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr "Gestartet, Version %s Cache deaktiviert"
 
-#: dnsmasq.c:739
+#: dnsmasq.c:828
 msgid "DNS service limited to local subnets"
 msgstr "DNS-Dienst auf lokale Subnetze eingeschränkt"
 
-#: dnsmasq.c:742
+#: dnsmasq.c:831
 #, c-format
 msgid "compile time options: %s"
 msgstr "Übersetzungsoptionen: %s"
 
-#: dnsmasq.c:751
+#: dnsmasq.c:840
 msgid "DBus support enabled: connected to system bus"
 msgstr "DBus-Unterstützung eingeschaltet: mit Systembus verbunden"
 
-#: dnsmasq.c:753
+#: dnsmasq.c:842
 msgid "DBus support enabled: bus connection pending"
 msgstr "DBus-Unterstützung eingeschaltet: warte auf Systembus-Verbindung"
 
-#: dnsmasq.c:771
+#: dnsmasq.c:850
+msgid "UBus support enabled: connected to system bus"
+msgstr "UBus-Unterstützung aktiviert: Mit Systembus verbunden"
+
+#: dnsmasq.c:852
+msgid "UBus support enabled: bus connection pending"
+msgstr "UBus-Unterstützung aktiviert: BUS-Verbindung wird hergestellt"
+
+#: dnsmasq.c:872
+msgid "DNSSEC validation enabled but all unsigned answers are trusted"
+msgstr "DNSSEC-Validierung aktiviert, jedoch wird allen unsignierten Antworten vertraut"
+
+#: dnsmasq.c:874
 msgid "DNSSEC validation enabled"
 msgstr "DNSSEC-Validierung aktiviert"
 
-#: dnsmasq.c:775
-#, fuzzy
+#: dnsmasq.c:878
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
-msgstr "DNSSEC Signatur-Zeitstempel werden erst ab dem ersten Neuladen des Caches überprüft"
+msgstr "DNSSEC-Signatur-Zeitstempel werden erst nach Empfang von SIGINT überprüft"
 
-#: dnsmasq.c:778
+#: dnsmasq.c:881
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr "DNSSEC Signatur-Zeitstempel werden erst überprüft, sobald die Systemuhrzeit gültig ist"
 
-#: dnsmasq.c:783
+#: dnsmasq.c:884
+#, c-format
+msgid "configured with trust anchor for %s keytag %u"
+msgstr "konfiguriert mit Vertrauensanker für% s Schlüsselwort % u"
+
+#: dnsmasq.c:890
 #, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr "Warnung: konnte den Besitzer von %s nicht ändern: %s"
 
-#: dnsmasq.c:787
+#: dnsmasq.c:894
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr "Aktiviere --bind-interfaces wegen Einschränkungen des Betriebssystems"
 
-#: dnsmasq.c:799
+#: dnsmasq.c:906
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr "Warnung: Schnittstelle %s existiert derzeit nicht"
 
-#: dnsmasq.c:804
+#: dnsmasq.c:911
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr "Warnung: Ignoriere \"resolv-file\", weil \"no-resolv\" aktiv ist"
 
-#: dnsmasq.c:807
+#: dnsmasq.c:914
 msgid "warning: no upstream servers configured"
 msgstr "Warnung: keine vorgelagerten (Upstream) Server konfiguriert"
 
-#: dnsmasq.c:811
+#: dnsmasq.c:918
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr "asynchrone Protokollierung eingeschaltet, Warteschlange fasst %d Nachrichten"
 
-#: dnsmasq.c:832
+#: dnsmasq.c:939
 msgid "IPv6 router advertisement enabled"
 msgstr "IPv6-Router-Advertisement aktiviert"
 
-#: dnsmasq.c:837
+#: dnsmasq.c:944
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr "DHCP, Sockets exklusiv an das Interface %s gebunden"
 
 # FIXME: this and the next few must be full strings to be translatable - do not assemble in code"
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 msgid "root is "
 msgstr "Wurzel ist "
 
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 msgid "enabled"
 msgstr "Aktiviert"
 
-#: dnsmasq.c:853
+#: dnsmasq.c:960
 msgid "secure mode"
 msgstr "sicherer Modus"
 
-#: dnsmasq.c:856
+#: dnsmasq.c:961
+msgid "single port mode"
+msgstr "Einzelport-Modus"
+
+#: dnsmasq.c:964
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr "Warnung: %s nicht zugreifbar"
 
-#: dnsmasq.c:860
+#: dnsmasq.c:968
 #, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr "Warnung: Das TFTP-Verzeichnis %s ist nicht zugreifbar"
 
-#: dnsmasq.c:886
+#: dnsmasq.c:994
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr "Begrenze gleichzeitige TFTP-Übertragungen auf maximal %d"
 
-#: dnsmasq.c:1056
+#: dnsmasq.c:1173
 msgid "connected to system DBus"
 msgstr "Mit System-DBus verbunden"
 
-#: dnsmasq.c:1215
+#: dnsmasq.c:1345
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr "kann nicht in den Hintergrund abspalten: %s"
 
-#: dnsmasq.c:1218
+#: dnsmasq.c:1349
 #, c-format
 msgid "failed to create helper: %s"
 msgstr "kann Helfer nicht erzeugen: %s"
 
-#: dnsmasq.c:1221
+#: dnsmasq.c:1353
 #, c-format
 msgid "setting capabilities failed: %s"
 msgstr "kann \"capabilities\" nicht setzen: %s"
 
-#: dnsmasq.c:1224
+#: dnsmasq.c:1357
 #, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr "Kann nicht Benutzerrechte %s annehmen: %s"
 
-#: dnsmasq.c:1227
+#: dnsmasq.c:1361
 #, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr "Kann nicht Gruppenrechte %s annehmen: %s"
 
-#: dnsmasq.c:1230
+#: dnsmasq.c:1365
 #, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr "kann die Prozessidentifikations-(PID)-Datei %s nicht öffnen: %s"
 
-#: dnsmasq.c:1233
+#: dnsmasq.c:1369
 #, c-format
 msgid "cannot open log %s: %s"
 msgstr "Kann Logdatei %s nicht öffnen: %s"
 
-#: dnsmasq.c:1236
+#: dnsmasq.c:1373
 #, c-format
 msgid "failed to load Lua script: %s"
 msgstr "Konnte Lua-Script nicht laden: %s"
 
-#: dnsmasq.c:1239
+#: dnsmasq.c:1377
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr "Das TFTP-Verzeichnis %s ist nicht zugreifbar: %s"
 
-#: dnsmasq.c:1242
+#: dnsmasq.c:1381
 #, c-format
 msgid "cannot create timestamp file %s: %s"
-msgstr "Kann keine timestamp-Datei %s erzeugen: %s "
+msgstr "Kann keine Zeitstempel-Datei %s erzeugen: %s"
 
-#: dnsmasq.c:1326
+#: dnsmasq.c:1465
 #, c-format
 msgid "script process killed by signal %d"
 msgstr "Scriptprozess durch Signal %d getötet"
 
-#: dnsmasq.c:1330
+#: dnsmasq.c:1469
 #, c-format
 msgid "script process exited with status %d"
 msgstr "Scriptprozess hat sich mit Status %d beendet"
 
-#: dnsmasq.c:1334
+#: dnsmasq.c:1473
 #, c-format
 msgid "failed to execute %s: %s"
 msgstr "konnte %s nicht ausführen: %s"
 
-#: dnsmasq.c:1374
+#: dnsmasq.c:1513
 msgid "now checking DNSSEC signature timestamps"
 msgstr "Prüfe jetzt DNSSEC Signatur-Zeitstempel"
 
-#: dnsmasq.c:1409 dnssec.c:160 dnssec.c:206
+#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
 #, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr "kann die mtime nicht auf %s aktualisieren: %s"
 
-#: dnsmasq.c:1416
+#: dnsmasq.c:1560
 msgid "exiting on receipt of SIGTERM"
 msgstr "beende nach Empfang von SIGTERM"
 
-#: dnsmasq.c:1444
+#: dnsmasq.c:1588
 #, c-format
 msgid "failed to access %s: %s"
 msgstr "konnte auf %s nicht zugreifen: %s"
 
-#: dnsmasq.c:1474
+#: dnsmasq.c:1618
 #, c-format
 msgid "reading %s"
 msgstr "lese %s"
 
-#: dnsmasq.c:1485
+#: dnsmasq.c:1629
 #, c-format
 msgid "no servers found in %s, will retry"
 msgstr "keine Server in %s gefunden, werde es später neu versuchen"
@@ -1619,7 +1709,7 @@ msgstr "kann nicht an DHCP-Server-Socket binden: %s"
 msgid "cannot create ICMP raw socket: %s."
 msgstr "kann ICMP-Rohdaten-Socket nicht erzeugen: %s."
 
-#: dhcp.c:252 dhcp6.c:173
+#: dhcp.c:252 dhcp6.c:180
 #, c-format
 msgid "unknown interface %s in bridge-interface"
 msgstr "unbekannte Schnittstelle %s in bridge-interface"
@@ -1629,337 +1719,342 @@ msgstr "unbekannte Schnittstelle %s in bridge-interface"
 msgid "DHCP packet received on %s which has no address"
 msgstr "DHCP-Paket ohne Adresse an Schnittstelle %s empfangen"
 
-#: dhcp.c:427
+#: dhcp.c:428
 #, c-format
 msgid "ARP-cache injection failed: %s"
 msgstr "APR-Cache Injektion fehlgeschlagen: %s"
 
-#: dhcp.c:470
+#: dhcp.c:471
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr "Fehler beim Senden des DHCP-Pakets an %s: %s"
 
-#: dhcp.c:531
+#: dhcp.c:526
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr "DHCP-Bereich %s - %s passt nicht zur Netzmaske %s"
 
-#: dhcp.c:854
+#: dhcp.c:914
 #, c-format
 msgid "bad line at %s line %d"
 msgstr "ungültige Zeile %2$d in Datei %1$s"
 
-#: dhcp.c:897
+#: dhcp.c:957
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr "ignoriere %s Zeile %d, doppelter Name oder doppelte IP-Adresse"
 
-#: dhcp.c:1041 rfc3315.c:2149
+#: dhcp.c:1100 rfc3315.c:2139
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr "DHCP Weiterleitung %s -> %s"
 
-#: lease.c:98
+#: lease.c:64
+#, c-format
+msgid "ignoring invalid line in lease database: %s %s %s %s ..."
+msgstr "ignoriere fehlerhafte Zeile in Lease-Datenbank: %s %s %s %s ..."
+
+#: lease.c:101
+#, c-format
+msgid "ignoring invalid line in lease database, bad address: %s"
+msgstr "ignoriere fehlerhafte Zeile in Lease-Datenbank, ungültige Adresse: %s"
+
+#: lease.c:108
 msgid "too many stored leases"
 msgstr "zu viele Leases gespeichert"
 
-#: lease.c:166
+#: lease.c:176
 #, c-format
 msgid "cannot open or create lease file %s: %s"
 msgstr "kann Lease-Datei %s nicht öffnen: %s"
 
-#: lease.c:175
-#, c-format
-msgid "failed to parse lease database, invalid line: %s %s %s %s ..."
-msgstr ""
+#: lease.c:185
+msgid "failed to parse lease database cleanly"
+msgstr "Fehler beim korrekten Parsen der Lease-Datenbank"
 
-#: lease.c:180
-#, fuzzy, c-format
+#: lease.c:188
+#, c-format
 msgid "failed to read lease file %s: %s"
-msgstr "konnte %s nicht lesen: %s"
+msgstr "konnte Lease-Datei %s nicht lesen: %s"
 
-#: lease.c:196
+#: lease.c:204
 #, c-format
 msgid "cannot run lease-init script %s: %s"
 msgstr "kann Lease-Start-Skript %s nicht ausführen: %s"
 
-#: lease.c:202
+#: lease.c:210
 #, c-format
 msgid "lease-init script returned exit code %s"
 msgstr "Lease-Start-Skript beendete sich mit Code %s"
 
 # FIXME: This should be %u s also in English according to NIST and SI rules. -- MA
-#: lease.c:373
+#: lease.c:381
 #, c-format
 msgid "failed to write %s: %s (retry in %us)"
 msgstr "Konnte %s nicht schreiben: %s (Neuversuch in %u s)"
 
-#: lease.c:937
+#: lease.c:955
 #, c-format
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr "Ignoriere Domäne %s für DHCP-Hostnamen %s"
 
 # FIXME: this and the next few are not translatable. Please provide full
 # strings, do not programmatically assemble them.
-#: rfc2131.c:347
+#: rfc2131.c:372
 #, c-format
 msgid "no address range available for DHCP request %s %s"
 msgstr "Kein verfügbarer DHCP-Bereich für Anfrage %s %s"
 
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "with subnet selector"
 msgstr "mit Subnetz-Wähler"
 
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "via"
 msgstr "via"
 
-#: rfc2131.c:360
+#: rfc2131.c:385
 #, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr "%u verfügbare(s) DHCP-Subnetz: %s/%s"
 
-#: rfc2131.c:363 rfc3315.c:306
+#: rfc2131.c:388 rfc3315.c:319
 #, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr "%u verfügbare(r) DHCP-Bereich: %s - %s"
 
-#: rfc2131.c:474
+#: rfc2131.c:499
 #, c-format
 msgid "%u vendor class: %s"
 msgstr "%u \"Vendor class\": %s"
 
-#: rfc2131.c:476
+#: rfc2131.c:501
 #, c-format
 msgid "%u user class: %s"
 msgstr "%u Benutzerklasse: %s"
 
 # FIXME: do not programmatically assemble strings - untranslatable
-#: rfc2131.c:510
+#: rfc2131.c:535
 msgid "disabled"
 msgstr "deaktiviert"
 
-#: rfc2131.c:551 rfc2131.c:1006 rfc2131.c:1430 rfc3315.c:616 rfc3315.c:869
-#: rfc3315.c:1148
+#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1097
 msgid "ignored"
 msgstr "ignoriert"
 
-#: rfc2131.c:566 rfc2131.c:1239 rfc3315.c:919
+#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
 msgid "address in use"
 msgstr "Adresse in Nutzung"
 
-#: rfc2131.c:580 rfc2131.c:1060
+#: rfc2131.c:605 rfc2131.c:1119
 msgid "no address available"
 msgstr "Keine Adresse verfügbar"
 
-#: rfc2131.c:587 rfc2131.c:1202
+#: rfc2131.c:612 rfc2131.c:1273
 msgid "wrong network"
 msgstr "Falsches Netzwerk"
 
-#: rfc2131.c:602
+#: rfc2131.c:627
 msgid "no address configured"
 msgstr "Keine Adresse konfiguriert"
 
-#: rfc2131.c:608 rfc2131.c:1252
+#: rfc2131.c:633 rfc2131.c:1323
 msgid "no leases left"
 msgstr "Keine Leases übrig"
 
-#: rfc2131.c:703 rfc3315.c:482
+#: rfc2131.c:734 rfc3315.c:499
 #, c-format
 msgid "%u client provides name: %s"
 msgstr "%u Klient stellt Name bereit: %s"
 
-#: rfc2131.c:808
+#: rfc2131.c:864
 msgid "PXE BIS not supported"
 msgstr "PXE BIS nicht unterstützt"
 
-#: rfc2131.c:974 rfc3315.c:1242
+#: rfc2131.c:1032 rfc3315.c:1197
 #, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr "schalte statische DHCP-Adresse %s für %s ab"
 
 # FIXME: do not assemble
-#: rfc2131.c:995
+#: rfc2131.c:1053
 msgid "unknown lease"
 msgstr "Unbekannter Lease"
 
-#: rfc2131.c:1029
+#: rfc2131.c:1088
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr "benutze konfigurierte Adresse %s nicht, weil sie an %s verleast ist"
 
-#: rfc2131.c:1039
+#: rfc2131.c:1098
 #, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr "benutze konfigurierte Adresse %s nicht, weil sie von Server/Relais verwendet wird"
 
-#: rfc2131.c:1042
+#: rfc2131.c:1101
 #, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr "benutze konfigurierte Adresse %s nicht, weil sie zuvor abgelehnt wurde"
 
 # FIXME: do not assemble
-#: rfc2131.c:1058 rfc2131.c:1245
+#: rfc2131.c:1117 rfc2131.c:1316
 msgid "no unique-id"
 msgstr "Keine eindeutige ID"
 
-#: rfc2131.c:1140
+#: rfc2131.c:1209
 msgid "wrong server-ID"
 msgstr "Falsche Server-ID"
 
-#: rfc2131.c:1159
+#: rfc2131.c:1228
 msgid "wrong address"
 msgstr "Falsche Adresse"
 
-#: rfc2131.c:1177 rfc3315.c:1015
+#: rfc2131.c:1246 rfc3315.c:961
 msgid "lease not found"
 msgstr "Lease nicht gefunden"
 
-#: rfc2131.c:1210
+#: rfc2131.c:1281
 msgid "address not available"
 msgstr "Adresse nicht verfügbar"
 
-#: rfc2131.c:1221
+#: rfc2131.c:1292
 msgid "static lease available"
 msgstr "Statischer Lease verfügbar"
 
-#: rfc2131.c:1225
+#: rfc2131.c:1296
 msgid "address reserved"
 msgstr "Adresse reserviert"
 
-#: rfc2131.c:1233
+#: rfc2131.c:1304
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr "Gebe Lease von %2$s an %1$s auf"
 
-#: rfc2131.c:1757
+#: rfc2131.c:1845
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr "%u Name der Bootdatei: %s"
 
-#: rfc2131.c:1766
+#: rfc2131.c:1854
 #, c-format
 msgid "%u server name: %s"
 msgstr "%u Servername: %s"
 
-#: rfc2131.c:1774
+#: rfc2131.c:1862
 #, c-format
 msgid "%u next server: %s"
 msgstr "%u nächster Server: %s"
 
-#: rfc2131.c:1777
+#: rfc2131.c:1865
 #, c-format
 msgid "%u broadcast response"
 msgstr "%u Antwort per Rundsendung"
 
-#: rfc2131.c:1840
+#: rfc2131.c:1928
 #, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr "kann DHCP/BOOTP-Opition %d nicht setzen: kein Platz mehr im Paket"
 
-#: rfc2131.c:2131
+#: rfc2131.c:2219
 msgid "PXE menu too large"
 msgstr "PXE-Menüeintrag zu groß"
 
-#: rfc2131.c:2270 rfc3315.c:1515
+#: rfc2131.c:2358 rfc3315.c:1470
 #, c-format
 msgid "%u requested options: %s"
 msgstr "%u angeforderte Optionen: %s"
 
-#: rfc2131.c:2587
+#: rfc2131.c:2675
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr "Kann RFC3925-Option nicht senden: zu viele Optionen für Unternehmen Nr. %d"
 
-#: rfc2131.c:2650
+#: rfc2131.c:2738
 #, c-format
 msgid "%u reply delay: %d"
-msgstr ""
+msgstr "%u Antwortverzögerung: %d"
 
-#: netlink.c:77
+#: netlink.c:76
 #, c-format
 msgid "cannot create netlink socket: %s"
 msgstr "kann Netlink-Socket nicht erzeugen: %s"
 
-#: netlink.c:355
+#: netlink.c:352
 #, c-format
 msgid "netlink returns error: %s"
 msgstr "Netlink liefert Fehler %s"
 
-#: dbus.c:186
-msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
-msgstr "Versuch, via DBus eine IPv6-Serveradresse zu setzen: keine IPv6-Unterstützung"
-
-#: dbus.c:439
+#: dbus.c:438
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr "Aktiviere --%s Option von D-Bus"
 
-#: dbus.c:444
+#: dbus.c:443
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr "Deaktiviere --%s Option von D-Bus"
 
-#: dbus.c:690
+#: dbus.c:717
 msgid "setting upstream servers from DBus"
 msgstr "vorgelagerte Server von DBus gesetzt"
 
-#: dbus.c:737
+#: dbus.c:764
 msgid "could not register a DBus message handler"
 msgstr "konnte Steuerungsprogramm für DBus-Nachrichten nicht anmelden"
 
-#: bpf.c:265
+#: bpf.c:261
 #, c-format
 msgid "cannot create DHCP BPF socket: %s"
 msgstr "konnte DHCP-BPF-Socket nicht einrichten: %s"
 
-#: bpf.c:293
+#: bpf.c:289
 #, c-format
 msgid "DHCP request for unsupported hardware type (%d) received on %s"
 msgstr "DHCP-Anfrage für nicht unterstützen Hardwaretyp (%d) auf %s empfangen"
 
-#: bpf.c:378
+#: bpf.c:374
 #, c-format
 msgid "cannot create PF_ROUTE socket: %s"
 msgstr "Kann PF_ROUTE socket nicht erzeugen: %s"
 
-#: bpf.c:399
+#: bpf.c:395
 msgid "Unknown protocol version from route socket"
 msgstr "Unbekannte Protokollversion vom Route Socket"
 
-#: helper.c:154
+#: helper.c:150
 msgid "lease() function missing in Lua script"
 msgstr "Die Funktion lease() fehlt im Lua-Script"
 
-#: tftp.c:319
+#: tftp.c:347
 msgid "unable to get free port for TFTP"
 msgstr "konnte keinen freien Port für TFTP bekommen"
 
-#: tftp.c:335
+#: tftp.c:363
 #, c-format
 msgid "unsupported request from %s"
 msgstr "nicht unterstützte Anfrage von %s"
 
-#: tftp.c:483
+#: tftp.c:510
 #, c-format
 msgid "file %s not found"
 msgstr "Datei %s nicht gefunden"
 
-#: tftp.c:592
-#, c-format
-msgid "error %d %s received from %s"
-msgstr "Fehler %d %s von %s empfangen"
-
-#: tftp.c:634
+#: tftp.c:628
 #, c-format
 msgid "failed sending %s to %s"
 msgstr "konnte %s nicht an %s senden"
 
-#: tftp.c:634
+#: tftp.c:628
 #, c-format
 msgid "sent %s to %s"
 msgstr "%s an %s verschickt"
 
+#: tftp.c:678
+#, c-format
+msgid "error %d %s received from %s"
+msgstr "Fehler %d %s von %s empfangen"
+
 #: log.c:190
 #, c-format
 msgid "overflow: %d log entries lost"
@@ -1974,7 +2069,7 @@ msgstr "Protokollierung fehlgeschlagen: %s"
 msgid "FAILED to start up"
 msgstr "Start fehlgeschlagen"
 
-#: conntrack.c:65
+#: conntrack.c:63
 #, c-format
 msgid "Conntrack connection mark retrieval failed: %s"
 msgstr "\"Conntrack connection mark\"-Abruf fehlgeschlagen: %s"
@@ -1994,78 +2089,72 @@ msgstr "kann SO_REUSE{ADDR|PORT} für DHCPv6-Socket nicht aktivieren: %s"
 msgid "failed to bind DHCPv6 server socket: %s"
 msgstr "Kann nicht an DHCPv6-Server-Socket binden: %s"
 
-#: rfc3315.c:157
+#: rfc3315.c:173
 #, c-format
 msgid "no address range available for DHCPv6 request from relay at %s"
 msgstr "Kein Adressbereich verfügbar für die DHCPv6-Anfrage vom Relay bei %s"
 
-#: rfc3315.c:166
+#: rfc3315.c:182
 #, c-format
 msgid "no address range available for DHCPv6 request via %s"
 msgstr "Kein Adressbereich verfügbar für die DHCPv6-Anfrage via %s"
 
-#: rfc3315.c:303
+#: rfc3315.c:316
 #, c-format
 msgid "%u available DHCPv6 subnet: %s/%d"
 msgstr "%u verfügbare(s) DHCPv6-Subnetz: %s/%d"
 
-#: rfc3315.c:386
+#: rfc3315.c:399
 #, c-format
 msgid "%u vendor class: %u"
 msgstr "%u Herstellerklasse: %u"
 
-#: rfc3315.c:434
+#: rfc3315.c:447
 #, c-format
 msgid "%u client MAC address: %s"
 msgstr "%u Klient MAC-Adresse: %s"
 
-# FIXME: do not assemble
-#: rfc3315.c:673
-#, c-format
-msgid "unknown prefix-class %d"
-msgstr "unbekannte Präfixklasse %d"
-
-#: rfc3315.c:816 rfc3315.c:911
+#: rfc3315.c:762 rfc3315.c:859
 msgid "address unavailable"
 msgstr "Adresse nicht verfügbar"
 
-#: rfc3315.c:828 rfc3315.c:959 rfc3315.c:1292
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
 msgid "success"
 msgstr "Erfolg"
 
-#: rfc3315.c:843 rfc3315.c:852 rfc3315.c:967 rfc3315.c:969
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
 msgid "no addresses available"
 msgstr "Keine Adressen verfügbar"
 
-#: rfc3315.c:946
+#: rfc3315.c:890
 msgid "not on link"
 msgstr "nicht on link"
 
-#: rfc3315.c:1019 rfc3315.c:1204 rfc3315.c:1281
+#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
 msgid "no binding found"
 msgstr "Keine Bindung gefunden"
 
-#: rfc3315.c:1057
+#: rfc3315.c:1002
 msgid "deprecated"
 msgstr "veraltet"
 
-#: rfc3315.c:1062
+#: rfc3315.c:1007
 msgid "address invalid"
 msgstr "Adresse ungültig"
 
-#: rfc3315.c:1109
+#: rfc3315.c:1057 rfc3315.c:1059
 msgid "confirm failed"
 msgstr "Bestätigung fehlgeschlagen"
 
-#: rfc3315.c:1125
+#: rfc3315.c:1074
 msgid "all addresses still on link"
 msgstr "Alle Adressen immer noch on link"
 
-#: rfc3315.c:1213
+#: rfc3315.c:1165
 msgid "release received"
 msgstr "Freigabe empfangen"
 
-#: rfc3315.c:2140
+#: rfc3315.c:2130
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr "Kann nicht zum DHCPv6 Server multicasten ohne korrekte Schnittstelle"
 
@@ -2079,76 +2168,76 @@ msgstr "Ignoriere doppelt vorhandene DHCP-Option %d"
 msgid "%u tags: %s"
 msgstr "%u Marken: %s"
 
-#: dhcp-common.c:407
+#: dhcp-common.c:444
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr "%s hat mehr als eine Adresse in hosts-Datei, benutze %s für DHCP"
 
-#: dhcp-common.c:430
+#: dhcp-common.c:478
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr "doppelte IP-Adresse %s (%s) in \"dhcp-config\"-Anweisung"
 
-#: dhcp-common.c:491
+#: dhcp-common.c:542
 #, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr "kann SO_BINDTODEVICE für DHCP-Socket nicht aktivieren: %s"
 
-#: dhcp-common.c:612
+#: dhcp-common.c:665
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr "Bekannte DHCP-Optionen:\n"
 
-#: dhcp-common.c:623
+#: dhcp-common.c:676
 #, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr "Bekannte DHCPv6-Optionen:\n"
 
-#: dhcp-common.c:820
+#: dhcp-common.c:873
 msgid ", prefix deprecated"
 msgstr ", Prefix veraltet"
 
-#: dhcp-common.c:823
+#: dhcp-common.c:876
 #, c-format
 msgid ", lease time "
-msgstr ", Lease Zeit"
+msgstr ", Lease Zeit "
 
-#: dhcp-common.c:865
+#: dhcp-common.c:918
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr "%s stateless auf %s%.0s%.0s%s"
 
-#: dhcp-common.c:867
+#: dhcp-common.c:920
 #, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr "%s, nur statische Leases auf %.0s%s%s%.0s"
 
-#: dhcp-common.c:869
+#: dhcp-common.c:922
 #, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr "%s, Proxy im Subnetz %.0s%s%.0s%.0s"
 
-#: dhcp-common.c:870
+#: dhcp-common.c:923
 #, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr "%s, IP-Bereich %s -- %s%s%.0s"
 
-#: dhcp-common.c:883
+#: dhcp-common.c:936
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr "DHCPv4-abgeleitete IPv6 Namen auf %s%s"
 
-#: dhcp-common.c:886
+#: dhcp-common.c:939
 #, c-format
 msgid "router advertisement on %s%s"
 msgstr "Router-Advertisment auf %s%s"
 
-#: dhcp-common.c:897
+#: dhcp-common.c:950
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr "DHCP Weiterleitung von %s nach %s über %s"
 
-#: dhcp-common.c:899
+#: dhcp-common.c:952
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr "DHCP Weiterleitung von %s nach %s"
@@ -2158,7 +2247,7 @@ msgstr "DHCP Weiterleitung von %s nach %s"
 msgid "cannot create ICMPv6 socket: %s"
 msgstr "Kann ICMPv6-Socket nicht erzeugen: %s"
 
-#: auth.c:449
+#: auth.c:439
 #, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr "ignoriere Zonentransfer-Anfrage von %s"
@@ -2173,20 +2262,24 @@ msgstr "konnte Kernelversion nicht finden: %s"
 msgid "failed to create IPset control socket: %s"
 msgstr "konnte IPset-Kontroll-Socket nicht erzeugen: %s"
 
-#: ipset.c:233
-#, fuzzy, c-format
+#: ipset.c:226
+#, c-format
 msgid "failed to update ipset %s: %s"
-msgstr "kann die mtime nicht auf %s aktualisieren: %s"
+msgstr "Aktualisierung von ipset %s fehlgeschlagen: %s"
 
-#: dnssec.c:208
-#, fuzzy
+#: dnssec.c:206
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
-msgstr "Prüfe jetzt DNSSEC Signatur-Zeitstempel"
+msgstr "Prüfe jetzt DNSSEC Signatur-Zeitstempel."
 
-#: blockdata.c:58
+#: dnssec.c:902
 #, c-format
-msgid "DNSSEC memory in use %u, max %u, allocated %u"
-msgstr "DNSSEC Speicher in Benutzung %u, Max %u, zugewiesen %u"
+msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
+msgstr "Unsichere DS-Antwort für %s, bitte Domainkonfiguration und Upstream DNS-Server für DNSSEC-Unterstützung überprüfen"
+
+#: blockdata.c:55
+#, c-format
+msgid "pool memory in use %u, max %u, allocated %u"
+msgstr "Pool Speicher in Benutzung %u, Max %u, zugewiesen %u"
 
 #: tables.c:61
 #, c-format
@@ -2209,20 +2302,20 @@ msgid "error: cannot strlcpy table name %s"
 msgstr "Fehler: Kann den Tabellennamen %s nicht strlcpy"
 
 #: tables.c:101
-#, fuzzy, c-format
+#, c-format
 msgid "IPset: error:%s"
-msgstr "DBus-Fehler: %s"
+msgstr "IPset: Fehler: %s"
 
 #: tables.c:108
 msgid "info: table created"
 msgstr "Info: Tabelle erstellt"
 
-#: tables.c:134
+#: tables.c:133
 #, c-format
 msgid "warning: DIOCR%sADDRS: %s"
 msgstr "Warnung: DIOCR%sADDRS: %s"
 
-#: tables.c:138
+#: tables.c:137
 #, c-format
 msgid "%d addresses %s"
 msgstr "%d Adressen %s"
@@ -2262,6 +2355,81 @@ msgstr "fehlerhaftes dynamisches Verzeichnis %s: %s"
 msgid "inotify, new or changed file %s"
 msgstr "inotify, neue oder geänderte Datei %s"
 
+#: dump.c:64
+#, c-format
+msgid "cannot create %s: %s"
+msgstr "kann %s nicht erstellen: %s"
+
+#: dump.c:70
+#, c-format
+msgid "bad header in %s"
+msgstr "Unzulässiger Header in %s"
+
+#: dump.c:201
+msgid "failed to write packet dump"
+msgstr "schreiben des Paketmitschnitt fehlgeschlagen"
+
+#: dump.c:203
+#, c-format
+msgid "dumping UDP packet %u mask 0x%04x"
+msgstr "Dumpe UDP Paket %u Maske 0x%04x"
+
+#: ubus.c:52
+#, c-format
+msgid "UBus subscription callback: %s subscriber(s)"
+msgstr "UBus-Subskription Rückruf: %s Teilnehmer"
+
+#: ubus.c:73
+#, c-format
+msgid "Cannot reconnect to UBus: %s"
+msgstr "Kann mit UBus nicht erneut verbinden: %s"
+
+#: ubus.c:89
+msgid "Cannot initialize UBus: connection failed"
+msgstr "Kann UBus nicht initialisieren: Verbindung fehlgeschlagen"
+
+#: ubus.c:102
+#, c-format
+msgid "Cannot add object to UBus: %s"
+msgstr "Kann Objekt zu UBus nicht hinzufügen: %s"
+
+#: ubus.c:112
+msgid "Connected to system UBus"
+msgstr "Mit System-UBus verbunden"
+
+#: ubus.c:122
+msgid "Cannot set UBus listeners: no connection"
+msgstr "Kann UBus-Zuhörer nicht setzen: Keine Verbindung"
+
+#: ubus.c:142
+msgid "Cannot poll UBus listeners: no connection"
+msgstr "Kann UBus-Zuhörer nicht abfragen: Keine Verbindung"
+
+#: ubus.c:155
+msgid "Disconnecting from UBus"
+msgstr "Mit System-UBus trennen"
+
+#: ubus.c:199
+#, c-format
+msgid "Failed to send UBus event: %s"
+msgstr "Fehlgeschlagen, folgendes UBus-Event zu senden: %s"
+
+#~ msgid "Specify DHCPv6 prefix class"
+#~ msgstr "Spezifiziere DHCPv6 Prefix Klasse"
+
+#~ msgid "cannot run scripts under uClinux"
+#~ msgstr "unter uClinux ist die Skriptausführung nicht möglich"
+
+#~ msgid "cannot match tags in --dhcp-host"
+#~ msgstr "Kann die Tags in --dhcp-host nicht abgleichen"
+
+#~ msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
+#~ msgstr "Versuch, via DBus eine IPv6-Serveradresse zu setzen: keine IPv6-Unterstützung"
+
+# FIXME: do not assemble
+#~ msgid "unknown prefix-class %d"
+#~ msgstr "unbekannte Präfixklasse %d"
+
 #~ msgid "bad TTL"
 #~ msgstr "unzulässige TTL"
 
index bcca828..c9051f4 100644 (file)
--- a/po/es.po
+++ b/po/es.po
@@ -16,70 +16,70 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: cache.c:518
+#: cache.c:559
 msgid "Internal error in cache."
 msgstr ""
 
-#: cache.c:928
+#: cache.c:1081
 #, fuzzy, c-format
 msgid "failed to load names from %s: %s"
 msgstr "no se pudo cargar nombres desde %s: %s"
 
-#: cache.c:954 dhcp.c:867
+#: cache.c:1103 dhcp.c:927
 #, fuzzy, c-format
 msgid "bad address at %s line %d"
 msgstr "dirección errónea en %s línea %d"
 
-#: cache.c:1007 dhcp.c:883
+#: cache.c:1156 dhcp.c:943
 #, c-format
 msgid "bad name at %s line %d"
 msgstr "nombre erróneo en %s línea %d"
 
-#: cache.c:1016 dhcp.c:958
+#: cache.c:1167 dhcp.c:1018
 #, c-format
 msgid "read %s - %d addresses"
 msgstr "direcciónes %s - %d leídas"
 
-#: cache.c:1129
+#: cache.c:1283
 msgid "cleared cache"
 msgstr "el caché fue liberado"
 
-#: cache.c:1158
+#: cache.c:1345
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr ""
 
-#: cache.c:1237
+#: cache.c:1391
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr "%s es un CNAME, no se le está dando concesión DHCP de %s"
 
-#: cache.c:1261
+#: cache.c:1415
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr "no otorgando nombre %s a concesión DHCP de %s porque el nombre existe en %s con dirección %s"
 
-#: cache.c:1418
+#: cache.c:1663
 #, c-format
 msgid "time %lu"
 msgstr "tiempo %lu"
 
-#: cache.c:1419
+#: cache.c:1664
 #, fuzzy, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr "tamaño de caché %d, %d/%d inserciónes de caché reutilizaron objetos no vencidos."
 
-#: cache.c:1421
+#: cache.c:1666
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr "búsquedas reenviadas %u, búsquedas respondidas localmente %u"
 
-#: cache.c:1424
+#: cache.c:1669
 #, fuzzy, c-format
 msgid "queries for authoritative zones %u"
 msgstr "Fijar TTL para respuestas autoritarias"
 
-#: cache.c:1450
+#: cache.c:1694
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr "servidor %s#%d: búsquedas enviadas %u, reintentadas o fallidas %u"
@@ -94,698 +94,736 @@ msgstr "no se pudo crear valor semilla para el generador de n
 msgid "failed to allocate memory"
 msgstr "no se pudo asignar memoria"
 
-#: util.c:281 option.c:619
+#: util.c:281 option.c:641
 msgid "could not get memory"
 msgstr "no se pudo adquirir memoria"
 
-#: util.c:291
+#: util.c:302
 #, fuzzy, c-format
 msgid "cannot create pipe: %s"
 msgstr "no se puede crear pipe: %s"
 
-#: util.c:299
+#: util.c:310
 #, fuzzy, c-format
 msgid "failed to allocate %d bytes"
 msgstr "no se pudo asignar %d bytes"
 
-#: util.c:468
+#: util.c:506
 #, c-format
 msgid "infinite"
 msgstr "infinito"
 
-#: option.c:344
+#: option.c:358
 msgid "Specify local address(es) to listen on."
 msgstr "Especificar dirección(es) locales dónde escuchar."
 
-#: option.c:345
+#: option.c:359
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr "Retornar ipaddr (dirección IP) para todos los hosts en los dominios especificados."
 
-#: option.c:346
+#: option.c:360
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr "Falsificar búsquedas reversas para rangos de dirección privados RFC1918."
 
-#: option.c:347
+#: option.c:361
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr "Tratar ipaddr (dirección IP) como NXDOMAIN (derrota comodín Verisign)."
 
-#: option.c:348
+#: option.c:362
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr "Especificar tamaño de caché en cuanto a cantidad de objetos (%s por predeterminado)."
 
-#: option.c:349
+#: option.c:363
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr "Especificar archivo de configuración (%s por predeterminado)."
 
-#: option.c:350
+#: option.c:364
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr "NO hacer un fork hacia el fondo: correr en modo debug."
 
-#: option.c:351
+#: option.c:365
 msgid "Do NOT forward queries with no domain part."
 msgstr "NO reenviar búsquedas sin parte de dominio."
 
-#: option.c:352
+#: option.c:366
 msgid "Return self-pointing MX records for local hosts."
 msgstr "Retornar expedientes MX auto-señaladores para hosts locales."
 
-#: option.c:353
+#: option.c:367
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr "Expandir nombres simples en /etc/hosts con domain-suffix (sufijo de dominio)."
 
-#: option.c:354
+#: option.c:368
 msgid "Don't forward spurious DNS requests from Windows hosts."
 msgstr "No reenviar pedidos DNS falsos desde máquinas Windows."
 
-#: option.c:355
+#: option.c:369
 msgid "Enable DHCP in the range given with lease duration."
 msgstr "Habilitar DHCP dentro del rango brindado con duración de concesión."
 
-#: option.c:356
+#: option.c:370
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr "Cambiar a este grupo después del inicio (%s por predeterminado)."
 
-#: option.c:357
+#: option.c:371
 msgid "Set address or hostname for a specified machine."
 msgstr "Fijar dirección o nombre de host para una máquina especificada."
 
-#: option.c:358
+#: option.c:372
 #, fuzzy
 msgid "Read DHCP host specs from file."
 msgstr "Leer especificaciones DHCP de host desde archivo"
 
-#: option.c:359
+#: option.c:373
 #, fuzzy
 msgid "Read DHCP option specs from file."
 msgstr "Leer opciones DHCP de host desde archivo"
 
-#: option.c:360
+#: option.c:374
 #, fuzzy
 msgid "Read DHCP host specs from a directory."
 msgstr "Leer especificaciones DHCP de host desde archivo"
 
-#: option.c:361
+#: option.c:375
 #, fuzzy
 msgid "Read DHCP options from a directory."
 msgstr "Leer opciones DHCP de host desde archivo"
 
-#: option.c:362
+#: option.c:376
 msgid "Evaluate conditional tag expression."
 msgstr "Evaluar expresión condicional de etiqueta."
 
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Do NOT load %s file."
 msgstr "NO cargar archivo %s."
 
-#: option.c:364
+#: option.c:378
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr "Especificar un archivo de hosts para ser leído adicionalmente a %s."
 
-#: option.c:365
+#: option.c:379
 #, fuzzy
 msgid "Read hosts files from a directory."
 msgstr "Leer especificaciones DHCP de host desde archivo"
 
-#: option.c:366
+#: option.c:380
 msgid "Specify interface(s) to listen on."
 msgstr "Especificar interfase(s) donde escuchar."
 
-#: option.c:367
+#: option.c:381
 msgid "Specify interface(s) NOT to listen on."
 msgstr "Especificar interfase(s) donde NO escuchar."
 
-#: option.c:368
+#: option.c:382
 #, fuzzy
 msgid "Map DHCP user class to tag."
 msgstr "Trazar clase de usuario DHCP a etiqueta."
 
-#: option.c:369
+#: option.c:383
 msgid "Map RFC3046 circuit-id to tag."
 msgstr "Trazar circuit-id (identificación de circuito) RFC3046 a etiqueta."
 
-#: option.c:370
+#: option.c:384
 msgid "Map RFC3046 remote-id to tag."
 msgstr "Trazar remote-id (identificación remota) RFC3046 a etiqueta."
 
-#: option.c:371
+#: option.c:385
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr "Trazar subscriber-id (identificación de suscritor) RFC3993 a etiqueta."
 
-#: option.c:372
+#: option.c:386
 #, fuzzy
 msgid "Don't do DHCP for hosts with tag set."
 msgstr "No hacer DHCP para hosts con etiqueta fijada."
 
-#: option.c:373
+#: option.c:387
 #, fuzzy
 msgid "Force broadcast replies for hosts with tag set."
 msgstr "Forzar respuestas broadcast para hosts con etiqueta fijada."
 
-#: option.c:374
+#: option.c:388
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr "NO hacer un fork hacia el fondo, NO correr en modo debug."
 
-#: option.c:375
+#: option.c:389
 msgid "Assume we are the only DHCP server on the local network."
 msgstr "Asumir que somos el único servidor DHCP en la red local."
 
-#: option.c:376
+#: option.c:390
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr "Especificar donde almacenar concesión DHCP (%s por predeterminado)."
 
-#: option.c:377
+#: option.c:391
 msgid "Return MX records for local hosts."
 msgstr "Retornar expedientes MX para hosts locales."
 
-#: option.c:378
+#: option.c:392
 msgid "Specify an MX record."
 msgstr "Especificar un expediente MX."
 
-#: option.c:379
+#: option.c:393
 msgid "Specify BOOTP options to DHCP server."
 msgstr "Especificar opciones BOOTP a servidor DHCP."
 
-#: option.c:380
+#: option.c:394
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr "NO revisar archivo %s periódicamente, recargar solo con SIGHUP."
 
-#: option.c:381
+#: option.c:395
 msgid "Do NOT cache failed search results."
 msgstr "NO almacenar en caché resultados de búsquedas fallidas."
 
-#: option.c:382
+#: option.c:396
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr "Usar servidores DNS estrictamente en el órden brindado en %s."
 
-#: option.c:383
+#: option.c:397
 #, fuzzy
 msgid "Specify options to be sent to DHCP clients."
 msgstr "Especificar opciones para ser enviadas a clientes DHCP."
 
-#: option.c:384
+#: option.c:398
 msgid "DHCP option sent even if the client does not request it."
 msgstr "Opción DHCP enviada aún si el cliente no la pide."
 
-#: option.c:385
+#: option.c:399
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr "Especificar puerto donde escuchar por búsquedas DNS (53 por predeterminado)."
 
-#: option.c:386
+#: option.c:400
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr "Tamaño máximo de paquetes UDP soportado para EDNS.0 (%s por predeterminado)."
 
-#: option.c:387
+#: option.c:401
 #, fuzzy
 msgid "Log DNS queries."
 msgstr "Bitacorear búsquedas DNS."
 
-#: option.c:388
+#: option.c:402
 #, fuzzy
 msgid "Force the originating port for upstream DNS queries."
 msgstr "Enforzar el puerto original para búsquedas DNS subida."
 
-#: option.c:389
+#: option.c:403
 msgid "Do NOT read resolv.conf."
 msgstr "NO leer resolv.conf."
 
-#: option.c:390
+#: option.c:404
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr "Especificar el path hacia resolv.conf (%s por predeterminado)."
 
-#: option.c:391
+#: option.c:405
 #, fuzzy
 msgid "Specify path to file with server= options"
 msgstr "Especificar path de archivo PID (%s por predeterminado)."
 
-#: option.c:392
+#: option.c:406
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr "Especificar dirección(es) de servidores subida con dominios opcionales."
 
-#: option.c:393
+#: option.c:407
 #, fuzzy
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr "Especificar dirección(es) de servidores subida con dominios opcionales."
 
-#: option.c:394
+#: option.c:408
 msgid "Never forward queries to specified domains."
 msgstr "Nunca reenviar búsquedas a dominios especificados."
 
-#: option.c:395
+#: option.c:409
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr "Especificar el dominio para ser asignado en concesión DHCP."
 
-#: option.c:396
+#: option.c:410
 msgid "Specify default target in an MX record."
 msgstr "Especificar destino predeterminado en un expediente MX."
 
-#: option.c:397
+#: option.c:411
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr "Especificar tiempo de vida en segundos para respuestas desde /etc/hosts."
 
-#: option.c:398
+#: option.c:412
 #, fuzzy
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr "Especificar tiempo de vida en segundos para caché negativo."
 
-#: option.c:399
+#: option.c:413
 #, fuzzy
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr "Especificar tiempo de vida en segundos para respuestas desde /etc/hosts."
 
-#: option.c:400
+#: option.c:414
 #, fuzzy
 msgid "Specify time-to-live ceiling for cache."
 msgstr "Especificar tiempo de vida en segundos para caché negativo."
 
-#: option.c:401
+#: option.c:415
 #, fuzzy
 msgid "Specify time-to-live floor for cache."
 msgstr "Especificar tiempo de vida en segundos para caché negativo."
 
-#: option.c:402
+#: option.c:416
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr "Cambiar a este usuario despues del inicio (%s por predeterminado)."
 
-#: option.c:403
+#: option.c:417
 #, fuzzy
 msgid "Map DHCP vendor class to tag."
 msgstr "Trazar clase de vendedor DHCP a etiqueta."
 
-#: option.c:404
+#: option.c:418
 msgid "Display dnsmasq version and copyright information."
 msgstr "Mostrar información sobre la versión y copyright de dnsmasq."
 
-#: option.c:405
+#: option.c:419
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr "Traducir direcciones IPv4 desde servidores subida."
 
-#: option.c:406
+#: option.c:420
 msgid "Specify a SRV record."
 msgstr "Especificar un expediente SRV."
 
-#: option.c:407
+#: option.c:421
 #, fuzzy
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr "Mostrar este mensaje. Usar --help dhcp para opciones DHCP conocidas."
 
-#: option.c:408
+#: option.c:422
 #, fuzzy, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr "Especificar path de archivo PID (%s por predeterminado)."
 
-#: option.c:409
+#: option.c:423
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr "Especificar número máximo de concesión DHCP (%s por predeterminado)."
 
-#: option.c:410
+#: option.c:424
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr "Responder a búsquedas DNS en base a la interfase a la cuál fueron enviadas."
 
-#: option.c:411
+#: option.c:425
 msgid "Specify TXT DNS record."
 msgstr "Especificar expediente DNS TXT."
 
-#: option.c:412
+#: option.c:426
 #, fuzzy
 msgid "Specify PTR DNS record."
 msgstr "Especificar expediente DNS PTR."
 
-#: option.c:413
+#: option.c:427
 msgid "Give DNS name to IPv4 address of interface."
 msgstr "Otorgar nombre DNS a dirección IPv4 de interfase."
 
-#: option.c:414
+#: option.c:428
 msgid "Bind only to interfaces in use."
 msgstr "Acoplar solo a interfases en uso."
 
-#: option.c:415
+#: option.c:429
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr "Leer información sobre hosts DHCP estáticos desde %s."
 
-#: option.c:416
+#: option.c:430
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr "Habilitar la interfase DBus para fijar servidores subida, etc."
 
-#: option.c:417
+#: option.c:431
+msgid "Enable the UBus interface."
+msgstr ""
+
+#: option.c:432
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr "No proveer DHCP en esta interfase, sólo proveer DNS."
 
-#: option.c:418
+#: option.c:433
 msgid "Enable dynamic address allocation for bootp."
 msgstr "Habilitar alocación dinámica de direcciónes para BOOTP."
 
-#: option.c:419
+#: option.c:434
 #, fuzzy
 msgid "Map MAC address (with wildcards) to option set."
 msgstr "Trazar dirección MAC (con comodínes) a opción fijada."
 
-#: option.c:420
+#: option.c:435
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr "Tratar pedidos DHCP en alias como si llegaran de la interfase."
 
-#: option.c:421
+#: option.c:436
+msgid "Specify extra networks sharing a broadcast domain for DHCP"
+msgstr ""
+
+#: option.c:437
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr "Deshabilitar verificación de direcciónes para echo ICMP en el servidor DHCP."
 
-#: option.c:422
+#: option.c:438
 #, fuzzy
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr "Archivo guión para ejecutar cuando se crea o destruye una concesión DHCP."
 
-#: option.c:423
+#: option.c:439
 #, fuzzy
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr "Archivo guión para ejecutar cuando se crea o destruye una concesión DHCP."
 
-#: option.c:424
+#: option.c:440
 #, fuzzy
 msgid "Run lease-change scripts as this user."
 msgstr "Correr archivo guión de cambio de concesión como este usuario."
 
-#: option.c:425
+#: option.c:441
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr ""
 
-#: option.c:426
+#: option.c:442
 msgid "Read configuration from all the files in this directory."
 msgstr "Leer configuración desde todos los archivos en este directorio."
 
-#: option.c:427
+#: option.c:443
 #, fuzzy
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr "Bitacorear a esta facilidad syslog o archivo. (DAEMON por predeterminado)"
 
-#: option.c:428
+#: option.c:444
 msgid "Do not use leasefile."
 msgstr "No usar archivo de concesión."
 
-#: option.c:429
+#: option.c:445
 #, fuzzy, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr "Número máximo de búsquedas DNS simultáneas. (%s por predeterminado)"
 
-#: option.c:430
+#: option.c:446
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr "Liberar caché DNS al recargar %s."
 
-#: option.c:431
+#: option.c:447
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr "Ignorar nombres de host brindados por clientes DHCP."
 
-#: option.c:432
+#: option.c:448
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr "NO reutilizar campos de nombre de archivo y servidor para opciones DHCP extra."
 
-#: option.c:433
+#: option.c:449
 msgid "Enable integrated read-only TFTP server."
 msgstr "Habilitar servidor integrado TFTP solo-lectura."
 
-#: option.c:434
+#: option.c:450
 msgid "Export files by TFTP only from the specified subtree."
 msgstr "Exportar archivos vía TFTP solo del sub-árbol especificado."
 
-#: option.c:435
+#: option.c:451
 #, fuzzy
 msgid "Add client IP or hardware address to tftp-root."
 msgstr "Agregar IP de cliente a tftp-root."
 
-#: option.c:436
+#: option.c:452
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr "Permitir acceso solo a archivos pertenecientes al usuario que corre dnsmasq."
 
-#: option.c:437
+#: option.c:453
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr ""
 
-#: option.c:438
+#: option.c:454
 #, fuzzy, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr "Número máximo de transferencias TFTP simultáneas (%s por predeterminado)."
 
-#: option.c:439
+#: option.c:455
 #, fuzzy
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr "Número máximo de transferencias TFTP simultáneas (%s por predeterminado)."
 
-#: option.c:440
+#: option.c:456
 msgid "Disable the TFTP blocksize extension."
 msgstr "Deshabilitar la extensión TFTP blocksize (tamaño de bloque)."
 
-#: option.c:441
+#: option.c:457
 msgid "Convert TFTP filenames to lowercase"
 msgstr "Convertir a minúsculas los nombres de archivos TFTP"
 
-#: option.c:442
+#: option.c:458
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr "Rango de puertos efímeros para ser usados en transferencias TFTP."
 
-#: option.c:443
+#: option.c:459
+msgid "Use only one port for TFTP server."
+msgstr ""
+
+#: option.c:460
 msgid "Extra logging for DHCP."
 msgstr "Log extra para DHCP."
 
-#: option.c:444
+#: option.c:461
 msgid "Enable async. logging; optionally set queue length."
 msgstr "Habilitar registro asíncrono; opcionalmente fijar tamaño de cola."
 
-#: option.c:445
+#: option.c:462
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr "Detener revinculación DNS. Filtrar rangos de IP privados al resolver."
 
-#: option.c:446
+#: option.c:463
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr "Permitir revinculación de 127.0.0.0/8, para servidores RBL."
 
-#: option.c:447
+#: option.c:464
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr "Inhibir protección de revinculación DNS en este dominio."
 
-#: option.c:448
+#: option.c:465
 msgid "Always perform DNS queries to all servers."
 msgstr "Siempre realizar búsquedas DNS a todos los servidores."
 
-#: option.c:449
+#: option.c:466
 #, fuzzy
 msgid "Set tag if client includes matching option in request."
 msgstr "Fijar etiqueta si cliente incluye opción coincidente en pedido."
 
-#: option.c:450
+#: option.c:467
+#, fuzzy
+msgid "Set tag if client provides given name."
+msgstr "Fijar etiqueta si cliente incluye opción coincidente en pedido."
+
+#: option.c:468
 msgid "Use alternative ports for DHCP."
 msgstr "Usar puertos alternativos para DHCP."
 
-#: option.c:451
+#: option.c:469
 #, fuzzy
 msgid "Specify NAPTR DNS record."
 msgstr "Especificar expediente DNS NAPTR."
 
-#: option.c:452
+#: option.c:470
 msgid "Specify lowest port available for DNS query transmission."
 msgstr "Especificar puerto más bajo disponible para transmisión de búsquedas DNS."
 
-#: option.c:453
+#: option.c:471
 #, fuzzy
 msgid "Specify highest port available for DNS query transmission."
 msgstr "Especificar puerto más bajo disponible para transmisión de búsquedas DNS."
 
-#: option.c:454
+#: option.c:472
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr "Usar solo nombres de dominio completamente calificados para clientes DHCP."
 
-#: option.c:455
+#: option.c:473
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr "Generar hostnames basados en direcciones MAC para clientes sin nombre."
 
-#: option.c:456
+#: option.c:474
 msgid "Use these DHCP relays as full proxies."
 msgstr "Usar estos relays DHCP como proxies completos."
 
-#: option.c:457
+#: option.c:475
 msgid "Relay DHCP requests to a remote server"
 msgstr ""
 
-#: option.c:458
+#: option.c:476
 msgid "Specify alias name for LOCAL DNS name."
 msgstr "Especificar nombre alias para nombre DNS LOCAL."
 
-#: option.c:459
+#: option.c:477
 #, fuzzy
 msgid "Prompt to send to PXE clients."
 msgstr "Aviso a ser enviado a clientes PXE."
 
-#: option.c:460
+#: option.c:478
 msgid "Boot service for PXE menu."
 msgstr "Servicio de arranque para menú PXE."
 
-#: option.c:461
+#: option.c:479
 msgid "Check configuration syntax."
 msgstr "Revisar sintaxis de configuración."
 
-#: option.c:462
+#: option.c:480
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr "Añadir direcciones MAC de los peticionarios a los filtros DNS enviados"
 
-#: option.c:463
+#: option.c:481
 #, fuzzy
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr "Añadir direcciones MAC de los peticionarios a los filtros DNS enviados"
 
-#: option.c:464
+#: option.c:482
 #, fuzzy
 msgid "Add client identification to forwarded DNS queries."
 msgstr "Añadir direcciones MAC de los peticionarios a los filtros DNS enviados"
 
-#: option.c:465
+#: option.c:483
 #, fuzzy
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr "Traducir direcciones IPv4 desde servidores subida."
 
-#: option.c:466
+#: option.c:484
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr "Intento de instaurar direcciones IP secuenciales a cliente DHCP"
 
-#: option.c:467
+#: option.c:485
+#, fuzzy
+msgid "Ignore client identifier option sent by DHCP clients."
+msgstr "Ignorar nombres de host brindados por clientes DHCP."
+
+#: option.c:486
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr "Copiar la marca de connection-track desde los filtros a las conexiones salientes"
 
-#: option.c:468
+#: option.c:487
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr "Permite a clientes DHCP realizar sus propias actualizaciones DDNS"
 
-#: option.c:469
+#: option.c:488
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr "Enviar anuncios del router a los interfases realizando DHCPv6"
 
-#: option.c:470
+#: option.c:489
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr ""
 
-#: option.c:471
+#: option.c:490
 #, fuzzy
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr "Especificar un expediente MX."
 
-#: option.c:472
+#: option.c:491
+msgid "Specify certification authority authorization record"
+msgstr ""
+
+#: option.c:492
 #, fuzzy
 msgid "Specify arbitrary DNS resource record"
 msgstr "Especificar expediente DNS TXT."
 
-#: option.c:473
+#: option.c:493
 #, fuzzy
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr "interfase desconocida %s en bridge-interfase"
 
-#: option.c:474
+#: option.c:494
 msgid "Export local names to global DNS"
 msgstr "Exportar nombres DNS locales a globales"
 
-#: option.c:475
+#: option.c:495
 msgid "Domain to export to global DNS"
 msgstr "Dominio a exportar a DNS global"
 
-#: option.c:476
+#: option.c:496
 msgid "Set TTL for authoritative replies"
 msgstr "Fijar TTL para respuestas autoritarias"
 
-#: option.c:477
+#: option.c:497
 #, fuzzy
 msgid "Set authoritative zone information"
 msgstr "Fijar información de zona autoritaria"
 
-#: option.c:478
+#: option.c:498
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr "Nombres de servidor secundario autoritatorios para dominios enviados"
 
-#: option.c:479
+#: option.c:499
 msgid "Peers which are allowed to do zone transfer"
 msgstr "Colegas autorizados a la zona de transferencia (transfer)"
 
-#: option.c:480
+#: option.c:500
 msgid "Specify ipsets to which matching domains should be added"
 msgstr "Especificar los ipsets coincidentes en dominio que debrían ser añadidos"
 
-#: option.c:481
+#: option.c:501
 #, fuzzy
 msgid "Specify a domain and address range for synthesised names"
 msgstr "Especificar dominio y rango de direcciones para los nombres acrónimos"
 
-#: option.c:482
+#: option.c:502
 msgid "Activate DNSSEC validation"
 msgstr ""
 
-#: option.c:483
+#: option.c:503
 msgid "Specify trust anchor key digest."
 msgstr ""
 
-#: option.c:484
+#: option.c:504
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr ""
 
-#: option.c:485
+#: option.c:505
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr ""
 
-#: option.c:486
+#: option.c:506
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr ""
 
-#: option.c:487
+#: option.c:507
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr ""
 
-#: option.c:489
-msgid "Specify DHCPv6 prefix class"
-msgstr "Especificar prefijo de clase DHCPv6"
-
-#: option.c:491
+#: option.c:508
 msgid "Set MTU, priority, resend-interval and router-lifetime"
 msgstr ""
 
-#: option.c:492
+#: option.c:509
 msgid "Do not log routine DHCP."
 msgstr ""
 
-#: option.c:493
+#: option.c:510
 msgid "Do not log routine DHCPv6."
 msgstr ""
 
-#: option.c:494
+#: option.c:511
 msgid "Do not log RA."
 msgstr ""
 
-#: option.c:495
+#: option.c:512
 msgid "Accept queries only from directly-connected networks."
 msgstr ""
 
-#: option.c:496
+#: option.c:513
 msgid "Detect and remove DNS forwarding loops."
 msgstr ""
 
-#: option.c:497
+#: option.c:514
 msgid "Ignore DNS responses containing ipaddr."
 msgstr ""
 
-#: option.c:498
+#: option.c:515
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr ""
 
-#: option.c:499
+#: option.c:516
 msgid "Delay DHCP replies for at least number of seconds."
 msgstr ""
 
-#: option.c:703
+#: option.c:517
+msgid "Enables DHCPv4 Rapid Commit option."
+msgstr ""
+
+#: option.c:518
+msgid "Path to debug packet dump file"
+msgstr ""
+
+#: option.c:519
+msgid "Mask which packets to dump"
+msgstr ""
+
+#: option.c:520
+msgid "Call dhcp-script when lease expiry changes."
+msgstr ""
+
+#: option.c:725
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
@@ -794,344 +832,359 @@ msgstr ""
 "Modo de uso: dnsmasq [opciones]\n"
 "\n"
 
-#: option.c:705
+#: option.c:727
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr "Usar opciones cortas solo en la línea de comandos.\n"
 
-#: option.c:707
+#: option.c:729
 #, fuzzy, c-format
 msgid "Valid options are:\n"
 msgstr "Opciones válidas son :\n"
 
-#: option.c:754 option.c:868
+#: option.c:776 option.c:884
 #, fuzzy
 msgid "bad address"
 msgstr "dirección IP errónea"
 
-#: option.c:779 option.c:783
+#: option.c:799 option.c:803
 msgid "bad port"
 msgstr "puerto erróneo"
 
-#: option.c:797 option.c:826 option.c:861
+#: option.c:815 option.c:844 option.c:878
 msgid "interface binding not supported"
 msgstr "vinculación de interfase no está soportado"
 
-#: option.c:821 option.c:856
+#: option.c:839 option.c:873
 msgid "interface can only be specified once"
 msgstr ""
 
-#: option.c:835 option.c:3809
+#: option.c:852 option.c:4042
 #, fuzzy
 msgid "bad interface name"
 msgstr "nombre de interfase erróneo"
 
-#: option.c:1062
+#: option.c:1184
 msgid "unsupported encapsulation for IPv6 option"
 msgstr "Encapsulación no soportada para opción IPv6"
 
-#: option.c:1076
+#: option.c:1198
 msgid "bad dhcp-option"
 msgstr "opción dhcp-option errónea"
 
-#: option.c:1144
+#: option.c:1270
 #, fuzzy
 msgid "bad IP address"
 msgstr "dirección IP errónea"
 
-#: option.c:1147 option.c:1286 option.c:3079
+#: option.c:1273 option.c:1412 option.c:3297
 #, fuzzy
 msgid "bad IPv6 address"
 msgstr "dirección IP errónea"
 
-#: option.c:1240
+#: option.c:1366
 #, fuzzy
 msgid "bad IPv4 address"
 msgstr "dirección IP errónea"
 
-#: option.c:1313 option.c:1407
+#: option.c:1439 option.c:1533
 msgid "bad domain in dhcp-option"
 msgstr "dominio erróneo en dhcp-option"
 
-#: option.c:1445
+#: option.c:1571
 msgid "dhcp-option too long"
 msgstr "opción dhcp-option demasiado larga"
 
-#: option.c:1452
+#: option.c:1578
 msgid "illegal dhcp-match"
 msgstr "dhcp-match ilegal"
 
-#: option.c:1514
+#: option.c:1647
 msgid "illegal repeated flag"
 msgstr "opción repetida ilegal"
 
-#: option.c:1522
+#: option.c:1655
 msgid "illegal repeated keyword"
 msgstr "palabra clave repetida ilegal"
 
-#: option.c:1593 option.c:4443
+#: option.c:1726 option.c:4764
 #, fuzzy, c-format
 msgid "cannot access directory %s: %s"
 msgstr "no se puede acceder a directorio %s: %s"
 
-#: option.c:1639 tftp.c:537
+#: option.c:1772 tftp.c:564 dump.c:68
 #, fuzzy, c-format
 msgid "cannot access %s: %s"
 msgstr "no se puede acceder %s: %s"
 
-#: option.c:1727
+#: option.c:1879
 msgid "setting log facility is not possible under Android"
 msgstr "la creación de un registro no es posible en Android"
 
-#: option.c:1736
+#: option.c:1888
 msgid "bad log facility"
 msgstr "ubicación del registro errónea"
 
-#: option.c:1789
+#: option.c:1941
 msgid "bad MX preference"
 msgstr "preferencia MX errónea"
 
-#: option.c:1794
+#: option.c:1946
 msgid "bad MX name"
 msgstr "nombre MX erróneo"
 
-#: option.c:1808
+#: option.c:1960
 msgid "bad MX target"
 msgstr "destino MX erróneo"
 
-#: option.c:1820
-msgid "cannot run scripts under uClinux"
-msgstr "no se pueden correr archivos 'script' bajo uClinux"
-
-#: option.c:1822
+#: option.c:1980
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr "recompilar con HAVE_SCRIPT definido para habilitar guiónes de cambio de concesión"
 
-#: option.c:1826
+#: option.c:1984
 #, fuzzy
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr "recompilar con HAVE_SCRIPT definido para habilitar 'scripts' en Lua"
 
-#: option.c:2095 option.c:2106 option.c:2143 option.c:2199 option.c:2482
+#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
 #, fuzzy
 msgid "bad prefix"
 msgstr "prefijo erróneo"
 
-#: option.c:2504
+#: option.c:2658
 #, fuzzy
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr "recompilar con HAVE_SCRIPT definido para habilitar directivas ipset"
 
-#: option.c:2713
+#: option.c:2871
 #, fuzzy
 msgid "bad port range"
 msgstr "rango de puertos erróneo"
 
-#: option.c:2739
+#: option.c:2897
 msgid "bad bridge-interface"
 msgstr "opción bridge-interface (interfase puente) errónea"
 
-#: option.c:2807
+#: option.c:2941
+msgid "bad shared-network"
+msgstr ""
+
+#: option.c:2996
 msgid "only one tag allowed"
 msgstr "solo una etiqueta permitida"
 
-#: option.c:2827 option.c:2839 option.c:2948 option.c:2953 option.c:2992
+#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
 msgid "bad dhcp-range"
 msgstr "opción dhcp-range (rango DHCP) errónea"
 
-#: option.c:2854
+#: option.c:3050
 msgid "inconsistent DHCP range"
 msgstr "rango DHCP inconsistente"
 
-#: option.c:2916
+#: option.c:3115
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr "la longitud del prefijo debe ser 64 exacto para subredes RA"
 
-#: option.c:2918
+#: option.c:3117
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr "la longitud del prefijo debe ser 64 exacto para subredes constructoras"
 
-#: option.c:2922
+#: option.c:3120
 msgid "prefix length must be at least 64"
 msgstr "la longitud del prefijo debe ser al menos 64"
 
-#: option.c:2925
+#: option.c:3123
 #, fuzzy
 msgid "inconsistent DHCPv6 range"
 msgstr "rango DHCP inconsistente"
 
-#: option.c:2936
+#: option.c:3142
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr "prefijo debe ser cero con argumento \"constructor:\""
 
-#: option.c:3049 option.c:3097
+#: option.c:3262 option.c:3340
 #, fuzzy
 msgid "bad hex constant"
 msgstr "constante hexadecimal errónea"
 
-#: option.c:3071
-msgid "cannot match tags in --dhcp-host"
-msgstr "no coinciden etiquetas en --dhcp-host"
+#: option.c:3315
+#, fuzzy
+msgid "bad IPv6 prefix"
+msgstr "prefijo erróneo"
 
-#: option.c:3119
+#: option.c:3362
 #, fuzzy, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr "dirección IP duplicada %s en %s."
 
-#: option.c:3177
+#: option.c:3422
 #, fuzzy
 msgid "bad DHCP host name"
 msgstr "nombre de host DHCP erróneo"
 
-#: option.c:3259
+#: option.c:3508
 #, fuzzy
 msgid "bad tag-if"
 msgstr "etiqueta tag-if errónea"
 
-#: option.c:3616 option.c:4039
+#: option.c:3851 option.c:4324
 msgid "invalid port number"
 msgstr "número de puerto inválido"
 
-#: option.c:3678
+#: option.c:3907
 #, fuzzy
 msgid "bad dhcp-proxy address"
 msgstr "dirección IP errónea"
 
-#: option.c:3704
+#: option.c:3935
 #, fuzzy
 msgid "Bad dhcp-relay"
 msgstr "opción dhcp-range (rango DHCP) errónea"
 
-#: option.c:3745
+#: option.c:3979
 msgid "bad RA-params"
 msgstr ""
 
-#: option.c:3754
+#: option.c:3989
 msgid "bad DUID"
 msgstr "DUID erróneo"
 
-#: option.c:3796
+#: option.c:4023
+#, fuzzy
+msgid "missing address in alias"
+msgstr "dirección en uso"
+
+#: option.c:4029
 #, fuzzy
 msgid "invalid alias range"
 msgstr "rango alias inválido"
 
-#: option.c:3850 option.c:3862
+#: option.c:4081 option.c:4097
 msgid "bad CNAME"
 msgstr "CNAME erróneo"
 
-#: option.c:3866
+#: option.c:4105
 msgid "duplicate CNAME"
 msgstr "CNAME duplicado"
 
-#: option.c:3889
+#: option.c:4132
 #, fuzzy
 msgid "bad PTR record"
 msgstr "registro PTR erróneo"
 
-#: option.c:3920
+#: option.c:4167
 #, fuzzy
 msgid "bad NAPTR record"
 msgstr "registro NAPTR erróneo"
 
-#: option.c:3954
+#: option.c:4203
 #, fuzzy
 msgid "bad RR record"
 msgstr "registro PTR erróneo"
 
-#: option.c:3984
+#: option.c:4236
+#, fuzzy
+msgid "bad CAA record"
+msgstr "registro PTR erróneo"
+
+#: option.c:4265
 msgid "bad TXT record"
 msgstr "registro TXT erróneo"
 
-#: option.c:4025
+#: option.c:4308
 msgid "bad SRV record"
 msgstr "registro SRV erróneo"
 
-#: option.c:4032
+#: option.c:4315
 msgid "bad SRV target"
 msgstr "destino SRV erróneo"
 
-#: option.c:4046
+#: option.c:4334
 msgid "invalid priority"
 msgstr "prioridad inválida"
 
-#: option.c:4049
+#: option.c:4339
 msgid "invalid weight"
 msgstr "peso inválido"
 
-#: option.c:4073
+#: option.c:4362
 #, fuzzy
 msgid "Bad host-record"
 msgstr "registro PTR erróneo"
 
-#: option.c:4097
+#: option.c:4402
 #, fuzzy
 msgid "Bad name in host-record"
 msgstr "nombre erróneo en %s"
 
-#: option.c:4162
+#: option.c:4444
+msgid "bad value for dnssec-check-unsigned"
+msgstr ""
+
+#: option.c:4480
 #, fuzzy
 msgid "bad trust anchor"
 msgstr "rango de puertos erróneo"
 
-#: option.c:4176
+#: option.c:4496
 msgid "bad HEX in trust anchor"
 msgstr ""
 
-#: option.c:4186
+#: option.c:4507
 #, fuzzy
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr "opción no soportada (verificar que dnsmasq fue compilado con soporte para DHCP/TFTP/DBus)"
 
-#: option.c:4246
+#: option.c:4567
 msgid "missing \""
 msgstr "falta \""
 
-#: option.c:4303
+#: option.c:4624
 msgid "bad option"
 msgstr "opción errónea"
 
-#: option.c:4305
+#: option.c:4626
 msgid "extraneous parameter"
 msgstr "parámetro extraño"
 
-#: option.c:4307
+#: option.c:4628
 msgid "missing parameter"
 msgstr "parámetro ausente"
 
-#: option.c:4309
+#: option.c:4630
 #, fuzzy
 msgid "illegal option"
 msgstr "opción errónea"
 
-#: option.c:4316
+#: option.c:4637
 msgid "error"
 msgstr "error"
 
-#: option.c:4318
+#: option.c:4639
 #, fuzzy, c-format
 msgid " at line %d of %s"
 msgstr "%s en línea %d de %%s"
 
-#: option.c:4333 option.c:4580 option.c:4616
+#: option.c:4654 option.c:4939 option.c:4950
 #, fuzzy, c-format
 msgid "read %s"
 msgstr "lee %s"
 
-#: option.c:4396 option.c:4519 tftp.c:715
+#: option.c:4717 option.c:4840 tftp.c:754
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "no se puede leer %s: %s"
 
-#: option.c:4688
+#: option.c:5027
 msgid "junk found in command line"
 msgstr "basura encontrada en linea de comando"
 
-#: option.c:4729
+#: option.c:5067
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr "Versión dnsmasq %s  %s\n"
 
-#: option.c:4730
+#: option.c:5068
 #, fuzzy, c-format
 msgid ""
 "Compile time options: %s\n"
@@ -1140,511 +1193,563 @@ msgstr ""
 "Opciones de compilación %s\n"
 "\n"
 
-#: option.c:4731
+#: option.c:5069
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr "Este software viene SIN NINGUNA GARANTIA.\n"
 
-#: option.c:4732
+#: option.c:5070
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr "Dnsmasq es software libre, y usted está autorizado a redistribuirlo\n"
 
-#: option.c:4733
+#: option.c:5071
 #, fuzzy, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr "bajo los términos de la GNU General Public License, versión 2 o 3.\n"
 
-#: option.c:4744
+#: option.c:5088
 msgid "try --help"
 msgstr "pruebe --help"
 
-#: option.c:4746
+#: option.c:5090
 msgid "try -w"
 msgstr "pruebe -w"
 
-#: option.c:4748
+#: option.c:5092
 #, fuzzy, c-format
 msgid "bad command line options: %s"
 msgstr "opciones de línea de comandos erróneas: %s"
 
-#: option.c:4818
+#: option.c:5161
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr ""
 
-#: option.c:4854
+#: option.c:5195
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr "no se puede obtener host-name (nombre de host): %s"
 
-#: option.c:4882
+#: option.c:5223
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr "solo un archivo resolv.conf está permitido en modo no-poll."
 
-#: option.c:4892
+#: option.c:5233
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr "debe haber exáctamente un resolv.conf desde donde leer dominio."
 
-#: option.c:4895 network.c:1623 dhcp.c:816
+#: option.c:5236 network.c:1594 dhcp.c:876
 #, fuzzy, c-format
 msgid "failed to read %s: %s"
 msgstr "no se pudo leer %s: %s"
 
-#: option.c:4912
+#: option.c:5253
 #, c-format
 msgid "no search directive found in %s"
 msgstr "ninguna directiva de búsqueda encontrada en %s"
 
-#: option.c:4933
+#: option.c:5274
 #, fuzzy
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr "debe haber un dominio predeterminado cuando --dhcp-fqdn está fijado"
 
-#: option.c:4942
+#: option.c:5283
 msgid "syntax check OK"
 msgstr "revisión de sintaxis OK"
 
-#: forward.c:102
+#: forward.c:99
 #, fuzzy, c-format
 msgid "failed to send packet: %s"
 msgstr "no se pudo escuchar en socket: %s"
 
-#: forward.c:598
+#: forward.c:614
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr ""
 
-#: forward.c:652
+#: forward.c:677
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr "servidor DNS %s rechazó realizar una búsqueda recursiva"
 
-#: forward.c:684
+#: forward.c:709
 #, fuzzy, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr "posible ataque de revinculación DNS detectado"
 
-#: forward.c:870
+#: forward.c:961
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
 msgstr ""
 
-#: forward.c:1266 forward.c:1704
+#: forward.c:1370 forward.c:1830
 msgid "Ignoring query from non-local network"
 msgstr ""
 
-#: forward.c:2184
+#: forward.c:2321
 #, fuzzy, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr "Número máximo de búsquedas DNS simultáneas alcanzado. (%s por predeterminado)"
 
-#: network.c:720
+#: network.c:698
 #, fuzzy, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr "no se pudo crear un zócalo de escucha: %s"
 
-#: network.c:1031
+#: network.c:1002
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr ""
 
-#: network.c:1038
+#: network.c:1009
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr ""
 
-#: network.c:1047
+#: network.c:1018
 #, fuzzy, c-format
 msgid "warning: using interface %s instead"
 msgstr "advertencia: interfase %s no existe actualmente"
 
-#: network.c:1056
+#: network.c:1027
 #, fuzzy, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr "usando direcciones locales solo para %s %s"
 
-#: network.c:1114
+#: network.c:1085
 #, fuzzy, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr "el interfase % falló al unirse al grupo multicast DHCPv6: %s"
 
-#: network.c:1119
+#: network.c:1090
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr ""
 
-#: network.c:1337
+#: network.c:1307
 #, fuzzy, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr "no se pudo acoplar al zócalo del servidor para %s: %s"
 
-#: network.c:1528
+#: network.c:1499
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr "ignorando servidor DNS %s - interfase local"
 
-#: network.c:1539
+#: network.c:1510
 #, fuzzy, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr "ignorando servidor DNS %s - no se puede crear/acoplar zócalo: %s"
 
-#: network.c:1559
+#: network.c:1530
 msgid "(no DNSSEC)"
 msgstr ""
 
-#: network.c:1562
+#: network.c:1533
 msgid "unqualified"
 msgstr "no cualificado"
 
-#: network.c:1562
+#: network.c:1533
 msgid "names"
 msgstr "nombres"
 
-#: network.c:1564
+#: network.c:1535
 msgid "default"
 msgstr "predeterminado"
 
-#: network.c:1566
+#: network.c:1537
 msgid "domain"
 msgstr "dominio"
 
-#: network.c:1572
-#, c-format
-msgid "using local addresses only for %s %s"
+#: network.c:1543
+#, fuzzy, c-format
+msgid "using only locally-known addresses for %s %s"
 msgstr "usando direcciones locales solo para %s %s"
 
-#: network.c:1575
+#: network.c:1546
 #, fuzzy, c-format
 msgid "using standard nameservers for %s %s"
 msgstr "usando nombres estándar %s#%d para %s %s"
 
-#: network.c:1577
+#: network.c:1548
 #, fuzzy, c-format
 msgid "using nameserver %s#%d for %s %s %s"
 msgstr "usando nombre de servidor %s#%d para %s %s"
 
-#: network.c:1581
+#: network.c:1552
 #, fuzzy, c-format
 msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr "usando nombre de servidor %s#%d para %s %s"
 
-#: network.c:1584
+#: network.c:1555
 #, fuzzy, c-format
 msgid "using nameserver %s#%d(via %s)"
 msgstr "usando nombre de servidor %s#%d(vía %s)"
 
-#: network.c:1586
+#: network.c:1557
 #, c-format
 msgid "using nameserver %s#%d"
 msgstr "usando nombre de servidor %s#%d"
 
-#: network.c:1591
+#: network.c:1562
 #, fuzzy, c-format
 msgid "using %d more local addresses"
 msgstr "usando nombre de servidor %s#%d"
 
-#: network.c:1593
+#: network.c:1564
 #, fuzzy, c-format
 msgid "using %d more nameservers"
 msgstr "usando nombre de servidor %s#%d"
 
-#: dnsmasq.c:171
+#: dnsmasq.c:173
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr ""
 
-#: dnsmasq.c:186
+#: dnsmasq.c:188
 msgid "no root trust anchor provided for DNSSEC"
 msgstr ""
 
-#: dnsmasq.c:189
+#: dnsmasq.c:191
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr ""
 
-#: dnsmasq.c:191
+#: dnsmasq.c:193
 #, fuzzy
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr "DBus no disponible: fijar HAVE_DBUS en src/config.h"
 
-#: dnsmasq.c:197
+#: dnsmasq.c:199
 #, fuzzy
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr "servidor TFTP no disponible: fijar HAVE_TFTP en src/config.h"
 
-#: dnsmasq.c:202
+#: dnsmasq.c:204
 #, fuzzy
 msgid "cannot use --conntrack AND --query-port"
 msgstr "No puede usar --conntrack AND --query-port"
 
-#: dnsmasq.c:205
+#: dnsmasq.c:207
 #, fuzzy
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr "servidor TFTP no disponible: fijar HAVE_TFTP en src/config.h"
 
-#: dnsmasq.c:210
+#: dnsmasq.c:212
 #, fuzzy
 msgid "asynchronous logging is not available under Solaris"
 msgstr "registro asíncrono no está disponible bajo Solaris"
 
-#: dnsmasq.c:215
+#: dnsmasq.c:217
 #, fuzzy
 msgid "asynchronous logging is not available under Android"
 msgstr "registro asíncrono no está disponible bajo Solaris"
 
-#: dnsmasq.c:220
+#: dnsmasq.c:222
 #, fuzzy
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr "DBus no disponible: fijar HAVE_DBUS en src/config.h"
 
-#: dnsmasq.c:225
+#: dnsmasq.c:227
 #, fuzzy
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr "servidor TFTP no disponible: fijar HAVE_TFTP en src/config.h"
 
-#: dnsmasq.c:229
+#: dnsmasq.c:232
+#, fuzzy
+msgid "Ubus not available: set HAVE_UBUS in src/config.h"
+msgstr "DBus no disponible: fijar HAVE_DBUS en src/config.h"
+
+#: dnsmasq.c:236
 msgid "max_port cannot be smaller than min_port"
 msgstr ""
 
-#: dnsmasq.c:236
+#: dnsmasq.c:243
+msgid "--auth-server required when an auth zone is defined."
+msgstr ""
+
+#: dnsmasq.c:248
 msgid "zone serial must be configured in --auth-soa"
 msgstr "zona serie debe ser configurada en --auth-soa"
 
-#: dnsmasq.c:254
+#: dnsmasq.c:268
 msgid "dhcp-range constructor not available on this platform"
 msgstr "constructor rango dhcp no disponible en esta plataforma"
 
-#: dnsmasq.c:300
+#: dnsmasq.c:332
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr "no puede usar --bind-interfases y --bind-dynamic"
 
-#: dnsmasq.c:303
+#: dnsmasq.c:335
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr "no se pudo encontrar lista de interfases: %s"
 
-#: dnsmasq.c:312
+#: dnsmasq.c:344
 #, c-format
 msgid "unknown interface %s"
 msgstr "interfase desconocida %s"
 
-#: dnsmasq.c:377 dnsmasq.c:1054
+#: dnsmasq.c:406
+#, fuzzy
+msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
+msgstr "DBus no disponible: fijar HAVE_DBUS en src/config.h"
+
+#: dnsmasq.c:416 dnsmasq.c:1171
 #, c-format
 msgid "DBus error: %s"
 msgstr "error DBus: %s"
 
-#: dnsmasq.c:380
+#: dnsmasq.c:419
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr "DBus no disponible: fijar HAVE_DBUS en src/config.h"
 
-#: dnsmasq.c:410
+#: dnsmasq.c:429
+#, fuzzy
+msgid "UBus not available: set HAVE_UBUS in src/config.h"
+msgstr "DBus no disponible: fijar HAVE_DBUS en src/config.h"
+
+#: dnsmasq.c:459
 #, c-format
 msgid "unknown user or group: %s"
 msgstr "usuario o grupo desconocido: %s"
 
-#: dnsmasq.c:465
+#: dnsmasq.c:535
+#, c-format
+msgid "process is missing required capability %s"
+msgstr ""
+
+#: dnsmasq.c:567
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr "no se puede cambiar directorio a raíz de sistema de archivos: %s"
 
-#: dnsmasq.c:730
+#: dnsmasq.c:815
 #, fuzzy, c-format
 msgid "started, version %s DNS disabled"
 msgstr "iniciado, versión %s DNS deshabilitado"
 
-#: dnsmasq.c:734
+#: dnsmasq.c:820
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr "iniciado, versión %s tamaño de caché %d"
 
-#: dnsmasq.c:736
+#: dnsmasq.c:822
+msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
+msgstr ""
+
+#: dnsmasq.c:825
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr "iniciado, versión %s caché deshabilitado"
 
-#: dnsmasq.c:739
+#: dnsmasq.c:828
 msgid "DNS service limited to local subnets"
 msgstr ""
 
-#: dnsmasq.c:742
+#: dnsmasq.c:831
 #, c-format
 msgid "compile time options: %s"
 msgstr "opciones de compilación: %s"
 
-#: dnsmasq.c:751
+#: dnsmasq.c:840
 msgid "DBus support enabled: connected to system bus"
 msgstr "soporte DBus habilitado: conectado a bus de sistema"
 
-#: dnsmasq.c:753
+#: dnsmasq.c:842
 msgid "DBus support enabled: bus connection pending"
 msgstr "soporte DBus habilitado: conexión a bus pendiente"
 
-#: dnsmasq.c:771
+#: dnsmasq.c:850
+#, fuzzy
+msgid "UBus support enabled: connected to system bus"
+msgstr "soporte DBus habilitado: conectado a bus de sistema"
+
+#: dnsmasq.c:852
+#, fuzzy
+msgid "UBus support enabled: bus connection pending"
+msgstr "soporte DBus habilitado: conexión a bus pendiente"
+
+#: dnsmasq.c:872
+msgid "DNSSEC validation enabled but all unsigned answers are trusted"
+msgstr ""
+
+#: dnsmasq.c:874
 msgid "DNSSEC validation enabled"
 msgstr ""
 
-#: dnsmasq.c:775
+#: dnsmasq.c:878
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr ""
 
-#: dnsmasq.c:778
+#: dnsmasq.c:881
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr ""
 
-#: dnsmasq.c:783
+#: dnsmasq.c:884
+#, c-format
+msgid "configured with trust anchor for %s keytag %u"
+msgstr ""
+
+#: dnsmasq.c:890
 #, fuzzy, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr "advertencia: no se pudo cambiar propietario de %s: %s"
 
-#: dnsmasq.c:787
+#: dnsmasq.c:894
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr "fijando opción --bind-interfases debido a limitaciones de sistema operativo"
 
-#: dnsmasq.c:799
+#: dnsmasq.c:906
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr "advertencia: interfase %s no existe actualmente"
 
-#: dnsmasq.c:804
+#: dnsmasq.c:911
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr "advertencia: ignorando opción resolv-file porque no-resolv está fijado"
 
-#: dnsmasq.c:807
+#: dnsmasq.c:914
 #, fuzzy
 msgid "warning: no upstream servers configured"
 msgstr "advertencia: ningún servidor de subida configurado"
 
-#: dnsmasq.c:811
+#: dnsmasq.c:918
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr "registro asíncrono habilitado, el límite de la cola es %d mensajes"
 
-#: dnsmasq.c:832
+#: dnsmasq.c:939
 msgid "IPv6 router advertisement enabled"
 msgstr "Anuncio de router IPv6 habilitado"
 
-#: dnsmasq.c:837
+#: dnsmasq.c:944
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr ""
 
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 msgid "root is "
 msgstr "root está "
 
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 #, fuzzy
 msgid "enabled"
 msgstr "habilitado"
 
-#: dnsmasq.c:853
+#: dnsmasq.c:960
 msgid "secure mode"
 msgstr "modo seguro"
 
-#: dnsmasq.c:856
+#: dnsmasq.c:961
+#, fuzzy
+msgid "single port mode"
+msgstr "número de puerto inválido"
+
+#: dnsmasq.c:964
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:860
+#: dnsmasq.c:968
 #, fuzzy, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr "directorio TFTP % inaccesible: %s"
 
-#: dnsmasq.c:886
+#: dnsmasq.c:994
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr "limitando número máximo de transferencias TFTP simultáneas a %d"
 
-#: dnsmasq.c:1056
+#: dnsmasq.c:1173
 msgid "connected to system DBus"
 msgstr "conectado a DBus de sistema"
 
-#: dnsmasq.c:1215
+#: dnsmasq.c:1345
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr "no se puede hacer fork en background: %s"
 
-#: dnsmasq.c:1218
+#: dnsmasq.c:1349
 #, fuzzy, c-format
 msgid "failed to create helper: %s"
 msgstr "no se pudo crear ayudante: %s"
 
-#: dnsmasq.c:1221
+#: dnsmasq.c:1353
 #, fuzzy, c-format
 msgid "setting capabilities failed: %s"
 msgstr "configuración de capacidades ha fallado: %s"
 
-#: dnsmasq.c:1224
+#: dnsmasq.c:1357
 #, fuzzy, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr "no se pudo cambiar user-id a %s: %s"
 
-#: dnsmasq.c:1227
+#: dnsmasq.c:1361
 #, fuzzy, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr "no se pudo cambiar group-id a %s: %s"
 
-#: dnsmasq.c:1230
+#: dnsmasq.c:1365
 #, fuzzy, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr "no se pudo abrir archivo PID %s: %s"
 
-#: dnsmasq.c:1233
+#: dnsmasq.c:1369
 #, fuzzy, c-format
 msgid "cannot open log %s: %s"
 msgstr "no se puede abrir registro %s: %s"
 
-#: dnsmasq.c:1236
+#: dnsmasq.c:1373
 #, fuzzy, c-format
 msgid "failed to load Lua script: %s"
 msgstr "no se pudo cargar script Lua %s: %s"
 
-#: dnsmasq.c:1239
+#: dnsmasq.c:1377
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr "directorio TFTP % inaccesible: %s"
 
-#: dnsmasq.c:1242
+#: dnsmasq.c:1381
 #, fuzzy, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr "no se puede abrir o crear archivo de concesión %s: %s"
 
-#: dnsmasq.c:1326
+#: dnsmasq.c:1465
 #, fuzzy, c-format
 msgid "script process killed by signal %d"
 msgstr "proceso script eliminado por señal %d"
 
-#: dnsmasq.c:1330
+#: dnsmasq.c:1469
 #, fuzzy, c-format
 msgid "script process exited with status %d"
 msgstr "proceso script salió con con estado %d"
 
-#: dnsmasq.c:1334
+#: dnsmasq.c:1473
 #, fuzzy, c-format
 msgid "failed to execute %s: %s"
 msgstr "no se pudo ejecutar %s: %s"
 
-#: dnsmasq.c:1374
+#: dnsmasq.c:1513
 msgid "now checking DNSSEC signature timestamps"
 msgstr ""
 
-#: dnsmasq.c:1409 dnssec.c:160 dnssec.c:206
+#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
 #, fuzzy, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr "no se pudo abrir archivo PID %s: %s"
 
-#: dnsmasq.c:1416
+#: dnsmasq.c:1560
 msgid "exiting on receipt of SIGTERM"
 msgstr "saliendo al recibir SIGTERM"
 
-#: dnsmasq.c:1444
+#: dnsmasq.c:1588
 #, fuzzy, c-format
 msgid "failed to access %s: %s"
 msgstr "no se pudo acceder %s: %s"
 
-#: dnsmasq.c:1474
+#: dnsmasq.c:1618
 #, c-format
 msgid "reading %s"
 msgstr "leyendo %s"
 
-#: dnsmasq.c:1485
+#: dnsmasq.c:1629
 #, fuzzy, c-format
 msgid "no servers found in %s, will retry"
 msgstr "ningún servidor encontrado en %s, se reintentará"
@@ -1674,7 +1779,7 @@ msgstr "no se pudo acoplar z
 msgid "cannot create ICMP raw socket: %s."
 msgstr "no se puede crear zócalo puro ICMP: %s."
 
-#: dhcp.c:252 dhcp6.c:173
+#: dhcp.c:252 dhcp6.c:180
 #, fuzzy, c-format
 msgid "unknown interface %s in bridge-interface"
 msgstr "interfase desconocida %s en bridge-interface"
@@ -1684,331 +1789,337 @@ msgstr "interfase desconocida %s en bridge-interface"
 msgid "DHCP packet received on %s which has no address"
 msgstr "Paquete DHCP recibido en %s que no tiene dirección"
 
-#: dhcp.c:427
+#: dhcp.c:428
 #, c-format
 msgid "ARP-cache injection failed: %s"
 msgstr ""
 
-#: dhcp.c:470
+#: dhcp.c:471
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr ""
 
-#: dhcp.c:531
+#: dhcp.c:526
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr "rango DHCP %s -- %s no coincide con máscara de subred %s"
 
-#: dhcp.c:854
+#: dhcp.c:914
 #, fuzzy, c-format
 msgid "bad line at %s line %d"
 msgstr "línea errónea en %s línea %d"
 
-#: dhcp.c:897
+#: dhcp.c:957
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr "ignorando %s línea %d, nombre o dirección IP duplicada"
 
-#: dhcp.c:1041 rfc3315.c:2149
+#: dhcp.c:1100 rfc3315.c:2139
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr "DHCP relay %s -> %s"
 
-#: lease.c:98
+#: lease.c:64
+#, c-format
+msgid "ignoring invalid line in lease database: %s %s %s %s ..."
+msgstr ""
+
+#: lease.c:101
+#, c-format
+msgid "ignoring invalid line in lease database, bad address: %s"
+msgstr ""
+
+#: lease.c:108
 msgid "too many stored leases"
 msgstr "demasiadas concesiones almacenadas"
 
-#: lease.c:166
+#: lease.c:176
 #, fuzzy, c-format
 msgid "cannot open or create lease file %s: %s"
 msgstr "no se puede abrir o crear archivo de concesión %s: %s"
 
-#: lease.c:175
-#, c-format
-msgid "failed to parse lease database, invalid line: %s %s %s %s ..."
-msgstr ""
+#: lease.c:185
+#, fuzzy
+msgid "failed to parse lease database cleanly"
+msgstr "no se pudo leer %s: %s"
 
-#: lease.c:180
+#: lease.c:188
 #, fuzzy, c-format
 msgid "failed to read lease file %s: %s"
 msgstr "no se pudo leer %s: %s"
 
-#: lease.c:196
+#: lease.c:204
 #, fuzzy, c-format
 msgid "cannot run lease-init script %s: %s"
 msgstr "no se puede ejecutar archivo script lease-init %s: %s"
 
-#: lease.c:202
+#: lease.c:210
 #, c-format
 msgid "lease-init script returned exit code %s"
 msgstr "archivo guión lease-init retornó código de salida %s"
 
-#: lease.c:373
+#: lease.c:381
 #, fuzzy, c-format
 msgid "failed to write %s: %s (retry in %us)"
 msgstr "error al escribir %s: %s (reintentar en %us)"
 
-#: lease.c:937
+#: lease.c:955
 #, c-format
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr "Ignorando dominio %s para nombre de host DHCP %s"
 
-#: rfc2131.c:347
+#: rfc2131.c:372
 #, c-format
 msgid "no address range available for DHCP request %s %s"
 msgstr "ningún rango de direcciónes disponible para pedido DHCP %s %s"
 
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "with subnet selector"
 msgstr "con selector de subred"
 
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "via"
 msgstr "vía"
 
-#: rfc2131.c:360
+#: rfc2131.c:385
 #, fuzzy, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr "%u Subred DHCP disponible: %s/%s"
 
-#: rfc2131.c:363 rfc3315.c:306
+#: rfc2131.c:388 rfc3315.c:319
 #, fuzzy, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr "%u Rango DHCP disponible: %s -- %s"
 
-#: rfc2131.c:474
+#: rfc2131.c:499
 #, fuzzy, c-format
 msgid "%u vendor class: %s"
 msgstr "%u Clase de vendedor: %s"
 
-#: rfc2131.c:476
+#: rfc2131.c:501
 #, fuzzy, c-format
 msgid "%u user class: %s"
 msgstr "%u Clase de usuario: %s"
 
-#: rfc2131.c:510
+#: rfc2131.c:535
 msgid "disabled"
 msgstr "deshabilitado"
 
-#: rfc2131.c:551 rfc2131.c:1006 rfc2131.c:1430 rfc3315.c:616 rfc3315.c:869
-#: rfc3315.c:1148
+#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1097
 msgid "ignored"
 msgstr "ignorado"
 
-#: rfc2131.c:566 rfc2131.c:1239 rfc3315.c:919
+#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
 msgid "address in use"
 msgstr "dirección en uso"
 
-#: rfc2131.c:580 rfc2131.c:1060
+#: rfc2131.c:605 rfc2131.c:1119
 msgid "no address available"
 msgstr "ninguna dirección disponible"
 
-#: rfc2131.c:587 rfc2131.c:1202
+#: rfc2131.c:612 rfc2131.c:1273
 msgid "wrong network"
 msgstr "red equivocada"
 
-#: rfc2131.c:602
+#: rfc2131.c:627
 msgid "no address configured"
 msgstr "ninguna dirección configurada"
 
-#: rfc2131.c:608 rfc2131.c:1252
+#: rfc2131.c:633 rfc2131.c:1323
 msgid "no leases left"
 msgstr "no sobra ninguna concesión"
 
-#: rfc2131.c:703 rfc3315.c:482
+#: rfc2131.c:734 rfc3315.c:499
 #, fuzzy, c-format
 msgid "%u client provides name: %s"
 msgstr "%u cliente provee nombre: %s"
 
-#: rfc2131.c:808
+#: rfc2131.c:864
 msgid "PXE BIS not supported"
 msgstr "no hay soporte para BIS PXE"
 
-#: rfc2131.c:974 rfc3315.c:1242
+#: rfc2131.c:1032 rfc3315.c:1197
 #, fuzzy, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr "deshabilitando dirección DHCP estática %s para %s"
 
-#: rfc2131.c:995
+#: rfc2131.c:1053
 msgid "unknown lease"
 msgstr "concesión desconocida"
 
-#: rfc2131.c:1029
+#: rfc2131.c:1088
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr "no usando dirección configurada %s porque está concedida a %s"
 
-#: rfc2131.c:1039
+#: rfc2131.c:1098
 #, fuzzy, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr "no usando dirección configurada %s porque está en uso por el servidor o relay"
 
-#: rfc2131.c:1042
+#: rfc2131.c:1101
 #, fuzzy, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr "no usando dirección configurada %s porque fué previamente denegada"
 
-#: rfc2131.c:1058 rfc2131.c:1245
+#: rfc2131.c:1117 rfc2131.c:1316
 msgid "no unique-id"
 msgstr "ningún unique-id (identificación única)"
 
-#: rfc2131.c:1140
+#: rfc2131.c:1209
 msgid "wrong server-ID"
 msgstr "ID de servidor equivocada"
 
-#: rfc2131.c:1159
+#: rfc2131.c:1228
 msgid "wrong address"
 msgstr "dirección equivocada"
 
-#: rfc2131.c:1177 rfc3315.c:1015
+#: rfc2131.c:1246 rfc3315.c:961
 msgid "lease not found"
 msgstr "concesión no encontrada"
 
-#: rfc2131.c:1210
+#: rfc2131.c:1281
 msgid "address not available"
 msgstr "dirección no disponible"
 
-#: rfc2131.c:1221
+#: rfc2131.c:1292
 msgid "static lease available"
 msgstr "concesión estática disponible"
 
-#: rfc2131.c:1225
+#: rfc2131.c:1296
 msgid "address reserved"
 msgstr "dirección reservada"
 
-#: rfc2131.c:1233
+#: rfc2131.c:1304
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr "abandonando concesión a %s de %s"
 
-#: rfc2131.c:1757
+#: rfc2131.c:1845
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr "%u nombre de bootfile: %s"
 
-#: rfc2131.c:1766
+#: rfc2131.c:1854
 #, c-format
 msgid "%u server name: %s"
 msgstr "%u nombre de servidor: %s"
 
-#: rfc2131.c:1774
+#: rfc2131.c:1862
 #, fuzzy, c-format
 msgid "%u next server: %s"
 msgstr "%u siguiente servidor: %s"
 
-#: rfc2131.c:1777
+#: rfc2131.c:1865
 #, c-format
 msgid "%u broadcast response"
 msgstr "%u respuesta broadcast"
 
-#: rfc2131.c:1840
+#: rfc2131.c:1928
 #, fuzzy, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr "no se puede enviar opción DHCP/BOOTP %d: no queda espacio en el paquete"
 
-#: rfc2131.c:2131
+#: rfc2131.c:2219
 msgid "PXE menu too large"
 msgstr "menú PXE demasiado largo"
 
-#: rfc2131.c:2270 rfc3315.c:1515
+#: rfc2131.c:2358 rfc3315.c:1470
 #, fuzzy, c-format
 msgid "%u requested options: %s"
 msgstr "%u opciones solicitadas: %s"
 
-#: rfc2131.c:2587
+#: rfc2131.c:2675
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr "no se puede enviar opción RFC3925: demasiadas opciones para número enterprise %d"
 
-#: rfc2131.c:2650
+#: rfc2131.c:2738
 #, c-format
 msgid "%u reply delay: %d"
 msgstr ""
 
-#: netlink.c:77
+#: netlink.c:76
 #, fuzzy, c-format
 msgid "cannot create netlink socket: %s"
 msgstr "no se puede crear zócalo netlink: %s"
 
-#: netlink.c:355
+#: netlink.c:352
 #, fuzzy, c-format
 msgid "netlink returns error: %s"
 msgstr "netlink retorna error: %s"
 
-#: dbus.c:186
-msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
-msgstr "intento de fijar dirección de servidor IPv6 vía DBus - no hay soporte IPv6"
-
-#: dbus.c:439
+#: dbus.c:438
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:444
+#: dbus.c:443
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:690
+#: dbus.c:717
 msgid "setting upstream servers from DBus"
 msgstr "fijando servidores subida desde DBus"
 
-#: dbus.c:737
+#: dbus.c:764
 msgid "could not register a DBus message handler"
 msgstr "no se pudo registrar un manejador de mensajes DBus"
 
-#: bpf.c:265
+#: bpf.c:261
 #, c-format
 msgid "cannot create DHCP BPF socket: %s"
 msgstr "no se puede crear zócalo BPF DHCP: %s"
 
-#: bpf.c:293
+#: bpf.c:289
 #, fuzzy, c-format
 msgid "DHCP request for unsupported hardware type (%d) received on %s"
 msgstr "pedido DHCP por tipo de hardware no-soportado (%d) recibido en %s"
 
-#: bpf.c:378
+#: bpf.c:374
 #, fuzzy, c-format
 msgid "cannot create PF_ROUTE socket: %s"
 msgstr "no se puede crear zócalo DHCP: %s"
 
-#: bpf.c:399
+#: bpf.c:395
 msgid "Unknown protocol version from route socket"
 msgstr ""
 
-#: helper.c:154
+#: helper.c:150
 msgid "lease() function missing in Lua script"
 msgstr "la función lease() no se encuentra en el script Lua"
 
-#: tftp.c:319
+#: tftp.c:347
 msgid "unable to get free port for TFTP"
 msgstr "incapaz de conseguir puerto libre para TFTP"
 
-#: tftp.c:335
+#: tftp.c:363
 #, c-format
 msgid "unsupported request from %s"
 msgstr "pedido no-soportado desde %s"
 
-#: tftp.c:483
+#: tftp.c:510
 #, fuzzy, c-format
 msgid "file %s not found"
 msgstr "archivo %s no encontrado"
 
-#: tftp.c:592
-#, fuzzy, c-format
-msgid "error %d %s received from %s"
-msgstr "error TFTP %d %s recibido de %s"
-
-#: tftp.c:634
+#: tftp.c:628
 #, fuzzy, c-format
 msgid "failed sending %s to %s"
 msgstr "TFTP no pudo enviar %s a %s"
 
-#: tftp.c:634
+#: tftp.c:628
 #, fuzzy, c-format
 msgid "sent %s to %s"
 msgstr "TFTP envió %s a %s"
 
+#: tftp.c:678
+#, fuzzy, c-format
+msgid "error %d %s received from %s"
+msgstr "error TFTP %d %s recibido de %s"
+
 #: log.c:190
 #, c-format
 msgid "overflow: %d log entries lost"
@@ -2023,7 +2134,7 @@ msgstr "registro fall
 msgid "FAILED to start up"
 msgstr "el inicio ha FALLADO"
 
-#: conntrack.c:65
+#: conntrack.c:63
 #, c-format
 msgid "Conntrack connection mark retrieval failed: %s"
 msgstr "Conexión conntrack con marca recuperación falló"
@@ -2043,81 +2154,76 @@ msgstr "no se pudo fijar SO_REUSE{ADDR|PORT} en z
 msgid "failed to bind DHCPv6 server socket: %s"
 msgstr "no se pudo acoplar zócalo de servidor DHCP: %s"
 
-#: rfc3315.c:157
+#: rfc3315.c:173
 #, fuzzy, c-format
 msgid "no address range available for DHCPv6 request from relay at %s"
 msgstr "ningún rango de direcciónes disponible para pedido DHCP %s %s"
 
-#: rfc3315.c:166
+#: rfc3315.c:182
 #, fuzzy, c-format
 msgid "no address range available for DHCPv6 request via %s"
 msgstr "ningún rango de direcciónes disponible para pedido DHCP %s %s"
 
-#: rfc3315.c:303
+#: rfc3315.c:316
 #, fuzzy, c-format
 msgid "%u available DHCPv6 subnet: %s/%d"
 msgstr "%u Subred DHCP disponible: %s/%s"
 
-#: rfc3315.c:386
+#: rfc3315.c:399
 #, fuzzy, c-format
 msgid "%u vendor class: %u"
 msgstr "%u Clase de vendedor: %s"
 
-#: rfc3315.c:434
+#: rfc3315.c:447
 #, fuzzy, c-format
 msgid "%u client MAC address: %s"
 msgstr "%u cliente provee nombre: %s"
 
-#: rfc3315.c:673
-#, fuzzy, c-format
-msgid "unknown prefix-class %d"
-msgstr "clase de prefijo desconocida"
-
-#: rfc3315.c:816 rfc3315.c:911
+#: rfc3315.c:762 rfc3315.c:859
 #, fuzzy
 msgid "address unavailable"
 msgstr "dirección no disponible"
 
-#: rfc3315.c:828 rfc3315.c:959 rfc3315.c:1292
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
 msgid "success"
 msgstr ""
 
-#: rfc3315.c:843 rfc3315.c:852 rfc3315.c:967 rfc3315.c:969
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
 #, fuzzy
 msgid "no addresses available"
 msgstr "ninguna dirección disponible"
 
-#: rfc3315.c:946
+#: rfc3315.c:890
 msgid "not on link"
 msgstr "no en el enlace"
 
-#: rfc3315.c:1019 rfc3315.c:1204 rfc3315.c:1281
+#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
 msgid "no binding found"
 msgstr "uniones no encontradas"
 
-#: rfc3315.c:1057
+#: rfc3315.c:1002
 msgid "deprecated"
 msgstr "descartado"
 
-#: rfc3315.c:1062
+#: rfc3315.c:1007
 #, fuzzy
 msgid "address invalid"
 msgstr "dirección en uso"
 
-#: rfc3315.c:1109
+#: rfc3315.c:1057 rfc3315.c:1059
 msgid "confirm failed"
 msgstr "confirmación falló"
 
-#: rfc3315.c:1125
+#: rfc3315.c:1074
 #, fuzzy
 msgid "all addresses still on link"
 msgstr "dirección errónea en %s línea %d"
 
-#: rfc3315.c:1213
+#: rfc3315.c:1165
 msgid "release received"
 msgstr "concesión recibida"
 
-#: rfc3315.c:2140
+#: rfc3315.c:2130
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr "No puede hacer multicast DHCPv6 sin el interfase correcto"
 
@@ -2131,76 +2237,76 @@ msgstr "Ignorando opci
 msgid "%u tags: %s"
 msgstr "%u etiquetas: %s"
 
-#: dhcp-common.c:407
+#: dhcp-common.c:444
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr "%s tiene más de una dirección en hostsfile, usando %s para DHCP"
 
-#: dhcp-common.c:430
+#: dhcp-common.c:478
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr "dirección IP duplicada %s (%s) en directiva dhcp-config"
 
-#: dhcp-common.c:491
+#: dhcp-common.c:542
 #, fuzzy, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr "no se pudo fijar SO_REUSE{ADDR|PORT} en socket DHCP: %s"
 
-#: dhcp-common.c:612
+#: dhcp-common.c:665
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr "Opciones DHCP conocidas:\n"
 
-#: dhcp-common.c:623
+#: dhcp-common.c:676
 #, fuzzy, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr "Opciones DHCP conocidas:\n"
 
-#: dhcp-common.c:820
+#: dhcp-common.c:873
 msgid ", prefix deprecated"
 msgstr ", prefijo descartado"
 
-#: dhcp-common.c:823
+#: dhcp-common.c:876
 #, c-format
 msgid ", lease time "
 msgstr ", tiempo de concesión"
 
-#: dhcp-common.c:865
+#: dhcp-common.c:918
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr "%s apátrida en %s%.0s%.0s%s"
 
-#: dhcp-common.c:867
+#: dhcp-common.c:920
 #, fuzzy, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr "DHCP, concesión estática solo en %.0s%s, tiempo de concesión %s"
 
-#: dhcp-common.c:869
+#: dhcp-common.c:922
 #, fuzzy, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr "DHCP, proxy en subred %.0s%s%.0s"
 
-#: dhcp-common.c:870
+#: dhcp-common.c:923
 #, fuzzy, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr "DHCP, rango de IPs %s -- %s, tiempo de concesión %s"
 
-#: dhcp-common.c:883
+#: dhcp-common.c:936
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr ""
 
-#: dhcp-common.c:886
+#: dhcp-common.c:939
 #, fuzzy, c-format
 msgid "router advertisement on %s%s"
 msgstr "DHCP, concesión estáticos solo en %.0s%s, tiempo de concesión %s"
 
-#: dhcp-common.c:897
+#: dhcp-common.c:950
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr ""
 
-#: dhcp-common.c:899
+#: dhcp-common.c:952
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr ""
@@ -2210,7 +2316,7 @@ msgstr ""
 msgid "cannot create ICMPv6 socket: %s"
 msgstr "no se puede crear socket DHCP: %s"
 
-#: auth.c:449
+#: auth.c:439
 #, fuzzy, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr "pedido no-soportado desde %s"
@@ -2225,18 +2331,23 @@ msgstr "no se pudo acoplar socket de servidor DHCP: %s"
 msgid "failed to create IPset control socket: %s"
 msgstr "no se pudo crear socket TFTP: %s"
 
-#: ipset.c:233
+#: ipset.c:226
 #, fuzzy, c-format
 msgid "failed to update ipset %s: %s"
 msgstr "no se pudo abrir archivo PID %s: %s"
 
-#: dnssec.c:208
+#: dnssec.c:206
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
 msgstr ""
 
-#: blockdata.c:58
+#: dnssec.c:902
+#, c-format
+msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
+msgstr ""
+
+#: blockdata.c:55
 #, c-format
-msgid "DNSSEC memory in use %u, max %u, allocated %u"
+msgid "pool memory in use %u, max %u, allocated %u"
 msgstr ""
 
 #: tables.c:61
@@ -2268,12 +2379,12 @@ msgstr "error DBus: %s"
 msgid "info: table created"
 msgstr ""
 
-#: tables.c:134
+#: tables.c:133
 #, c-format
 msgid "warning: DIOCR%sADDRS: %s"
 msgstr ""
 
-#: tables.c:138
+#: tables.c:137
 #, fuzzy, c-format
 msgid "%d addresses %s"
 msgstr "dirección IP errónea"
@@ -2313,6 +2424,83 @@ msgstr "no se puede acceder a directorio %s: %s"
 msgid "inotify, new or changed file %s"
 msgstr ""
 
+#: dump.c:64
+#, fuzzy, c-format
+msgid "cannot create %s: %s"
+msgstr "no se puede leer %s: %s"
+
+#: dump.c:70
+#, fuzzy, c-format
+msgid "bad header in %s"
+msgstr "dirección en uso"
+
+#: dump.c:201
+#, fuzzy
+msgid "failed to write packet dump"
+msgstr "no se pudo escuchar en socket: %s"
+
+#: dump.c:203
+#, c-format
+msgid "dumping UDP packet %u mask 0x%04x"
+msgstr ""
+
+#: ubus.c:52
+#, c-format
+msgid "UBus subscription callback: %s subscriber(s)"
+msgstr ""
+
+#: ubus.c:73
+#, fuzzy, c-format
+msgid "Cannot reconnect to UBus: %s"
+msgstr "no se puede abrir registro %s: %s"
+
+#: ubus.c:89
+msgid "Cannot initialize UBus: connection failed"
+msgstr ""
+
+#: ubus.c:102
+#, fuzzy, c-format
+msgid "Cannot add object to UBus: %s"
+msgstr "no se puede abrir registro %s: %s"
+
+#: ubus.c:112
+#, fuzzy
+msgid "Connected to system UBus"
+msgstr "conectado a DBus de sistema"
+
+#: ubus.c:122
+msgid "Cannot set UBus listeners: no connection"
+msgstr ""
+
+#: ubus.c:142
+msgid "Cannot poll UBus listeners: no connection"
+msgstr ""
+
+#: ubus.c:155
+msgid "Disconnecting from UBus"
+msgstr ""
+
+#: ubus.c:199
+#, fuzzy, c-format
+msgid "Failed to send UBus event: %s"
+msgstr "no se pudo escuchar en socket: %s"
+
+#~ msgid "Specify DHCPv6 prefix class"
+#~ msgstr "Especificar prefijo de clase DHCPv6"
+
+#~ msgid "cannot run scripts under uClinux"
+#~ msgstr "no se pueden correr archivos 'script' bajo uClinux"
+
+#~ msgid "cannot match tags in --dhcp-host"
+#~ msgstr "no coinciden etiquetas en --dhcp-host"
+
+#~ msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
+#~ msgstr "intento de fijar dirección de servidor IPv6 vía DBus - no hay soporte IPv6"
+
+#, fuzzy
+#~ msgid "unknown prefix-class %d"
+#~ msgstr "clase de prefijo desconocida"
+
 #, fuzzy
 #~ msgid "cannot cannonicalise resolv-file %s: %s"
 #~ msgstr "no se puede abrir o crear archivo de concesión %s: %s"
index d3c54d7..f5cac78 100644 (file)
--- a/po/fi.po
+++ b/po/fi.po
@@ -16,70 +16,70 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: cache.c:518
+#: cache.c:559
 msgid "Internal error in cache."
 msgstr ""
 
-#: cache.c:928
+#: cache.c:1081
 #, c-format
 msgid "failed to load names from %s: %s"
 msgstr ""
 
-#: cache.c:954 dhcp.c:867
+#: cache.c:1103 dhcp.c:927
 #, c-format
 msgid "bad address at %s line %d"
 msgstr ""
 
-#: cache.c:1007 dhcp.c:883
+#: cache.c:1156 dhcp.c:943
 #, c-format
 msgid "bad name at %s line %d"
 msgstr ""
 
-#: cache.c:1016 dhcp.c:958
+#: cache.c:1167 dhcp.c:1018
 #, c-format
 msgid "read %s - %d addresses"
 msgstr ""
 
-#: cache.c:1129
+#: cache.c:1283
 msgid "cleared cache"
 msgstr ""
 
-#: cache.c:1158
+#: cache.c:1345
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr ""
 
-#: cache.c:1237
+#: cache.c:1391
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr ""
 
-#: cache.c:1261
+#: cache.c:1415
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr ""
 
-#: cache.c:1418
+#: cache.c:1663
 #, c-format
 msgid "time %lu"
 msgstr ""
 
-#: cache.c:1419
+#: cache.c:1664
 #, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr ""
 
-#: cache.c:1421
+#: cache.c:1666
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr ""
 
-#: cache.c:1424
+#: cache.c:1669
 #, c-format
 msgid "queries for authoritative zones %u"
 msgstr ""
 
-#: cache.c:1450
+#: cache.c:1694
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr ""
@@ -93,1479 +93,1573 @@ msgstr ""
 msgid "failed to allocate memory"
 msgstr ""
 
-#: util.c:281 option.c:619
+#: util.c:281 option.c:641
 msgid "could not get memory"
 msgstr ""
 
-#: util.c:291
+#: util.c:302
 #, c-format
 msgid "cannot create pipe: %s"
 msgstr ""
 
-#: util.c:299
+#: util.c:310
 #, c-format
 msgid "failed to allocate %d bytes"
 msgstr ""
 
-#: util.c:468
+#: util.c:506
 #, c-format
 msgid "infinite"
 msgstr ""
 
-#: option.c:344
+#: option.c:358
 msgid "Specify local address(es) to listen on."
 msgstr ""
 
-#: option.c:345
+#: option.c:359
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr ""
 
-#: option.c:346
+#: option.c:360
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr ""
 
-#: option.c:347
+#: option.c:361
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr ""
 
-#: option.c:348
+#: option.c:362
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr ""
 
-#: option.c:349
+#: option.c:363
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr ""
 
-#: option.c:350
+#: option.c:364
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr ""
 
-#: option.c:351
+#: option.c:365
 msgid "Do NOT forward queries with no domain part."
 msgstr ""
 
-#: option.c:352
+#: option.c:366
 msgid "Return self-pointing MX records for local hosts."
 msgstr ""
 
-#: option.c:353
+#: option.c:367
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr ""
 
-#: option.c:354
+#: option.c:368
 msgid "Don't forward spurious DNS requests from Windows hosts."
 msgstr ""
 
-#: option.c:355
+#: option.c:369
 msgid "Enable DHCP in the range given with lease duration."
 msgstr ""
 
-#: option.c:356
+#: option.c:370
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr ""
 
-#: option.c:357
+#: option.c:371
 msgid "Set address or hostname for a specified machine."
 msgstr ""
 
-#: option.c:358
+#: option.c:372
 msgid "Read DHCP host specs from file."
 msgstr ""
 
-#: option.c:359
+#: option.c:373
 msgid "Read DHCP option specs from file."
 msgstr ""
 
-#: option.c:360
+#: option.c:374
 msgid "Read DHCP host specs from a directory."
 msgstr ""
 
-#: option.c:361
+#: option.c:375
 msgid "Read DHCP options from a directory."
 msgstr ""
 
-#: option.c:362
+#: option.c:376
 msgid "Evaluate conditional tag expression."
 msgstr ""
 
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Do NOT load %s file."
 msgstr ""
 
-#: option.c:364
+#: option.c:378
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr ""
 
-#: option.c:365
+#: option.c:379
 msgid "Read hosts files from a directory."
 msgstr ""
 
-#: option.c:366
+#: option.c:380
 msgid "Specify interface(s) to listen on."
 msgstr ""
 
-#: option.c:367
+#: option.c:381
 msgid "Specify interface(s) NOT to listen on."
 msgstr ""
 
-#: option.c:368
+#: option.c:382
 msgid "Map DHCP user class to tag."
 msgstr ""
 
-#: option.c:369
+#: option.c:383
 msgid "Map RFC3046 circuit-id to tag."
 msgstr ""
 
-#: option.c:370
+#: option.c:384
 msgid "Map RFC3046 remote-id to tag."
 msgstr ""
 
-#: option.c:371
+#: option.c:385
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr ""
 
-#: option.c:372
+#: option.c:386
 msgid "Don't do DHCP for hosts with tag set."
 msgstr ""
 
-#: option.c:373
+#: option.c:387
 msgid "Force broadcast replies for hosts with tag set."
 msgstr ""
 
-#: option.c:374
+#: option.c:388
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr ""
 
-#: option.c:375
+#: option.c:389
 msgid "Assume we are the only DHCP server on the local network."
 msgstr ""
 
-#: option.c:376
+#: option.c:390
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr ""
 
-#: option.c:377
+#: option.c:391
 msgid "Return MX records for local hosts."
 msgstr ""
 
-#: option.c:378
+#: option.c:392
 msgid "Specify an MX record."
 msgstr ""
 
-#: option.c:379
+#: option.c:393
 msgid "Specify BOOTP options to DHCP server."
 msgstr ""
 
-#: option.c:380
+#: option.c:394
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr ""
 
-#: option.c:381
+#: option.c:395
 msgid "Do NOT cache failed search results."
 msgstr ""
 
-#: option.c:382
+#: option.c:396
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr ""
 
-#: option.c:383
+#: option.c:397
 msgid "Specify options to be sent to DHCP clients."
 msgstr ""
 
-#: option.c:384
+#: option.c:398
 msgid "DHCP option sent even if the client does not request it."
 msgstr ""
 
-#: option.c:385
+#: option.c:399
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr ""
 
-#: option.c:386
+#: option.c:400
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr ""
 
-#: option.c:387
+#: option.c:401
 msgid "Log DNS queries."
 msgstr ""
 
-#: option.c:388
+#: option.c:402
 msgid "Force the originating port for upstream DNS queries."
 msgstr ""
 
-#: option.c:389
+#: option.c:403
 msgid "Do NOT read resolv.conf."
 msgstr ""
 
-#: option.c:390
+#: option.c:404
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr ""
 
-#: option.c:391
+#: option.c:405
 msgid "Specify path to file with server= options"
 msgstr ""
 
-#: option.c:392
+#: option.c:406
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr ""
 
-#: option.c:393
+#: option.c:407
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr ""
 
-#: option.c:394
+#: option.c:408
 msgid "Never forward queries to specified domains."
 msgstr ""
 
-#: option.c:395
+#: option.c:409
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr ""
 
-#: option.c:396
+#: option.c:410
 msgid "Specify default target in an MX record."
 msgstr ""
 
-#: option.c:397
+#: option.c:411
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr ""
 
-#: option.c:398
+#: option.c:412
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr ""
 
-#: option.c:399
+#: option.c:413
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr ""
 
-#: option.c:400
+#: option.c:414
 msgid "Specify time-to-live ceiling for cache."
 msgstr ""
 
-#: option.c:401
+#: option.c:415
 msgid "Specify time-to-live floor for cache."
 msgstr ""
 
-#: option.c:402
+#: option.c:416
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr ""
 
-#: option.c:403
+#: option.c:417
 msgid "Map DHCP vendor class to tag."
 msgstr ""
 
-#: option.c:404
+#: option.c:418
 msgid "Display dnsmasq version and copyright information."
 msgstr ""
 
-#: option.c:405
+#: option.c:419
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr ""
 
-#: option.c:406
+#: option.c:420
 msgid "Specify a SRV record."
 msgstr ""
 
-#: option.c:407
+#: option.c:421
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr ""
 
-#: option.c:408
+#: option.c:422
 #, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr ""
 
-#: option.c:409
+#: option.c:423
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr ""
 
-#: option.c:410
+#: option.c:424
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr ""
 
-#: option.c:411
+#: option.c:425
 msgid "Specify TXT DNS record."
 msgstr ""
 
-#: option.c:412
+#: option.c:426
 msgid "Specify PTR DNS record."
 msgstr ""
 
-#: option.c:413
+#: option.c:427
 msgid "Give DNS name to IPv4 address of interface."
 msgstr ""
 
-#: option.c:414
+#: option.c:428
 msgid "Bind only to interfaces in use."
 msgstr ""
 
-#: option.c:415
+#: option.c:429
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr ""
 
-#: option.c:416
+#: option.c:430
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr ""
 
-#: option.c:417
+#: option.c:431
+msgid "Enable the UBus interface."
+msgstr ""
+
+#: option.c:432
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr ""
 
-#: option.c:418
+#: option.c:433
 msgid "Enable dynamic address allocation for bootp."
 msgstr ""
 
-#: option.c:419
+#: option.c:434
 msgid "Map MAC address (with wildcards) to option set."
 msgstr ""
 
-#: option.c:420
+#: option.c:435
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr ""
 
-#: option.c:421
+#: option.c:436
+msgid "Specify extra networks sharing a broadcast domain for DHCP"
+msgstr ""
+
+#: option.c:437
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr ""
 
-#: option.c:422
+#: option.c:438
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:423
+#: option.c:439
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:424
+#: option.c:440
 msgid "Run lease-change scripts as this user."
 msgstr ""
 
-#: option.c:425
+#: option.c:441
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr ""
 
-#: option.c:426
+#: option.c:442
 msgid "Read configuration from all the files in this directory."
 msgstr ""
 
-#: option.c:427
+#: option.c:443
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr ""
 
-#: option.c:428
+#: option.c:444
 msgid "Do not use leasefile."
 msgstr ""
 
-#: option.c:429
+#: option.c:445
 #, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr ""
 
-#: option.c:430
+#: option.c:446
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr ""
 
-#: option.c:431
+#: option.c:447
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr ""
 
-#: option.c:432
+#: option.c:448
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr ""
 
-#: option.c:433
+#: option.c:449
 msgid "Enable integrated read-only TFTP server."
 msgstr ""
 
-#: option.c:434
+#: option.c:450
 msgid "Export files by TFTP only from the specified subtree."
 msgstr ""
 
-#: option.c:435
+#: option.c:451
 msgid "Add client IP or hardware address to tftp-root."
 msgstr ""
 
-#: option.c:436
+#: option.c:452
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr ""
 
-#: option.c:437
+#: option.c:453
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr ""
 
-#: option.c:438
+#: option.c:454
 #, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr ""
 
-#: option.c:439
+#: option.c:455
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr ""
 
-#: option.c:440
+#: option.c:456
 msgid "Disable the TFTP blocksize extension."
 msgstr ""
 
-#: option.c:441
+#: option.c:457
 msgid "Convert TFTP filenames to lowercase"
 msgstr ""
 
-#: option.c:442
+#: option.c:458
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr ""
 
-#: option.c:443
+#: option.c:459
+msgid "Use only one port for TFTP server."
+msgstr ""
+
+#: option.c:460
 msgid "Extra logging for DHCP."
 msgstr ""
 
-#: option.c:444
+#: option.c:461
 msgid "Enable async. logging; optionally set queue length."
 msgstr ""
 
-#: option.c:445
+#: option.c:462
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr ""
 
-#: option.c:446
+#: option.c:463
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr ""
 
-#: option.c:447
+#: option.c:464
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr ""
 
-#: option.c:448
+#: option.c:465
 msgid "Always perform DNS queries to all servers."
 msgstr ""
 
-#: option.c:449
+#: option.c:466
 msgid "Set tag if client includes matching option in request."
 msgstr ""
 
-#: option.c:450
+#: option.c:467
+msgid "Set tag if client provides given name."
+msgstr ""
+
+#: option.c:468
 msgid "Use alternative ports for DHCP."
 msgstr ""
 
-#: option.c:451
+#: option.c:469
 msgid "Specify NAPTR DNS record."
 msgstr ""
 
-#: option.c:452
+#: option.c:470
 msgid "Specify lowest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:453
+#: option.c:471
 msgid "Specify highest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:454
+#: option.c:472
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr ""
 
-#: option.c:455
+#: option.c:473
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr ""
 
-#: option.c:456
+#: option.c:474
 msgid "Use these DHCP relays as full proxies."
 msgstr ""
 
-#: option.c:457
+#: option.c:475
 msgid "Relay DHCP requests to a remote server"
 msgstr ""
 
-#: option.c:458
+#: option.c:476
 msgid "Specify alias name for LOCAL DNS name."
 msgstr ""
 
-#: option.c:459
+#: option.c:477
 msgid "Prompt to send to PXE clients."
 msgstr ""
 
-#: option.c:460
+#: option.c:478
 msgid "Boot service for PXE menu."
 msgstr ""
 
-#: option.c:461
+#: option.c:479
 msgid "Check configuration syntax."
 msgstr ""
 
-#: option.c:462
+#: option.c:480
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr ""
 
-#: option.c:463
+#: option.c:481
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr ""
 
-#: option.c:464
+#: option.c:482
 msgid "Add client identification to forwarded DNS queries."
 msgstr ""
 
-#: option.c:465
+#: option.c:483
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr ""
 
-#: option.c:466
+#: option.c:484
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr ""
 
-#: option.c:467
+#: option.c:485
+msgid "Ignore client identifier option sent by DHCP clients."
+msgstr ""
+
+#: option.c:486
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr ""
 
-#: option.c:468
+#: option.c:487
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr ""
 
-#: option.c:469
+#: option.c:488
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr ""
 
-#: option.c:470
+#: option.c:489
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr ""
 
-#: option.c:471
+#: option.c:490
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr ""
 
-#: option.c:472
+#: option.c:491
+msgid "Specify certification authority authorization record"
+msgstr ""
+
+#: option.c:492
 msgid "Specify arbitrary DNS resource record"
 msgstr ""
 
-#: option.c:473
+#: option.c:493
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr ""
 
-#: option.c:474
+#: option.c:494
 msgid "Export local names to global DNS"
 msgstr ""
 
-#: option.c:475
+#: option.c:495
 msgid "Domain to export to global DNS"
 msgstr ""
 
-#: option.c:476
+#: option.c:496
 msgid "Set TTL for authoritative replies"
 msgstr ""
 
-#: option.c:477
+#: option.c:497
 msgid "Set authoritative zone information"
 msgstr ""
 
-#: option.c:478
+#: option.c:498
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr ""
 
-#: option.c:479
+#: option.c:499
 msgid "Peers which are allowed to do zone transfer"
 msgstr ""
 
-#: option.c:480
+#: option.c:500
 msgid "Specify ipsets to which matching domains should be added"
 msgstr ""
 
-#: option.c:481
+#: option.c:501
 msgid "Specify a domain and address range for synthesised names"
 msgstr ""
 
-#: option.c:482
+#: option.c:502
 msgid "Activate DNSSEC validation"
 msgstr ""
 
-#: option.c:483
+#: option.c:503
 msgid "Specify trust anchor key digest."
 msgstr ""
 
-#: option.c:484
+#: option.c:504
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr ""
 
-#: option.c:485
+#: option.c:505
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr ""
 
-#: option.c:486
+#: option.c:506
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr ""
 
-#: option.c:487
+#: option.c:507
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr ""
 
-#: option.c:489
-msgid "Specify DHCPv6 prefix class"
-msgstr ""
-
-#: option.c:491
+#: option.c:508
 msgid "Set MTU, priority, resend-interval and router-lifetime"
 msgstr ""
 
-#: option.c:492
+#: option.c:509
 msgid "Do not log routine DHCP."
 msgstr ""
 
-#: option.c:493
+#: option.c:510
 msgid "Do not log routine DHCPv6."
 msgstr ""
 
-#: option.c:494
+#: option.c:511
 msgid "Do not log RA."
 msgstr ""
 
-#: option.c:495
+#: option.c:512
 msgid "Accept queries only from directly-connected networks."
 msgstr ""
 
-#: option.c:496
+#: option.c:513
 msgid "Detect and remove DNS forwarding loops."
 msgstr ""
 
-#: option.c:497
+#: option.c:514
 msgid "Ignore DNS responses containing ipaddr."
 msgstr ""
 
-#: option.c:498
+#: option.c:515
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr ""
 
-#: option.c:499
+#: option.c:516
 msgid "Delay DHCP replies for at least number of seconds."
 msgstr ""
 
-#: option.c:703
+#: option.c:517
+msgid "Enables DHCPv4 Rapid Commit option."
+msgstr ""
+
+#: option.c:518
+msgid "Path to debug packet dump file"
+msgstr ""
+
+#: option.c:519
+msgid "Mask which packets to dump"
+msgstr ""
+
+#: option.c:520
+msgid "Call dhcp-script when lease expiry changes."
+msgstr ""
+
+#: option.c:725
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
 "\n"
 msgstr ""
 
-#: option.c:705
+#: option.c:727
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr ""
 
-#: option.c:707
+#: option.c:729
 #, c-format
 msgid "Valid options are:\n"
 msgstr ""
 
-#: option.c:754 option.c:868
+#: option.c:776 option.c:884
 msgid "bad address"
 msgstr ""
 
-#: option.c:779 option.c:783
+#: option.c:799 option.c:803
 msgid "bad port"
 msgstr ""
 
-#: option.c:797 option.c:826 option.c:861
+#: option.c:815 option.c:844 option.c:878
 msgid "interface binding not supported"
 msgstr ""
 
-#: option.c:821 option.c:856
+#: option.c:839 option.c:873
 msgid "interface can only be specified once"
 msgstr ""
 
-#: option.c:835 option.c:3809
+#: option.c:852 option.c:4042
 msgid "bad interface name"
 msgstr ""
 
-#: option.c:1062
+#: option.c:1184
 msgid "unsupported encapsulation for IPv6 option"
 msgstr ""
 
-#: option.c:1076
+#: option.c:1198
 msgid "bad dhcp-option"
 msgstr ""
 
-#: option.c:1144
+#: option.c:1270
 msgid "bad IP address"
 msgstr ""
 
-#: option.c:1147 option.c:1286 option.c:3079
+#: option.c:1273 option.c:1412 option.c:3297
 msgid "bad IPv6 address"
 msgstr ""
 
-#: option.c:1240
+#: option.c:1366
 msgid "bad IPv4 address"
 msgstr ""
 
-#: option.c:1313 option.c:1407
+#: option.c:1439 option.c:1533
 msgid "bad domain in dhcp-option"
 msgstr ""
 
-#: option.c:1445
+#: option.c:1571
 msgid "dhcp-option too long"
 msgstr ""
 
-#: option.c:1452
+#: option.c:1578
 msgid "illegal dhcp-match"
 msgstr ""
 
-#: option.c:1514
+#: option.c:1647
 msgid "illegal repeated flag"
 msgstr ""
 
-#: option.c:1522
+#: option.c:1655
 msgid "illegal repeated keyword"
 msgstr ""
 
-#: option.c:1593 option.c:4443
+#: option.c:1726 option.c:4764
 #, c-format
 msgid "cannot access directory %s: %s"
 msgstr ""
 
-#: option.c:1639 tftp.c:537
+#: option.c:1772 tftp.c:564 dump.c:68
 #, c-format
 msgid "cannot access %s: %s"
 msgstr ""
 
-#: option.c:1727
+#: option.c:1879
 msgid "setting log facility is not possible under Android"
 msgstr ""
 
-#: option.c:1736
+#: option.c:1888
 msgid "bad log facility"
 msgstr ""
 
-#: option.c:1789
+#: option.c:1941
 msgid "bad MX preference"
 msgstr ""
 
-#: option.c:1794
+#: option.c:1946
 msgid "bad MX name"
 msgstr ""
 
-#: option.c:1808
+#: option.c:1960
 msgid "bad MX target"
 msgstr ""
 
-#: option.c:1820
-msgid "cannot run scripts under uClinux"
-msgstr ""
-
-#: option.c:1822
+#: option.c:1980
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr ""
 
-#: option.c:1826
+#: option.c:1984
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr ""
 
-#: option.c:2095 option.c:2106 option.c:2143 option.c:2199 option.c:2482
+#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
 msgid "bad prefix"
 msgstr ""
 
-#: option.c:2504
+#: option.c:2658
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr ""
 
-#: option.c:2713
+#: option.c:2871
 msgid "bad port range"
 msgstr ""
 
-#: option.c:2739
+#: option.c:2897
 msgid "bad bridge-interface"
 msgstr ""
 
-#: option.c:2807
+#: option.c:2941
+msgid "bad shared-network"
+msgstr ""
+
+#: option.c:2996
 msgid "only one tag allowed"
 msgstr ""
 
-#: option.c:2827 option.c:2839 option.c:2948 option.c:2953 option.c:2992
+#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
 msgid "bad dhcp-range"
 msgstr ""
 
-#: option.c:2854
+#: option.c:3050
 msgid "inconsistent DHCP range"
 msgstr ""
 
-#: option.c:2916
+#: option.c:3115
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr ""
 
-#: option.c:2918
+#: option.c:3117
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr ""
 
-#: option.c:2922
+#: option.c:3120
 msgid "prefix length must be at least 64"
 msgstr ""
 
-#: option.c:2925
+#: option.c:3123
 msgid "inconsistent DHCPv6 range"
 msgstr ""
 
-#: option.c:2936
+#: option.c:3142
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr ""
 
-#: option.c:3049 option.c:3097
+#: option.c:3262 option.c:3340
 msgid "bad hex constant"
 msgstr ""
 
-#: option.c:3071
-msgid "cannot match tags in --dhcp-host"
+#: option.c:3315
+msgid "bad IPv6 prefix"
 msgstr ""
 
-#: option.c:3119
+#: option.c:3362
 #, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr ""
 
-#: option.c:3177
+#: option.c:3422
 msgid "bad DHCP host name"
 msgstr ""
 
-#: option.c:3259
+#: option.c:3508
 msgid "bad tag-if"
 msgstr ""
 
-#: option.c:3616 option.c:4039
+#: option.c:3851 option.c:4324
 msgid "invalid port number"
 msgstr ""
 
-#: option.c:3678
+#: option.c:3907
 msgid "bad dhcp-proxy address"
 msgstr ""
 
-#: option.c:3704
+#: option.c:3935
 msgid "Bad dhcp-relay"
 msgstr ""
 
-#: option.c:3745
+#: option.c:3979
 msgid "bad RA-params"
 msgstr ""
 
-#: option.c:3754
+#: option.c:3989
 msgid "bad DUID"
 msgstr ""
 
-#: option.c:3796
+#: option.c:4023
+msgid "missing address in alias"
+msgstr ""
+
+#: option.c:4029
 msgid "invalid alias range"
 msgstr ""
 
-#: option.c:3850 option.c:3862
+#: option.c:4081 option.c:4097
 msgid "bad CNAME"
 msgstr ""
 
-#: option.c:3866
+#: option.c:4105
 msgid "duplicate CNAME"
 msgstr ""
 
-#: option.c:3889
+#: option.c:4132
 msgid "bad PTR record"
 msgstr ""
 
-#: option.c:3920
+#: option.c:4167
 msgid "bad NAPTR record"
 msgstr ""
 
-#: option.c:3954
+#: option.c:4203
 msgid "bad RR record"
 msgstr ""
 
-#: option.c:3984
+#: option.c:4236
+msgid "bad CAA record"
+msgstr ""
+
+#: option.c:4265
 msgid "bad TXT record"
 msgstr ""
 
-#: option.c:4025
+#: option.c:4308
 msgid "bad SRV record"
 msgstr ""
 
-#: option.c:4032
+#: option.c:4315
 msgid "bad SRV target"
 msgstr ""
 
-#: option.c:4046
+#: option.c:4334
 msgid "invalid priority"
 msgstr ""
 
-#: option.c:4049
+#: option.c:4339
 msgid "invalid weight"
 msgstr ""
 
-#: option.c:4073
+#: option.c:4362
 msgid "Bad host-record"
 msgstr ""
 
-#: option.c:4097
+#: option.c:4402
 msgid "Bad name in host-record"
 msgstr ""
 
-#: option.c:4162
+#: option.c:4444
+msgid "bad value for dnssec-check-unsigned"
+msgstr ""
+
+#: option.c:4480
 msgid "bad trust anchor"
 msgstr ""
 
-#: option.c:4176
+#: option.c:4496
 msgid "bad HEX in trust anchor"
 msgstr ""
 
-#: option.c:4186
+#: option.c:4507
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr ""
 
-#: option.c:4246
+#: option.c:4567
 msgid "missing \""
 msgstr ""
 
-#: option.c:4303
+#: option.c:4624
 msgid "bad option"
 msgstr ""
 
-#: option.c:4305
+#: option.c:4626
 msgid "extraneous parameter"
 msgstr ""
 
-#: option.c:4307
+#: option.c:4628
 msgid "missing parameter"
 msgstr ""
 
-#: option.c:4309
+#: option.c:4630
 msgid "illegal option"
 msgstr ""
 
-#: option.c:4316
+#: option.c:4637
 msgid "error"
 msgstr ""
 
-#: option.c:4318
+#: option.c:4639
 #, c-format
 msgid " at line %d of %s"
 msgstr ""
 
-#: option.c:4333 option.c:4580 option.c:4616
+#: option.c:4654 option.c:4939 option.c:4950
 #, c-format
 msgid "read %s"
 msgstr ""
 
-#: option.c:4396 option.c:4519 tftp.c:715
+#: option.c:4717 option.c:4840 tftp.c:754
 #, c-format
 msgid "cannot read %s: %s"
 msgstr ""
 
-#: option.c:4688
+#: option.c:5027
 msgid "junk found in command line"
 msgstr ""
 
-#: option.c:4729
+#: option.c:5067
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr ""
 
-#: option.c:4730
+#: option.c:5068
 #, c-format
 msgid ""
 "Compile time options: %s\n"
 "\n"
 msgstr ""
 
-#: option.c:4731
+#: option.c:5069
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr ""
 
-#: option.c:4732
+#: option.c:5070
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr ""
 
-#: option.c:4733
+#: option.c:5071
 #, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr ""
 
-#: option.c:4744
+#: option.c:5088
 msgid "try --help"
 msgstr ""
 
-#: option.c:4746
+#: option.c:5090
 msgid "try -w"
 msgstr ""
 
-#: option.c:4748
+#: option.c:5092
 #, c-format
 msgid "bad command line options: %s"
 msgstr ""
 
-#: option.c:4818
+#: option.c:5161
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr ""
 
-#: option.c:4854
+#: option.c:5195
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr ""
 
-#: option.c:4882
+#: option.c:5223
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr ""
 
-#: option.c:4892
+#: option.c:5233
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr ""
 
-#: option.c:4895 network.c:1623 dhcp.c:816
+#: option.c:5236 network.c:1594 dhcp.c:876
 #, c-format
 msgid "failed to read %s: %s"
 msgstr ""
 
-#: option.c:4912
+#: option.c:5253
 #, c-format
 msgid "no search directive found in %s"
 msgstr ""
 
-#: option.c:4933
+#: option.c:5274
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr ""
 
-#: option.c:4942
+#: option.c:5283
 msgid "syntax check OK"
 msgstr ""
 
-#: forward.c:102
+#: forward.c:99
 #, c-format
 msgid "failed to send packet: %s"
 msgstr ""
 
-#: forward.c:598
+#: forward.c:614
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr ""
 
-#: forward.c:652
+#: forward.c:677
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr ""
 
-#: forward.c:684
+#: forward.c:709
 #, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr ""
 
-#: forward.c:870
+#: forward.c:961
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
 msgstr ""
 
-#: forward.c:1266 forward.c:1704
+#: forward.c:1370 forward.c:1830
 msgid "Ignoring query from non-local network"
 msgstr ""
 
-#: forward.c:2184
+#: forward.c:2321
 #, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr ""
 
-#: network.c:720
+#: network.c:698
 #, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr ""
 
-#: network.c:1031
+#: network.c:1002
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr ""
 
-#: network.c:1038
+#: network.c:1009
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr ""
 
-#: network.c:1047
+#: network.c:1018
 #, c-format
 msgid "warning: using interface %s instead"
 msgstr ""
 
-#: network.c:1056
+#: network.c:1027
 #, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr ""
 
-#: network.c:1114
+#: network.c:1085
 #, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr ""
 
-#: network.c:1119
+#: network.c:1090
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr ""
 
-#: network.c:1337
+#: network.c:1307
 #, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr ""
 
-#: network.c:1528
+#: network.c:1499
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr ""
 
-#: network.c:1539
+#: network.c:1510
 #, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr ""
 
-#: network.c:1559
+#: network.c:1530
 msgid "(no DNSSEC)"
 msgstr ""
 
-#: network.c:1562
+#: network.c:1533
 msgid "unqualified"
 msgstr ""
 
-#: network.c:1562
+#: network.c:1533
 msgid "names"
 msgstr ""
 
-#: network.c:1564
+#: network.c:1535
 msgid "default"
 msgstr ""
 
-#: network.c:1566
+#: network.c:1537
 msgid "domain"
 msgstr ""
 
-#: network.c:1572
+#: network.c:1543
 #, c-format
-msgid "using local addresses only for %s %s"
+msgid "using only locally-known addresses for %s %s"
 msgstr ""
 
-#: network.c:1575
+#: network.c:1546
 #, c-format
 msgid "using standard nameservers for %s %s"
 msgstr ""
 
-#: network.c:1577
+#: network.c:1548
 #, c-format
 msgid "using nameserver %s#%d for %s %s %s"
 msgstr ""
 
-#: network.c:1581
+#: network.c:1552
 #, c-format
 msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr ""
 
-#: network.c:1584
+#: network.c:1555
 #, c-format
 msgid "using nameserver %s#%d(via %s)"
 msgstr ""
 
-#: network.c:1586
+#: network.c:1557
 #, c-format
 msgid "using nameserver %s#%d"
 msgstr ""
 
-#: network.c:1591
+#: network.c:1562
 #, c-format
 msgid "using %d more local addresses"
 msgstr ""
 
-#: network.c:1593
+#: network.c:1564
 #, c-format
 msgid "using %d more nameservers"
 msgstr ""
 
-#: dnsmasq.c:171
+#: dnsmasq.c:173
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr ""
 
-#: dnsmasq.c:186
+#: dnsmasq.c:188
 msgid "no root trust anchor provided for DNSSEC"
 msgstr ""
 
-#: dnsmasq.c:189
+#: dnsmasq.c:191
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr ""
 
-#: dnsmasq.c:191
+#: dnsmasq.c:193
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:197
+#: dnsmasq.c:199
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:202
+#: dnsmasq.c:204
 msgid "cannot use --conntrack AND --query-port"
 msgstr ""
 
-#: dnsmasq.c:205
+#: dnsmasq.c:207
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:210
+#: dnsmasq.c:212
 msgid "asynchronous logging is not available under Solaris"
 msgstr ""
 
-#: dnsmasq.c:215
+#: dnsmasq.c:217
 msgid "asynchronous logging is not available under Android"
 msgstr ""
 
-#: dnsmasq.c:220
+#: dnsmasq.c:222
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:225
+#: dnsmasq.c:227
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:229
-msgid "max_port cannot be smaller than min_port"
+#: dnsmasq.c:232
+msgid "Ubus not available: set HAVE_UBUS in src/config.h"
 msgstr ""
 
 #: dnsmasq.c:236
+msgid "max_port cannot be smaller than min_port"
+msgstr ""
+
+#: dnsmasq.c:243
+msgid "--auth-server required when an auth zone is defined."
+msgstr ""
+
+#: dnsmasq.c:248
 msgid "zone serial must be configured in --auth-soa"
 msgstr ""
 
-#: dnsmasq.c:254
+#: dnsmasq.c:268
 msgid "dhcp-range constructor not available on this platform"
 msgstr ""
 
-#: dnsmasq.c:300
+#: dnsmasq.c:332
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr ""
 
-#: dnsmasq.c:303
+#: dnsmasq.c:335
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr ""
 
-#: dnsmasq.c:312
+#: dnsmasq.c:344
 #, c-format
 msgid "unknown interface %s"
 msgstr ""
 
-#: dnsmasq.c:377 dnsmasq.c:1054
+#: dnsmasq.c:406
+msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
+msgstr ""
+
+#: dnsmasq.c:416 dnsmasq.c:1171
 #, c-format
 msgid "DBus error: %s"
 msgstr ""
 
-#: dnsmasq.c:380
+#: dnsmasq.c:419
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:410
+#: dnsmasq.c:429
+msgid "UBus not available: set HAVE_UBUS in src/config.h"
+msgstr ""
+
+#: dnsmasq.c:459
 #, c-format
 msgid "unknown user or group: %s"
 msgstr ""
 
-#: dnsmasq.c:465
+#: dnsmasq.c:535
+#, c-format
+msgid "process is missing required capability %s"
+msgstr ""
+
+#: dnsmasq.c:567
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr ""
 
-#: dnsmasq.c:730
+#: dnsmasq.c:815
 #, c-format
 msgid "started, version %s DNS disabled"
 msgstr ""
 
-#: dnsmasq.c:734
+#: dnsmasq.c:820
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr ""
 
-#: dnsmasq.c:736
+#: dnsmasq.c:822
+msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
+msgstr ""
+
+#: dnsmasq.c:825
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr ""
 
-#: dnsmasq.c:739
+#: dnsmasq.c:828
 msgid "DNS service limited to local subnets"
 msgstr ""
 
-#: dnsmasq.c:742
+#: dnsmasq.c:831
 #, c-format
 msgid "compile time options: %s"
 msgstr ""
 
-#: dnsmasq.c:751
+#: dnsmasq.c:840
 msgid "DBus support enabled: connected to system bus"
 msgstr ""
 
-#: dnsmasq.c:753
+#: dnsmasq.c:842
 msgid "DBus support enabled: bus connection pending"
 msgstr ""
 
-#: dnsmasq.c:771
+#: dnsmasq.c:850
+msgid "UBus support enabled: connected to system bus"
+msgstr ""
+
+#: dnsmasq.c:852
+msgid "UBus support enabled: bus connection pending"
+msgstr ""
+
+#: dnsmasq.c:872
+msgid "DNSSEC validation enabled but all unsigned answers are trusted"
+msgstr ""
+
+#: dnsmasq.c:874
 msgid "DNSSEC validation enabled"
 msgstr ""
 
-#: dnsmasq.c:775
+#: dnsmasq.c:878
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr ""
 
-#: dnsmasq.c:778
+#: dnsmasq.c:881
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr ""
 
-#: dnsmasq.c:783
+#: dnsmasq.c:884
+#, c-format
+msgid "configured with trust anchor for %s keytag %u"
+msgstr ""
+
+#: dnsmasq.c:890
 #, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr ""
 
-#: dnsmasq.c:787
+#: dnsmasq.c:894
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr ""
 
-#: dnsmasq.c:799
+#: dnsmasq.c:906
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr ""
 
-#: dnsmasq.c:804
+#: dnsmasq.c:911
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr ""
 
-#: dnsmasq.c:807
+#: dnsmasq.c:914
 msgid "warning: no upstream servers configured"
 msgstr ""
 
-#: dnsmasq.c:811
+#: dnsmasq.c:918
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr ""
 
-#: dnsmasq.c:832
+#: dnsmasq.c:939
 msgid "IPv6 router advertisement enabled"
 msgstr ""
 
-#: dnsmasq.c:837
+#: dnsmasq.c:944
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr ""
 
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 msgid "root is "
 msgstr ""
 
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 msgid "enabled"
 msgstr ""
 
-#: dnsmasq.c:853
+#: dnsmasq.c:960
 msgid "secure mode"
 msgstr ""
 
-#: dnsmasq.c:856
+#: dnsmasq.c:961
+msgid "single port mode"
+msgstr ""
+
+#: dnsmasq.c:964
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:860
+#: dnsmasq.c:968
 #, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:886
+#: dnsmasq.c:994
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr ""
 
-#: dnsmasq.c:1056
+#: dnsmasq.c:1173
 msgid "connected to system DBus"
 msgstr ""
 
-#: dnsmasq.c:1215
+#: dnsmasq.c:1345
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr ""
 
-#: dnsmasq.c:1218
+#: dnsmasq.c:1349
 #, c-format
 msgid "failed to create helper: %s"
 msgstr ""
 
-#: dnsmasq.c:1221
+#: dnsmasq.c:1353
 #, c-format
 msgid "setting capabilities failed: %s"
 msgstr ""
 
-#: dnsmasq.c:1224
+#: dnsmasq.c:1357
 #, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1227
+#: dnsmasq.c:1361
 #, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1230
+#: dnsmasq.c:1365
 #, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1233
+#: dnsmasq.c:1369
 #, c-format
 msgid "cannot open log %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1236
+#: dnsmasq.c:1373
 #, c-format
 msgid "failed to load Lua script: %s"
 msgstr ""
 
-#: dnsmasq.c:1239
+#: dnsmasq.c:1377
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr ""
 
-#: dnsmasq.c:1242
+#: dnsmasq.c:1381
 #, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1326
+#: dnsmasq.c:1465
 #, c-format
 msgid "script process killed by signal %d"
 msgstr ""
 
-#: dnsmasq.c:1330
+#: dnsmasq.c:1469
 #, c-format
 msgid "script process exited with status %d"
 msgstr ""
 
-#: dnsmasq.c:1334
+#: dnsmasq.c:1473
 #, c-format
 msgid "failed to execute %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1374
+#: dnsmasq.c:1513
 msgid "now checking DNSSEC signature timestamps"
 msgstr ""
 
-#: dnsmasq.c:1409 dnssec.c:160 dnssec.c:206
+#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
 #, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1416
+#: dnsmasq.c:1560
 msgid "exiting on receipt of SIGTERM"
 msgstr ""
 
-#: dnsmasq.c:1444
+#: dnsmasq.c:1588
 #, c-format
 msgid "failed to access %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1474
+#: dnsmasq.c:1618
 #, c-format
 msgid "reading %s"
 msgstr ""
 
-#: dnsmasq.c:1485
+#: dnsmasq.c:1629
 #, c-format
 msgid "no servers found in %s, will retry"
 msgstr ""
@@ -1595,7 +1689,7 @@ msgstr ""
 msgid "cannot create ICMP raw socket: %s."
 msgstr ""
 
-#: dhcp.c:252 dhcp6.c:173
+#: dhcp.c:252 dhcp6.c:180
 #, c-format
 msgid "unknown interface %s in bridge-interface"
 msgstr ""
@@ -1605,329 +1699,334 @@ msgstr ""
 msgid "DHCP packet received on %s which has no address"
 msgstr ""
 
-#: dhcp.c:427
+#: dhcp.c:428
 #, c-format
 msgid "ARP-cache injection failed: %s"
 msgstr ""
 
-#: dhcp.c:470
+#: dhcp.c:471
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr ""
 
-#: dhcp.c:531
+#: dhcp.c:526
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr ""
 
-#: dhcp.c:854
+#: dhcp.c:914
 #, c-format
 msgid "bad line at %s line %d"
 msgstr ""
 
-#: dhcp.c:897
+#: dhcp.c:957
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr ""
 
-#: dhcp.c:1041 rfc3315.c:2149
+#: dhcp.c:1100 rfc3315.c:2139
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr ""
 
-#: lease.c:98
+#: lease.c:64
+#, c-format
+msgid "ignoring invalid line in lease database: %s %s %s %s ..."
+msgstr ""
+
+#: lease.c:101
+#, c-format
+msgid "ignoring invalid line in lease database, bad address: %s"
+msgstr ""
+
+#: lease.c:108
 msgid "too many stored leases"
 msgstr ""
 
-#: lease.c:166
+#: lease.c:176
 #, c-format
 msgid "cannot open or create lease file %s: %s"
 msgstr ""
 
-#: lease.c:175
-#, c-format
-msgid "failed to parse lease database, invalid line: %s %s %s %s ..."
+#: lease.c:185
+msgid "failed to parse lease database cleanly"
 msgstr ""
 
-#: lease.c:180
+#: lease.c:188
 #, c-format
 msgid "failed to read lease file %s: %s"
 msgstr ""
 
-#: lease.c:196
+#: lease.c:204
 #, c-format
 msgid "cannot run lease-init script %s: %s"
 msgstr ""
 
-#: lease.c:202
+#: lease.c:210
 #, c-format
 msgid "lease-init script returned exit code %s"
 msgstr ""
 
-#: lease.c:373
+#: lease.c:381
 #, c-format
 msgid "failed to write %s: %s (retry in %us)"
 msgstr ""
 
-#: lease.c:937
+#: lease.c:955
 #, c-format
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr ""
 
-#: rfc2131.c:347
+#: rfc2131.c:372
 #, c-format
 msgid "no address range available for DHCP request %s %s"
 msgstr ""
 
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "with subnet selector"
 msgstr ""
 
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "via"
 msgstr ""
 
-#: rfc2131.c:360
+#: rfc2131.c:385
 #, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr ""
 
-#: rfc2131.c:363 rfc3315.c:306
+#: rfc2131.c:388 rfc3315.c:319
 #, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr ""
 
-#: rfc2131.c:474
+#: rfc2131.c:499
 #, c-format
 msgid "%u vendor class: %s"
 msgstr ""
 
-#: rfc2131.c:476
+#: rfc2131.c:501
 #, c-format
 msgid "%u user class: %s"
 msgstr ""
 
-#: rfc2131.c:510
+#: rfc2131.c:535
 msgid "disabled"
 msgstr ""
 
-#: rfc2131.c:551 rfc2131.c:1006 rfc2131.c:1430 rfc3315.c:616 rfc3315.c:869
-#: rfc3315.c:1148
+#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1097
 msgid "ignored"
 msgstr ""
 
-#: rfc2131.c:566 rfc2131.c:1239 rfc3315.c:919
+#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
 msgid "address in use"
 msgstr ""
 
-#: rfc2131.c:580 rfc2131.c:1060
+#: rfc2131.c:605 rfc2131.c:1119
 msgid "no address available"
 msgstr ""
 
-#: rfc2131.c:587 rfc2131.c:1202
+#: rfc2131.c:612 rfc2131.c:1273
 msgid "wrong network"
 msgstr ""
 
-#: rfc2131.c:602
+#: rfc2131.c:627
 msgid "no address configured"
 msgstr ""
 
-#: rfc2131.c:608 rfc2131.c:1252
+#: rfc2131.c:633 rfc2131.c:1323
 msgid "no leases left"
 msgstr ""
 
-#: rfc2131.c:703 rfc3315.c:482
+#: rfc2131.c:734 rfc3315.c:499
 #, c-format
 msgid "%u client provides name: %s"
 msgstr ""
 
-#: rfc2131.c:808
+#: rfc2131.c:864
 msgid "PXE BIS not supported"
 msgstr ""
 
-#: rfc2131.c:974 rfc3315.c:1242
+#: rfc2131.c:1032 rfc3315.c:1197
 #, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr ""
 
-#: rfc2131.c:995
+#: rfc2131.c:1053
 msgid "unknown lease"
 msgstr ""
 
-#: rfc2131.c:1029
+#: rfc2131.c:1088
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr ""
 
-#: rfc2131.c:1039
+#: rfc2131.c:1098
 #, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr ""
 
-#: rfc2131.c:1042
+#: rfc2131.c:1101
 #, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr ""
 
-#: rfc2131.c:1058 rfc2131.c:1245
+#: rfc2131.c:1117 rfc2131.c:1316
 msgid "no unique-id"
 msgstr ""
 
-#: rfc2131.c:1140
+#: rfc2131.c:1209
 msgid "wrong server-ID"
 msgstr ""
 
-#: rfc2131.c:1159
+#: rfc2131.c:1228
 msgid "wrong address"
 msgstr ""
 
-#: rfc2131.c:1177 rfc3315.c:1015
+#: rfc2131.c:1246 rfc3315.c:961
 msgid "lease not found"
 msgstr ""
 
-#: rfc2131.c:1210
+#: rfc2131.c:1281
 msgid "address not available"
 msgstr ""
 
-#: rfc2131.c:1221
+#: rfc2131.c:1292
 msgid "static lease available"
 msgstr ""
 
-#: rfc2131.c:1225
+#: rfc2131.c:1296
 msgid "address reserved"
 msgstr ""
 
-#: rfc2131.c:1233
+#: rfc2131.c:1304
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr ""
 
-#: rfc2131.c:1757
+#: rfc2131.c:1845
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr ""
 
-#: rfc2131.c:1766
+#: rfc2131.c:1854
 #, c-format
 msgid "%u server name: %s"
 msgstr ""
 
-#: rfc2131.c:1774
+#: rfc2131.c:1862
 #, c-format
 msgid "%u next server: %s"
 msgstr ""
 
-#: rfc2131.c:1777
+#: rfc2131.c:1865
 #, c-format
 msgid "%u broadcast response"
 msgstr ""
 
-#: rfc2131.c:1840
+#: rfc2131.c:1928
 #, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr ""
 
-#: rfc2131.c:2131
+#: rfc2131.c:2219
 msgid "PXE menu too large"
 msgstr ""
 
-#: rfc2131.c:2270 rfc3315.c:1515
+#: rfc2131.c:2358 rfc3315.c:1470
 #, c-format
 msgid "%u requested options: %s"
 msgstr ""
 
-#: rfc2131.c:2587
+#: rfc2131.c:2675
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr ""
 
-#: rfc2131.c:2650
+#: rfc2131.c:2738
 #, c-format
 msgid "%u reply delay: %d"
 msgstr ""
 
-#: netlink.c:77
+#: netlink.c:76
 #, c-format
 msgid "cannot create netlink socket: %s"
 msgstr ""
 
-#: netlink.c:355
+#: netlink.c:352
 #, c-format
 msgid "netlink returns error: %s"
 msgstr ""
 
-#: dbus.c:186
-msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
-msgstr ""
-
-#: dbus.c:439
+#: dbus.c:438
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:444
+#: dbus.c:443
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:690
+#: dbus.c:717
 msgid "setting upstream servers from DBus"
 msgstr ""
 
-#: dbus.c:737
+#: dbus.c:764
 msgid "could not register a DBus message handler"
 msgstr ""
 
-#: bpf.c:265
+#: bpf.c:261
 #, c-format
 msgid "cannot create DHCP BPF socket: %s"
 msgstr ""
 
-#: bpf.c:293
+#: bpf.c:289
 #, c-format
 msgid "DHCP request for unsupported hardware type (%d) received on %s"
 msgstr ""
 
-#: bpf.c:378
+#: bpf.c:374
 #, c-format
 msgid "cannot create PF_ROUTE socket: %s"
 msgstr ""
 
-#: bpf.c:399
+#: bpf.c:395
 msgid "Unknown protocol version from route socket"
 msgstr ""
 
-#: helper.c:154
+#: helper.c:150
 msgid "lease() function missing in Lua script"
 msgstr ""
 
-#: tftp.c:319
+#: tftp.c:347
 msgid "unable to get free port for TFTP"
 msgstr ""
 
-#: tftp.c:335
+#: tftp.c:363
 #, c-format
 msgid "unsupported request from %s"
 msgstr ""
 
-#: tftp.c:483
+#: tftp.c:510
 #, c-format
 msgid "file %s not found"
 msgstr ""
 
-#: tftp.c:592
+#: tftp.c:628
 #, c-format
-msgid "error %d %s received from %s"
+msgid "failed sending %s to %s"
 msgstr ""
 
-#: tftp.c:634
+#: tftp.c:628
 #, c-format
-msgid "failed sending %s to %s"
+msgid "sent %s to %s"
 msgstr ""
 
-#: tftp.c:634
+#: tftp.c:678
 #, c-format
-msgid "sent %s to %s"
+msgid "error %d %s received from %s"
 msgstr ""
 
 #: log.c:190
@@ -1944,7 +2043,7 @@ msgstr ""
 msgid "FAILED to start up"
 msgstr ""
 
-#: conntrack.c:65
+#: conntrack.c:63
 #, c-format
 msgid "Conntrack connection mark retrieval failed: %s"
 msgstr ""
@@ -1964,77 +2063,72 @@ msgstr ""
 msgid "failed to bind DHCPv6 server socket: %s"
 msgstr ""
 
-#: rfc3315.c:157
+#: rfc3315.c:173
 #, c-format
 msgid "no address range available for DHCPv6 request from relay at %s"
 msgstr ""
 
-#: rfc3315.c:166
+#: rfc3315.c:182
 #, c-format
 msgid "no address range available for DHCPv6 request via %s"
 msgstr ""
 
-#: rfc3315.c:303
+#: rfc3315.c:316
 #, c-format
 msgid "%u available DHCPv6 subnet: %s/%d"
 msgstr ""
 
-#: rfc3315.c:386
+#: rfc3315.c:399
 #, c-format
 msgid "%u vendor class: %u"
 msgstr ""
 
-#: rfc3315.c:434
+#: rfc3315.c:447
 #, c-format
 msgid "%u client MAC address: %s"
 msgstr ""
 
-#: rfc3315.c:673
-#, c-format
-msgid "unknown prefix-class %d"
-msgstr ""
-
-#: rfc3315.c:816 rfc3315.c:911
+#: rfc3315.c:762 rfc3315.c:859
 msgid "address unavailable"
 msgstr ""
 
-#: rfc3315.c:828 rfc3315.c:959 rfc3315.c:1292
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
 msgid "success"
 msgstr ""
 
-#: rfc3315.c:843 rfc3315.c:852 rfc3315.c:967 rfc3315.c:969
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
 msgid "no addresses available"
 msgstr ""
 
-#: rfc3315.c:946
+#: rfc3315.c:890
 msgid "not on link"
 msgstr ""
 
-#: rfc3315.c:1019 rfc3315.c:1204 rfc3315.c:1281
+#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
 msgid "no binding found"
 msgstr ""
 
-#: rfc3315.c:1057
+#: rfc3315.c:1002
 msgid "deprecated"
 msgstr ""
 
-#: rfc3315.c:1062
+#: rfc3315.c:1007
 msgid "address invalid"
 msgstr ""
 
-#: rfc3315.c:1109
+#: rfc3315.c:1057 rfc3315.c:1059
 msgid "confirm failed"
 msgstr ""
 
-#: rfc3315.c:1125
+#: rfc3315.c:1074
 msgid "all addresses still on link"
 msgstr ""
 
-#: rfc3315.c:1213
+#: rfc3315.c:1165
 msgid "release received"
 msgstr ""
 
-#: rfc3315.c:2140
+#: rfc3315.c:2130
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr ""
 
@@ -2048,76 +2142,76 @@ msgstr ""
 msgid "%u tags: %s"
 msgstr ""
 
-#: dhcp-common.c:407
+#: dhcp-common.c:444
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr ""
 
-#: dhcp-common.c:430
+#: dhcp-common.c:478
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr ""
 
-#: dhcp-common.c:491
+#: dhcp-common.c:542
 #, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr ""
 
-#: dhcp-common.c:612
+#: dhcp-common.c:665
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr ""
 
-#: dhcp-common.c:623
+#: dhcp-common.c:676
 #, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr ""
 
-#: dhcp-common.c:820
+#: dhcp-common.c:873
 msgid ", prefix deprecated"
 msgstr ""
 
-#: dhcp-common.c:823
+#: dhcp-common.c:876
 #, c-format
 msgid ", lease time "
 msgstr ""
 
-#: dhcp-common.c:865
+#: dhcp-common.c:918
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr ""
 
-#: dhcp-common.c:867
+#: dhcp-common.c:920
 #, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr ""
 
-#: dhcp-common.c:869
+#: dhcp-common.c:922
 #, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr ""
 
-#: dhcp-common.c:870
+#: dhcp-common.c:923
 #, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr ""
 
-#: dhcp-common.c:883
+#: dhcp-common.c:936
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr ""
 
-#: dhcp-common.c:886
+#: dhcp-common.c:939
 #, c-format
 msgid "router advertisement on %s%s"
 msgstr ""
 
-#: dhcp-common.c:897
+#: dhcp-common.c:950
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr ""
 
-#: dhcp-common.c:899
+#: dhcp-common.c:952
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr ""
@@ -2127,7 +2221,7 @@ msgstr ""
 msgid "cannot create ICMPv6 socket: %s"
 msgstr ""
 
-#: auth.c:449
+#: auth.c:439
 #, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr ""
@@ -2142,18 +2236,23 @@ msgstr ""
 msgid "failed to create IPset control socket: %s"
 msgstr ""
 
-#: ipset.c:233
+#: ipset.c:226
 #, c-format
 msgid "failed to update ipset %s: %s"
 msgstr ""
 
-#: dnssec.c:208
+#: dnssec.c:206
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
 msgstr ""
 
-#: blockdata.c:58
+#: dnssec.c:902
 #, c-format
-msgid "DNSSEC memory in use %u, max %u, allocated %u"
+msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
+msgstr ""
+
+#: blockdata.c:55
+#, c-format
+msgid "pool memory in use %u, max %u, allocated %u"
 msgstr ""
 
 #: tables.c:61
@@ -2185,12 +2284,12 @@ msgstr ""
 msgid "info: table created"
 msgstr ""
 
-#: tables.c:134
+#: tables.c:133
 #, c-format
 msgid "warning: DIOCR%sADDRS: %s"
 msgstr ""
 
-#: tables.c:138
+#: tables.c:137
 #, c-format
 msgid "%d addresses %s"
 msgstr ""
@@ -2229,3 +2328,62 @@ msgstr ""
 #, c-format
 msgid "inotify, new or changed file %s"
 msgstr ""
+
+#: dump.c:64
+#, c-format
+msgid "cannot create %s: %s"
+msgstr ""
+
+#: dump.c:70
+#, c-format
+msgid "bad header in %s"
+msgstr ""
+
+#: dump.c:201
+msgid "failed to write packet dump"
+msgstr ""
+
+#: dump.c:203
+#, c-format
+msgid "dumping UDP packet %u mask 0x%04x"
+msgstr ""
+
+#: ubus.c:52
+#, c-format
+msgid "UBus subscription callback: %s subscriber(s)"
+msgstr ""
+
+#: ubus.c:73
+#, c-format
+msgid "Cannot reconnect to UBus: %s"
+msgstr ""
+
+#: ubus.c:89
+msgid "Cannot initialize UBus: connection failed"
+msgstr ""
+
+#: ubus.c:102
+#, c-format
+msgid "Cannot add object to UBus: %s"
+msgstr ""
+
+#: ubus.c:112
+msgid "Connected to system UBus"
+msgstr ""
+
+#: ubus.c:122
+msgid "Cannot set UBus listeners: no connection"
+msgstr ""
+
+#: ubus.c:142
+msgid "Cannot poll UBus listeners: no connection"
+msgstr ""
+
+#: ubus.c:155
+msgid "Disconnecting from UBus"
+msgstr ""
+
+#: ubus.c:199
+#, c-format
+msgid "Failed to send UBus event: %s"
+msgstr ""
index b532d4f..630885d 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -14,70 +14,70 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
 
-#: cache.c:518
+#: cache.c:559
 msgid "Internal error in cache."
 msgstr ""
 
-#: cache.c:928
+#: cache.c:1081
 #, c-format
 msgid "failed to load names from %s: %s"
 msgstr "Impossible de charger les noms à partir de %s : %s"
 
-#: cache.c:954 dhcp.c:867
+#: cache.c:1103 dhcp.c:927
 #, c-format
 msgid "bad address at %s line %d"
 msgstr "mauvaise adresse dans %s ligne %d"
 
-#: cache.c:1007 dhcp.c:883
+#: cache.c:1156 dhcp.c:943
 #, c-format
 msgid "bad name at %s line %d"
 msgstr "mauvais nom dans %s ligne %d"
 
-#: cache.c:1016 dhcp.c:958
+#: cache.c:1167 dhcp.c:1018
 #, c-format
 msgid "read %s - %d addresses"
 msgstr "lecture %s - %d adresses"
 
-#: cache.c:1129
+#: cache.c:1283
 msgid "cleared cache"
 msgstr "cache vidé"
 
-#: cache.c:1158
+#: cache.c:1345
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr "Aucune adresse IPv4 trouvée pour %s"
 
-#: cache.c:1237
+#: cache.c:1391
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr "%s est un CNAME, il ne sera pas donné au bail DHCP de %s"
 
-#: cache.c:1261
+#: cache.c:1415
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr "ne donne pas de nom %s au bail DHCP de %s parce-que le nom existe dans %s avec l'adresse %s"
 
-#: cache.c:1418
+#: cache.c:1663
 #, c-format
 msgid "time %lu"
 msgstr "horodatage %lu"
 
-#: cache.c:1419
+#: cache.c:1664
 #, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr "taille de cache %d, %d/%d insertions dans le cache entrées non-expirées réutilisées"
 
-#: cache.c:1421
+#: cache.c:1666
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr "requêtes transmises %u, requêtes résolues localement %u"
 
-#: cache.c:1424
+#: cache.c:1669
 #, fuzzy, c-format
 msgid "queries for authoritative zones %u"
 msgstr "Configure la durée de vie (Time To Live) pour les réponses faisant autorité"
 
-#: cache.c:1450
+#: cache.c:1694
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr "serveur %s#%d: requêtes envoyées %u, requêtes réessayées ou échouées %u"
@@ -91,690 +91,729 @@ msgstr "impossible d'initialiser le g
 msgid "failed to allocate memory"
 msgstr "impossible d'allouer la mémoire"
 
-#: util.c:281 option.c:619
+#: util.c:281 option.c:641
 msgid "could not get memory"
 msgstr "impossible d'allouer de la mémoire"
 
-#: util.c:291
+#: util.c:302
 #, c-format
 msgid "cannot create pipe: %s"
 msgstr "Ne peut pas créer le tube %s : %s"
 
-#: util.c:299
+#: util.c:310
 #, c-format
 msgid "failed to allocate %d bytes"
 msgstr "impossible d'allouer %d octets"
 
-#: util.c:468
+#: util.c:506
 #, c-format
 msgid "infinite"
 msgstr "illimité(e)"
 
-#: option.c:344
+#: option.c:358
 msgid "Specify local address(es) to listen on."
 msgstr "Spécifie la ou les adresse(s) locales où le démon doit se mettre à l'écoute."
 
-#: option.c:345
+#: option.c:359
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr "Retourne les adresses IP pour toutes les machines présentes dans les domaines spécifiés"
 
-#: option.c:346
+#: option.c:360
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr "Traduction inverse truquée pour la plage d'adresse privée RFC1918"
 
-#: option.c:347
+#: option.c:361
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr "Traite l'adresse IP comme un domaine inexistant NXDOMAIN (contourne le systeme de redirection de Verisign)"
 
-#: option.c:348
+#: option.c:362
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr "Spécifie le nombre d'entrées que contiendra le cache (par défaut : %s)."
 
-#: option.c:349
+#: option.c:363
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr "Spécifie le nom du fichier de configuration (par défaut : %s)"
 
-#: option.c:350
+#: option.c:364
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr "Ne passe pas en tâche de fond : démarre en mode debug"
 
-#: option.c:351
+#: option.c:365
 msgid "Do NOT forward queries with no domain part."
 msgstr "Ne retransmet pas les requêtes qui n'ont pas de domaine."
 
-#: option.c:352
+#: option.c:366
 msgid "Return self-pointing MX records for local hosts."
 msgstr "Retourne les champs MX pour les machines locales."
 
-#: option.c:353
+#: option.c:367
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr "Etend les noms uniques des machines dans /etc/hosts avec le suffixe du domaine."
 
-#: option.c:354
+#: option.c:368
 msgid "Don't forward spurious DNS requests from Windows hosts."
 msgstr "Ne retransmet pas les fausses requêtes DNS en provenance des machines Windows."
 
-#: option.c:355
+#: option.c:369
 msgid "Enable DHCP in the range given with lease duration."
 msgstr "Autorise DHCP dans la plage d'adresses donnée sur la durée de validité du bail."
 
-#: option.c:356
+#: option.c:370
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr "On change pour ce groupe après le démarrage (par défaut : %s)."
 
-#: option.c:357
+#: option.c:371
 msgid "Set address or hostname for a specified machine."
 msgstr "On assigne une adresse ou un nom pour une machine spécifiée."
 
-#: option.c:358
+#: option.c:372
 msgid "Read DHCP host specs from file."
 msgstr "Lecture des spécifications d'hôtes DHCP à partir du fichier"
 
-#: option.c:359
+#: option.c:373
 msgid "Read DHCP option specs from file."
 msgstr "Lecture des options DHCP à partir du fichier"
 
-#: option.c:360
+#: option.c:374
 #, fuzzy
 msgid "Read DHCP host specs from a directory."
 msgstr "Lecture des spécifications d'hôtes DHCP à partir du fichier"
 
-#: option.c:361
+#: option.c:375
 #, fuzzy
 msgid "Read DHCP options from a directory."
 msgstr "Lecture des options DHCP à partir du fichier"
 
-#: option.c:362
+#: option.c:376
 msgid "Evaluate conditional tag expression."
 msgstr "Expression d'évaluation conditionnelle d'étiquette"
 
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Do NOT load %s file."
 msgstr "Ne charge PAS le fichier %s."
 
-#: option.c:364
+#: option.c:378
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr "Spécifie un nom de fichier hosts à lire en complément de %s"
 
-#: option.c:365
+#: option.c:379
 #, fuzzy
 msgid "Read hosts files from a directory."
 msgstr "Lecture des spécifications d'hôtes DHCP à partir du fichier"
 
-#: option.c:366
+#: option.c:380
 msgid "Specify interface(s) to listen on."
 msgstr "Spécifie la ou les interface(s) où le démon doit se mettre à l'écoute."
 
-#: option.c:367
+#: option.c:381
 msgid "Specify interface(s) NOT to listen on."
 msgstr "Spécifie la ou les interface(s) que le démon ne doit PAS traiter."
 
 #
-#: option.c:368
+#: option.c:382
 msgid "Map DHCP user class to tag."
 msgstr "Associe les classes d'utilisateurs ('user class') DHCP aux options."
 
-#: option.c:369
+#: option.c:383
 msgid "Map RFC3046 circuit-id to tag."
 msgstr "Associe les identifiants de circuits RFC3046 ('circuit-id') aux options"
 
-#: option.c:370
+#: option.c:384
 msgid "Map RFC3046 remote-id to tag."
 msgstr "Associe les identifiants distants RFC3046 ('remote-id') aux options"
 
-#: option.c:371
+#: option.c:385
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr "Associe les identifiants de souscripteurs RFC3993 ('subscriber-id') aux options"
 
 #
-#: option.c:372
+#: option.c:386
 msgid "Don't do DHCP for hosts with tag set."
 msgstr "Ne pas autoriser DHCP pour les machines énumerées dans les options."
 
 #
-#: option.c:373
+#: option.c:387
 msgid "Force broadcast replies for hosts with tag set."
 msgstr "Forcer les réponses par 'broadcast' pour les machines énumerées dans les options."
 
-#: option.c:374
+#: option.c:388
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr "Ne passe pas en tâche de fond, ne pas s'exécuter en mode debug."
 
-#: option.c:375
+#: option.c:389
 msgid "Assume we are the only DHCP server on the local network."
 msgstr "On considère que l'on est le seul serveur DHCP sur le réseau local."
 
-#: option.c:376
+#: option.c:390
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr "Spécifie où il faut sauvegarder les baux DHCP (par défaut : %s)."
 
-#: option.c:377
+#: option.c:391
 msgid "Return MX records for local hosts."
 msgstr "Retourne les champs MX pour les machines locales."
 
-#: option.c:378
+#: option.c:392
 msgid "Specify an MX record."
 msgstr "Spécifie un champ MX."
 
-#: option.c:379
+#: option.c:393
 msgid "Specify BOOTP options to DHCP server."
 msgstr "Spécifie les options BOOTP pour le serveur DHCP."
 
-#: option.c:380
+#: option.c:394
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr "Ne pas scruter le fichier %s, ne recharger les modifications que sur réception du signal SIGHUP."
 
-#: option.c:381
+#: option.c:395
 msgid "Do NOT cache failed search results."
 msgstr "Ne place pas en cache le résultat des requêtes qui ont échouées."
 
-#: option.c:382
+#: option.c:396
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr "Utilise les serveurs de noms dans l'ordre donné dans %s."
 
 #
-#: option.c:383
+#: option.c:397
 msgid "Specify options to be sent to DHCP clients."
 msgstr "Options supplémentaires à associer aux clients DHCP."
 
-#: option.c:384
+#: option.c:398
 msgid "DHCP option sent even if the client does not request it."
 msgstr "Option DHCP envoyée même si le client de la demande pas."
 
-#: option.c:385
+#: option.c:399
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr "Spécifie le port où il faut écouter les requêtes DNS (par défaut : 53)."
 
-#: option.c:386
+#: option.c:400
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr "Taille maximale des paquets UDP supportés pour EDNS.0 (par défaut : %s)."
 
 #
-#: option.c:387
+#: option.c:401
 msgid "Log DNS queries."
 msgstr "Enregistre les requêtes DNS dans un journal d'activité."
 
 #
-#: option.c:388
+#: option.c:402
 msgid "Force the originating port for upstream DNS queries."
 msgstr "Force le port d'origine pour les requêtes vers les serveurs amonts."
 
-#: option.c:389
+#: option.c:403
 msgid "Do NOT read resolv.conf."
 msgstr "Ne pas lire le fichier resolv.conf."
 
-#: option.c:390
+#: option.c:404
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr "Spécifie le chemin pour le fichier resolv.conf (par défaut : %s)."
 
-#: option.c:391
+#: option.c:405
 #, fuzzy
 msgid "Specify path to file with server= options"
 msgstr "Spécifie un chemin pour le fichier PID (par défaut : %s)."
 
-#: option.c:392
+#: option.c:406
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr "Spécifie la ou les adresses des serveurs amonts avec des domaines optionels."
 
-#: option.c:393
+#: option.c:407
 #, fuzzy
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr "Spécifie la ou les adresses des serveurs amonts avec des domaines optionels."
 
-#: option.c:394
+#: option.c:408
 msgid "Never forward queries to specified domains."
 msgstr "Ne jamais retransmettre les requêtes pour les domaines spécifiés."
 
-#: option.c:395
+#: option.c:409
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr "Spécifie le domaine qui doit etre assigné aux baux DHCP."
 
-#: option.c:396
+#: option.c:410
 msgid "Specify default target in an MX record."
 msgstr "Spécifie la cible par défaut dans un champ MX."
 
-#: option.c:397
+#: option.c:411
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr "Spécifie le TTL en secondes pour les réponses qui utilisent /etc/hosts."
 
 #
-#: option.c:398
+#: option.c:412
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr "Spécifie le TTL en secondes pour les réponses qui utilisent /etc/hosts."
 
-#: option.c:399
+#: option.c:413
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr "Spécifie, en secondes, la valeur maximum de TTL à renvoyer aux clients."
 
 #
-#: option.c:400
+#: option.c:414
 #, fuzzy
 msgid "Specify time-to-live ceiling for cache."
 msgstr "Spécifie le TTL en secondes pour les réponses qui utilisent /etc/hosts."
 
 #
-#: option.c:401
+#: option.c:415
 #, fuzzy
 msgid "Specify time-to-live floor for cache."
 msgstr "Spécifie le TTL en secondes pour les réponses qui utilisent /etc/hosts."
 
-#: option.c:402
+#: option.c:416
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr "Change pour cet utilisateur après le démarrage (par défaut : %s)."
 
 #
-#: option.c:403
+#: option.c:417
 msgid "Map DHCP vendor class to tag."
 msgstr "Associe les classes de fournisseurs ('vendor class') DHCP aux options."
 
-#: option.c:404
+#: option.c:418
 msgid "Display dnsmasq version and copyright information."
 msgstr "Affiche la version de Dnsmasq et les informations liées au copyright."
 
-#: option.c:405
+#: option.c:419
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr "Traduit les adresses IPV4 des serveurs amonts."
 
-#: option.c:406
+#: option.c:420
 msgid "Specify a SRV record."
 msgstr "Spécifie un champ SRV."
 
-#: option.c:407
+#: option.c:421
 #, fuzzy
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr "Afficher ce message. Utiliser --help dhcp pour obtenir la liste des options DHCP connues."
 
-#: option.c:408
+#: option.c:422
 #, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr "Spécifie un chemin pour le fichier PID (par défaut : %s)."
 
-#: option.c:409
+#: option.c:423
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr "Spécifie le nombre maximum de baux DHCP (par défaut : %s)."
 
-#: option.c:410
+#: option.c:424
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr "Repond aux requêtes DNS en se basant sur l'interface ou a été envoyée la requête."
 
-#: option.c:411
+#: option.c:425
 msgid "Specify TXT DNS record."
 msgstr "Spécifie un champ DNS TXT"
 
 #
-#: option.c:412
+#: option.c:426
 msgid "Specify PTR DNS record."
 msgstr "Spécifie un champ DNS PTR"
 
-#: option.c:413
+#: option.c:427
 msgid "Give DNS name to IPv4 address of interface."
 msgstr "Donne le nom DNS pour l'adresse IPv4 de l'interface."
 
-#: option.c:414
+#: option.c:428
 msgid "Bind only to interfaces in use."
 msgstr "Association uniquement aux interfaces réseau actuellement actives."
 
-#: option.c:415
+#: option.c:429
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr "Lecture des informations de DHCP statique à partir de %s."
 
-#: option.c:416
+#: option.c:430
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr "Autorise l'interface DBus pour la configuration des serveurs amonts, etc."
 
-#: option.c:417
+#: option.c:431
+msgid "Enable the UBus interface."
+msgstr ""
+
+#: option.c:432
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr "Ne pas assurer de fonction DHCP sur cette interface, mais seulement la fonction DNS."
 
-#: option.c:418
+#: option.c:433
 msgid "Enable dynamic address allocation for bootp."
 msgstr "Autorise l'allocation dynamique d'adresse pour bootp."
 
 #
-#: option.c:419
+#: option.c:434
 msgid "Map MAC address (with wildcards) to option set."
 msgstr "Associe l'adresse MAC (avec les jokers) aux options."
 
-#: option.c:420
+#: option.c:435
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr "Traiter les requêtes DHCP sur les alias comme arrivant de l'interface."
 
-#: option.c:421
+#: option.c:436
+msgid "Specify extra networks sharing a broadcast domain for DHCP"
+msgstr ""
+
+#: option.c:437
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr "Supprime la vérification d'adresse sur le serveur au moyen de paquets ICMP echo"
 
-#: option.c:422
+#: option.c:438
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr "Script shell à exécuter lors de la création ou destruction de bail DHCP."
 
-#: option.c:423
+#: option.c:439
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr "Script Lua à exécuter lors de la création ou destruction de bail DHCP."
 
-#: option.c:424
+#: option.c:440
 msgid "Run lease-change scripts as this user."
 msgstr "Lancer le script 'lease-change' avec cet utilisateur."
 
-#: option.c:425
+#: option.c:441
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr ""
 
-#: option.c:426
+#: option.c:442
 msgid "Read configuration from all the files in this directory."
 msgstr "Lecture de la configuration dans tous les fichiers de ce répertoire."
 
 #
-#: option.c:427
+#: option.c:443
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr "Enregistrer les journaux d'activité dans cette facilité syslog. (défaut : DAEMON)"
 
-#: option.c:428
+#: option.c:444
 msgid "Do not use leasefile."
 msgstr "Ne pas utiliser de fichier de baux."
 
-#: option.c:429
+#: option.c:445
 #, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr "Spécifie le nombre maximum de requêtes DHCP concurrentes (par défaut : %s)."
 
-#: option.c:430
+#: option.c:446
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr "Vider le cache DNS lors du rechargement de %s."
 
-#: option.c:431
+#: option.c:447
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr "Ignorer les noms d'hôtes fournis par les clients DHCP"
 
-#: option.c:432
+#: option.c:448
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr "Ne pas réutiliser les champs nom de fichier et serveur dans les options DHCP supplémentaires."
 
-#: option.c:433
+#: option.c:449
 msgid "Enable integrated read-only TFTP server."
 msgstr "Activer le server TFTP intégré (fonctionnant en lecture seulement)"
 
-#: option.c:434
+#: option.c:450
 msgid "Export files by TFTP only from the specified subtree."
 msgstr "N'exporter par TFTP que les fichiers de l'arborescence de fichier spécifiée"
 
-#: option.c:435
+#: option.c:451
 #, fuzzy
 msgid "Add client IP or hardware address to tftp-root."
 msgstr "Ajouter les adresses IP clientes à la racine tftp ('tftp-root')."
 
-#: option.c:436
+#: option.c:452
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr "Accès aux seuls fichiers appartenants à l'utilisateur sous lequel tourne dnsmasq"
 
-#: option.c:437
+#: option.c:453
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr ""
 
-#: option.c:438
+#: option.c:454
 #, fuzzy, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr "Spécifie le nombre maximum de transfert TFTP concurrents (défaut : %s)."
 
-#: option.c:439
+#: option.c:455
 #, fuzzy
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr "Spécifie le nombre maximum de transfert TFTP concurrents (défaut : %s)."
 
-#: option.c:440
+#: option.c:456
 msgid "Disable the TFTP blocksize extension."
 msgstr "Désactivation de l'extension TFTP « taille de bloc »"
 
-#: option.c:441
+#: option.c:457
 msgid "Convert TFTP filenames to lowercase"
 msgstr "Convertis les noms de fichiers TFTP en minuscule"
 
-#: option.c:442
+#: option.c:458
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr "Gamme de ports dans laquelle seront choisis les ports temporaires utilisés dans les transferts TFTP."
 
-#: option.c:443
+#: option.c:459
+msgid "Use only one port for TFTP server."
+msgstr ""
+
+#: option.c:460
 msgid "Extra logging for DHCP."
 msgstr "Traces supplémentaires pour le DHCP."
 
-#: option.c:444
+#: option.c:461
 msgid "Enable async. logging; optionally set queue length."
 msgstr "Active l'écriture de traces en mode asynchrone. Peut prendre en option la valeur de la longueur de la queue."
 
-#: option.c:445
+#: option.c:462
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr "Stopper la réassociation DNS ('DNS rebinding'). Filtre les gammes d'adresses IP privées lors de la résolution."
 
-#: option.c:446
+#: option.c:463
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr "Autorise la réassociation de 127.0.0/8, pour les serveurs RBL (Realtime Blackhole List)"
 
-#: option.c:447
+#: option.c:464
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr "Désactive la protection contre les réassociation DNS pour ce domaine"
 
-#: option.c:448
+#: option.c:465
 msgid "Always perform DNS queries to all servers."
 msgstr "Toujours effectuer les requêtes DNS à tous les serveurs."
 
 #
-#: option.c:449
+#: option.c:466
 msgid "Set tag if client includes matching option in request."
 msgstr "Spécifie le label si le client inclus l'option dans la requête."
 
-#: option.c:450
+#
+#: option.c:467
+#, fuzzy
+msgid "Set tag if client provides given name."
+msgstr "Spécifie le label si le client inclus l'option dans la requête."
+
+#: option.c:468
 msgid "Use alternative ports for DHCP."
 msgstr "Utiliser des ports alternatifs pour le DHCP."
 
 #
-#: option.c:451
+#: option.c:469
 msgid "Specify NAPTR DNS record."
 msgstr "Spécifie un champ DNS NAPTR."
 
-#: option.c:452
+#: option.c:470
 msgid "Specify lowest port available for DNS query transmission."
 msgstr "Définie le plus petit port utilisé pour la transmission d'une requête DNS."
 
-#: option.c:453
+#: option.c:471
 #, fuzzy
 msgid "Specify highest port available for DNS query transmission."
 msgstr "Définie le plus petit port utilisé pour la transmission d'une requête DNS."
 
-#: option.c:454
+#: option.c:472
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr "Utilise seulement les noms de domaine pleinement qualifiés pour les clients DHCP."
 
-#: option.c:455
+#: option.c:473
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr "Génère les noms d'hôtes à partir de l'adresse MAC pour les clients sans nom."
 
-#: option.c:456
+#: option.c:474
 msgid "Use these DHCP relays as full proxies."
 msgstr "Utilise ces relais DHCP en temps que proxy complets."
 
-#: option.c:457
+#: option.c:475
 msgid "Relay DHCP requests to a remote server"
 msgstr "Requêtes de relais DHCP à un serveur distant"
 
-#: option.c:458
+#: option.c:476
 msgid "Specify alias name for LOCAL DNS name."
 msgstr "Spécifie un alias pour un nom DNS local."
 
 #
-#: option.c:459
+#: option.c:477
 msgid "Prompt to send to PXE clients."
 msgstr "Invite à envoyer aux clients PXE."
 
-#: option.c:460
+#: option.c:478
 msgid "Boot service for PXE menu."
 msgstr "Service de démarrage pour menu PXE."
 
-#: option.c:461
+#: option.c:479
 msgid "Check configuration syntax."
 msgstr "vérification de la syntaxe de la configuration."
 
-#: option.c:462
+#: option.c:480
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr "Ajoute l'adresse MAC du requêteur aux requêtes DNS transmises"
 
-#: option.c:463
+#: option.c:481
 #, fuzzy
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr "Ajoute l'adresse MAC du requêteur aux requêtes DNS transmises"
 
-#: option.c:464
+#: option.c:482
 #, fuzzy
 msgid "Add client identification to forwarded DNS queries."
 msgstr "Ajoute l'adresse MAC du requêteur aux requêtes DNS transmises"
 
-#: option.c:465
+#: option.c:483
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr "Copie dans la réponse DNS le résultat de la validation DNSSEC effectuée par les serveurs DNS amonts."
 
-#: option.c:466
+#: option.c:484
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr "Essaie d'allouer des adresses IP séquentielles aux clients DHCP."
 
-#: option.c:467
+#: option.c:485
+#, fuzzy
+msgid "Ignore client identifier option sent by DHCP clients."
+msgstr "Ignorer les noms d'hôtes fournis par les clients DHCP"
+
+#: option.c:486
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr "Copie les marques de suivi de connexion pour les requêtes amont."
 
-#: option.c:468
+#: option.c:487
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr "Autoriser les clients DHCP à faire leurs propres mises à jour DDNS (Dynamic DNS)"
 
-#: option.c:469
+#: option.c:488
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr "Envoyer des annonces de routeurs pour toutes les interfaces faisant du DHCPv6"
 
-#: option.c:470
+#: option.c:489
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr "Spécifie pour le serveur DHCPv6 un identifiant unique DHCP (DUID) basé sur un numéro unique de vendeur (DUID_EN)"
 
-#: option.c:471
+#: option.c:490
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr "Spécifie les enregistrements (A/AAAA et PTR) d'un hôte."
 
-#: option.c:472
+#: option.c:491
+msgid "Specify certification authority authorization record"
+msgstr ""
+
+#: option.c:492
 msgid "Specify arbitrary DNS resource record"
 msgstr "Définie une resource DNS d'un type spécifique"
 
-#: option.c:473
+#: option.c:493
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr "Se lie aux interfaces préexistantes - vérifie l'apparition de nouvelles interfaces"
 
-#: option.c:474
+#: option.c:494
 msgid "Export local names to global DNS"
 msgstr "Exporte les noms locaux dans le DNS global"
 
-#: option.c:475
+#: option.c:495
 msgid "Domain to export to global DNS"
 msgstr "Domaine à exporter dans le DNS global"
 
-#: option.c:476
+#: option.c:496
 msgid "Set TTL for authoritative replies"
 msgstr "Configure la durée de vie (Time To Live) pour les réponses faisant autorité"
 
-#: option.c:477
+#: option.c:497
 #, fuzzy
 msgid "Set authoritative zone information"
 msgstr "Configure les informations pour une zone de nom faisant autorité"
 
-#: option.c:478
+#: option.c:498
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr "Serveurs de noms secondaires faisant autorité pour les domaines délégués"
 
-#: option.c:479
+#: option.c:499
 msgid "Peers which are allowed to do zone transfer"
 msgstr "Pairs autorisés à faire des transferts de zone"
 
-#: option.c:480
+#: option.c:500
 msgid "Specify ipsets to which matching domains should be added"
 msgstr "Spécifie les ipsets auxquels les domaines correspondants doivent-être ajoutés"
 
-#: option.c:481
+#: option.c:501
 #, fuzzy
 msgid "Specify a domain and address range for synthesised names"
 msgstr "Spécifie un domaine et une plage d'adresses pour les noms auto-générés"
 
-#: option.c:482
+#: option.c:502
 msgid "Activate DNSSEC validation"
 msgstr ""
 
-#: option.c:483
+#: option.c:503
 msgid "Specify trust anchor key digest."
 msgstr ""
 
-#: option.c:484
+#: option.c:504
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr ""
 
-#: option.c:485
+#: option.c:505
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr ""
 
-#: option.c:486
+#: option.c:506
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr ""
 
-#: option.c:487
+#: option.c:507
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr ""
 
-#: option.c:489
-msgid "Specify DHCPv6 prefix class"
-msgstr "Spécifie le préfixe de classe DHCPv6"
-
-#: option.c:491
+#: option.c:508
 msgid "Set MTU, priority, resend-interval and router-lifetime"
 msgstr ""
 
-#: option.c:492
+#: option.c:509
 msgid "Do not log routine DHCP."
 msgstr ""
 
-#: option.c:493
+#: option.c:510
 msgid "Do not log routine DHCPv6."
 msgstr ""
 
-#: option.c:494
+#: option.c:511
 msgid "Do not log RA."
 msgstr ""
 
-#: option.c:495
+#: option.c:512
 msgid "Accept queries only from directly-connected networks."
 msgstr ""
 
-#: option.c:496
+#: option.c:513
 msgid "Detect and remove DNS forwarding loops."
 msgstr ""
 
-#: option.c:497
+#: option.c:514
 msgid "Ignore DNS responses containing ipaddr."
 msgstr ""
 
-#: option.c:498
+#: option.c:515
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr ""
 
-#: option.c:499
+#: option.c:516
 msgid "Delay DHCP replies for at least number of seconds."
 msgstr ""
 
-#: option.c:703
+#: option.c:517
+msgid "Enables DHCPv4 Rapid Commit option."
+msgstr ""
+
+#: option.c:518
+msgid "Path to debug packet dump file"
+msgstr ""
+
+#: option.c:519
+msgid "Mask which packets to dump"
+msgstr ""
+
+#: option.c:520
+msgid "Call dhcp-script when lease expiry changes."
+msgstr ""
+
+#: option.c:725
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
@@ -783,338 +822,354 @@ msgstr ""
 "Usage : dnsmasq [options]\n"
 "\n"
 
-#: option.c:705
+#: option.c:727
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr "Utilisez les options courtes uniquement sur la ligne de commande.\n"
 
-#: option.c:707
+#: option.c:729
 #, c-format
 msgid "Valid options are:\n"
 msgstr "Les options valides sont :\n"
 
 #
-#: option.c:754 option.c:868
+#: option.c:776 option.c:884
 msgid "bad address"
 msgstr "mauvaise adresse"
 
-#: option.c:779 option.c:783
+#: option.c:799 option.c:803
 msgid "bad port"
 msgstr "numéro de port incorrect"
 
-#: option.c:797 option.c:826 option.c:861
+#: option.c:815 option.c:844 option.c:878
 msgid "interface binding not supported"
 msgstr "association d'interface non supportée"
 
-#: option.c:821 option.c:856
+#: option.c:839 option.c:873
 msgid "interface can only be specified once"
 msgstr ""
 
 #
-#: option.c:835 option.c:3809
+#: option.c:852 option.c:4042
 msgid "bad interface name"
 msgstr "nom d'interface invalide"
 
-#: option.c:1062
+#: option.c:1184
 msgid "unsupported encapsulation for IPv6 option"
 msgstr "encapsulation d'option non supportée pour IPv6"
 
-#: option.c:1076
+#: option.c:1198
 msgid "bad dhcp-option"
 msgstr "mauvaise valeur de 'dhcp-option'"
 
 #
-#: option.c:1144
+#: option.c:1270
 msgid "bad IP address"
 msgstr "mauvaise adresse IP"
 
 #
-#: option.c:1147 option.c:1286 option.c:3079
+#: option.c:1273 option.c:1412 option.c:3297
 msgid "bad IPv6 address"
 msgstr "mauvaise adresse IPv6"
 
 #
-#: option.c:1240
+#: option.c:1366
 #, fuzzy
 msgid "bad IPv4 address"
 msgstr "mauvaise adresse IPv6"
 
-#: option.c:1313 option.c:1407
+#: option.c:1439 option.c:1533
 msgid "bad domain in dhcp-option"
 msgstr "mauvais domaine dans dhcp-option"
 
-#: option.c:1445
+#: option.c:1571
 msgid "dhcp-option too long"
 msgstr "dhcp-option trop long"
 
-#: option.c:1452
+#: option.c:1578
 msgid "illegal dhcp-match"
 msgstr "valeur illégale pour 'dhcp-match'"
 
-#: option.c:1514
+#: option.c:1647
 msgid "illegal repeated flag"
 msgstr "Une option ne pouvant être spécifié qu'une seule fois à été donnée plusieurs fois"
 
-#: option.c:1522
+#: option.c:1655
 msgid "illegal repeated keyword"
 msgstr "Mot-clef ne pouvant être répété"
 
-#: option.c:1593 option.c:4443
+#: option.c:1726 option.c:4764
 #, c-format
 msgid "cannot access directory %s: %s"
 msgstr "Ne peut pas lire le répertoire %s : %s"
 
-#: option.c:1639 tftp.c:537
+#: option.c:1772 tftp.c:564 dump.c:68
 #, c-format
 msgid "cannot access %s: %s"
 msgstr "Ne peut pas lire %s : %s"
 
-#: option.c:1727
+#: option.c:1879
 msgid "setting log facility is not possible under Android"
 msgstr "Sous android, impossible de positionner la cible (facility) pour les traces (logs)."
 
-#: option.c:1736
+#: option.c:1888
 msgid "bad log facility"
 msgstr "Mauvaise cible (facility) pour les traces."
 
-#: option.c:1789
+#: option.c:1941
 msgid "bad MX preference"
 msgstr "préference MX incorrecte"
 
-#: option.c:1794
+#: option.c:1946
 msgid "bad MX name"
 msgstr "nom MX incorrect"
 
-#: option.c:1808
+#: option.c:1960
 msgid "bad MX target"
 msgstr "valeur MX cible incorrecte"
 
-#: option.c:1820
-msgid "cannot run scripts under uClinux"
-msgstr "ne peut exécuter de script sous uClinux"
-
-#: option.c:1822
+#: option.c:1980
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr "recompiler en définissant HAVE_SCRIPT pour permettre l'exécution de scripts shell au changement de bail (lease-change)"
 
-#: option.c:1826
+#: option.c:1984
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr "recompiler en définissant HAVE_LUASCRIPT pour permettre l'exécution de scripts LUA au changement de bail (lease-change)"
 
-#: option.c:2095 option.c:2106 option.c:2143 option.c:2199 option.c:2482
+#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
 msgid "bad prefix"
 msgstr "mauvais préfixe"
 
-#: option.c:2504
+#: option.c:2658
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr "recompiler en définissant HAVE_IPSET pour permettre l'utilisation de directives de groupes d'IP (IPset)"
 
 #
-#: option.c:2713
+#: option.c:2871
 msgid "bad port range"
 msgstr "gamme de ports incorrecte"
 
-#: option.c:2739
+#: option.c:2897
 msgid "bad bridge-interface"
 msgstr "interface-pont incorrecte"
 
-#: option.c:2807
+#: option.c:2941
+msgid "bad shared-network"
+msgstr ""
+
+#: option.c:2996
 msgid "only one tag allowed"
 msgstr "une seule étiquette est autorisée"
 
-#: option.c:2827 option.c:2839 option.c:2948 option.c:2953 option.c:2992
+#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
 msgid "bad dhcp-range"
 msgstr "plage d'adresses DHCP (dhcp-range) incorrecte"
 
-#: option.c:2854
+#: option.c:3050
 msgid "inconsistent DHCP range"
 msgstr "plage d'adresses DHCP incohérente"
 
-#: option.c:2916
+#: option.c:3115
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr "la taille du préfixe doit être exactement 64 pour les sous-réseaux d'annonces de routeurs (RA)"
 
-#: option.c:2918
+#: option.c:3117
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr "la taille du préfixe doit être exactement 64 pour le constructeur de sous-réseaux"
 
-#: option.c:2922
+#: option.c:3120
 msgid "prefix length must be at least 64"
 msgstr "la taille de préfixe doit être au minimum 64"
 
-#: option.c:2925
+#: option.c:3123
 msgid "inconsistent DHCPv6 range"
 msgstr "plage d'adresses DHCPv6 incohérente"
 
-#: option.c:2936
+#: option.c:3142
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr "le préfixe doit avoir une taille de 0 lorsque l'argument \"constructor:\" est utilisé"
 
-#: option.c:3049 option.c:3097
+#: option.c:3262 option.c:3340
 msgid "bad hex constant"
 msgstr "mauvaise constante hexadecimale"
 
-#: option.c:3071
-msgid "cannot match tags in --dhcp-host"
-msgstr "L'utilisation de labels est prohibée dans --dhcp-host"
+#: option.c:3315
+#, fuzzy
+msgid "bad IPv6 prefix"
+msgstr "mauvais préfixe"
 
-#: option.c:3119
+#: option.c:3362
 #, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr "adresse IP dhcp-host dupliquée dans %s."
 
 #
-#: option.c:3177
+#: option.c:3422
 msgid "bad DHCP host name"
 msgstr "nom d'hôte DHCP incorrect"
 
-#: option.c:3259
+#: option.c:3508
 msgid "bad tag-if"
 msgstr "mauvaise étiquette tag-if"
 
-#: option.c:3616 option.c:4039
+#: option.c:3851 option.c:4324
 msgid "invalid port number"
 msgstr "numéro de port invalide"
 
 #
-#: option.c:3678
+#: option.c:3907
 msgid "bad dhcp-proxy address"
 msgstr "adresse dhcp-proxy incorrecte"
 
-#: option.c:3704
+#: option.c:3935
 msgid "Bad dhcp-relay"
 msgstr "valeur incorrecte pour le relais DHCP (dhcp-relay)"
 
-#: option.c:3745
+#: option.c:3979
 msgid "bad RA-params"
 msgstr ""
 
-#: option.c:3754
+#: option.c:3989
 msgid "bad DUID"
 msgstr "mauvais identifiant unique DHCP (DUID)"
 
+#: option.c:4023
+#, fuzzy
+msgid "missing address in alias"
+msgstr "adresse non valide"
+
 #
-#: option.c:3796
+#: option.c:4029
 msgid "invalid alias range"
 msgstr "poids invalide"
 
-#: option.c:3850 option.c:3862
+#: option.c:4081 option.c:4097
 msgid "bad CNAME"
 msgstr "mauvais CNAME"
 
-#: option.c:3866
+#: option.c:4105
 msgid "duplicate CNAME"
 msgstr "ce CNAME existe déja"
 
 #
-#: option.c:3889
+#: option.c:4132
 msgid "bad PTR record"
 msgstr "mauvais champ PTR"
 
 #
-#: option.c:3920
+#: option.c:4167
 msgid "bad NAPTR record"
 msgstr "mauvais champ NAPTR"
 
 #
-#: option.c:3954
+#: option.c:4203
 msgid "bad RR record"
 msgstr "mauvais enregistrement RR"
 
-#: option.c:3984
+#
+#: option.c:4236
+#, fuzzy
+msgid "bad CAA record"
+msgstr "mauvais enregistrement RR"
+
+#: option.c:4265
 msgid "bad TXT record"
 msgstr "champ TXT invalide"
 
-#: option.c:4025
+#: option.c:4308
 msgid "bad SRV record"
 msgstr "champ SRV invalide"
 
-#: option.c:4032
+#: option.c:4315
 msgid "bad SRV target"
 msgstr "cible SRV invalide"
 
-#: option.c:4046
+#: option.c:4334
 msgid "invalid priority"
 msgstr "priorité invalide"
 
-#: option.c:4049
+#: option.c:4339
 msgid "invalid weight"
 msgstr "poids invalide"
 
 #
-#: option.c:4073
+#: option.c:4362
 msgid "Bad host-record"
 msgstr "mauvais champ host-record"
 
-#: option.c:4097
+#: option.c:4402
 msgid "Bad name in host-record"
 msgstr "mauvais nom dans le champ host-record"
 
+#: option.c:4444
+msgid "bad value for dnssec-check-unsigned"
+msgstr ""
+
 #
-#: option.c:4162
+#: option.c:4480
 #, fuzzy
 msgid "bad trust anchor"
 msgstr "gamme de ports incorrecte"
 
-#: option.c:4176
+#: option.c:4496
 msgid "bad HEX in trust anchor"
 msgstr ""
 
-#: option.c:4186
+#: option.c:4507
 #, fuzzy
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr "option non supportée (vérifier que Dnsmasq a été compilé avec le support DHCP/TFTP/DBus)"
 
-#: option.c:4246
+#: option.c:4567
 msgid "missing \""
 msgstr "il manque \""
 
-#: option.c:4303
+#: option.c:4624
 msgid "bad option"
 msgstr "mauvaise option"
 
-#: option.c:4305
+#: option.c:4626
 msgid "extraneous parameter"
 msgstr "paramètre en trop"
 
-#: option.c:4307
+#: option.c:4628
 msgid "missing parameter"
 msgstr "paramètre manquant"
 
-#: option.c:4309
+#: option.c:4630
 #, fuzzy
 msgid "illegal option"
 msgstr "mauvaise option"
 
-#: option.c:4316
+#: option.c:4637
 msgid "error"
 msgstr "erreur"
 
-#: option.c:4318
+#: option.c:4639
 #, c-format
 msgid " at line %d of %s"
 msgstr "à la ligne %d de %s"
 
-#: option.c:4333 option.c:4580 option.c:4616
+#: option.c:4654 option.c:4939 option.c:4950
 #, c-format
 msgid "read %s"
 msgstr "Lecture de %s"
 
-#: option.c:4396 option.c:4519 tftp.c:715
+#: option.c:4717 option.c:4840 tftp.c:754
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "Ne peut pas lire %s : %s"
 
-#: option.c:4688
+#: option.c:5027
 msgid "junk found in command line"
 msgstr "la ligne de commande contient des éléments indésirables ou incompréhensibles"
 
-#: option.c:4729
+#: option.c:5067
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr "Version de Dnsmasq %s  %s\n"
 
-#: option.c:4730
+#: option.c:5068
 #, c-format
 msgid ""
 "Compile time options: %s\n"
@@ -1123,510 +1178,562 @@ msgstr ""
 "Options à la compilation %s\n"
 "\n"
 
-#: option.c:4731
+#: option.c:5069
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr "Ce logiciel est fourni sans AUCUNE GARANTIE.\n"
 
-#: option.c:4732
+#: option.c:5070
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr "Dnsmasq est un logiciel libre, il vous est permis de le redistribuer\n"
 
-#: option.c:4733
+#: option.c:5071
 #, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr "sous les termes de la licence GPL (GNU General Public License), version 2 ou 3.\n"
 
-#: option.c:4744
+#: option.c:5088
 msgid "try --help"
 msgstr "essayez avec --help"
 
-#: option.c:4746
+#: option.c:5090
 msgid "try -w"
 msgstr "essayez avec -w"
 
-#: option.c:4748
+#: option.c:5092
 #, c-format
 msgid "bad command line options: %s"
 msgstr "mauvaises options en ligne de commande : %s."
 
-#: option.c:4818
+#: option.c:5161
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr ""
 
-#: option.c:4854
+#: option.c:5195
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr "ne peut pas obtenir le nom de la machine : %s"
 
-#: option.c:4882
+#: option.c:5223
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr "seul un fichier resolv.conf est autorisé dans le mode no-poll"
 
-#: option.c:4892
+#: option.c:5233
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr "un fichier resolv.conf (et un seul) est nécessaire pour y récuperer le nom de domaine."
 
-#: option.c:4895 network.c:1623 dhcp.c:816
+#: option.c:5236 network.c:1594 dhcp.c:876
 #, c-format
 msgid "failed to read %s: %s"
 msgstr "impossible de lire %s : %s"
 
-#: option.c:4912
+#: option.c:5253
 #, c-format
 msgid "no search directive found in %s"
 msgstr "pas de directive de recherche trouvée dans %s"
 
-#: option.c:4933
+#: option.c:5274
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr "un domaine par défaut doit être spécifié lorsque l'option --dhcp-fqdn est utilisée"
 
-#: option.c:4942
+#: option.c:5283
 msgid "syntax check OK"
 msgstr "vérification de syntaxe OK"
 
-#: forward.c:102
+#: forward.c:99
 #, c-format
 msgid "failed to send packet: %s"
 msgstr "impossible d'envoyer le paquet : %s"
 
-#: forward.c:598
+#: forward.c:614
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr ""
 
-#: forward.c:652
+#: forward.c:677
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr "le serveur de nom %s a refusé de faire une recherche récursive"
 
-#: forward.c:684
+#: forward.c:709
 #, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr "détection d'une possible attaque de type DNS-rebind: %s"
 
-#: forward.c:870
+#: forward.c:961
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
 msgstr ""
 
-#: forward.c:1266 forward.c:1704
+#: forward.c:1370 forward.c:1830
 msgid "Ignoring query from non-local network"
 msgstr ""
 
-#: forward.c:2184
+#: forward.c:2321
 #, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr "Nombre maximum de requêtes DNS concurrentes atteint (maximum : %d)."
 
-#: network.c:720
+#: network.c:698
 #, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr "impossible de créer une socket d'écoute pour %s : %s"
 
-#: network.c:1031
+#: network.c:1002
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr ""
 
-#: network.c:1038
+#: network.c:1009
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr ""
 
-#: network.c:1047
+#: network.c:1018
 #, fuzzy, c-format
 msgid "warning: using interface %s instead"
 msgstr "attention : l'interface %s n'existe pas actuellement"
 
-#: network.c:1056
+#: network.c:1027
 #, fuzzy, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr "utilise les adresses locales seulement pour %s %s"
 
-#: network.c:1114
+#: network.c:1085
 #, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr "impossible de faire rejoindre l'interface %s dans le groupe multicast DHCPv6 %s"
 
-#: network.c:1119
+#: network.c:1090
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr ""
 
-#: network.c:1337
+#: network.c:1307
 #, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr "impossible de lier la socket de serveur pour %s : %s"
 
-#: network.c:1528
+#: network.c:1499
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr "ignore le serveur de nom %s - interface locale"
 
-#: network.c:1539
+#: network.c:1510
 #, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr "ignore le serveur de nom %s - ne peut construire/lier la socket : %m"
 
-#: network.c:1559
+#: network.c:1530
 msgid "(no DNSSEC)"
 msgstr ""
 
-#: network.c:1562
+#: network.c:1533
 msgid "unqualified"
 msgstr "non-qualifié(e)"
 
-#: network.c:1562
+#: network.c:1533
 msgid "names"
 msgstr "noms"
 
-#: network.c:1564
+#: network.c:1535
 msgid "default"
 msgstr "défaut"
 
-#: network.c:1566
+#: network.c:1537
 msgid "domain"
 msgstr "domaine"
 
-#: network.c:1572
-#, c-format
-msgid "using local addresses only for %s %s"
+#: network.c:1543
+#, fuzzy, c-format
+msgid "using only locally-known addresses for %s %s"
 msgstr "utilise les adresses locales seulement pour %s %s"
 
-#: network.c:1575
+#: network.c:1546
 #, c-format
 msgid "using standard nameservers for %s %s"
 msgstr "utilisation des serveurs de nom standards pour %s %s"
 
-#: network.c:1577
+#: network.c:1548
 #, fuzzy, c-format
 msgid "using nameserver %s#%d for %s %s %s"
 msgstr "utilise le serveur de nom %s#%d pour %s %s"
 
-#: network.c:1581
+#: network.c:1552
 #, fuzzy, c-format
 msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr "utilise le serveur de nom %s#%d pour %s %s"
 
-#: network.c:1584
+#: network.c:1555
 #, c-format
 msgid "using nameserver %s#%d(via %s)"
 msgstr "utilise le serveur de nom %s#%d (via %s)"
 
-#: network.c:1586
+#: network.c:1557
 #, c-format
 msgid "using nameserver %s#%d"
 msgstr "utilise le serveur de nom %s#%d"
 
-#: network.c:1591
+#: network.c:1562
 #, fuzzy, c-format
 msgid "using %d more local addresses"
 msgstr "utilise le serveur de nom %s#%d"
 
-#: network.c:1593
+#: network.c:1564
 #, fuzzy, c-format
 msgid "using %d more nameservers"
 msgstr "utilise le serveur de nom %s#%d"
 
-#: dnsmasq.c:171
+#: dnsmasq.c:173
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr ""
 
-#: dnsmasq.c:186
+#: dnsmasq.c:188
 msgid "no root trust anchor provided for DNSSEC"
 msgstr ""
 
-#: dnsmasq.c:189
+#: dnsmasq.c:191
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr ""
 
-#: dnsmasq.c:191
+#: dnsmasq.c:193
 #, fuzzy
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr "DBus n'est pas disponible : activez HAVE_DBUS dans src/config.h"
 
 #
-#: dnsmasq.c:197
+#: dnsmasq.c:199
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr "TFTP n'est pas disponible : activez HAVE_TFTP dans src/config.h"
 
-#: dnsmasq.c:202
+#: dnsmasq.c:204
 #, fuzzy
 msgid "cannot use --conntrack AND --query-port"
 msgstr "impossible d'utiliser conjointement --conntrack et --query-port"
 
 #
-#: dnsmasq.c:205
+#: dnsmasq.c:207
 #, fuzzy
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr "Support de suivi de connexion non disponible : activez HAVE_CONNTRACK dans src/config.h"
 
-#: dnsmasq.c:210
+#: dnsmasq.c:212
 msgid "asynchronous logging is not available under Solaris"
 msgstr "l'écriture de traces en mode asynchrone n'est pas disponible sous Solaris."
 
-#: dnsmasq.c:215
+#: dnsmasq.c:217
 msgid "asynchronous logging is not available under Android"
 msgstr "l'écriture de traces en mode asynchrone n'est pas disponible sous Android."
 
-#: dnsmasq.c:220
+#: dnsmasq.c:222
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr "le mode « autorité DNS » n'est pas disponible : activez HAVE_AUTH dans src/config.h"
 
 #
-#: dnsmasq.c:225
+#: dnsmasq.c:227
 #, fuzzy
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr "TFTP n'est pas disponible : activez HAVE_TFTP dans src/config.h"
 
-#: dnsmasq.c:229
+#: dnsmasq.c:232
+#, fuzzy
+msgid "Ubus not available: set HAVE_UBUS in src/config.h"
+msgstr "DBus n'est pas disponible : activez HAVE_DBUS dans src/config.h"
+
+#: dnsmasq.c:236
 msgid "max_port cannot be smaller than min_port"
 msgstr ""
 
-#: dnsmasq.c:236
+#: dnsmasq.c:243
+msgid "--auth-server required when an auth zone is defined."
+msgstr ""
+
+#: dnsmasq.c:248
 msgid "zone serial must be configured in --auth-soa"
 msgstr "le numéro de série de la zone doit être configuré dans --auth-soa"
 
-#: dnsmasq.c:254
+#: dnsmasq.c:268
 msgid "dhcp-range constructor not available on this platform"
 msgstr "le constructeur de plage dhcp n'est pas disponible sur cette plate-forme"
 
-#: dnsmasq.c:300
+#: dnsmasq.c:332
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr "--bind-interfaces et --bind-dynamic sont mutuellement exclusives"
 
-#: dnsmasq.c:303
+#: dnsmasq.c:335
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr "impossible de trouver la liste des interfaces : %s"
 
-#: dnsmasq.c:312
+#: dnsmasq.c:344
 #, c-format
 msgid "unknown interface %s"
 msgstr "interface %s inconnue"
 
-#: dnsmasq.c:377 dnsmasq.c:1054
+#: dnsmasq.c:406
+#, fuzzy
+msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
+msgstr "DBus n'est pas disponible : activez HAVE_DBUS dans src/config.h"
+
+#: dnsmasq.c:416 dnsmasq.c:1171
 #, c-format
 msgid "DBus error: %s"
 msgstr "Erreur DBus : %s"
 
-#: dnsmasq.c:380
+#: dnsmasq.c:419
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr "DBus n'est pas disponible : activez HAVE_DBUS dans src/config.h"
 
-#: dnsmasq.c:410
+#: dnsmasq.c:429
+#, fuzzy
+msgid "UBus not available: set HAVE_UBUS in src/config.h"
+msgstr "DBus n'est pas disponible : activez HAVE_DBUS dans src/config.h"
+
+#: dnsmasq.c:459
 #, c-format
 msgid "unknown user or group: %s"
 msgstr "utilisateur ou groupe inconnu : %s"
 
-#: dnsmasq.c:465
+#: dnsmasq.c:535
+#, c-format
+msgid "process is missing required capability %s"
+msgstr ""
+
+#: dnsmasq.c:567
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr "Ne peut effectuer un 'chdir' à la racine du système de fichier : %s"
 
-#: dnsmasq.c:730
+#: dnsmasq.c:815
 #, c-format
 msgid "started, version %s DNS disabled"
 msgstr "démarrage avec le DNS désactivé (version %s)"
 
-#: dnsmasq.c:734
+#: dnsmasq.c:820
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr "demarré, version %s (taille de cache %d)"
 
-#: dnsmasq.c:736
+#: dnsmasq.c:822
+msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
+msgstr ""
+
+#: dnsmasq.c:825
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr "démarrage avec le cache désactivé (version %s)"
 
-#: dnsmasq.c:739
+#: dnsmasq.c:828
 msgid "DNS service limited to local subnets"
 msgstr ""
 
-#: dnsmasq.c:742
+#: dnsmasq.c:831
 #, c-format
 msgid "compile time options: %s"
 msgstr "options à la compilation : %s"
 
-#: dnsmasq.c:751
+#: dnsmasq.c:840
 msgid "DBus support enabled: connected to system bus"
 msgstr "Support DBus autorisé : connecté au bus système"
 
-#: dnsmasq.c:753
+#: dnsmasq.c:842
 msgid "DBus support enabled: bus connection pending"
 msgstr "Support DBus autorisé : connexion au bus en attente"
 
-#: dnsmasq.c:771
+#: dnsmasq.c:850
+#, fuzzy
+msgid "UBus support enabled: connected to system bus"
+msgstr "Support DBus autorisé : connecté au bus système"
+
+#: dnsmasq.c:852
+#, fuzzy
+msgid "UBus support enabled: bus connection pending"
+msgstr "Support DBus autorisé : connexion au bus en attente"
+
+#: dnsmasq.c:872
+msgid "DNSSEC validation enabled but all unsigned answers are trusted"
+msgstr ""
+
+#: dnsmasq.c:874
 msgid "DNSSEC validation enabled"
 msgstr ""
 
-#: dnsmasq.c:775
+#: dnsmasq.c:878
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr ""
 
-#: dnsmasq.c:778
+#: dnsmasq.c:881
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr ""
 
-#: dnsmasq.c:783
+#: dnsmasq.c:884
+#, c-format
+msgid "configured with trust anchor for %s keytag %u"
+msgstr ""
+
+#: dnsmasq.c:890
 #, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr "Impossible de changer pour l'utilisateur %s : %s"
 
-#: dnsmasq.c:787
+#: dnsmasq.c:894
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr "active l'option --bind-interfaces à cause de limitations dans le système d'exploitation"
 
-#: dnsmasq.c:799
+#: dnsmasq.c:906
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr "attention : l'interface %s n'existe pas actuellement"
 
-#: dnsmasq.c:804
+#: dnsmasq.c:911
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr "attention : l'option « resolv-file » sera ignorée car « no-resolv » a été spécifié"
 
 #
-#: dnsmasq.c:807
+#: dnsmasq.c:914
 msgid "warning: no upstream servers configured"
 msgstr "attention : aucun serveur amont n'est configuré"
 
-#: dnsmasq.c:811
+#: dnsmasq.c:918
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr "mode asynchrone d'écriture de traces, la taille maximum de la queue est de %d messages."
 
-#: dnsmasq.c:832
+#: dnsmasq.c:939
 msgid "IPv6 router advertisement enabled"
 msgstr "annonces de routeur IPv6 activées"
 
-#: dnsmasq.c:837
+#: dnsmasq.c:944
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr ""
 
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 msgid "root is "
 msgstr "root est"
 
 #
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 msgid "enabled"
 msgstr "activé"
 
-#: dnsmasq.c:853
+#: dnsmasq.c:960
 msgid "secure mode"
 msgstr "mode sécurisé"
 
-#: dnsmasq.c:856
+#: dnsmasq.c:961
+#, fuzzy
+msgid "single port mode"
+msgstr "numéro de port invalide"
+
+#: dnsmasq.c:964
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:860
+#: dnsmasq.c:968
 #, fuzzy, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr "répertoire TFTP %s inaccessible : %s"
 
-#: dnsmasq.c:886
+#: dnsmasq.c:994
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr "le nombre maximum de transferts TFTP simultanés sera restreint à %d"
 
-#: dnsmasq.c:1056
+#: dnsmasq.c:1173
 msgid "connected to system DBus"
 msgstr "connecté au systeme DBus"
 
-#: dnsmasq.c:1215
+#: dnsmasq.c:1345
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr "Ne peut se lancer en tâche de fond : %s"
 
-#: dnsmasq.c:1218
+#: dnsmasq.c:1349
 #, c-format
 msgid "failed to create helper: %s"
 msgstr "impossible de créer le 'helper' : %s"
 
-#: dnsmasq.c:1221
+#: dnsmasq.c:1353
 #, c-format
 msgid "setting capabilities failed: %s"
 msgstr "impossible de configurer la capacité %s"
 
-#: dnsmasq.c:1224
+#: dnsmasq.c:1357
 #, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr "Impossible de changer l'identifiant utilisateur pour %s : %s"
 
-#: dnsmasq.c:1227
+#: dnsmasq.c:1361
 #, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr "Impossible de changer l'identifiant de groupe pour %s : %s"
 
-#: dnsmasq.c:1230
+#: dnsmasq.c:1365
 #, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr "impossible de lire le fichier de PID %s : %s"
 
-#: dnsmasq.c:1233
+#: dnsmasq.c:1369
 #, c-format
 msgid "cannot open log %s: %s"
 msgstr "Ne peut ouvrir le fichier de log %s : %s"
 
 #
-#: dnsmasq.c:1236
+#: dnsmasq.c:1373
 #, c-format
 msgid "failed to load Lua script: %s"
 msgstr "impossible de charger le script Lua : %s"
 
-#: dnsmasq.c:1239
+#: dnsmasq.c:1377
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr "répertoire TFTP %s inaccessible : %s"
 
-#: dnsmasq.c:1242
+#: dnsmasq.c:1381
 #, fuzzy, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr "ne peut ouvrir ou créer le fichiers de baux %s : %s"
 
-#: dnsmasq.c:1326
+#: dnsmasq.c:1465
 #, c-format
 msgid "script process killed by signal %d"
 msgstr "Le script a été terminé par le signal %d"
 
-#: dnsmasq.c:1330
+#: dnsmasq.c:1469
 #, c-format
 msgid "script process exited with status %d"
 msgstr "Le script s'est terminé avec le statut %d"
 
-#: dnsmasq.c:1334
+#: dnsmasq.c:1473
 #, c-format
 msgid "failed to execute %s: %s"
 msgstr "impossible d'exécuter à %s : %s"
 
-#: dnsmasq.c:1374
+#: dnsmasq.c:1513
 msgid "now checking DNSSEC signature timestamps"
 msgstr ""
 
-#: dnsmasq.c:1409 dnssec.c:160 dnssec.c:206
+#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
 #, fuzzy, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr "impossible de lire le fichier de PID %s : %s"
 
-#: dnsmasq.c:1416
+#: dnsmasq.c:1560
 msgid "exiting on receipt of SIGTERM"
 msgstr "sortie sur réception du signal SIGTERM"
 
-#: dnsmasq.c:1444
+#: dnsmasq.c:1588
 #, c-format
 msgid "failed to access %s: %s"
 msgstr "impossible d'accéder à %s : %s"
 
-#: dnsmasq.c:1474
+#: dnsmasq.c:1618
 #, c-format
 msgid "reading %s"
 msgstr "Lecture de %s"
 
-#: dnsmasq.c:1485
+#: dnsmasq.c:1629
 #, c-format
 msgid "no servers found in %s, will retry"
 msgstr "aucun serveur trouvé dans %s, va réessayer"
@@ -1656,7 +1763,7 @@ msgstr "impossible de lier la socket serveur DHCP : %s"
 msgid "cannot create ICMP raw socket: %s."
 msgstr "ne peut créer de socket en mode raw pour ICMP : %s."
 
-#: dhcp.c:252 dhcp6.c:173
+#: dhcp.c:252 dhcp6.c:180
 #, c-format
 msgid "unknown interface %s in bridge-interface"
 msgstr "interface %s inconnue spécifiée comme interface de pont"
@@ -1666,331 +1773,337 @@ msgstr "interface %s inconnue sp
 msgid "DHCP packet received on %s which has no address"
 msgstr "Paquet DHCP reçu sur %s qui n'a pas d'adresse"
 
-#: dhcp.c:427
+#: dhcp.c:428
 #, c-format
 msgid "ARP-cache injection failed: %s"
 msgstr ""
 
-#: dhcp.c:470
+#: dhcp.c:471
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr ""
 
-#: dhcp.c:531
+#: dhcp.c:526
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr "La plage d'adresses DHCP %s -- %s n'est pas cohérente avec le masque de réseau %s"
 
-#: dhcp.c:854
+#: dhcp.c:914
 #, c-format
 msgid "bad line at %s line %d"
 msgstr "mauvaise ligne dans %s ligne %d"
 
-#: dhcp.c:897
+#: dhcp.c:957
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr "ignore %s à la ligne %d : duplication de nom ou d'adresse IP"
 
-#: dhcp.c:1041 rfc3315.c:2149
+#: dhcp.c:1100 rfc3315.c:2139
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr "Relais DHCP %s -> %s"
 
-#: lease.c:98
+#: lease.c:64
+#, c-format
+msgid "ignoring invalid line in lease database: %s %s %s %s ..."
+msgstr ""
+
+#: lease.c:101
+#, c-format
+msgid "ignoring invalid line in lease database, bad address: %s"
+msgstr ""
+
+#: lease.c:108
 msgid "too many stored leases"
 msgstr "beaucoup trop de baux enregistrés"
 
-#: lease.c:166
+#: lease.c:176
 #, c-format
 msgid "cannot open or create lease file %s: %s"
 msgstr "ne peut ouvrir ou créer le fichiers de baux %s : %s"
 
-#: lease.c:175
-#, c-format
-msgid "failed to parse lease database, invalid line: %s %s %s %s ..."
-msgstr ""
+#: lease.c:185
+#, fuzzy
+msgid "failed to parse lease database cleanly"
+msgstr "impossible de lire %s : %s"
 
-#: lease.c:180
+#: lease.c:188
 #, fuzzy, c-format
 msgid "failed to read lease file %s: %s"
 msgstr "impossible de lire %s : %s"
 
-#: lease.c:196
+#: lease.c:204
 #, c-format
 msgid "cannot run lease-init script %s: %s"
 msgstr "Ne peut pas exécuter le script lease-init %s : %s"
 
-#: lease.c:202
+#: lease.c:210
 #, c-format
 msgid "lease-init script returned exit code %s"
 msgstr "le script lease-init a retourné le code %s"
 
-#: lease.c:373
+#: lease.c:381
 #, c-format
 msgid "failed to write %s: %s (retry in %us)"
 msgstr "impossible de lire %s : %s (prochain essai dans %us)"
 
-#: lease.c:937
+#: lease.c:955
 #, c-format
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr "Le domaine %s est ignoré pour l'hôte DHCP %s"
 
-#: rfc2131.c:347
+#: rfc2131.c:372
 #, c-format
 msgid "no address range available for DHCP request %s %s"
 msgstr "pas de plage d'adresse disponible pour la requête DHCP %s %s"
 
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "with subnet selector"
 msgstr "avec sélecteur de sous-reseau"
 
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "via"
 msgstr "par l'intermédiaire de"
 
-#: rfc2131.c:360
+#: rfc2131.c:385
 #, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr "%u sous-réseaux DHCP disponibles : %s/%s"
 
-#: rfc2131.c:363 rfc3315.c:306
+#: rfc2131.c:388 rfc3315.c:319
 #, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr "%u la gamme DHCP disponible est : %s -- %s"
 
-#: rfc2131.c:474
+#: rfc2131.c:499
 #, c-format
 msgid "%u vendor class: %s"
 msgstr "%u Classe de vendeur ('Vendor Class') : %s"
 
-#: rfc2131.c:476
+#: rfc2131.c:501
 #, c-format
 msgid "%u user class: %s"
 msgstr "%u Classe d'utilisateur : %s"
 
-#: rfc2131.c:510
+#: rfc2131.c:535
 msgid "disabled"
 msgstr "désactivé"
 
-#: rfc2131.c:551 rfc2131.c:1006 rfc2131.c:1430 rfc3315.c:616 rfc3315.c:869
-#: rfc3315.c:1148
+#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1097
 msgid "ignored"
 msgstr "ignoré"
 
-#: rfc2131.c:566 rfc2131.c:1239 rfc3315.c:919
+#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
 msgid "address in use"
 msgstr "adresse déjà utilisée"
 
-#: rfc2131.c:580 rfc2131.c:1060
+#: rfc2131.c:605 rfc2131.c:1119
 msgid "no address available"
 msgstr "pas d'adresse disponible"
 
-#: rfc2131.c:587 rfc2131.c:1202
+#: rfc2131.c:612 rfc2131.c:1273
 msgid "wrong network"
 msgstr "mauvais réseau"
 
-#: rfc2131.c:602
+#: rfc2131.c:627
 msgid "no address configured"
 msgstr "pas d'adresse configurée"
 
-#: rfc2131.c:608 rfc2131.c:1252
+#: rfc2131.c:633 rfc2131.c:1323
 msgid "no leases left"
 msgstr "plus aucun bail disponible"
 
-#: rfc2131.c:703 rfc3315.c:482
+#: rfc2131.c:734 rfc3315.c:499
 #, c-format
 msgid "%u client provides name: %s"
 msgstr "le client %u fourni le nom : %s"
 
-#: rfc2131.c:808
+#: rfc2131.c:864
 msgid "PXE BIS not supported"
 msgstr "Service PXE BIS (Boot Integrity Services) non supporté"
 
-#: rfc2131.c:974 rfc3315.c:1242
+#: rfc2131.c:1032 rfc3315.c:1197
 #, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr "désactive l'adresse statique DHCP %s pour %s"
 
-#: rfc2131.c:995
+#: rfc2131.c:1053
 msgid "unknown lease"
 msgstr "bail inconnu"
 
-#: rfc2131.c:1029
+#: rfc2131.c:1088
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr "L'adresse statique %s ne sera pas utilisée car un bail est déjà attribué à %s"
 
-#: rfc2131.c:1039
+#: rfc2131.c:1098
 #, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr "L'adresse statique %s ne sera pas utilisée car elle est utilisée par le serveur ou un relai"
 
-#: rfc2131.c:1042
+#: rfc2131.c:1101
 #, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr "L'adresse statique %s ne sera pas utilisée car elle a préalablement été refusée"
 
-#: rfc2131.c:1058 rfc2131.c:1245
+#: rfc2131.c:1117 rfc2131.c:1316
 msgid "no unique-id"
 msgstr "pas d'identifiant unique"
 
-#: rfc2131.c:1140
+#: rfc2131.c:1209
 msgid "wrong server-ID"
 msgstr "mauvais identifiant de serveur"
 
-#: rfc2131.c:1159
+#: rfc2131.c:1228
 msgid "wrong address"
 msgstr "mauvaise adresse"
 
-#: rfc2131.c:1177 rfc3315.c:1015
+#: rfc2131.c:1246 rfc3315.c:961
 msgid "lease not found"
 msgstr "bail non trouvé"
 
-#: rfc2131.c:1210
+#: rfc2131.c:1281
 msgid "address not available"
 msgstr "adresse non disponible"
 
-#: rfc2131.c:1221
+#: rfc2131.c:1292
 msgid "static lease available"
 msgstr "bail statique disponible"
 
-#: rfc2131.c:1225
+#: rfc2131.c:1296
 msgid "address reserved"
 msgstr "adresse reservée"
 
-#: rfc2131.c:1233
+#: rfc2131.c:1304
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr "abandon du bail de %s pour %s"
 
-#: rfc2131.c:1757
+#: rfc2131.c:1845
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr "%u nom de fichier 'bootfile' : %s"
 
-#: rfc2131.c:1766
+#: rfc2131.c:1854
 #, c-format
 msgid "%u server name: %s"
 msgstr "%u nom du serveur : %s"
 
-#: rfc2131.c:1774
+#: rfc2131.c:1862
 #, c-format
 msgid "%u next server: %s"
 msgstr "%u serveur suivant : %s"
 
-#: rfc2131.c:1777
+#: rfc2131.c:1865
 #, c-format
 msgid "%u broadcast response"
 msgstr "%u réponse broadcast"
 
-#: rfc2131.c:1840
+#: rfc2131.c:1928
 #, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr "Impossible d'envoyer l'option DHCP/BOOTP %d : pas assez d'espace dans le paquet"
 
-#: rfc2131.c:2131
+#: rfc2131.c:2219
 msgid "PXE menu too large"
 msgstr "menu PXE trop grand"
 
-#: rfc2131.c:2270 rfc3315.c:1515
+#: rfc2131.c:2358 rfc3315.c:1470
 #, c-format
 msgid "%u requested options: %s"
 msgstr "%u options demandées : %s"
 
-#: rfc2131.c:2587
+#: rfc2131.c:2675
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr "ne peux envoyer l'option RFC3925 : trop d'options pour le numéro d'entreprise %d"
 
-#: rfc2131.c:2650
+#: rfc2131.c:2738
 #, c-format
 msgid "%u reply delay: %d"
 msgstr ""
 
-#: netlink.c:77
+#: netlink.c:76
 #, c-format
 msgid "cannot create netlink socket: %s"
 msgstr "ne peux lier une socket netlink : %s"
 
-#: netlink.c:355
+#: netlink.c:352
 #, c-format
 msgid "netlink returns error: %s"
 msgstr "Erreur netlink : %s"
 
-#: dbus.c:186
-msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
-msgstr "tentative de lier une adresse serveur IPV6 via DBus - pas de support IPV6"
-
-#: dbus.c:439
+#: dbus.c:438
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:444
+#: dbus.c:443
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:690
+#: dbus.c:717
 msgid "setting upstream servers from DBus"
 msgstr "configuration des serveurs amonts à partir de DBus"
 
-#: dbus.c:737
+#: dbus.c:764
 msgid "could not register a DBus message handler"
 msgstr "ne peut enregistrer une routine de traitement des messages DBus"
 
-#: bpf.c:265
+#: bpf.c:261
 #, c-format
 msgid "cannot create DHCP BPF socket: %s"
 msgstr "impossible de créer une socket BPF pour DHCP : %s"
 
-#: bpf.c:293
+#: bpf.c:289
 #, c-format
 msgid "DHCP request for unsupported hardware type (%d) received on %s"
 msgstr "requête DHCP pour un type de matériel non supporté (%d) reçue sur %s"
 
-#: bpf.c:378
+#: bpf.c:374
 #, fuzzy, c-format
 msgid "cannot create PF_ROUTE socket: %s"
 msgstr "ne peut créer la socket DHCP: %s"
 
-#: bpf.c:399
+#: bpf.c:395
 msgid "Unknown protocol version from route socket"
 msgstr ""
 
-#: helper.c:154
+#: helper.c:150
 msgid "lease() function missing in Lua script"
 msgstr "la fonction lease() est absente du script Lua"
 
-#: tftp.c:319
+#: tftp.c:347
 msgid "unable to get free port for TFTP"
 msgstr "impossible d'obtenir un port libre pour TFTP"
 
-#: tftp.c:335
+#: tftp.c:363
 #, c-format
 msgid "unsupported request from %s"
 msgstr "requête de %s non supportée"
 
-#: tftp.c:483
+#: tftp.c:510
 #, c-format
 msgid "file %s not found"
 msgstr "fichier %s non trouvé"
 
-#: tftp.c:592
-#, c-format
-msgid "error %d %s received from %s"
-msgstr "erreur %d %s reçu de %s"
-
-#: tftp.c:634
+#: tftp.c:628
 #, c-format
 msgid "failed sending %s to %s"
 msgstr "impossible d'envoyer %s à %s"
 
-#: tftp.c:634
+#: tftp.c:628
 #, c-format
 msgid "sent %s to %s"
 msgstr "envoyé %s à %s"
 
+#: tftp.c:678
+#, c-format
+msgid "error %d %s received from %s"
+msgstr "erreur %d %s reçu de %s"
+
 #: log.c:190
 #, c-format
 msgid "overflow: %d log entries lost"
@@ -2005,7 +2118,7 @@ msgstr "trace perdue : %s"
 msgid "FAILED to start up"
 msgstr "IMPOSSIBLE de démarrer"
 
-#: conntrack.c:65
+#: conntrack.c:63
 #, c-format
 msgid "Conntrack connection mark retrieval failed: %s"
 msgstr "La récupération de la marque de suivi de connexion a échoué : %s"
@@ -2025,77 +2138,72 @@ msgstr "impossible de d
 msgid "failed to bind DHCPv6 server socket: %s"
 msgstr "impossible de lier la socket serveur DHCPv6 : %s"
 
-#: rfc3315.c:157
+#: rfc3315.c:173
 #, c-format
 msgid "no address range available for DHCPv6 request from relay at %s"
 msgstr "pas de plage d'adresse disponible pour la requête DHCPv6 transmise via le relai %s"
 
-#: rfc3315.c:166
+#: rfc3315.c:182
 #, c-format
 msgid "no address range available for DHCPv6 request via %s"
 msgstr "pas de plage d'adresse disponible pour la requête DHCPv6 via %s"
 
-#: rfc3315.c:303
+#: rfc3315.c:316
 #, c-format
 msgid "%u available DHCPv6 subnet: %s/%d"
 msgstr "%u sous-réseaux DHCPv6 disponibles : %s/%d"
 
-#: rfc3315.c:386
+#: rfc3315.c:399
 #, c-format
 msgid "%u vendor class: %u"
 msgstr "%u Classe de vendeur ('Vendor Class') : %u"
 
-#: rfc3315.c:434
+#: rfc3315.c:447
 #, c-format
 msgid "%u client MAC address: %s"
 msgstr "%u MAC adresse du client : %s"
 
-#: rfc3315.c:673
-#, c-format
-msgid "unknown prefix-class %d"
-msgstr "préfixe de classe inconnu %d"
-
-#: rfc3315.c:816 rfc3315.c:911
+#: rfc3315.c:762 rfc3315.c:859
 msgid "address unavailable"
 msgstr "adresse non disponible"
 
-#: rfc3315.c:828 rfc3315.c:959 rfc3315.c:1292
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
 msgid "success"
 msgstr "réussi"
 
-#: rfc3315.c:843 rfc3315.c:852 rfc3315.c:967 rfc3315.c:969
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
 msgid "no addresses available"
 msgstr "pas d'adresse disponible"
 
-#: rfc3315.c:946
+#: rfc3315.c:890
 msgid "not on link"
 msgstr "pas sur ce lien"
 
-#: rfc3315.c:1019 rfc3315.c:1204 rfc3315.c:1281
+#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
 msgid "no binding found"
 msgstr "aucune liaison trouvée"
 
-#: rfc3315.c:1057
+#: rfc3315.c:1002
 msgid "deprecated"
 msgstr "obsolète"
 
-#: rfc3315.c:1062
+#: rfc3315.c:1007
 msgid "address invalid"
 msgstr "adresse non valide"
 
-#: rfc3315.c:1109
+#: rfc3315.c:1057 rfc3315.c:1059
 msgid "confirm failed"
 msgstr "confirmation d'échec"
 
-#: rfc3315.c:1125
+#: rfc3315.c:1074
 msgid "all addresses still on link"
 msgstr "toutes les adresses sont toujours sur le lien"
 
-#: rfc3315.c:1213
+#: rfc3315.c:1165
 msgid "release received"
 msgstr "libération reçue"
 
-#: rfc3315.c:2140
+#: rfc3315.c:2130
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr "Impossible de faire du multicast au server DHCPv6 sans interface valide"
 
@@ -2109,76 +2217,76 @@ msgstr "L'option dhcp-option redondante %d sera ignor
 msgid "%u tags: %s"
 msgstr "%u options: %s"
 
-#: dhcp-common.c:407
+#: dhcp-common.c:444
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr "%s a plus d'une adresse dans le fichier d'hôte, utilisation de %s pour le DHCP."
 
-#: dhcp-common.c:430
+#: dhcp-common.c:478
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr "adresse IP %s (%s) dupliquée dans la directive dhcp-config."
 
-#: dhcp-common.c:491
+#: dhcp-common.c:542
 #, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr "impossible de déclarer SO_BINDTODEVICE sur la socket DHCP : %s"
 
-#: dhcp-common.c:612
+#: dhcp-common.c:665
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr "Options DHCP connues :\n"
 
-#: dhcp-common.c:623
+#: dhcp-common.c:676
 #, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr "Options DHCPv6 connues :\n"
 
-#: dhcp-common.c:820
+#: dhcp-common.c:873
 msgid ", prefix deprecated"
 msgstr ", préfixe obsolète"
 
-#: dhcp-common.c:823
+#: dhcp-common.c:876
 #, c-format
 msgid ", lease time "
 msgstr ", durée de bail "
 
-#: dhcp-common.c:865
+#: dhcp-common.c:918
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr "%s sans état (stateless) sur %s%.0s%.0s%s"
 
-#: dhcp-common.c:867
+#: dhcp-common.c:920
 #, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr "%s, baux statiques seulement sur %.0s%s%s%.0s"
 
-#: dhcp-common.c:869
+#: dhcp-common.c:922
 #, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr "%s, proxy sur le sous-réseau %.0s%s%.0s"
 
-#: dhcp-common.c:870
+#: dhcp-common.c:923
 #, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr "%s, plage d'adresses IP %s -- %s%s%.0s"
 
-#: dhcp-common.c:883
+#: dhcp-common.c:936
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr "noms IPv6 dérivés de DHCPv4 sur %s%s"
 
-#: dhcp-common.c:886
+#: dhcp-common.c:939
 #, c-format
 msgid "router advertisement on %s%s"
 msgstr "annonces de routeurs sur %s%s"
 
-#: dhcp-common.c:897
+#: dhcp-common.c:950
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr "Relais DHCP de %s à %s via %s"
 
-#: dhcp-common.c:899
+#: dhcp-common.c:952
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr "Relais DHCP de %s à %s"
@@ -2188,7 +2296,7 @@ msgstr "Relais DHCP de %s 
 msgid "cannot create ICMPv6 socket: %s"
 msgstr "ne peut créer la socket ICMPv6: %s"
 
-#: auth.c:449
+#: auth.c:439
 #, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr "la requête de transfert de zone en provenance de %s est ignorée"
@@ -2203,18 +2311,23 @@ msgstr "impossible de trouver la version de noyau : %s"
 msgid "failed to create IPset control socket: %s"
 msgstr "impossible de créer une socket de contrôle IPset : %s"
 
-#: ipset.c:233
+#: ipset.c:226
 #, fuzzy, c-format
 msgid "failed to update ipset %s: %s"
 msgstr "impossible de lire le fichier de PID %s : %s"
 
-#: dnssec.c:208
+#: dnssec.c:206
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
 msgstr ""
 
-#: blockdata.c:58
+#: dnssec.c:902
+#, c-format
+msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
+msgstr ""
+
+#: blockdata.c:55
 #, c-format
-msgid "DNSSEC memory in use %u, max %u, allocated %u"
+msgid "pool memory in use %u, max %u, allocated %u"
 msgstr ""
 
 #: tables.c:61
@@ -2246,13 +2359,13 @@ msgstr "Erreur DBus : %s"
 msgid "info: table created"
 msgstr ""
 
-#: tables.c:134
+#: tables.c:133
 #, c-format
 msgid "warning: DIOCR%sADDRS: %s"
 msgstr ""
 
 #
-#: tables.c:138
+#: tables.c:137
 #, fuzzy, c-format
 msgid "%d addresses %s"
 msgstr "mauvaise adresse"
@@ -2292,6 +2405,82 @@ msgstr "Ne peut pas lire le r
 msgid "inotify, new or changed file %s"
 msgstr ""
 
+#: dump.c:64
+#, fuzzy, c-format
+msgid "cannot create %s: %s"
+msgstr "Ne peut pas lire %s : %s"
+
+#: dump.c:70
+#, fuzzy, c-format
+msgid "bad header in %s"
+msgstr "adresse déjà utilisée"
+
+#: dump.c:201
+#, fuzzy
+msgid "failed to write packet dump"
+msgstr "impossible d'envoyer le paquet : %s"
+
+#: dump.c:203
+#, c-format
+msgid "dumping UDP packet %u mask 0x%04x"
+msgstr ""
+
+#: ubus.c:52
+#, c-format
+msgid "UBus subscription callback: %s subscriber(s)"
+msgstr ""
+
+#: ubus.c:73
+#, fuzzy, c-format
+msgid "Cannot reconnect to UBus: %s"
+msgstr "Ne peut ouvrir le fichier de log %s : %s"
+
+#: ubus.c:89
+msgid "Cannot initialize UBus: connection failed"
+msgstr ""
+
+#: ubus.c:102
+#, fuzzy, c-format
+msgid "Cannot add object to UBus: %s"
+msgstr "Ne peut ouvrir le fichier de log %s : %s"
+
+#: ubus.c:112
+#, fuzzy
+msgid "Connected to system UBus"
+msgstr "connecté au systeme DBus"
+
+#: ubus.c:122
+msgid "Cannot set UBus listeners: no connection"
+msgstr ""
+
+#: ubus.c:142
+msgid "Cannot poll UBus listeners: no connection"
+msgstr ""
+
+#: ubus.c:155
+msgid "Disconnecting from UBus"
+msgstr ""
+
+#: ubus.c:199
+#, fuzzy, c-format
+msgid "Failed to send UBus event: %s"
+msgstr "impossible d'envoyer le paquet : %s"
+
+#~ msgid "Specify DHCPv6 prefix class"
+#~ msgstr "Spécifie le préfixe de classe DHCPv6"
+
+#~ msgid "cannot run scripts under uClinux"
+#~ msgstr "ne peut exécuter de script sous uClinux"
+
+#~ msgid "cannot match tags in --dhcp-host"
+#~ msgstr "L'utilisation de labels est prohibée dans --dhcp-host"
+
+#~ msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
+#~ msgstr "tentative de lier une adresse serveur IPV6 via DBus - pas de support IPV6"
+
+#~ msgid "unknown prefix-class %d"
+#~ msgstr "préfixe de classe inconnu %d"
+
 #, fuzzy
 #~ msgid "cannot cannonicalise resolv-file %s: %s"
 #~ msgstr "ne peut ouvrir ou créer le fichiers de baux %s : %s"
index 3634add..5b74aa8 100644 (file)
--- a/po/id.po
+++ b/po/id.po
@@ -15,77 +15,77 @@ msgstr ""
 "Content-Type: text/plain; charset=ASCII\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: cache.c:518
+#: cache.c:559
 msgid "Internal error in cache."
 msgstr ""
 
 # OK
-#: cache.c:928
+#: cache.c:1081
 #, fuzzy, c-format
 msgid "failed to load names from %s: %s"
 msgstr "gagal memuat nama-nama dari %s: %s"
 
 # OK
-#: cache.c:954 dhcp.c:867
+#: cache.c:1103 dhcp.c:927
 #, fuzzy, c-format
 msgid "bad address at %s line %d"
 msgstr "kesalahan nama pada %s baris %d"
 
 # OK
-#: cache.c:1007 dhcp.c:883
+#: cache.c:1156 dhcp.c:943
 #, c-format
 msgid "bad name at %s line %d"
 msgstr "kesalahan nama pada %s baris %d"
 
 # OK
-#: cache.c:1016 dhcp.c:958
+#: cache.c:1167 dhcp.c:1018
 #, c-format
 msgid "read %s - %d addresses"
 msgstr "membaca %s - %d alamat"
 
 # OK
-#: cache.c:1129
+#: cache.c:1283
 msgid "cleared cache"
 msgstr "cache telah dihapus"
 
-#: cache.c:1158
+#: cache.c:1345
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr ""
 
-#: cache.c:1237
+#: cache.c:1391
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr ""
 
 # OK
-#: cache.c:1261
+#: cache.c:1415
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr "tidak memberikan nama %s kepada lease DHCP %s karena nama telah ada dalam %sdengan alamat %s"
 
-#: cache.c:1418
+#: cache.c:1663
 #, c-format
 msgid "time %lu"
 msgstr ""
 
 # OK
-#: cache.c:1419
+#: cache.c:1664
 #, fuzzy, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr "ukuran cache %d, %d/%d penyisipan cache menimpa cache yang belum kadaluwarsa"
 
-#: cache.c:1421
+#: cache.c:1666
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr ""
 
-#: cache.c:1424
+#: cache.c:1669
 #, c-format
 msgid "queries for authoritative zones %u"
 msgstr ""
 
-#: cache.c:1450
+#: cache.c:1694
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr ""
@@ -103,769 +103,807 @@ msgid "failed to allocate memory"
 msgstr "gagal memuat %S: %m"
 
 # OK
-#: util.c:281 option.c:619
+#: util.c:281 option.c:641
 msgid "could not get memory"
 msgstr "tidak bisa mendapatkan memory"
 
 # OK
-#: util.c:291
+#: util.c:302
 #, fuzzy, c-format
 msgid "cannot create pipe: %s"
 msgstr "tidak bisa membaca %s: %s"
 
 # OK
-#: util.c:299
+#: util.c:310
 #, fuzzy, c-format
 msgid "failed to allocate %d bytes"
 msgstr "gagal memuat %S: %m"
 
 # OK
-#: util.c:468
+#: util.c:506
 #, c-format
 msgid "infinite"
 msgstr "tak terbatas"
 
 # OK
-#: option.c:344
+#: option.c:358
 msgid "Specify local address(es) to listen on."
 msgstr "Tentukan alamat lokal untuk mendengarkan."
 
 # OK
-#: option.c:345
+#: option.c:359
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr "Menghasilkan ipaddr untuk semua host dalam domain yang dipilih."
 
 # OK
-#: option.c:346
+#: option.c:360
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr "Fake pencarian balik untuk alamat private sesuai dengan RFC1918."
 
 # OK
-#: option.c:347
+#: option.c:361
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr "Perlakukan ipaddr sebagai NXDOMAIN (mengalahkan wildcard Verisign)."
 
 # OK
-#: option.c:348
+#: option.c:362
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr "Tentukan ukuran cache, dalam jumlah isian (default %s)."
 
 # OK
-#: option.c:349
+#: option.c:363
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr "Tentukan file konfigurasi (default %s)."
 
 # OK
-#: option.c:350
+#: option.c:364
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr "JANGAN berjalan di background: berjalan dalam modus debug."
 
 # OK
-#: option.c:351
+#: option.c:365
 msgid "Do NOT forward queries with no domain part."
 msgstr "JANGAN teruskan permintaan tanpa bagian domain."
 
 # OK
-#: option.c:352
+#: option.c:366
 msgid "Return self-pointing MX records for local hosts."
 msgstr "Mengembalikan record MX untuk diri sendiri host-host lokal."
 
 # OK
-#: option.c:353
+#: option.c:367
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr "Melengkapi nama-nama di /etc/hosts dengan akhiran domain."
 
 # OK
-#: option.c:354
+#: option.c:368
 msgid "Don't forward spurious DNS requests from Windows hosts."
 msgstr "Jangan meneruskan permintaan DNS spurious dari host-host Windows."
 
 # OK
-#: option.c:355
+#: option.c:369
 msgid "Enable DHCP in the range given with lease duration."
 msgstr "Bolehkan DHCP dalam jangkauan yang diberikan dengan durasi lease."
 
 # OK
-#: option.c:356
+#: option.c:370
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr "Ubah ke group ini setelah mulai (default %s)."
 
 # OK
-#: option.c:357
+#: option.c:371
 msgid "Set address or hostname for a specified machine."
 msgstr "Setel alamat atau nama host untuk mesin yang disebutkan."
 
 # OK
-#: option.c:358
+#: option.c:372
 #, fuzzy
 msgid "Read DHCP host specs from file."
 msgstr "nama MX salah"
 
-#: option.c:359
+#: option.c:373
 msgid "Read DHCP option specs from file."
 msgstr ""
 
 # OK
-#: option.c:360
+#: option.c:374
 #, fuzzy
 msgid "Read DHCP host specs from a directory."
 msgstr "nama MX salah"
 
 # OK
-#: option.c:361
+#: option.c:375
 #, fuzzy
 msgid "Read DHCP options from a directory."
 msgstr "nama MX salah"
 
-#: option.c:362
+#: option.c:376
 msgid "Evaluate conditional tag expression."
 msgstr ""
 
 # OK
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Do NOT load %s file."
 msgstr "JANGAN muat file %s."
 
 # OK
-#: option.c:364
+#: option.c:378
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr "Sebutkan sebuah file hosts yang harus dibaca sebagai tambahan untuk %s."
 
 # OK
-#: option.c:365
+#: option.c:379
 #, fuzzy
 msgid "Read hosts files from a directory."
 msgstr "nama MX salah"
 
 # OK
-#: option.c:366
+#: option.c:380
 msgid "Specify interface(s) to listen on."
 msgstr "Sebutkan antarmuka untuk mendengarkan."
 
 # OK
-#: option.c:367
+#: option.c:381
 msgid "Specify interface(s) NOT to listen on."
 msgstr "Sebutkan antarmuka untuk TIDAK mendengarkan."
 
 # OK
-#: option.c:368
+#: option.c:382
 #, fuzzy
 msgid "Map DHCP user class to tag."
 msgstr "Petakan kelas user DHCP ke setelan yang dipilih."
 
-#: option.c:369
+#: option.c:383
 msgid "Map RFC3046 circuit-id to tag."
 msgstr ""
 
-#: option.c:370
+#: option.c:384
 msgid "Map RFC3046 remote-id to tag."
 msgstr ""
 
-#: option.c:371
+#: option.c:385
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr ""
 
 # OK
-#: option.c:372
+#: option.c:386
 #, fuzzy
 msgid "Don't do DHCP for hosts with tag set."
 msgstr "Jangan menggunakan DHCP untuk host-host yang dipilih."
 
 # OK
-#: option.c:373
+#: option.c:387
 #, fuzzy
 msgid "Force broadcast replies for hosts with tag set."
 msgstr "Jangan menggunakan DHCP untuk host-host yang dipilih."
 
 # OK
-#: option.c:374
+#: option.c:388
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr "JANGAN berjalan di background, jangan berjalan dalam modus debug."
 
 # OK
-#: option.c:375
+#: option.c:389
 msgid "Assume we are the only DHCP server on the local network."
 msgstr "Berpikir bahwa kita satu-satunya DHCP server dalam jaringan."
 
 # OK
-#: option.c:376
+#: option.c:390
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr "Sebutkan lokasi untuk menyimpan lease DHCP (default %s)."
 
 # OK
-#: option.c:377
+#: option.c:391
 msgid "Return MX records for local hosts."
 msgstr "Kembalikan rekord MX untuk host-host lokal."
 
 # OK
-#: option.c:378
+#: option.c:392
 msgid "Specify an MX record."
 msgstr "Sebutkan sebuah rekord MX."
 
 # OK
-#: option.c:379
+#: option.c:393
 msgid "Specify BOOTP options to DHCP server."
 msgstr "Sebutkan pilihan-pilihan BOOTP untuk DHCP server."
 
-#: option.c:380
+#: option.c:394
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr "Jangan kumpulkan file %s, muat kembali saat SIGHUP."
 
 # OK
-#: option.c:381
+#: option.c:395
 msgid "Do NOT cache failed search results."
 msgstr "JANGAN menyimpan hasil pencarian yang gagal."
 
 # OK
-#: option.c:382
+#: option.c:396
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr "Gunakan secara ketat namaserver yang disebutkan sesuai urutan di %s."
 
 # OK
-#: option.c:383
+#: option.c:397
 #, fuzzy
 msgid "Specify options to be sent to DHCP clients."
 msgstr "Setel pilihan-pilihan tambahan yang akan disetel untuk klien-klien DHCP."
 
-#: option.c:384
+#: option.c:398
 msgid "DHCP option sent even if the client does not request it."
 msgstr ""
 
 # OK
-#: option.c:385
+#: option.c:399
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr "Sebutkan port untuk mendengarkan permintaan DNS (default port 53)."
 
 # OK
-#: option.c:386
+#: option.c:400
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr "Ukuran maksimum paket UDP yang didukung untuk EDNS.0 (default %s)."
 
 # OK
-#: option.c:387
+#: option.c:401
 #, fuzzy
 msgid "Log DNS queries."
 msgstr "Permintaan log."
 
 # OK
-#: option.c:388
+#: option.c:402
 #, fuzzy
 msgid "Force the originating port for upstream DNS queries."
 msgstr "Paksa port asal untuk permintaan ke atas."
 
 # OK
-#: option.c:389
+#: option.c:403
 msgid "Do NOT read resolv.conf."
 msgstr "JANGAN baca resolv.conf."
 
 # OK
-#: option.c:390
+#: option.c:404
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr "Sebutkan path ke resolv.conf (default %s)."
 
 # OK
-#: option.c:391
+#: option.c:405
 #, fuzzy
 msgid "Specify path to file with server= options"
 msgstr "Sebutkan path file PID. (default %s)."
 
 # OK
-#: option.c:392
+#: option.c:406
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr "Sebutkan alamat-alamat server di atas, boleh dilengkapi dengan nama domain."
 
 # OK
-#: option.c:393
+#: option.c:407
 #, fuzzy
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr "Sebutkan alamat-alamat server di atas, boleh dilengkapi dengan nama domain."
 
 # OK
-#: option.c:394
+#: option.c:408
 msgid "Never forward queries to specified domains."
 msgstr "JANGAN pernah meneruskan permintaan ke domain yang disebutkan."
 
 # OK
-#: option.c:395
+#: option.c:409
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr "Sebutkan domain yang digunakan dalam lease DHCP."
 
 # OK
-#: option.c:396
+#: option.c:410
 msgid "Specify default target in an MX record."
 msgstr "Sebutkan tujuan default dalam rekord MX."
 
 # OK
-#: option.c:397
+#: option.c:411
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr "Sebutkan time-to-live dalam detik untuk jawaban dari /etc/hosts."
 
 # OK
-#: option.c:398
+#: option.c:412
 #, fuzzy
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr "Sebutkan time-to-live dalam detik untuk jawaban dari /etc/hosts."
 
 # OK
-#: option.c:399
+#: option.c:413
 #, fuzzy
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr "Sebutkan time-to-live dalam detik untuk jawaban dari /etc/hosts."
 
 # OK
-#: option.c:400
+#: option.c:414
 #, fuzzy
 msgid "Specify time-to-live ceiling for cache."
 msgstr "Sebutkan time-to-live dalam detik untuk jawaban dari /etc/hosts."
 
 # OK
-#: option.c:401
+#: option.c:415
 #, fuzzy
 msgid "Specify time-to-live floor for cache."
 msgstr "Sebutkan time-to-live dalam detik untuk jawaban dari /etc/hosts."
 
 # OK
-#: option.c:402
+#: option.c:416
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr "Ubah ke user ini setelah mulai. (default %s)."
 
 # OK
-#: option.c:403
+#: option.c:417
 #, fuzzy
 msgid "Map DHCP vendor class to tag."
 msgstr "Memetakan kelas vendor DHCP ke daftar pilihan."
 
 # OK
-#: option.c:404
+#: option.c:418
 msgid "Display dnsmasq version and copyright information."
 msgstr "Menampilkan versi dan informasi hak cipta dnsmasq."
 
 # OK
-#: option.c:405
+#: option.c:419
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr "Terjemahkan alamat-alamat IPv4 dari server-server di atas."
 
 # OK
-#: option.c:406
+#: option.c:420
 msgid "Specify a SRV record."
 msgstr "Sebutkan rekord SRV."
 
-#: option.c:407
+#: option.c:421
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr ""
 
 # OK
-#: option.c:408
+#: option.c:422
 #, fuzzy, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr "Sebutkan path file PID. (default %s)."
 
 # OK
-#: option.c:409
+#: option.c:423
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr "Sebutkan jumlah maksimum lease DHCP (default %s)."
 
 # OK
-#: option.c:410
+#: option.c:424
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr "Jawab permintaan DNS berdasarkan antarmuka dimana permintaan dikirimkan."
 
 # OK
-#: option.c:411
+#: option.c:425
 msgid "Specify TXT DNS record."
 msgstr "Sebutkan rekord TXT DNS."
 
 # OK
-#: option.c:412
+#: option.c:426
 #, fuzzy
 msgid "Specify PTR DNS record."
 msgstr "Sebutkan rekord TXT DNS."
 
-#: option.c:413
+#: option.c:427
 msgid "Give DNS name to IPv4 address of interface."
 msgstr ""
 
 # OK
-#: option.c:414
+#: option.c:428
 msgid "Bind only to interfaces in use."
 msgstr "Hanya kaitkan ke antarmuka yang sedang digunakan saja."
 
 # OK
-#: option.c:415
+#: option.c:429
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr "Baca informasi statik host DHCP dari %s."
 
 # OK
-#: option.c:416
+#: option.c:430
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr "Mungkinkan antar muka DBus untuk menyetel server-server di atas, dsb."
 
+#: option.c:431
+msgid "Enable the UBus interface."
+msgstr ""
+
 # OK
-#: option.c:417
+#: option.c:432
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr "JANGAN menyediakan DHCP pada antarmuka ini, hanya menyediakan DNS."
 
 # OK
-#: option.c:418
+#: option.c:433
 msgid "Enable dynamic address allocation for bootp."
 msgstr "Mungkinkan alokasi alamat dinamis untuk bootp."
 
 # OK
-#: option.c:419
+#: option.c:434
 #, fuzzy
 msgid "Map MAC address (with wildcards) to option set."
 msgstr "Memetakan kelas vendor DHCP ke daftar pilihan."
 
-#: option.c:420
+#: option.c:435
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr ""
 
-#: option.c:421
+#: option.c:436
+msgid "Specify extra networks sharing a broadcast domain for DHCP"
+msgstr ""
+
+#: option.c:437
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr ""
 
-#: option.c:422
+#: option.c:438
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:423
+#: option.c:439
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:424
+#: option.c:440
 msgid "Run lease-change scripts as this user."
 msgstr ""
 
-#: option.c:425
+#: option.c:441
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr ""
 
-#: option.c:426
+#: option.c:442
 msgid "Read configuration from all the files in this directory."
 msgstr ""
 
 # OK
-#: option.c:427
+#: option.c:443
 #, fuzzy
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr "Ubah ke user ini setelah mulai. (default %s)."
 
-#: option.c:428
+#: option.c:444
 msgid "Do not use leasefile."
 msgstr ""
 
 # OK
-#: option.c:429
+#: option.c:445
 #, fuzzy, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr "Sebutkan jumlah maksimum lease DHCP (default %s)."
 
-#: option.c:430
+#: option.c:446
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr ""
 
-#: option.c:431
+#: option.c:447
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr ""
 
-#: option.c:432
+#: option.c:448
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr ""
 
-#: option.c:433
+#: option.c:449
 msgid "Enable integrated read-only TFTP server."
 msgstr ""
 
-#: option.c:434
+#: option.c:450
 msgid "Export files by TFTP only from the specified subtree."
 msgstr ""
 
-#: option.c:435
+#: option.c:451
 msgid "Add client IP or hardware address to tftp-root."
 msgstr ""
 
-#: option.c:436
+#: option.c:452
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr ""
 
-#: option.c:437
+#: option.c:453
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr ""
 
 # OK
-#: option.c:438
+#: option.c:454
 #, fuzzy, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr "Sebutkan jumlah maksimum lease DHCP (default %s)."
 
 # OK
-#: option.c:439
+#: option.c:455
 #, fuzzy
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr "Sebutkan jumlah maksimum lease DHCP (default %s)."
 
-#: option.c:440
+#: option.c:456
 msgid "Disable the TFTP blocksize extension."
 msgstr ""
 
-#: option.c:441
+#: option.c:457
 msgid "Convert TFTP filenames to lowercase"
 msgstr ""
 
-#: option.c:442
+#: option.c:458
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr ""
 
-#: option.c:443
+#: option.c:459
+msgid "Use only one port for TFTP server."
+msgstr ""
+
+#: option.c:460
 msgid "Extra logging for DHCP."
 msgstr ""
 
-#: option.c:444
+#: option.c:461
 msgid "Enable async. logging; optionally set queue length."
 msgstr ""
 
-#: option.c:445
+#: option.c:462
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr ""
 
-#: option.c:446
+#: option.c:463
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr ""
 
-#: option.c:447
+#: option.c:464
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr ""
 
-#: option.c:448
+#: option.c:465
 msgid "Always perform DNS queries to all servers."
 msgstr ""
 
-#: option.c:449
+#: option.c:466
 msgid "Set tag if client includes matching option in request."
 msgstr ""
 
-#: option.c:450
+#: option.c:467
+msgid "Set tag if client provides given name."
+msgstr ""
+
+#: option.c:468
 msgid "Use alternative ports for DHCP."
 msgstr ""
 
 # OK
-#: option.c:451
+#: option.c:469
 #, fuzzy
 msgid "Specify NAPTR DNS record."
 msgstr "Sebutkan rekord TXT DNS."
 
-#: option.c:452
+#: option.c:470
 msgid "Specify lowest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:453
+#: option.c:471
 msgid "Specify highest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:454
+#: option.c:472
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr ""
 
-#: option.c:455
+#: option.c:473
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr ""
 
-#: option.c:456
+#: option.c:474
 msgid "Use these DHCP relays as full proxies."
 msgstr ""
 
-#: option.c:457
+#: option.c:475
 msgid "Relay DHCP requests to a remote server"
 msgstr ""
 
-#: option.c:458
+#: option.c:476
 msgid "Specify alias name for LOCAL DNS name."
 msgstr ""
 
 # OK
-#: option.c:459
+#: option.c:477
 #, fuzzy
 msgid "Prompt to send to PXE clients."
 msgstr "Setel pilihan-pilihan tambahan yang akan disetel untuk klien-klien DHCP."
 
-#: option.c:460
+#: option.c:478
 msgid "Boot service for PXE menu."
 msgstr ""
 
-#: option.c:461
+#: option.c:479
 msgid "Check configuration syntax."
 msgstr ""
 
-#: option.c:462
+#: option.c:480
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr ""
 
-#: option.c:463
+#: option.c:481
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr ""
 
 # OK
-#: option.c:464
+#: option.c:482
 #, fuzzy
 msgid "Add client identification to forwarded DNS queries."
 msgstr "Paksa port asal untuk permintaan ke atas."
 
 # OK
-#: option.c:465
+#: option.c:483
 #, fuzzy
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr "Terjemahkan alamat-alamat IPv4 dari server-server di atas."
 
-#: option.c:466
+#: option.c:484
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr ""
 
-#: option.c:467
+# OK
+#: option.c:485
+#, fuzzy
+msgid "Ignore client identifier option sent by DHCP clients."
+msgstr "Setel pilihan-pilihan tambahan yang akan disetel untuk klien-klien DHCP."
+
+#: option.c:486
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr ""
 
-#: option.c:468
+#: option.c:487
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr ""
 
-#: option.c:469
+#: option.c:488
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr ""
 
-#: option.c:470
+#: option.c:489
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr ""
 
 # OK
-#: option.c:471
+#: option.c:490
 #, fuzzy
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr "Sebutkan sebuah rekord MX."
 
+#: option.c:491
+msgid "Specify certification authority authorization record"
+msgstr ""
+
 # OK
-#: option.c:472
+#: option.c:492
 #, fuzzy
 msgid "Specify arbitrary DNS resource record"
 msgstr "Sebutkan rekord TXT DNS."
 
 # OK
-#: option.c:473
+#: option.c:493
 #, fuzzy
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr "antarmuka tidak dikenal %s"
 
-#: option.c:474
+#: option.c:494
 msgid "Export local names to global DNS"
 msgstr ""
 
-#: option.c:475
+#: option.c:495
 msgid "Domain to export to global DNS"
 msgstr ""
 
-#: option.c:476
+#: option.c:496
 msgid "Set TTL for authoritative replies"
 msgstr ""
 
-#: option.c:477
+#: option.c:497
 msgid "Set authoritative zone information"
 msgstr ""
 
-#: option.c:478
+#: option.c:498
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr ""
 
-#: option.c:479
+#: option.c:499
 msgid "Peers which are allowed to do zone transfer"
 msgstr ""
 
-#: option.c:480
+#: option.c:500
 msgid "Specify ipsets to which matching domains should be added"
 msgstr ""
 
-#: option.c:481
+#: option.c:501
 msgid "Specify a domain and address range for synthesised names"
 msgstr ""
 
-#: option.c:482
+#: option.c:502
 msgid "Activate DNSSEC validation"
 msgstr ""
 
-#: option.c:483
+#: option.c:503
 msgid "Specify trust anchor key digest."
 msgstr ""
 
-#: option.c:484
+#: option.c:504
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr ""
 
-#: option.c:485
+#: option.c:505
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr ""
 
-#: option.c:486
+#: option.c:506
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr ""
 
-#: option.c:487
+#: option.c:507
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr ""
 
-#: option.c:489
-msgid "Specify DHCPv6 prefix class"
-msgstr ""
-
-#: option.c:491
+#: option.c:508
 msgid "Set MTU, priority, resend-interval and router-lifetime"
 msgstr ""
 
-#: option.c:492
+#: option.c:509
 msgid "Do not log routine DHCP."
 msgstr ""
 
-#: option.c:493
+#: option.c:510
 msgid "Do not log routine DHCPv6."
 msgstr ""
 
-#: option.c:494
+#: option.c:511
 msgid "Do not log RA."
 msgstr ""
 
-#: option.c:495
+#: option.c:512
 msgid "Accept queries only from directly-connected networks."
 msgstr ""
 
-#: option.c:496
+#: option.c:513
 msgid "Detect and remove DNS forwarding loops."
 msgstr ""
 
-#: option.c:497
+#: option.c:514
 msgid "Ignore DNS responses containing ipaddr."
 msgstr ""
 
-#: option.c:498
+#: option.c:515
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr ""
 
-#: option.c:499
+#: option.c:516
 msgid "Delay DHCP replies for at least number of seconds."
 msgstr ""
 
+#: option.c:517
+msgid "Enables DHCPv4 Rapid Commit option."
+msgstr ""
+
+#: option.c:518
+msgid "Path to debug packet dump file"
+msgstr ""
+
+#: option.c:519
+msgid "Mask which packets to dump"
+msgstr ""
+
+#: option.c:520
+msgid "Call dhcp-script when lease expiry changes."
+msgstr ""
+
 # OK
-#: option.c:703
+#: option.c:725
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
@@ -875,391 +913,409 @@ msgstr ""
 "\n"
 
 # OK
-#: option.c:705
+#: option.c:727
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr "Gunakan pilihan pendek saja pada perintah baris.\n"
 
 # OK
-#: option.c:707
+#: option.c:729
 #, fuzzy, c-format
 msgid "Valid options are:\n"
 msgstr "Pilihan yang boleh adalah:\n"
 
 # OK
-#: option.c:754 option.c:868
+#: option.c:776 option.c:884
 #, fuzzy
 msgid "bad address"
 msgstr "membaca %s - %d alamat"
 
 # OK
-#: option.c:779 option.c:783
+#: option.c:799 option.c:803
 msgid "bad port"
 msgstr "port salah"
 
-#: option.c:797 option.c:826 option.c:861
+#: option.c:815 option.c:844 option.c:878
 msgid "interface binding not supported"
 msgstr ""
 
-#: option.c:821 option.c:856
+#: option.c:839 option.c:873
 msgid "interface can only be specified once"
 msgstr ""
 
 # OK
-#: option.c:835 option.c:3809
+#: option.c:852 option.c:4042
 #, fuzzy
 msgid "bad interface name"
 msgstr "nama MX salah"
 
-#: option.c:1062
+#: option.c:1184
 msgid "unsupported encapsulation for IPv6 option"
 msgstr ""
 
 # OK
-#: option.c:1076
+#: option.c:1198
 msgid "bad dhcp-option"
 msgstr "dhcp-option salah"
 
 # OK
-#: option.c:1144
+#: option.c:1270
 #, fuzzy
 msgid "bad IP address"
 msgstr "membaca %s - %d alamat"
 
 # OK
-#: option.c:1147 option.c:1286 option.c:3079
+#: option.c:1273 option.c:1412 option.c:3297
 #, fuzzy
 msgid "bad IPv6 address"
 msgstr "membaca %s - %d alamat"
 
 # OK
-#: option.c:1240
+#: option.c:1366
 #, fuzzy
 msgid "bad IPv4 address"
 msgstr "membaca %s - %d alamat"
 
 # OK
-#: option.c:1313 option.c:1407
+#: option.c:1439 option.c:1533
 msgid "bad domain in dhcp-option"
 msgstr "domain dalam dhcp-option salah"
 
 # OK
-#: option.c:1445
+#: option.c:1571
 msgid "dhcp-option too long"
 msgstr "dhcp-option terlalu panjang"
 
-#: option.c:1452
+#: option.c:1578
 msgid "illegal dhcp-match"
 msgstr ""
 
-#: option.c:1514
+#: option.c:1647
 msgid "illegal repeated flag"
 msgstr ""
 
-#: option.c:1522
+#: option.c:1655
 msgid "illegal repeated keyword"
 msgstr ""
 
 # OK
-#: option.c:1593 option.c:4443
+#: option.c:1726 option.c:4764
 #, fuzzy, c-format
 msgid "cannot access directory %s: %s"
 msgstr "tidak bisa membaca %s: %s"
 
 # OK
-#: option.c:1639 tftp.c:537
+#: option.c:1772 tftp.c:564 dump.c:68
 #, fuzzy, c-format
 msgid "cannot access %s: %s"
 msgstr "tidak bisa membaca %s: %s"
 
-#: option.c:1727
+#: option.c:1879
 msgid "setting log facility is not possible under Android"
 msgstr ""
 
-#: option.c:1736
+#: option.c:1888
 msgid "bad log facility"
 msgstr ""
 
 # OK
-#: option.c:1789
+#: option.c:1941
 msgid "bad MX preference"
 msgstr "kesukaan MX salah"
 
 # OK
-#: option.c:1794
+#: option.c:1946
 msgid "bad MX name"
 msgstr "nama MX salah"
 
 # OK
-#: option.c:1808
+#: option.c:1960
 msgid "bad MX target"
 msgstr "target MX salah"
 
-#: option.c:1820
-msgid "cannot run scripts under uClinux"
-msgstr ""
-
-#: option.c:1822
+#: option.c:1980
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr ""
 
-#: option.c:1826
+#: option.c:1984
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr ""
 
 # OK
-#: option.c:2095 option.c:2106 option.c:2143 option.c:2199 option.c:2482
+#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
 #, fuzzy
 msgid "bad prefix"
 msgstr "port salah"
 
-#: option.c:2504
+#: option.c:2658
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr ""
 
 # OK
-#: option.c:2713
+#: option.c:2871
 #, fuzzy
 msgid "bad port range"
 msgstr "port salah"
 
-#: option.c:2739
+#: option.c:2897
 msgid "bad bridge-interface"
 msgstr ""
 
-#: option.c:2807
+#: option.c:2941
+msgid "bad shared-network"
+msgstr ""
+
+#: option.c:2996
 msgid "only one tag allowed"
 msgstr ""
 
 # OK
-#: option.c:2827 option.c:2839 option.c:2948 option.c:2953 option.c:2992
+#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
 msgid "bad dhcp-range"
 msgstr "dhcp-range salah"
 
 # OK
-#: option.c:2854
+#: option.c:3050
 msgid "inconsistent DHCP range"
 msgstr "jangkauan DHCP tidak konsisten"
 
-#: option.c:2916
+#: option.c:3115
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr ""
 
-#: option.c:2918
+#: option.c:3117
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr ""
 
-#: option.c:2922
+#: option.c:3120
 msgid "prefix length must be at least 64"
 msgstr ""
 
 # OK
-#: option.c:2925
+#: option.c:3123
 #, fuzzy
 msgid "inconsistent DHCPv6 range"
 msgstr "jangkauan DHCP tidak konsisten"
 
-#: option.c:2936
+#: option.c:3142
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr ""
 
 # OK
-#: option.c:3049 option.c:3097
+#: option.c:3262 option.c:3340
 #, fuzzy
 msgid "bad hex constant"
 msgstr "dhcp-host salah"
 
-#: option.c:3071
-msgid "cannot match tags in --dhcp-host"
-msgstr ""
+# OK
+#: option.c:3315
+#, fuzzy
+msgid "bad IPv6 prefix"
+msgstr "port salah"
 
 # OK
-#: option.c:3119
+#: option.c:3362
 #, fuzzy, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr "alamat IP kembar %s dalam direktif dhcp-config"
 
 # OK
-#: option.c:3177
+#: option.c:3422
 #, fuzzy
 msgid "bad DHCP host name"
 msgstr "nama MX salah"
 
 # OK
-#: option.c:3259
+#: option.c:3508
 #, fuzzy
 msgid "bad tag-if"
 msgstr "target MX salah"
 
 # OK
-#: option.c:3616 option.c:4039
+#: option.c:3851 option.c:4324
 msgid "invalid port number"
 msgstr "nomor port tidak benar"
 
 # OK
-#: option.c:3678
+#: option.c:3907
 #, fuzzy
 msgid "bad dhcp-proxy address"
 msgstr "membaca %s - %d alamat"
 
 # OK
-#: option.c:3704
+#: option.c:3935
 #, fuzzy
 msgid "Bad dhcp-relay"
 msgstr "dhcp-range salah"
 
-#: option.c:3745
+#: option.c:3979
 msgid "bad RA-params"
 msgstr ""
 
-#: option.c:3754
+#: option.c:3989
 msgid "bad DUID"
 msgstr ""
 
 # OK
-#: option.c:3796
+#: option.c:4023
+#, fuzzy
+msgid "missing address in alias"
+msgstr "alamat telah digunakan"
+
+# OK
+#: option.c:4029
 #, fuzzy
 msgid "invalid alias range"
 msgstr "weight tidak benar"
 
-#: option.c:3850 option.c:3862
+#: option.c:4081 option.c:4097
 msgid "bad CNAME"
 msgstr ""
 
-#: option.c:3866
+#: option.c:4105
 msgid "duplicate CNAME"
 msgstr ""
 
 # OK
-#: option.c:3889
+#: option.c:4132
 #, fuzzy
 msgid "bad PTR record"
 msgstr "rekord SRV salah"
 
 # OK
-#: option.c:3920
+#: option.c:4167
 #, fuzzy
 msgid "bad NAPTR record"
 msgstr "rekord SRV salah"
 
 # OK
-#: option.c:3954
+#: option.c:4203
 #, fuzzy
 msgid "bad RR record"
 msgstr "rekord SRV salah"
 
 # OK
-#: option.c:3984
+#: option.c:4236
+#, fuzzy
+msgid "bad CAA record"
+msgstr "rekord SRV salah"
+
+# OK
+#: option.c:4265
 msgid "bad TXT record"
 msgstr "rekord TXT salah"
 
 # OK
-#: option.c:4025
+#: option.c:4308
 msgid "bad SRV record"
 msgstr "rekord SRV salah"
 
 # OK
-#: option.c:4032
+#: option.c:4315
 msgid "bad SRV target"
 msgstr "target SRV salah"
 
 # OK
-#: option.c:4046
+#: option.c:4334
 msgid "invalid priority"
 msgstr "prioritas tidak benar"
 
 # OK
-#: option.c:4049
+#: option.c:4339
 msgid "invalid weight"
 msgstr "weight tidak benar"
 
 # OK
-#: option.c:4073
+#: option.c:4362
 #, fuzzy
 msgid "Bad host-record"
 msgstr "rekord SRV salah"
 
 # OK
-#: option.c:4097
+#: option.c:4402
 #, fuzzy
 msgid "Bad name in host-record"
 msgstr "kesalahan nama di %s"
 
+#: option.c:4444
+msgid "bad value for dnssec-check-unsigned"
+msgstr ""
+
 # OK
-#: option.c:4162
+#: option.c:4480
 #, fuzzy
 msgid "bad trust anchor"
 msgstr "port salah"
 
-#: option.c:4176
+#: option.c:4496
 msgid "bad HEX in trust anchor"
 msgstr ""
 
-#: option.c:4186
+#: option.c:4507
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr ""
 
 # OK
-#: option.c:4246
+#: option.c:4567
 msgid "missing \""
 msgstr "kurang \""
 
 # OK
-#: option.c:4303
+#: option.c:4624
 msgid "bad option"
 msgstr "pilihan salah"
 
 # OK
-#: option.c:4305
+#: option.c:4626
 msgid "extraneous parameter"
 msgstr "parameter berlebihan"
 
 # OK
-#: option.c:4307
+#: option.c:4628
 msgid "missing parameter"
 msgstr "parameter kurang"
 
 # OK
-#: option.c:4309
+#: option.c:4630
 #, fuzzy
 msgid "illegal option"
 msgstr "pilihan salah"
 
 # OK
-#: option.c:4316
+#: option.c:4637
 msgid "error"
 msgstr "kesalahan"
 
 # OK
-#: option.c:4318
+#: option.c:4639
 #, fuzzy, c-format
 msgid " at line %d of %s"
 msgstr "%s pada baris %d dari %%s"
 
 # OK
-#: option.c:4333 option.c:4580 option.c:4616
+#: option.c:4654 option.c:4939 option.c:4950
 #, fuzzy, c-format
 msgid "read %s"
 msgstr "membaca %s"
 
 # OK
-#: option.c:4396 option.c:4519 tftp.c:715
+#: option.c:4717 option.c:4840 tftp.c:754
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "tidak bisa membaca %s: %s"
 
-#: option.c:4688
+#: option.c:5027
 msgid "junk found in command line"
 msgstr ""
 
 # OK
-#: option.c:4729
+#: option.c:5067
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr "Dnsmasq versi %s  %s\n"
 
 # OK
-#: option.c:4730
+#: option.c:5068
 #, fuzzy, c-format
 msgid ""
 "Compile time options: %s\n"
@@ -1269,567 +1325,625 @@ msgstr ""
 "\n"
 
 # OK
-#: option.c:4731
+#: option.c:5069
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr "Perangkat lunak ini tersedia TANPA JAMINAN SEDIKITPUN.\n"
 
 # OK
-#: option.c:4732
+#: option.c:5070
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr "Dnsdmasq adalah perangkat lunak bebas, dan Anda dipersilahkan untuk membagikannya\n"
 
 # OK
-#: option.c:4733
+#: option.c:5071
 #, fuzzy, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr "dengan aturan GNU General Public License, versi 2.\n"
 
-#: option.c:4744
+#: option.c:5088
 msgid "try --help"
 msgstr ""
 
-#: option.c:4746
+#: option.c:5090
 msgid "try -w"
 msgstr ""
 
 # OK
-#: option.c:4748
+#: option.c:5092
 #, fuzzy, c-format
 msgid "bad command line options: %s"
 msgstr "pilihan baris perintah salah: %s."
 
-#: option.c:4818
+#: option.c:5161
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr ""
 
 # OK
-#: option.c:4854
+#: option.c:5195
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr "tidak bisa mendapatkan host-name: %s"
 
 # OK
-#: option.c:4882
+#: option.c:5223
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr "hanya satu file resolv.conf yang diperbolehkan dalam modus no-poll."
 
 # OK
-#: option.c:4892
+#: option.c:5233
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr "harus mempunyai tepat satu resolv.conf untuk mendapatkan nama domain."
 
 # OK
-#: option.c:4895 network.c:1623 dhcp.c:816
+#: option.c:5236 network.c:1594 dhcp.c:876
 #, fuzzy, c-format
 msgid "failed to read %s: %s"
 msgstr "gagal membaca %s: %s"
 
 # OK
-#: option.c:4912
+#: option.c:5253
 #, c-format
 msgid "no search directive found in %s"
 msgstr "tidak ditemukan direktif search di %s"
 
-#: option.c:4933
+#: option.c:5274
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr ""
 
-#: option.c:4942
+#: option.c:5283
 msgid "syntax check OK"
 msgstr ""
 
 # OK
-#: forward.c:102
+#: forward.c:99
 #, fuzzy, c-format
 msgid "failed to send packet: %s"
 msgstr "gagal mendengarkan di socket: %s"
 
-#: forward.c:598
+#: forward.c:614
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr ""
 
 # OK
-#: forward.c:652
+#: forward.c:677
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr "nameserver %s menolak melakukan resolusi rekursif"
 
-#: forward.c:684
+#: forward.c:709
 #, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr ""
 
-#: forward.c:870
+#: forward.c:961
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
 msgstr ""
 
-#: forward.c:1266 forward.c:1704
+#: forward.c:1370 forward.c:1830
 msgid "Ignoring query from non-local network"
 msgstr ""
 
 # OK
-#: forward.c:2184
+#: forward.c:2321
 #, fuzzy, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr "Sebutkan jumlah maksimum lease DHCP (default %s)."
 
 # OK
-#: network.c:720
+#: network.c:698
 #, fuzzy, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr "gagal membuat socket: %s "
 
-#: network.c:1031
+#: network.c:1002
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr ""
 
-#: network.c:1038
+#: network.c:1009
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr ""
 
 # OK
-#: network.c:1047
+#: network.c:1018
 #, fuzzy, c-format
 msgid "warning: using interface %s instead"
 msgstr "peringatan: antarmuka %s tidak ada"
 
 # OK
-#: network.c:1056
+#: network.c:1027
 #, fuzzy, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr "menggunakan alamat lokal saja untuk %s %s"
 
 # OK
-#: network.c:1114
+#: network.c:1085
 #, fuzzy, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr "gagal mem-bind socket server DHCP: %s"
 
-#: network.c:1119
+#: network.c:1090
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr ""
 
-#: network.c:1337
+#: network.c:1307
 #, fuzzy, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr "gagal mem-bind socket untuk mendengarkan %s: %s"
 
 # OK
-#: network.c:1528
+#: network.c:1499
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr "mengabaikan nameserver %s - antarmuka lokal"
 
 # OK
-#: network.c:1539
+#: network.c:1510
 #, fuzzy, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr "mengabaikan nameserver %s - tak dapat membuat/mem-bind socket: %s"
 
-#: network.c:1559
+#: network.c:1530
 msgid "(no DNSSEC)"
 msgstr ""
 
 # OK
-#: network.c:1562
+#: network.c:1533
 msgid "unqualified"
 msgstr "tidak memenuhi syarat"
 
-#: network.c:1562
+#: network.c:1533
 msgid "names"
 msgstr ""
 
-#: network.c:1564
+#: network.c:1535
 msgid "default"
 msgstr ""
 
 # OK
-#: network.c:1566
+#: network.c:1537
 msgid "domain"
 msgstr "domain"
 
 # OK
-#: network.c:1572
-#, c-format
-msgid "using local addresses only for %s %s"
+#: network.c:1543
+#, fuzzy, c-format
+msgid "using only locally-known addresses for %s %s"
 msgstr "menggunakan alamat lokal saja untuk %s %s"
 
 # OK
-#: network.c:1575
+#: network.c:1546
 #, fuzzy, c-format
 msgid "using standard nameservers for %s %s"
 msgstr "menggunakan nameserver %s#%d untuk %s %s"
 
 # OK
-#: network.c:1577
+#: network.c:1548
 #, fuzzy, c-format
 msgid "using nameserver %s#%d for %s %s %s"
 msgstr "menggunakan nameserver %s#%d untuk %s %s"
 
 # OK
-#: network.c:1581
+#: network.c:1552
 #, fuzzy, c-format
 msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr "menggunakan nameserver %s#%d untuk %s %s"
 
 # OK
-#: network.c:1584
+#: network.c:1555
 #, fuzzy, c-format
 msgid "using nameserver %s#%d(via %s)"
 msgstr "menggunakan nameserver %s#%d"
 
 # OK
-#: network.c:1586
+#: network.c:1557
 #, c-format
 msgid "using nameserver %s#%d"
 msgstr "menggunakan nameserver %s#%d"
 
 # OK
-#: network.c:1591
+#: network.c:1562
 #, fuzzy, c-format
 msgid "using %d more local addresses"
 msgstr "menggunakan nameserver %s#%d"
 
 # OK
-#: network.c:1593
+#: network.c:1564
 #, fuzzy, c-format
 msgid "using %d more nameservers"
 msgstr "menggunakan nameserver %s#%d"
 
-#: dnsmasq.c:171
+#: dnsmasq.c:173
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr ""
 
-#: dnsmasq.c:186
+#: dnsmasq.c:188
 msgid "no root trust anchor provided for DNSSEC"
 msgstr ""
 
-#: dnsmasq.c:189
+#: dnsmasq.c:191
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr ""
 
 # OK
-#: dnsmasq.c:191
+#: dnsmasq.c:193
 #, fuzzy
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr "DBus tidak tersedia: setel HAVE_DBUS dalam src/config.h"
 
 # OK
-#: dnsmasq.c:197
+#: dnsmasq.c:199
 #, fuzzy
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr "DBus tidak tersedia: setel HAVE_DBUS dalam src/config.h"
 
-#: dnsmasq.c:202
+#: dnsmasq.c:204
 msgid "cannot use --conntrack AND --query-port"
 msgstr ""
 
 # OK
-#: dnsmasq.c:205
+#: dnsmasq.c:207
 #, fuzzy
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr "DBus tidak tersedia: setel HAVE_DBUS dalam src/config.h"
 
-#: dnsmasq.c:210
+#: dnsmasq.c:212
 msgid "asynchronous logging is not available under Solaris"
 msgstr ""
 
-#: dnsmasq.c:215
+#: dnsmasq.c:217
 msgid "asynchronous logging is not available under Android"
 msgstr ""
 
 # OK
-#: dnsmasq.c:220
+#: dnsmasq.c:222
 #, fuzzy
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr "DBus tidak tersedia: setel HAVE_DBUS dalam src/config.h"
 
 # OK
-#: dnsmasq.c:225
+#: dnsmasq.c:227
 #, fuzzy
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr "DBus tidak tersedia: setel HAVE_DBUS dalam src/config.h"
 
-#: dnsmasq.c:229
+# OK
+#: dnsmasq.c:232
+#, fuzzy
+msgid "Ubus not available: set HAVE_UBUS in src/config.h"
+msgstr "DBus tidak tersedia: setel HAVE_DBUS dalam src/config.h"
+
+#: dnsmasq.c:236
 msgid "max_port cannot be smaller than min_port"
 msgstr ""
 
-#: dnsmasq.c:236
+#: dnsmasq.c:243
+msgid "--auth-server required when an auth zone is defined."
+msgstr ""
+
+#: dnsmasq.c:248
 msgid "zone serial must be configured in --auth-soa"
 msgstr ""
 
-#: dnsmasq.c:254
+#: dnsmasq.c:268
 msgid "dhcp-range constructor not available on this platform"
 msgstr ""
 
-#: dnsmasq.c:300
+#: dnsmasq.c:332
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr ""
 
 # OK
-#: dnsmasq.c:303
+#: dnsmasq.c:335
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr "gagal mendapatkan daftar antarmuka: %s"
 
 # OK
-#: dnsmasq.c:312
+#: dnsmasq.c:344
 #, c-format
 msgid "unknown interface %s"
 msgstr "antarmuka tidak dikenal %s"
 
 # OK
-#: dnsmasq.c:377 dnsmasq.c:1054
+#: dnsmasq.c:406
+#, fuzzy
+msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
+msgstr "DBus tidak tersedia: setel HAVE_DBUS dalam src/config.h"
+
+# OK
+#: dnsmasq.c:416 dnsmasq.c:1171
 #, c-format
 msgid "DBus error: %s"
 msgstr "DBus error: %s"
 
 # OK
-#: dnsmasq.c:380
+#: dnsmasq.c:419
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr "DBus tidak tersedia: setel HAVE_DBUS dalam src/config.h"
 
-#: dnsmasq.c:410
+# OK
+#: dnsmasq.c:429
+#, fuzzy
+msgid "UBus not available: set HAVE_UBUS in src/config.h"
+msgstr "DBus tidak tersedia: setel HAVE_DBUS dalam src/config.h"
+
+#: dnsmasq.c:459
 #, c-format
 msgid "unknown user or group: %s"
 msgstr ""
 
-#: dnsmasq.c:465
+#: dnsmasq.c:535
+#, c-format
+msgid "process is missing required capability %s"
+msgstr ""
+
+#: dnsmasq.c:567
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr ""
 
 # OK
-#: dnsmasq.c:730
+#: dnsmasq.c:815
 #, fuzzy, c-format
 msgid "started, version %s DNS disabled"
 msgstr "dimulai, cache versi %s di disable"
 
 # OK
-#: dnsmasq.c:734
+#: dnsmasq.c:820
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr "dimulai, versi %s ukuran cache %d"
 
+#: dnsmasq.c:822
+msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
+msgstr ""
+
 # OK
-#: dnsmasq.c:736
+#: dnsmasq.c:825
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr "dimulai, cache versi %s di disable"
 
-#: dnsmasq.c:739
+#: dnsmasq.c:828
 msgid "DNS service limited to local subnets"
 msgstr ""
 
 # OK
-#: dnsmasq.c:742
+#: dnsmasq.c:831
 #, c-format
 msgid "compile time options: %s"
 msgstr "pilihan-pilihan saat kompilasi: %s"
 
 # OK
-#: dnsmasq.c:751
+#: dnsmasq.c:840
 msgid "DBus support enabled: connected to system bus"
 msgstr "dukungan DBus dimungkinkan: terkoneksi pada bus sistem"
 
 # OK
-#: dnsmasq.c:753
+#: dnsmasq.c:842
 msgid "DBus support enabled: bus connection pending"
 msgstr "dukungan DBus dimungkinkan: koneksi bus ditunda"
 
-#: dnsmasq.c:771
+# OK
+#: dnsmasq.c:850
+#, fuzzy
+msgid "UBus support enabled: connected to system bus"
+msgstr "dukungan DBus dimungkinkan: terkoneksi pada bus sistem"
+
+# OK
+#: dnsmasq.c:852
+#, fuzzy
+msgid "UBus support enabled: bus connection pending"
+msgstr "dukungan DBus dimungkinkan: koneksi bus ditunda"
+
+#: dnsmasq.c:872
+msgid "DNSSEC validation enabled but all unsigned answers are trusted"
+msgstr ""
+
+#: dnsmasq.c:874
 msgid "DNSSEC validation enabled"
 msgstr ""
 
-#: dnsmasq.c:775
+#: dnsmasq.c:878
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr ""
 
-#: dnsmasq.c:778
+#: dnsmasq.c:881
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr ""
 
+#: dnsmasq.c:884
+#, c-format
+msgid "configured with trust anchor for %s keytag %u"
+msgstr ""
+
 # OK
-#: dnsmasq.c:783
+#: dnsmasq.c:890
 #, fuzzy, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr "gagal memuat nama-nama dari %s: %s"
 
 # OK
-#: dnsmasq.c:787
+#: dnsmasq.c:894
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr "setelan opsi --bind-interfaces disebabkan keterbatasan OS"
 
 # OK
-#: dnsmasq.c:799
+#: dnsmasq.c:906
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr "peringatan: antarmuka %s tidak ada"
 
-#: dnsmasq.c:804
+#: dnsmasq.c:911
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr ""
 
 # OK
-#: dnsmasq.c:807
+#: dnsmasq.c:914
 #, fuzzy
 msgid "warning: no upstream servers configured"
 msgstr "menyetel server-server di atas dengan DBus"
 
-#: dnsmasq.c:811
+#: dnsmasq.c:918
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr ""
 
-#: dnsmasq.c:832
+#: dnsmasq.c:939
 msgid "IPv6 router advertisement enabled"
 msgstr ""
 
-#: dnsmasq.c:837
+#: dnsmasq.c:944
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr ""
 
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 msgid "root is "
 msgstr ""
 
 # OK
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 #, fuzzy
 msgid "enabled"
 msgstr "di disable"
 
-#: dnsmasq.c:853
+#: dnsmasq.c:960
 msgid "secure mode"
 msgstr ""
 
-#: dnsmasq.c:856
+# OK
+#: dnsmasq.c:961
+#, fuzzy
+msgid "single port mode"
+msgstr "nomor port tidak benar"
+
+#: dnsmasq.c:964
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:860
+#: dnsmasq.c:968
 #, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:886
+#: dnsmasq.c:994
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr ""
 
 # OK
-#: dnsmasq.c:1056
+#: dnsmasq.c:1173
 msgid "connected to system DBus"
 msgstr "terhubung ke sistem DBus"
 
-#: dnsmasq.c:1215
+#: dnsmasq.c:1345
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr ""
 
 # OK
-#: dnsmasq.c:1218
+#: dnsmasq.c:1349
 #, fuzzy, c-format
 msgid "failed to create helper: %s"
 msgstr "gagal membaca %s: %s"
 
-#: dnsmasq.c:1221
+#: dnsmasq.c:1353
 #, c-format
 msgid "setting capabilities failed: %s"
 msgstr ""
 
 # OK
-#: dnsmasq.c:1224
+#: dnsmasq.c:1357
 #, fuzzy, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr "gagal memuat nama-nama dari %s: %s"
 
 # OK
-#: dnsmasq.c:1227
+#: dnsmasq.c:1361
 #, fuzzy, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr "gagal memuat nama-nama dari %s: %s"
 
 # OK
-#: dnsmasq.c:1230
+#: dnsmasq.c:1365
 #, fuzzy, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr "gagal membaca %s: %s"
 
 # OK
-#: dnsmasq.c:1233
+#: dnsmasq.c:1369
 #, fuzzy, c-format
 msgid "cannot open log %s: %s"
 msgstr "tidak bisa membuka %s:%s"
 
 # OK
-#: dnsmasq.c:1236
+#: dnsmasq.c:1373
 #, fuzzy, c-format
 msgid "failed to load Lua script: %s"
 msgstr "gagal memuat %S: %s"
 
-#: dnsmasq.c:1239
+#: dnsmasq.c:1377
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr ""
 
 # OK
-#: dnsmasq.c:1242
+#: dnsmasq.c:1381
 #, fuzzy, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr "tidak dapat membuka atau membuat file lease: %s"
 
-#: dnsmasq.c:1326
+#: dnsmasq.c:1465
 #, c-format
 msgid "script process killed by signal %d"
 msgstr ""
 
-#: dnsmasq.c:1330
+#: dnsmasq.c:1469
 #, c-format
 msgid "script process exited with status %d"
 msgstr ""
 
 # OK
-#: dnsmasq.c:1334
+#: dnsmasq.c:1473
 #, fuzzy, c-format
 msgid "failed to execute %s: %s"
 msgstr "gagal mengakses %s: %s"
 
-#: dnsmasq.c:1374
+#: dnsmasq.c:1513
 msgid "now checking DNSSEC signature timestamps"
 msgstr ""
 
 # OK
-#: dnsmasq.c:1409 dnssec.c:160 dnssec.c:206
+#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
 #, fuzzy, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr "gagal membaca %s: %s"
 
-#: dnsmasq.c:1416
+#: dnsmasq.c:1560
 msgid "exiting on receipt of SIGTERM"
 msgstr "keluar karena menerima SIGTERM"
 
 # OK
-#: dnsmasq.c:1444
+#: dnsmasq.c:1588
 #, fuzzy, c-format
 msgid "failed to access %s: %s"
 msgstr "gagal mengakses %s: %s"
 
 # OK
-#: dnsmasq.c:1474
+#: dnsmasq.c:1618
 #, c-format
 msgid "reading %s"
 msgstr "membaca %s"
 
 # OK
-#: dnsmasq.c:1485
+#: dnsmasq.c:1629
 #, fuzzy, c-format
 msgid "no servers found in %s, will retry"
 msgstr "tidak ditemukan direktif search di %s"
@@ -1865,7 +1979,7 @@ msgid "cannot create ICMP raw socket: %s."
 msgstr "tidak dapat membuat socket ICMP raw: %s"
 
 # OK
-#: dhcp.c:252 dhcp6.c:173
+#: dhcp.c:252 dhcp6.c:180
 #, fuzzy, c-format
 msgid "unknown interface %s in bridge-interface"
 msgstr "antarmuka tidak dikenal %s"
@@ -1875,371 +1989,377 @@ msgstr "antarmuka tidak dikenal %s"
 msgid "DHCP packet received on %s which has no address"
 msgstr ""
 
-#: dhcp.c:427
+#: dhcp.c:428
 #, c-format
 msgid "ARP-cache injection failed: %s"
 msgstr ""
 
-#: dhcp.c:470
+#: dhcp.c:471
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr ""
 
 # OK
-#: dhcp.c:531
+#: dhcp.c:526
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr "jangkauan DHCP %s -- %s tidak konsisten dengan netmask %s"
 
 # OK
-#: dhcp.c:854
+#: dhcp.c:914
 #, fuzzy, c-format
 msgid "bad line at %s line %d"
 msgstr "kesalahan nama pada %s baris %d"
 
-#: dhcp.c:897
+#: dhcp.c:957
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr ""
 
-#: dhcp.c:1041 rfc3315.c:2149
+#: dhcp.c:1100 rfc3315.c:2139
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr ""
 
+#: lease.c:64
+#, c-format
+msgid "ignoring invalid line in lease database: %s %s %s %s ..."
+msgstr ""
+
+#: lease.c:101
+#, c-format
+msgid "ignoring invalid line in lease database, bad address: %s"
+msgstr ""
+
 # OK
-#: lease.c:98
+#: lease.c:108
 msgid "too many stored leases"
 msgstr "terlalu banyak lease yang disimpan"
 
 # OK
-#: lease.c:166
+#: lease.c:176
 #, fuzzy, c-format
 msgid "cannot open or create lease file %s: %s"
 msgstr "tidak dapat membuka atau membuat file lease: %s"
 
-#: lease.c:175
-#, c-format
-msgid "failed to parse lease database, invalid line: %s %s %s %s ..."
-msgstr ""
+# OK
+#: lease.c:185
+#, fuzzy
+msgid "failed to parse lease database cleanly"
+msgstr "gagal membaca %s: %s"
 
 # OK
-#: lease.c:180
+#: lease.c:188
 #, fuzzy, c-format
 msgid "failed to read lease file %s: %s"
 msgstr "gagal membaca %s: %s"
 
 # OK
-#: lease.c:196
+#: lease.c:204
 #, fuzzy, c-format
 msgid "cannot run lease-init script %s: %s"
 msgstr "tidak bisa membaca %s: %s"
 
-#: lease.c:202
+#: lease.c:210
 #, c-format
 msgid "lease-init script returned exit code %s"
 msgstr ""
 
 # OK
-#: lease.c:373
+#: lease.c:381
 #, fuzzy, c-format
 msgid "failed to write %s: %s (retry in %us)"
 msgstr "gagal membaca %s: %s"
 
-#: lease.c:937
+#: lease.c:955
 #, c-format
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr ""
 
 # OK
-#: rfc2131.c:347
+#: rfc2131.c:372
 #, c-format
 msgid "no address range available for DHCP request %s %s"
 msgstr "tidak ada alamat yang bisa dipakai untuk permintaan DHCP %s %s"
 
 # OK
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "with subnet selector"
 msgstr "dengan pemilih subnet"
 
 # OK
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "via"
 msgstr "lewat"
 
 # OK
-#: rfc2131.c:360
+#: rfc2131.c:385
 #, fuzzy, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr "tidak ada alamat yang bisa dipakai untuk permintaan DHCP %s %s"
 
-#: rfc2131.c:363 rfc3315.c:306
+#: rfc2131.c:388 rfc3315.c:319
 #, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr ""
 
 # OK
-#: rfc2131.c:474
+#: rfc2131.c:499
 #, fuzzy, c-format
 msgid "%u vendor class: %s"
 msgstr "DBus error: %s"
 
 # OK
-#: rfc2131.c:476
+#: rfc2131.c:501
 #, fuzzy, c-format
 msgid "%u user class: %s"
 msgstr "DBus error: %s"
 
 # OK
-#: rfc2131.c:510
+#: rfc2131.c:535
 msgid "disabled"
 msgstr "di disable"
 
 # OK
-#: rfc2131.c:551 rfc2131.c:1006 rfc2131.c:1430 rfc3315.c:616 rfc3315.c:869
-#: rfc3315.c:1148
+#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1097
 msgid "ignored"
 msgstr "diabaikan"
 
 # OK
-#: rfc2131.c:566 rfc2131.c:1239 rfc3315.c:919
+#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
 msgid "address in use"
 msgstr "alamat telah digunakan"
 
 # OK
-#: rfc2131.c:580 rfc2131.c:1060
+#: rfc2131.c:605 rfc2131.c:1119
 msgid "no address available"
 msgstr "tak ada alamat yang tersedia"
 
 # OK
-#: rfc2131.c:587 rfc2131.c:1202
+#: rfc2131.c:612 rfc2131.c:1273
 msgid "wrong network"
 msgstr "jaringan yang salah"
 
 # OK
-#: rfc2131.c:602
+#: rfc2131.c:627
 msgid "no address configured"
 msgstr "tak ada alamat yang disetel"
 
 # OK
-#: rfc2131.c:608 rfc2131.c:1252
+#: rfc2131.c:633 rfc2131.c:1323
 msgid "no leases left"
 msgstr "tak ada lease yang tersisa"
 
-#: rfc2131.c:703 rfc3315.c:482
+#: rfc2131.c:734 rfc3315.c:499
 #, c-format
 msgid "%u client provides name: %s"
 msgstr ""
 
-#: rfc2131.c:808
+#: rfc2131.c:864
 msgid "PXE BIS not supported"
 msgstr ""
 
 # OK
-#: rfc2131.c:974 rfc3315.c:1242
+#: rfc2131.c:1032 rfc3315.c:1197
 #, fuzzy, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr "men-disable alamat statik DHCP %s"
 
 # OK
-#: rfc2131.c:995
+#: rfc2131.c:1053
 msgid "unknown lease"
 msgstr "lease tidak diketahui"
 
-#: rfc2131.c:1029
+#: rfc2131.c:1088
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr ""
 
-#: rfc2131.c:1039
+#: rfc2131.c:1098
 #, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr ""
 
-#: rfc2131.c:1042
+#: rfc2131.c:1101
 #, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr ""
 
-#: rfc2131.c:1058 rfc2131.c:1245
+#: rfc2131.c:1117 rfc2131.c:1316
 msgid "no unique-id"
 msgstr ""
 
-#: rfc2131.c:1140
+#: rfc2131.c:1209
 msgid "wrong server-ID"
 msgstr ""
 
 # OK
-#: rfc2131.c:1159
+#: rfc2131.c:1228
 msgid "wrong address"
 msgstr "alamat salah"
 
 # OK
-#: rfc2131.c:1177 rfc3315.c:1015
+#: rfc2131.c:1246 rfc3315.c:961
 msgid "lease not found"
 msgstr "lease tak ditemukan"
 
 # OK
-#: rfc2131.c:1210
+#: rfc2131.c:1281
 msgid "address not available"
 msgstr "alamat tak tersedia"
 
 # OK
-#: rfc2131.c:1221
+#: rfc2131.c:1292
 msgid "static lease available"
 msgstr "lease statik tak tersedia"
 
 # OK
-#: rfc2131.c:1225
+#: rfc2131.c:1296
 msgid "address reserved"
 msgstr "alamat telah dipesan"
 
-#: rfc2131.c:1233
+#: rfc2131.c:1304
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr ""
 
-#: rfc2131.c:1757
+#: rfc2131.c:1845
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr ""
 
 # OK
-#: rfc2131.c:1766
+#: rfc2131.c:1854
 #, fuzzy, c-format
 msgid "%u server name: %s"
 msgstr "DBus error: %s"
 
 # OK
-#: rfc2131.c:1774
+#: rfc2131.c:1862
 #, fuzzy, c-format
 msgid "%u next server: %s"
 msgstr "DBus error: %s"
 
-#: rfc2131.c:1777
+#: rfc2131.c:1865
 #, c-format
 msgid "%u broadcast response"
 msgstr ""
 
-#: rfc2131.c:1840
+#: rfc2131.c:1928
 #, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr ""
 
-#: rfc2131.c:2131
+#: rfc2131.c:2219
 msgid "PXE menu too large"
 msgstr ""
 
 # OK
-#: rfc2131.c:2270 rfc3315.c:1515
+#: rfc2131.c:2358 rfc3315.c:1470
 #, fuzzy, c-format
 msgid "%u requested options: %s"
 msgstr "pilihan-pilihan saat kompilasi: %s"
 
-#: rfc2131.c:2587
+#: rfc2131.c:2675
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr ""
 
-#: rfc2131.c:2650
+#: rfc2131.c:2738
 #, c-format
 msgid "%u reply delay: %d"
 msgstr ""
 
 # OK
-#: netlink.c:77
+#: netlink.c:76
 #, fuzzy, c-format
 msgid "cannot create netlink socket: %s"
 msgstr "tidak bisa mem-bind netlink socket: %s"
 
 # OK
-#: netlink.c:355
+#: netlink.c:352
 #, fuzzy, c-format
 msgid "netlink returns error: %s"
 msgstr "DBus error: %s"
 
-# OK
-#: dbus.c:186
-msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
-msgstr "mencoba menyetel sebuah alamat IPv6 server lewat DBus - tidak ada dukungan untuk IPv6"
-
-#: dbus.c:439
+#: dbus.c:438
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:444
+#: dbus.c:443
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr ""
 
 # OK
-#: dbus.c:690
+#: dbus.c:717
 msgid "setting upstream servers from DBus"
 msgstr "menyetel server-server di atas dengan DBus"
 
 # OK
-#: dbus.c:737
+#: dbus.c:764
 msgid "could not register a DBus message handler"
 msgstr "tidak bisa mendaftar sebuah DBus message handler"
 
 # OK
-#: bpf.c:265
+#: bpf.c:261
 #, c-format
 msgid "cannot create DHCP BPF socket: %s"
 msgstr "tidak dapat membuat socket DHCP BPF: %s"
 
 # OK
-#: bpf.c:293
+#: bpf.c:289
 #, fuzzy, c-format
 msgid "DHCP request for unsupported hardware type (%d) received on %s"
 msgstr "permintaan DHCP untuk tipe hardware yang tidak didukung (%d) diterima pada %s"
 
 # OK
-#: bpf.c:378
+#: bpf.c:374
 #, fuzzy, c-format
 msgid "cannot create PF_ROUTE socket: %s"
 msgstr "tidak bisa membuat socket DHCP: %s"
 
-#: bpf.c:399
+#: bpf.c:395
 msgid "Unknown protocol version from route socket"
 msgstr ""
 
-#: helper.c:154
+#: helper.c:150
 msgid "lease() function missing in Lua script"
 msgstr ""
 
-#: tftp.c:319
+#: tftp.c:347
 msgid "unable to get free port for TFTP"
 msgstr ""
 
-#: tftp.c:335
+#: tftp.c:363
 #, c-format
 msgid "unsupported request from %s"
 msgstr ""
 
 # OK
-#: tftp.c:483
+#: tftp.c:510
 #, fuzzy, c-format
 msgid "file %s not found"
 msgstr "lease tak ditemukan"
 
-#: tftp.c:592
-#, c-format
-msgid "error %d %s received from %s"
-msgstr ""
-
 # OK
-#: tftp.c:634
+#: tftp.c:628
 #, fuzzy, c-format
 msgid "failed sending %s to %s"
 msgstr "gagal membaca %s: %s"
 
-#: tftp.c:634
+#: tftp.c:628
 #, c-format
 msgid "sent %s to %s"
 msgstr ""
 
+#: tftp.c:678
+#, c-format
+msgid "error %d %s received from %s"
+msgstr ""
+
 #: log.c:190
 #, c-format
 msgid "overflow: %d log entries lost"
@@ -2255,7 +2375,7 @@ msgstr ""
 msgid "FAILED to start up"
 msgstr "GAGAL untuk memulai"
 
-#: conntrack.c:65
+#: conntrack.c:63
 #, c-format
 msgid "Conntrack connection mark retrieval failed: %s"
 msgstr ""
@@ -2279,90 +2399,84 @@ msgid "failed to bind DHCPv6 server socket: %s"
 msgstr "gagal mem-bind socket server DHCP: %s"
 
 # OK
-#: rfc3315.c:157
+#: rfc3315.c:173
 #, fuzzy, c-format
 msgid "no address range available for DHCPv6 request from relay at %s"
 msgstr "tidak ada alamat yang bisa dipakai untuk permintaan DHCP %s %s"
 
 # OK
-#: rfc3315.c:166
+#: rfc3315.c:182
 #, fuzzy, c-format
 msgid "no address range available for DHCPv6 request via %s"
 msgstr "tidak ada alamat yang bisa dipakai untuk permintaan DHCP %s %s"
 
 # OK
-#: rfc3315.c:303
+#: rfc3315.c:316
 #, fuzzy, c-format
 msgid "%u available DHCPv6 subnet: %s/%d"
 msgstr "tidak ada alamat yang bisa dipakai untuk permintaan DHCP %s %s"
 
 # OK
-#: rfc3315.c:386
+#: rfc3315.c:399
 #, fuzzy, c-format
 msgid "%u vendor class: %u"
 msgstr "DBus error: %s"
 
 # OK
-#: rfc3315.c:434
+#: rfc3315.c:447
 #, fuzzy, c-format
 msgid "%u client MAC address: %s"
 msgstr "tidak ada antarmuka dengan alamat %s"
 
 # OK
-#: rfc3315.c:673
-#, fuzzy, c-format
-msgid "unknown prefix-class %d"
-msgstr "lease tidak diketahui"
-
-# OK
-#: rfc3315.c:816 rfc3315.c:911
+#: rfc3315.c:762 rfc3315.c:859
 #, fuzzy
 msgid "address unavailable"
 msgstr "alamat tak tersedia"
 
-#: rfc3315.c:828 rfc3315.c:959 rfc3315.c:1292
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
 msgid "success"
 msgstr ""
 
 # OK
-#: rfc3315.c:843 rfc3315.c:852 rfc3315.c:967 rfc3315.c:969
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
 #, fuzzy
 msgid "no addresses available"
 msgstr "tak ada alamat yang tersedia"
 
-#: rfc3315.c:946
+#: rfc3315.c:890
 msgid "not on link"
 msgstr ""
 
-#: rfc3315.c:1019 rfc3315.c:1204 rfc3315.c:1281
+#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
 msgid "no binding found"
 msgstr ""
 
-#: rfc3315.c:1057
+#: rfc3315.c:1002
 msgid "deprecated"
 msgstr ""
 
 # OK
-#: rfc3315.c:1062
+#: rfc3315.c:1007
 #, fuzzy
 msgid "address invalid"
 msgstr "alamat telah digunakan"
 
-#: rfc3315.c:1109
+#: rfc3315.c:1057 rfc3315.c:1059
 msgid "confirm failed"
 msgstr ""
 
 # OK
-#: rfc3315.c:1125
+#: rfc3315.c:1074
 #, fuzzy
 msgid "all addresses still on link"
 msgstr "kesalahan nama pada %s baris %d"
 
-#: rfc3315.c:1213
+#: rfc3315.c:1165
 msgid "release received"
 msgstr ""
 
-#: rfc3315.c:2140
+#: rfc3315.c:2130
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr ""
 
@@ -2376,81 +2490,81 @@ msgstr ""
 msgid "%u tags: %s"
 msgstr ""
 
-#: dhcp-common.c:407
+#: dhcp-common.c:444
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr ""
 
 # OK
-#: dhcp-common.c:430
+#: dhcp-common.c:478
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr "alamat IP kembar %s (%s) dalam direktif dhcp-config"
 
 # OK
-#: dhcp-common.c:491
+#: dhcp-common.c:542
 #, fuzzy, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr "gagal menyetel SO_REUSEADDR pada socket DHCP: %s"
 
-#: dhcp-common.c:612
+#: dhcp-common.c:665
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr ""
 
-#: dhcp-common.c:623
+#: dhcp-common.c:676
 #, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr ""
 
-#: dhcp-common.c:820
+#: dhcp-common.c:873
 msgid ", prefix deprecated"
 msgstr ""
 
-#: dhcp-common.c:823
+#: dhcp-common.c:876
 #, c-format
 msgid ", lease time "
 msgstr ""
 
-#: dhcp-common.c:865
+#: dhcp-common.c:918
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr ""
 
 # OK
-#: dhcp-common.c:867
+#: dhcp-common.c:920
 #, fuzzy, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr "DHCP, lease static pada %.0s%s, waktu lease %s"
 
-#: dhcp-common.c:869
+#: dhcp-common.c:922
 #, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr ""
 
 # OK
-#: dhcp-common.c:870
+#: dhcp-common.c:923
 #, fuzzy, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr "DHCP, jangkaun IP %s -- %s, waktu lease %s"
 
-#: dhcp-common.c:883
+#: dhcp-common.c:936
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr ""
 
 # OK
-#: dhcp-common.c:886
+#: dhcp-common.c:939
 #, fuzzy, c-format
 msgid "router advertisement on %s%s"
 msgstr "DHCP, lease static pada %.0s%s, waktu lease %s"
 
-#: dhcp-common.c:897
+#: dhcp-common.c:950
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr ""
 
-#: dhcp-common.c:899
+#: dhcp-common.c:952
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr ""
@@ -2461,7 +2575,7 @@ msgstr ""
 msgid "cannot create ICMPv6 socket: %s"
 msgstr "tidak bisa membuat socket DHCP: %s"
 
-#: auth.c:449
+#: auth.c:439
 #, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr ""
@@ -2479,18 +2593,23 @@ msgid "failed to create IPset control socket: %s"
 msgstr "gagal membuat socket: %s "
 
 # OK
-#: ipset.c:233
+#: ipset.c:226
 #, fuzzy, c-format
 msgid "failed to update ipset %s: %s"
 msgstr "gagal membaca %s: %s"
 
-#: dnssec.c:208
+#: dnssec.c:206
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
 msgstr ""
 
-#: blockdata.c:58
+#: dnssec.c:902
+#, c-format
+msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
+msgstr ""
+
+#: blockdata.c:55
 #, c-format
-msgid "DNSSEC memory in use %u, max %u, allocated %u"
+msgid "pool memory in use %u, max %u, allocated %u"
 msgstr ""
 
 # OK
@@ -2526,13 +2645,13 @@ msgstr "DBus error: %s"
 msgid "info: table created"
 msgstr ""
 
-#: tables.c:134
+#: tables.c:133
 #, c-format
 msgid "warning: DIOCR%sADDRS: %s"
 msgstr ""
 
 # OK
-#: tables.c:138
+#: tables.c:137
 #, fuzzy, c-format
 msgid "%d addresses %s"
 msgstr "membaca %s - %d alamat"
@@ -2577,6 +2696,83 @@ msgid "inotify, new or changed file %s"
 msgstr ""
 
 # OK
+#: dump.c:64
+#, fuzzy, c-format
+msgid "cannot create %s: %s"
+msgstr "tidak bisa membaca %s: %s"
+
+# OK
+#: dump.c:70
+#, fuzzy, c-format
+msgid "bad header in %s"
+msgstr "alamat telah digunakan"
+
+# OK
+#: dump.c:201
+#, fuzzy
+msgid "failed to write packet dump"
+msgstr "gagal mendengarkan di socket: %s"
+
+#: dump.c:203
+#, c-format
+msgid "dumping UDP packet %u mask 0x%04x"
+msgstr ""
+
+#: ubus.c:52
+#, c-format
+msgid "UBus subscription callback: %s subscriber(s)"
+msgstr ""
+
+# OK
+#: ubus.c:73
+#, fuzzy, c-format
+msgid "Cannot reconnect to UBus: %s"
+msgstr "tidak bisa membuka %s:%s"
+
+#: ubus.c:89
+msgid "Cannot initialize UBus: connection failed"
+msgstr ""
+
+# OK
+#: ubus.c:102
+#, fuzzy, c-format
+msgid "Cannot add object to UBus: %s"
+msgstr "tidak bisa membuka %s:%s"
+
+# OK
+#: ubus.c:112
+#, fuzzy
+msgid "Connected to system UBus"
+msgstr "terhubung ke sistem DBus"
+
+#: ubus.c:122
+msgid "Cannot set UBus listeners: no connection"
+msgstr ""
+
+#: ubus.c:142
+msgid "Cannot poll UBus listeners: no connection"
+msgstr ""
+
+#: ubus.c:155
+msgid "Disconnecting from UBus"
+msgstr ""
+
+# OK
+#: ubus.c:199
+#, fuzzy, c-format
+msgid "Failed to send UBus event: %s"
+msgstr "gagal mendengarkan di socket: %s"
+
+# OK
+#~ msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
+#~ msgstr "mencoba menyetel sebuah alamat IPv6 server lewat DBus - tidak ada dukungan untuk IPv6"
+
+# OK
+#, fuzzy
+#~ msgid "unknown prefix-class %d"
+#~ msgstr "lease tidak diketahui"
+
+# OK
 #, fuzzy
 #~ msgid "cannot cannonicalise resolv-file %s: %s"
 #~ msgstr "tidak dapat membuka atau membuat file lease: %s"
index aafc9b6..4d29751 100644 (file)
--- a/po/it.po
+++ b/po/it.po
@@ -16,70 +16,70 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: cache.c:518
+#: cache.c:559
 msgid "Internal error in cache."
 msgstr ""
 
-#: cache.c:928
+#: cache.c:1081
 #, c-format
 msgid "failed to load names from %s: %s"
 msgstr ""
 
-#: cache.c:954 dhcp.c:867
+#: cache.c:1103 dhcp.c:927
 #, c-format
 msgid "bad address at %s line %d"
 msgstr ""
 
-#: cache.c:1007 dhcp.c:883
+#: cache.c:1156 dhcp.c:943
 #, c-format
 msgid "bad name at %s line %d"
 msgstr ""
 
-#: cache.c:1016 dhcp.c:958
+#: cache.c:1167 dhcp.c:1018
 #, c-format
 msgid "read %s - %d addresses"
 msgstr ""
 
-#: cache.c:1129
+#: cache.c:1283
 msgid "cleared cache"
 msgstr ""
 
-#: cache.c:1158
+#: cache.c:1345
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr ""
 
-#: cache.c:1237
+#: cache.c:1391
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr ""
 
-#: cache.c:1261
+#: cache.c:1415
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr ""
 
-#: cache.c:1418
+#: cache.c:1663
 #, c-format
 msgid "time %lu"
 msgstr ""
 
-#: cache.c:1419
+#: cache.c:1664
 #, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr ""
 
-#: cache.c:1421
+#: cache.c:1666
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr ""
 
-#: cache.c:1424
+#: cache.c:1669
 #, c-format
 msgid "queries for authoritative zones %u"
 msgstr ""
 
-#: cache.c:1450
+#: cache.c:1694
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr ""
@@ -93,1479 +93,1573 @@ msgstr ""
 msgid "failed to allocate memory"
 msgstr ""
 
-#: util.c:281 option.c:619
+#: util.c:281 option.c:641
 msgid "could not get memory"
 msgstr ""
 
-#: util.c:291
+#: util.c:302
 #, c-format
 msgid "cannot create pipe: %s"
 msgstr ""
 
-#: util.c:299
+#: util.c:310
 #, c-format
 msgid "failed to allocate %d bytes"
 msgstr ""
 
-#: util.c:468
+#: util.c:506
 #, c-format
 msgid "infinite"
 msgstr ""
 
-#: option.c:344
+#: option.c:358
 msgid "Specify local address(es) to listen on."
 msgstr ""
 
-#: option.c:345
+#: option.c:359
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr ""
 
-#: option.c:346
+#: option.c:360
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr ""
 
-#: option.c:347
+#: option.c:361
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr ""
 
-#: option.c:348
+#: option.c:362
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr ""
 
-#: option.c:349
+#: option.c:363
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr ""
 
-#: option.c:350
+#: option.c:364
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr ""
 
-#: option.c:351
+#: option.c:365
 msgid "Do NOT forward queries with no domain part."
 msgstr ""
 
-#: option.c:352
+#: option.c:366
 msgid "Return self-pointing MX records for local hosts."
 msgstr ""
 
-#: option.c:353
+#: option.c:367
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr ""
 
-#: option.c:354
+#: option.c:368
 msgid "Don't forward spurious DNS requests from Windows hosts."
 msgstr ""
 
-#: option.c:355
+#: option.c:369
 msgid "Enable DHCP in the range given with lease duration."
 msgstr ""
 
-#: option.c:356
+#: option.c:370
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr ""
 
-#: option.c:357
+#: option.c:371
 msgid "Set address or hostname for a specified machine."
 msgstr ""
 
-#: option.c:358
+#: option.c:372
 msgid "Read DHCP host specs from file."
 msgstr ""
 
-#: option.c:359
+#: option.c:373
 msgid "Read DHCP option specs from file."
 msgstr ""
 
-#: option.c:360
+#: option.c:374
 msgid "Read DHCP host specs from a directory."
 msgstr ""
 
-#: option.c:361
+#: option.c:375
 msgid "Read DHCP options from a directory."
 msgstr ""
 
-#: option.c:362
+#: option.c:376
 msgid "Evaluate conditional tag expression."
 msgstr ""
 
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Do NOT load %s file."
 msgstr ""
 
-#: option.c:364
+#: option.c:378
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr ""
 
-#: option.c:365
+#: option.c:379
 msgid "Read hosts files from a directory."
 msgstr ""
 
-#: option.c:366
+#: option.c:380
 msgid "Specify interface(s) to listen on."
 msgstr ""
 
-#: option.c:367
+#: option.c:381
 msgid "Specify interface(s) NOT to listen on."
 msgstr ""
 
-#: option.c:368
+#: option.c:382
 msgid "Map DHCP user class to tag."
 msgstr ""
 
-#: option.c:369
+#: option.c:383
 msgid "Map RFC3046 circuit-id to tag."
 msgstr ""
 
-#: option.c:370
+#: option.c:384
 msgid "Map RFC3046 remote-id to tag."
 msgstr ""
 
-#: option.c:371
+#: option.c:385
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr ""
 
-#: option.c:372
+#: option.c:386
 msgid "Don't do DHCP for hosts with tag set."
 msgstr ""
 
-#: option.c:373
+#: option.c:387
 msgid "Force broadcast replies for hosts with tag set."
 msgstr ""
 
-#: option.c:374
+#: option.c:388
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr ""
 
-#: option.c:375
+#: option.c:389
 msgid "Assume we are the only DHCP server on the local network."
 msgstr ""
 
-#: option.c:376
+#: option.c:390
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr ""
 
-#: option.c:377
+#: option.c:391
 msgid "Return MX records for local hosts."
 msgstr ""
 
-#: option.c:378
+#: option.c:392
 msgid "Specify an MX record."
 msgstr ""
 
-#: option.c:379
+#: option.c:393
 msgid "Specify BOOTP options to DHCP server."
 msgstr ""
 
-#: option.c:380
+#: option.c:394
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr ""
 
-#: option.c:381
+#: option.c:395
 msgid "Do NOT cache failed search results."
 msgstr ""
 
-#: option.c:382
+#: option.c:396
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr ""
 
-#: option.c:383
+#: option.c:397
 msgid "Specify options to be sent to DHCP clients."
 msgstr ""
 
-#: option.c:384
+#: option.c:398
 msgid "DHCP option sent even if the client does not request it."
 msgstr ""
 
-#: option.c:385
+#: option.c:399
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr ""
 
-#: option.c:386
+#: option.c:400
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr ""
 
-#: option.c:387
+#: option.c:401
 msgid "Log DNS queries."
 msgstr ""
 
-#: option.c:388
+#: option.c:402
 msgid "Force the originating port for upstream DNS queries."
 msgstr ""
 
-#: option.c:389
+#: option.c:403
 msgid "Do NOT read resolv.conf."
 msgstr ""
 
-#: option.c:390
+#: option.c:404
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr ""
 
-#: option.c:391
+#: option.c:405
 msgid "Specify path to file with server= options"
 msgstr ""
 
-#: option.c:392
+#: option.c:406
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr ""
 
-#: option.c:393
+#: option.c:407
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr ""
 
-#: option.c:394
+#: option.c:408
 msgid "Never forward queries to specified domains."
 msgstr ""
 
-#: option.c:395
+#: option.c:409
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr ""
 
-#: option.c:396
+#: option.c:410
 msgid "Specify default target in an MX record."
 msgstr ""
 
-#: option.c:397
+#: option.c:411
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr ""
 
-#: option.c:398
+#: option.c:412
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr ""
 
-#: option.c:399
+#: option.c:413
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr ""
 
-#: option.c:400
+#: option.c:414
 msgid "Specify time-to-live ceiling for cache."
 msgstr ""
 
-#: option.c:401
+#: option.c:415
 msgid "Specify time-to-live floor for cache."
 msgstr ""
 
-#: option.c:402
+#: option.c:416
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr ""
 
-#: option.c:403
+#: option.c:417
 msgid "Map DHCP vendor class to tag."
 msgstr ""
 
-#: option.c:404
+#: option.c:418
 msgid "Display dnsmasq version and copyright information."
 msgstr ""
 
-#: option.c:405
+#: option.c:419
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr ""
 
-#: option.c:406
+#: option.c:420
 msgid "Specify a SRV record."
 msgstr ""
 
-#: option.c:407
+#: option.c:421
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr ""
 
-#: option.c:408
+#: option.c:422
 #, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr ""
 
-#: option.c:409
+#: option.c:423
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr ""
 
-#: option.c:410
+#: option.c:424
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr ""
 
-#: option.c:411
+#: option.c:425
 msgid "Specify TXT DNS record."
 msgstr ""
 
-#: option.c:412
+#: option.c:426
 msgid "Specify PTR DNS record."
 msgstr ""
 
-#: option.c:413
+#: option.c:427
 msgid "Give DNS name to IPv4 address of interface."
 msgstr ""
 
-#: option.c:414
+#: option.c:428
 msgid "Bind only to interfaces in use."
 msgstr ""
 
-#: option.c:415
+#: option.c:429
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr ""
 
-#: option.c:416
+#: option.c:430
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr ""
 
-#: option.c:417
+#: option.c:431
+msgid "Enable the UBus interface."
+msgstr ""
+
+#: option.c:432
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr ""
 
-#: option.c:418
+#: option.c:433
 msgid "Enable dynamic address allocation for bootp."
 msgstr ""
 
-#: option.c:419
+#: option.c:434
 msgid "Map MAC address (with wildcards) to option set."
 msgstr ""
 
-#: option.c:420
+#: option.c:435
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr ""
 
-#: option.c:421
+#: option.c:436
+msgid "Specify extra networks sharing a broadcast domain for DHCP"
+msgstr ""
+
+#: option.c:437
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr ""
 
-#: option.c:422
+#: option.c:438
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:423
+#: option.c:439
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:424
+#: option.c:440
 msgid "Run lease-change scripts as this user."
 msgstr ""
 
-#: option.c:425
+#: option.c:441
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr ""
 
-#: option.c:426
+#: option.c:442
 msgid "Read configuration from all the files in this directory."
 msgstr ""
 
-#: option.c:427
+#: option.c:443
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr ""
 
-#: option.c:428
+#: option.c:444
 msgid "Do not use leasefile."
 msgstr ""
 
-#: option.c:429
+#: option.c:445
 #, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr ""
 
-#: option.c:430
+#: option.c:446
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr ""
 
-#: option.c:431
+#: option.c:447
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr ""
 
-#: option.c:432
+#: option.c:448
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr ""
 
-#: option.c:433
+#: option.c:449
 msgid "Enable integrated read-only TFTP server."
 msgstr ""
 
-#: option.c:434
+#: option.c:450
 msgid "Export files by TFTP only from the specified subtree."
 msgstr ""
 
-#: option.c:435
+#: option.c:451
 msgid "Add client IP or hardware address to tftp-root."
 msgstr ""
 
-#: option.c:436
+#: option.c:452
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr ""
 
-#: option.c:437
+#: option.c:453
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr ""
 
-#: option.c:438
+#: option.c:454
 #, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr ""
 
-#: option.c:439
+#: option.c:455
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr ""
 
-#: option.c:440
+#: option.c:456
 msgid "Disable the TFTP blocksize extension."
 msgstr ""
 
-#: option.c:441
+#: option.c:457
 msgid "Convert TFTP filenames to lowercase"
 msgstr ""
 
-#: option.c:442
+#: option.c:458
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr ""
 
-#: option.c:443
+#: option.c:459
+msgid "Use only one port for TFTP server."
+msgstr ""
+
+#: option.c:460
 msgid "Extra logging for DHCP."
 msgstr ""
 
-#: option.c:444
+#: option.c:461
 msgid "Enable async. logging; optionally set queue length."
 msgstr ""
 
-#: option.c:445
+#: option.c:462
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr ""
 
-#: option.c:446
+#: option.c:463
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr ""
 
-#: option.c:447
+#: option.c:464
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr ""
 
-#: option.c:448
+#: option.c:465
 msgid "Always perform DNS queries to all servers."
 msgstr ""
 
-#: option.c:449
+#: option.c:466
 msgid "Set tag if client includes matching option in request."
 msgstr ""
 
-#: option.c:450
+#: option.c:467
+msgid "Set tag if client provides given name."
+msgstr ""
+
+#: option.c:468
 msgid "Use alternative ports for DHCP."
 msgstr ""
 
-#: option.c:451
+#: option.c:469
 msgid "Specify NAPTR DNS record."
 msgstr ""
 
-#: option.c:452
+#: option.c:470
 msgid "Specify lowest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:453
+#: option.c:471
 msgid "Specify highest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:454
+#: option.c:472
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr ""
 
-#: option.c:455
+#: option.c:473
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr ""
 
-#: option.c:456
+#: option.c:474
 msgid "Use these DHCP relays as full proxies."
 msgstr ""
 
-#: option.c:457
+#: option.c:475
 msgid "Relay DHCP requests to a remote server"
 msgstr ""
 
-#: option.c:458
+#: option.c:476
 msgid "Specify alias name for LOCAL DNS name."
 msgstr ""
 
-#: option.c:459
+#: option.c:477
 msgid "Prompt to send to PXE clients."
 msgstr ""
 
-#: option.c:460
+#: option.c:478
 msgid "Boot service for PXE menu."
 msgstr ""
 
-#: option.c:461
+#: option.c:479
 msgid "Check configuration syntax."
 msgstr ""
 
-#: option.c:462
+#: option.c:480
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr ""
 
-#: option.c:463
+#: option.c:481
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr ""
 
-#: option.c:464
+#: option.c:482
 msgid "Add client identification to forwarded DNS queries."
 msgstr ""
 
-#: option.c:465
+#: option.c:483
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr ""
 
-#: option.c:466
+#: option.c:484
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr ""
 
-#: option.c:467
+#: option.c:485
+msgid "Ignore client identifier option sent by DHCP clients."
+msgstr ""
+
+#: option.c:486
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr ""
 
-#: option.c:468
+#: option.c:487
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr ""
 
-#: option.c:469
+#: option.c:488
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr ""
 
-#: option.c:470
+#: option.c:489
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr ""
 
-#: option.c:471
+#: option.c:490
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr ""
 
-#: option.c:472
+#: option.c:491
+msgid "Specify certification authority authorization record"
+msgstr ""
+
+#: option.c:492
 msgid "Specify arbitrary DNS resource record"
 msgstr ""
 
-#: option.c:473
+#: option.c:493
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr ""
 
-#: option.c:474
+#: option.c:494
 msgid "Export local names to global DNS"
 msgstr ""
 
-#: option.c:475
+#: option.c:495
 msgid "Domain to export to global DNS"
 msgstr ""
 
-#: option.c:476
+#: option.c:496
 msgid "Set TTL for authoritative replies"
 msgstr ""
 
-#: option.c:477
+#: option.c:497
 msgid "Set authoritative zone information"
 msgstr ""
 
-#: option.c:478
+#: option.c:498
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr ""
 
-#: option.c:479
+#: option.c:499
 msgid "Peers which are allowed to do zone transfer"
 msgstr ""
 
-#: option.c:480
+#: option.c:500
 msgid "Specify ipsets to which matching domains should be added"
 msgstr ""
 
-#: option.c:481
+#: option.c:501
 msgid "Specify a domain and address range for synthesised names"
 msgstr ""
 
-#: option.c:482
+#: option.c:502
 msgid "Activate DNSSEC validation"
 msgstr ""
 
-#: option.c:483
+#: option.c:503
 msgid "Specify trust anchor key digest."
 msgstr ""
 
-#: option.c:484
+#: option.c:504
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr ""
 
-#: option.c:485
+#: option.c:505
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr ""
 
-#: option.c:486
+#: option.c:506
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr ""
 
-#: option.c:487
+#: option.c:507
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr ""
 
-#: option.c:489
-msgid "Specify DHCPv6 prefix class"
-msgstr ""
-
-#: option.c:491
+#: option.c:508
 msgid "Set MTU, priority, resend-interval and router-lifetime"
 msgstr ""
 
-#: option.c:492
+#: option.c:509
 msgid "Do not log routine DHCP."
 msgstr ""
 
-#: option.c:493
+#: option.c:510
 msgid "Do not log routine DHCPv6."
 msgstr ""
 
-#: option.c:494
+#: option.c:511
 msgid "Do not log RA."
 msgstr ""
 
-#: option.c:495
+#: option.c:512
 msgid "Accept queries only from directly-connected networks."
 msgstr ""
 
-#: option.c:496
+#: option.c:513
 msgid "Detect and remove DNS forwarding loops."
 msgstr ""
 
-#: option.c:497
+#: option.c:514
 msgid "Ignore DNS responses containing ipaddr."
 msgstr ""
 
-#: option.c:498
+#: option.c:515
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr ""
 
-#: option.c:499
+#: option.c:516
 msgid "Delay DHCP replies for at least number of seconds."
 msgstr ""
 
-#: option.c:703
+#: option.c:517
+msgid "Enables DHCPv4 Rapid Commit option."
+msgstr ""
+
+#: option.c:518
+msgid "Path to debug packet dump file"
+msgstr ""
+
+#: option.c:519
+msgid "Mask which packets to dump"
+msgstr ""
+
+#: option.c:520
+msgid "Call dhcp-script when lease expiry changes."
+msgstr ""
+
+#: option.c:725
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
 "\n"
 msgstr ""
 
-#: option.c:705
+#: option.c:727
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr ""
 
-#: option.c:707
+#: option.c:729
 #, c-format
 msgid "Valid options are:\n"
 msgstr ""
 
-#: option.c:754 option.c:868
+#: option.c:776 option.c:884
 msgid "bad address"
 msgstr ""
 
-#: option.c:779 option.c:783
+#: option.c:799 option.c:803
 msgid "bad port"
 msgstr ""
 
-#: option.c:797 option.c:826 option.c:861
+#: option.c:815 option.c:844 option.c:878
 msgid "interface binding not supported"
 msgstr ""
 
-#: option.c:821 option.c:856
+#: option.c:839 option.c:873
 msgid "interface can only be specified once"
 msgstr ""
 
-#: option.c:835 option.c:3809
+#: option.c:852 option.c:4042
 msgid "bad interface name"
 msgstr ""
 
-#: option.c:1062
+#: option.c:1184
 msgid "unsupported encapsulation for IPv6 option"
 msgstr ""
 
-#: option.c:1076
+#: option.c:1198
 msgid "bad dhcp-option"
 msgstr ""
 
-#: option.c:1144
+#: option.c:1270
 msgid "bad IP address"
 msgstr ""
 
-#: option.c:1147 option.c:1286 option.c:3079
+#: option.c:1273 option.c:1412 option.c:3297
 msgid "bad IPv6 address"
 msgstr ""
 
-#: option.c:1240
+#: option.c:1366
 msgid "bad IPv4 address"
 msgstr ""
 
-#: option.c:1313 option.c:1407
+#: option.c:1439 option.c:1533
 msgid "bad domain in dhcp-option"
 msgstr ""
 
-#: option.c:1445
+#: option.c:1571
 msgid "dhcp-option too long"
 msgstr ""
 
-#: option.c:1452
+#: option.c:1578
 msgid "illegal dhcp-match"
 msgstr ""
 
-#: option.c:1514
+#: option.c:1647
 msgid "illegal repeated flag"
 msgstr ""
 
-#: option.c:1522
+#: option.c:1655
 msgid "illegal repeated keyword"
 msgstr ""
 
-#: option.c:1593 option.c:4443
+#: option.c:1726 option.c:4764
 #, c-format
 msgid "cannot access directory %s: %s"
 msgstr ""
 
-#: option.c:1639 tftp.c:537
+#: option.c:1772 tftp.c:564 dump.c:68
 #, c-format
 msgid "cannot access %s: %s"
 msgstr ""
 
-#: option.c:1727
+#: option.c:1879
 msgid "setting log facility is not possible under Android"
 msgstr ""
 
-#: option.c:1736
+#: option.c:1888
 msgid "bad log facility"
 msgstr ""
 
-#: option.c:1789
+#: option.c:1941
 msgid "bad MX preference"
 msgstr ""
 
-#: option.c:1794
+#: option.c:1946
 msgid "bad MX name"
 msgstr ""
 
-#: option.c:1808
+#: option.c:1960
 msgid "bad MX target"
 msgstr ""
 
-#: option.c:1820
-msgid "cannot run scripts under uClinux"
-msgstr ""
-
-#: option.c:1822
+#: option.c:1980
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr ""
 
-#: option.c:1826
+#: option.c:1984
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr ""
 
-#: option.c:2095 option.c:2106 option.c:2143 option.c:2199 option.c:2482
+#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
 msgid "bad prefix"
 msgstr ""
 
-#: option.c:2504
+#: option.c:2658
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr ""
 
-#: option.c:2713
+#: option.c:2871
 msgid "bad port range"
 msgstr ""
 
-#: option.c:2739
+#: option.c:2897
 msgid "bad bridge-interface"
 msgstr ""
 
-#: option.c:2807
+#: option.c:2941
+msgid "bad shared-network"
+msgstr ""
+
+#: option.c:2996
 msgid "only one tag allowed"
 msgstr ""
 
-#: option.c:2827 option.c:2839 option.c:2948 option.c:2953 option.c:2992
+#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
 msgid "bad dhcp-range"
 msgstr ""
 
-#: option.c:2854
+#: option.c:3050
 msgid "inconsistent DHCP range"
 msgstr ""
 
-#: option.c:2916
+#: option.c:3115
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr ""
 
-#: option.c:2918
+#: option.c:3117
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr ""
 
-#: option.c:2922
+#: option.c:3120
 msgid "prefix length must be at least 64"
 msgstr ""
 
-#: option.c:2925
+#: option.c:3123
 msgid "inconsistent DHCPv6 range"
 msgstr ""
 
-#: option.c:2936
+#: option.c:3142
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr ""
 
-#: option.c:3049 option.c:3097
+#: option.c:3262 option.c:3340
 msgid "bad hex constant"
 msgstr ""
 
-#: option.c:3071
-msgid "cannot match tags in --dhcp-host"
+#: option.c:3315
+msgid "bad IPv6 prefix"
 msgstr ""
 
-#: option.c:3119
+#: option.c:3362
 #, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr ""
 
-#: option.c:3177
+#: option.c:3422
 msgid "bad DHCP host name"
 msgstr ""
 
-#: option.c:3259
+#: option.c:3508
 msgid "bad tag-if"
 msgstr ""
 
-#: option.c:3616 option.c:4039
+#: option.c:3851 option.c:4324
 msgid "invalid port number"
 msgstr ""
 
-#: option.c:3678
+#: option.c:3907
 msgid "bad dhcp-proxy address"
 msgstr ""
 
-#: option.c:3704
+#: option.c:3935
 msgid "Bad dhcp-relay"
 msgstr ""
 
-#: option.c:3745
+#: option.c:3979
 msgid "bad RA-params"
 msgstr ""
 
-#: option.c:3754
+#: option.c:3989
 msgid "bad DUID"
 msgstr ""
 
-#: option.c:3796
+#: option.c:4023
+msgid "missing address in alias"
+msgstr ""
+
+#: option.c:4029
 msgid "invalid alias range"
 msgstr ""
 
-#: option.c:3850 option.c:3862
+#: option.c:4081 option.c:4097
 msgid "bad CNAME"
 msgstr ""
 
-#: option.c:3866
+#: option.c:4105
 msgid "duplicate CNAME"
 msgstr ""
 
-#: option.c:3889
+#: option.c:4132
 msgid "bad PTR record"
 msgstr ""
 
-#: option.c:3920
+#: option.c:4167
 msgid "bad NAPTR record"
 msgstr ""
 
-#: option.c:3954
+#: option.c:4203
 msgid "bad RR record"
 msgstr ""
 
-#: option.c:3984
+#: option.c:4236
+msgid "bad CAA record"
+msgstr ""
+
+#: option.c:4265
 msgid "bad TXT record"
 msgstr ""
 
-#: option.c:4025
+#: option.c:4308
 msgid "bad SRV record"
 msgstr ""
 
-#: option.c:4032
+#: option.c:4315
 msgid "bad SRV target"
 msgstr ""
 
-#: option.c:4046
+#: option.c:4334
 msgid "invalid priority"
 msgstr ""
 
-#: option.c:4049
+#: option.c:4339
 msgid "invalid weight"
 msgstr ""
 
-#: option.c:4073
+#: option.c:4362
 msgid "Bad host-record"
 msgstr ""
 
-#: option.c:4097
+#: option.c:4402
 msgid "Bad name in host-record"
 msgstr ""
 
-#: option.c:4162
+#: option.c:4444
+msgid "bad value for dnssec-check-unsigned"
+msgstr ""
+
+#: option.c:4480
 msgid "bad trust anchor"
 msgstr ""
 
-#: option.c:4176
+#: option.c:4496
 msgid "bad HEX in trust anchor"
 msgstr ""
 
-#: option.c:4186
+#: option.c:4507
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr ""
 
-#: option.c:4246
+#: option.c:4567
 msgid "missing \""
 msgstr ""
 
-#: option.c:4303
+#: option.c:4624
 msgid "bad option"
 msgstr ""
 
-#: option.c:4305
+#: option.c:4626
 msgid "extraneous parameter"
 msgstr ""
 
-#: option.c:4307
+#: option.c:4628
 msgid "missing parameter"
 msgstr ""
 
-#: option.c:4309
+#: option.c:4630
 msgid "illegal option"
 msgstr ""
 
-#: option.c:4316
+#: option.c:4637
 msgid "error"
 msgstr ""
 
-#: option.c:4318
+#: option.c:4639
 #, c-format
 msgid " at line %d of %s"
 msgstr ""
 
-#: option.c:4333 option.c:4580 option.c:4616
+#: option.c:4654 option.c:4939 option.c:4950
 #, c-format
 msgid "read %s"
 msgstr ""
 
-#: option.c:4396 option.c:4519 tftp.c:715
+#: option.c:4717 option.c:4840 tftp.c:754
 #, c-format
 msgid "cannot read %s: %s"
 msgstr ""
 
-#: option.c:4688
+#: option.c:5027
 msgid "junk found in command line"
 msgstr ""
 
-#: option.c:4729
+#: option.c:5067
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr ""
 
-#: option.c:4730
+#: option.c:5068
 #, c-format
 msgid ""
 "Compile time options: %s\n"
 "\n"
 msgstr ""
 
-#: option.c:4731
+#: option.c:5069
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr ""
 
-#: option.c:4732
+#: option.c:5070
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr ""
 
-#: option.c:4733
+#: option.c:5071
 #, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr ""
 
-#: option.c:4744
+#: option.c:5088
 msgid "try --help"
 msgstr ""
 
-#: option.c:4746
+#: option.c:5090
 msgid "try -w"
 msgstr ""
 
-#: option.c:4748
+#: option.c:5092
 #, c-format
 msgid "bad command line options: %s"
 msgstr ""
 
-#: option.c:4818
+#: option.c:5161
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr ""
 
-#: option.c:4854
+#: option.c:5195
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr ""
 
-#: option.c:4882
+#: option.c:5223
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr ""
 
-#: option.c:4892
+#: option.c:5233
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr ""
 
-#: option.c:4895 network.c:1623 dhcp.c:816
+#: option.c:5236 network.c:1594 dhcp.c:876
 #, c-format
 msgid "failed to read %s: %s"
 msgstr ""
 
-#: option.c:4912
+#: option.c:5253
 #, c-format
 msgid "no search directive found in %s"
 msgstr ""
 
-#: option.c:4933
+#: option.c:5274
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr ""
 
-#: option.c:4942
+#: option.c:5283
 msgid "syntax check OK"
 msgstr ""
 
-#: forward.c:102
+#: forward.c:99
 #, c-format
 msgid "failed to send packet: %s"
 msgstr ""
 
-#: forward.c:598
+#: forward.c:614
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr ""
 
-#: forward.c:652
+#: forward.c:677
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr ""
 
-#: forward.c:684
+#: forward.c:709
 #, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr ""
 
-#: forward.c:870
+#: forward.c:961
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
 msgstr ""
 
-#: forward.c:1266 forward.c:1704
+#: forward.c:1370 forward.c:1830
 msgid "Ignoring query from non-local network"
 msgstr ""
 
-#: forward.c:2184
+#: forward.c:2321
 #, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr ""
 
-#: network.c:720
+#: network.c:698
 #, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr ""
 
-#: network.c:1031
+#: network.c:1002
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr ""
 
-#: network.c:1038
+#: network.c:1009
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr ""
 
-#: network.c:1047
+#: network.c:1018
 #, c-format
 msgid "warning: using interface %s instead"
 msgstr ""
 
-#: network.c:1056
+#: network.c:1027
 #, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr ""
 
-#: network.c:1114
+#: network.c:1085
 #, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr ""
 
-#: network.c:1119
+#: network.c:1090
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr ""
 
-#: network.c:1337
+#: network.c:1307
 #, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr ""
 
-#: network.c:1528
+#: network.c:1499
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr ""
 
-#: network.c:1539
+#: network.c:1510
 #, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr ""
 
-#: network.c:1559
+#: network.c:1530
 msgid "(no DNSSEC)"
 msgstr ""
 
-#: network.c:1562
+#: network.c:1533
 msgid "unqualified"
 msgstr ""
 
-#: network.c:1562
+#: network.c:1533
 msgid "names"
 msgstr ""
 
-#: network.c:1564
+#: network.c:1535
 msgid "default"
 msgstr ""
 
-#: network.c:1566
+#: network.c:1537
 msgid "domain"
 msgstr ""
 
-#: network.c:1572
+#: network.c:1543
 #, c-format
-msgid "using local addresses only for %s %s"
+msgid "using only locally-known addresses for %s %s"
 msgstr ""
 
-#: network.c:1575
+#: network.c:1546
 #, c-format
 msgid "using standard nameservers for %s %s"
 msgstr ""
 
-#: network.c:1577
+#: network.c:1548
 #, c-format
 msgid "using nameserver %s#%d for %s %s %s"
 msgstr ""
 
-#: network.c:1581
+#: network.c:1552
 #, c-format
 msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr ""
 
-#: network.c:1584
+#: network.c:1555
 #, c-format
 msgid "using nameserver %s#%d(via %s)"
 msgstr ""
 
-#: network.c:1586
+#: network.c:1557
 #, c-format
 msgid "using nameserver %s#%d"
 msgstr ""
 
-#: network.c:1591
+#: network.c:1562
 #, c-format
 msgid "using %d more local addresses"
 msgstr ""
 
-#: network.c:1593
+#: network.c:1564
 #, c-format
 msgid "using %d more nameservers"
 msgstr ""
 
-#: dnsmasq.c:171
+#: dnsmasq.c:173
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr ""
 
-#: dnsmasq.c:186
+#: dnsmasq.c:188
 msgid "no root trust anchor provided for DNSSEC"
 msgstr ""
 
-#: dnsmasq.c:189
+#: dnsmasq.c:191
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr ""
 
-#: dnsmasq.c:191
+#: dnsmasq.c:193
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:197
+#: dnsmasq.c:199
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:202
+#: dnsmasq.c:204
 msgid "cannot use --conntrack AND --query-port"
 msgstr ""
 
-#: dnsmasq.c:205
+#: dnsmasq.c:207
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:210
+#: dnsmasq.c:212
 msgid "asynchronous logging is not available under Solaris"
 msgstr ""
 
-#: dnsmasq.c:215
+#: dnsmasq.c:217
 msgid "asynchronous logging is not available under Android"
 msgstr ""
 
-#: dnsmasq.c:220
+#: dnsmasq.c:222
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:225
+#: dnsmasq.c:227
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:229
-msgid "max_port cannot be smaller than min_port"
+#: dnsmasq.c:232
+msgid "Ubus not available: set HAVE_UBUS in src/config.h"
 msgstr ""
 
 #: dnsmasq.c:236
+msgid "max_port cannot be smaller than min_port"
+msgstr ""
+
+#: dnsmasq.c:243
+msgid "--auth-server required when an auth zone is defined."
+msgstr ""
+
+#: dnsmasq.c:248
 msgid "zone serial must be configured in --auth-soa"
 msgstr ""
 
-#: dnsmasq.c:254
+#: dnsmasq.c:268
 msgid "dhcp-range constructor not available on this platform"
 msgstr ""
 
-#: dnsmasq.c:300
+#: dnsmasq.c:332
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr ""
 
-#: dnsmasq.c:303
+#: dnsmasq.c:335
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr ""
 
-#: dnsmasq.c:312
+#: dnsmasq.c:344
 #, c-format
 msgid "unknown interface %s"
 msgstr ""
 
-#: dnsmasq.c:377 dnsmasq.c:1054
+#: dnsmasq.c:406
+msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
+msgstr ""
+
+#: dnsmasq.c:416 dnsmasq.c:1171
 #, c-format
 msgid "DBus error: %s"
 msgstr ""
 
-#: dnsmasq.c:380
+#: dnsmasq.c:419
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:410
+#: dnsmasq.c:429
+msgid "UBus not available: set HAVE_UBUS in src/config.h"
+msgstr ""
+
+#: dnsmasq.c:459
 #, c-format
 msgid "unknown user or group: %s"
 msgstr ""
 
-#: dnsmasq.c:465
+#: dnsmasq.c:535
+#, c-format
+msgid "process is missing required capability %s"
+msgstr ""
+
+#: dnsmasq.c:567
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr ""
 
-#: dnsmasq.c:730
+#: dnsmasq.c:815
 #, c-format
 msgid "started, version %s DNS disabled"
 msgstr ""
 
-#: dnsmasq.c:734
+#: dnsmasq.c:820
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr ""
 
-#: dnsmasq.c:736
+#: dnsmasq.c:822
+msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
+msgstr ""
+
+#: dnsmasq.c:825
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr ""
 
-#: dnsmasq.c:739
+#: dnsmasq.c:828
 msgid "DNS service limited to local subnets"
 msgstr ""
 
-#: dnsmasq.c:742
+#: dnsmasq.c:831
 #, c-format
 msgid "compile time options: %s"
 msgstr ""
 
-#: dnsmasq.c:751
+#: dnsmasq.c:840
 msgid "DBus support enabled: connected to system bus"
 msgstr ""
 
-#: dnsmasq.c:753
+#: dnsmasq.c:842
 msgid "DBus support enabled: bus connection pending"
 msgstr ""
 
-#: dnsmasq.c:771
+#: dnsmasq.c:850
+msgid "UBus support enabled: connected to system bus"
+msgstr ""
+
+#: dnsmasq.c:852
+msgid "UBus support enabled: bus connection pending"
+msgstr ""
+
+#: dnsmasq.c:872
+msgid "DNSSEC validation enabled but all unsigned answers are trusted"
+msgstr ""
+
+#: dnsmasq.c:874
 msgid "DNSSEC validation enabled"
 msgstr ""
 
-#: dnsmasq.c:775
+#: dnsmasq.c:878
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr ""
 
-#: dnsmasq.c:778
+#: dnsmasq.c:881
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr ""
 
-#: dnsmasq.c:783
+#: dnsmasq.c:884
+#, c-format
+msgid "configured with trust anchor for %s keytag %u"
+msgstr ""
+
+#: dnsmasq.c:890
 #, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr ""
 
-#: dnsmasq.c:787
+#: dnsmasq.c:894
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr ""
 
-#: dnsmasq.c:799
+#: dnsmasq.c:906
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr ""
 
-#: dnsmasq.c:804
+#: dnsmasq.c:911
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr ""
 
-#: dnsmasq.c:807
+#: dnsmasq.c:914
 msgid "warning: no upstream servers configured"
 msgstr ""
 
-#: dnsmasq.c:811
+#: dnsmasq.c:918
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr ""
 
-#: dnsmasq.c:832
+#: dnsmasq.c:939
 msgid "IPv6 router advertisement enabled"
 msgstr ""
 
-#: dnsmasq.c:837
+#: dnsmasq.c:944
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr ""
 
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 msgid "root is "
 msgstr ""
 
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 msgid "enabled"
 msgstr ""
 
-#: dnsmasq.c:853
+#: dnsmasq.c:960
 msgid "secure mode"
 msgstr ""
 
-#: dnsmasq.c:856
+#: dnsmasq.c:961
+msgid "single port mode"
+msgstr ""
+
+#: dnsmasq.c:964
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:860
+#: dnsmasq.c:968
 #, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:886
+#: dnsmasq.c:994
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr ""
 
-#: dnsmasq.c:1056
+#: dnsmasq.c:1173
 msgid "connected to system DBus"
 msgstr ""
 
-#: dnsmasq.c:1215
+#: dnsmasq.c:1345
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr ""
 
-#: dnsmasq.c:1218
+#: dnsmasq.c:1349
 #, c-format
 msgid "failed to create helper: %s"
 msgstr ""
 
-#: dnsmasq.c:1221
+#: dnsmasq.c:1353
 #, c-format
 msgid "setting capabilities failed: %s"
 msgstr ""
 
-#: dnsmasq.c:1224
+#: dnsmasq.c:1357
 #, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1227
+#: dnsmasq.c:1361
 #, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1230
+#: dnsmasq.c:1365
 #, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1233
+#: dnsmasq.c:1369
 #, c-format
 msgid "cannot open log %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1236
+#: dnsmasq.c:1373
 #, c-format
 msgid "failed to load Lua script: %s"
 msgstr ""
 
-#: dnsmasq.c:1239
+#: dnsmasq.c:1377
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr ""
 
-#: dnsmasq.c:1242
+#: dnsmasq.c:1381
 #, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1326
+#: dnsmasq.c:1465
 #, c-format
 msgid "script process killed by signal %d"
 msgstr ""
 
-#: dnsmasq.c:1330
+#: dnsmasq.c:1469
 #, c-format
 msgid "script process exited with status %d"
 msgstr ""
 
-#: dnsmasq.c:1334
+#: dnsmasq.c:1473
 #, c-format
 msgid "failed to execute %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1374
+#: dnsmasq.c:1513
 msgid "now checking DNSSEC signature timestamps"
 msgstr ""
 
-#: dnsmasq.c:1409 dnssec.c:160 dnssec.c:206
+#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
 #, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1416
+#: dnsmasq.c:1560
 msgid "exiting on receipt of SIGTERM"
 msgstr ""
 
-#: dnsmasq.c:1444
+#: dnsmasq.c:1588
 #, c-format
 msgid "failed to access %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1474
+#: dnsmasq.c:1618
 #, c-format
 msgid "reading %s"
 msgstr ""
 
-#: dnsmasq.c:1485
+#: dnsmasq.c:1629
 #, c-format
 msgid "no servers found in %s, will retry"
 msgstr ""
@@ -1595,7 +1689,7 @@ msgstr ""
 msgid "cannot create ICMP raw socket: %s."
 msgstr ""
 
-#: dhcp.c:252 dhcp6.c:173
+#: dhcp.c:252 dhcp6.c:180
 #, c-format
 msgid "unknown interface %s in bridge-interface"
 msgstr ""
@@ -1605,329 +1699,334 @@ msgstr ""
 msgid "DHCP packet received on %s which has no address"
 msgstr ""
 
-#: dhcp.c:427
+#: dhcp.c:428
 #, c-format
 msgid "ARP-cache injection failed: %s"
 msgstr ""
 
-#: dhcp.c:470
+#: dhcp.c:471
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr ""
 
-#: dhcp.c:531
+#: dhcp.c:526
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr ""
 
-#: dhcp.c:854
+#: dhcp.c:914
 #, c-format
 msgid "bad line at %s line %d"
 msgstr ""
 
-#: dhcp.c:897
+#: dhcp.c:957
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr ""
 
-#: dhcp.c:1041 rfc3315.c:2149
+#: dhcp.c:1100 rfc3315.c:2139
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr ""
 
-#: lease.c:98
+#: lease.c:64
+#, c-format
+msgid "ignoring invalid line in lease database: %s %s %s %s ..."
+msgstr ""
+
+#: lease.c:101
+#, c-format
+msgid "ignoring invalid line in lease database, bad address: %s"
+msgstr ""
+
+#: lease.c:108
 msgid "too many stored leases"
 msgstr ""
 
-#: lease.c:166
+#: lease.c:176
 #, c-format
 msgid "cannot open or create lease file %s: %s"
 msgstr ""
 
-#: lease.c:175
-#, c-format
-msgid "failed to parse lease database, invalid line: %s %s %s %s ..."
+#: lease.c:185
+msgid "failed to parse lease database cleanly"
 msgstr ""
 
-#: lease.c:180
+#: lease.c:188
 #, c-format
 msgid "failed to read lease file %s: %s"
 msgstr ""
 
-#: lease.c:196
+#: lease.c:204
 #, c-format
 msgid "cannot run lease-init script %s: %s"
 msgstr ""
 
-#: lease.c:202
+#: lease.c:210
 #, c-format
 msgid "lease-init script returned exit code %s"
 msgstr ""
 
-#: lease.c:373
+#: lease.c:381
 #, c-format
 msgid "failed to write %s: %s (retry in %us)"
 msgstr ""
 
-#: lease.c:937
+#: lease.c:955
 #, c-format
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr ""
 
-#: rfc2131.c:347
+#: rfc2131.c:372
 #, c-format
 msgid "no address range available for DHCP request %s %s"
 msgstr ""
 
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "with subnet selector"
 msgstr ""
 
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "via"
 msgstr ""
 
-#: rfc2131.c:360
+#: rfc2131.c:385
 #, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr ""
 
-#: rfc2131.c:363 rfc3315.c:306
+#: rfc2131.c:388 rfc3315.c:319
 #, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr ""
 
-#: rfc2131.c:474
+#: rfc2131.c:499
 #, c-format
 msgid "%u vendor class: %s"
 msgstr ""
 
-#: rfc2131.c:476
+#: rfc2131.c:501
 #, c-format
 msgid "%u user class: %s"
 msgstr ""
 
-#: rfc2131.c:510
+#: rfc2131.c:535
 msgid "disabled"
 msgstr ""
 
-#: rfc2131.c:551 rfc2131.c:1006 rfc2131.c:1430 rfc3315.c:616 rfc3315.c:869
-#: rfc3315.c:1148
+#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1097
 msgid "ignored"
 msgstr ""
 
-#: rfc2131.c:566 rfc2131.c:1239 rfc3315.c:919
+#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
 msgid "address in use"
 msgstr ""
 
-#: rfc2131.c:580 rfc2131.c:1060
+#: rfc2131.c:605 rfc2131.c:1119
 msgid "no address available"
 msgstr ""
 
-#: rfc2131.c:587 rfc2131.c:1202
+#: rfc2131.c:612 rfc2131.c:1273
 msgid "wrong network"
 msgstr ""
 
-#: rfc2131.c:602
+#: rfc2131.c:627
 msgid "no address configured"
 msgstr ""
 
-#: rfc2131.c:608 rfc2131.c:1252
+#: rfc2131.c:633 rfc2131.c:1323
 msgid "no leases left"
 msgstr ""
 
-#: rfc2131.c:703 rfc3315.c:482
+#: rfc2131.c:734 rfc3315.c:499
 #, c-format
 msgid "%u client provides name: %s"
 msgstr ""
 
-#: rfc2131.c:808
+#: rfc2131.c:864
 msgid "PXE BIS not supported"
 msgstr ""
 
-#: rfc2131.c:974 rfc3315.c:1242
+#: rfc2131.c:1032 rfc3315.c:1197
 #, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr ""
 
-#: rfc2131.c:995
+#: rfc2131.c:1053
 msgid "unknown lease"
 msgstr ""
 
-#: rfc2131.c:1029
+#: rfc2131.c:1088
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr ""
 
-#: rfc2131.c:1039
+#: rfc2131.c:1098
 #, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr ""
 
-#: rfc2131.c:1042
+#: rfc2131.c:1101
 #, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr ""
 
-#: rfc2131.c:1058 rfc2131.c:1245
+#: rfc2131.c:1117 rfc2131.c:1316
 msgid "no unique-id"
 msgstr ""
 
-#: rfc2131.c:1140
+#: rfc2131.c:1209
 msgid "wrong server-ID"
 msgstr ""
 
-#: rfc2131.c:1159
+#: rfc2131.c:1228
 msgid "wrong address"
 msgstr ""
 
-#: rfc2131.c:1177 rfc3315.c:1015
+#: rfc2131.c:1246 rfc3315.c:961
 msgid "lease not found"
 msgstr ""
 
-#: rfc2131.c:1210
+#: rfc2131.c:1281
 msgid "address not available"
 msgstr ""
 
-#: rfc2131.c:1221
+#: rfc2131.c:1292
 msgid "static lease available"
 msgstr ""
 
-#: rfc2131.c:1225
+#: rfc2131.c:1296
 msgid "address reserved"
 msgstr ""
 
-#: rfc2131.c:1233
+#: rfc2131.c:1304
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr ""
 
-#: rfc2131.c:1757
+#: rfc2131.c:1845
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr ""
 
-#: rfc2131.c:1766
+#: rfc2131.c:1854
 #, c-format
 msgid "%u server name: %s"
 msgstr ""
 
-#: rfc2131.c:1774
+#: rfc2131.c:1862
 #, c-format
 msgid "%u next server: %s"
 msgstr ""
 
-#: rfc2131.c:1777
+#: rfc2131.c:1865
 #, c-format
 msgid "%u broadcast response"
 msgstr ""
 
-#: rfc2131.c:1840
+#: rfc2131.c:1928
 #, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr ""
 
-#: rfc2131.c:2131
+#: rfc2131.c:2219
 msgid "PXE menu too large"
 msgstr ""
 
-#: rfc2131.c:2270 rfc3315.c:1515
+#: rfc2131.c:2358 rfc3315.c:1470
 #, c-format
 msgid "%u requested options: %s"
 msgstr ""
 
-#: rfc2131.c:2587
+#: rfc2131.c:2675
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr ""
 
-#: rfc2131.c:2650
+#: rfc2131.c:2738
 #, c-format
 msgid "%u reply delay: %d"
 msgstr ""
 
-#: netlink.c:77
+#: netlink.c:76
 #, c-format
 msgid "cannot create netlink socket: %s"
 msgstr ""
 
-#: netlink.c:355
+#: netlink.c:352
 #, c-format
 msgid "netlink returns error: %s"
 msgstr ""
 
-#: dbus.c:186
-msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
-msgstr ""
-
-#: dbus.c:439
+#: dbus.c:438
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:444
+#: dbus.c:443
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:690
+#: dbus.c:717
 msgid "setting upstream servers from DBus"
 msgstr ""
 
-#: dbus.c:737
+#: dbus.c:764
 msgid "could not register a DBus message handler"
 msgstr ""
 
-#: bpf.c:265
+#: bpf.c:261
 #, c-format
 msgid "cannot create DHCP BPF socket: %s"
 msgstr ""
 
-#: bpf.c:293
+#: bpf.c:289
 #, c-format
 msgid "DHCP request for unsupported hardware type (%d) received on %s"
 msgstr ""
 
-#: bpf.c:378
+#: bpf.c:374
 #, c-format
 msgid "cannot create PF_ROUTE socket: %s"
 msgstr ""
 
-#: bpf.c:399
+#: bpf.c:395
 msgid "Unknown protocol version from route socket"
 msgstr ""
 
-#: helper.c:154
+#: helper.c:150
 msgid "lease() function missing in Lua script"
 msgstr ""
 
-#: tftp.c:319
+#: tftp.c:347
 msgid "unable to get free port for TFTP"
 msgstr ""
 
-#: tftp.c:335
+#: tftp.c:363
 #, c-format
 msgid "unsupported request from %s"
 msgstr ""
 
-#: tftp.c:483
+#: tftp.c:510
 #, c-format
 msgid "file %s not found"
 msgstr ""
 
-#: tftp.c:592
+#: tftp.c:628
 #, c-format
-msgid "error %d %s received from %s"
+msgid "failed sending %s to %s"
 msgstr ""
 
-#: tftp.c:634
+#: tftp.c:628
 #, c-format
-msgid "failed sending %s to %s"
+msgid "sent %s to %s"
 msgstr ""
 
-#: tftp.c:634
+#: tftp.c:678
 #, c-format
-msgid "sent %s to %s"
+msgid "error %d %s received from %s"
 msgstr ""
 
 #: log.c:190
@@ -1944,7 +2043,7 @@ msgstr ""
 msgid "FAILED to start up"
 msgstr ""
 
-#: conntrack.c:65
+#: conntrack.c:63
 #, c-format
 msgid "Conntrack connection mark retrieval failed: %s"
 msgstr ""
@@ -1964,77 +2063,72 @@ msgstr ""
 msgid "failed to bind DHCPv6 server socket: %s"
 msgstr ""
 
-#: rfc3315.c:157
+#: rfc3315.c:173
 #, c-format
 msgid "no address range available for DHCPv6 request from relay at %s"
 msgstr ""
 
-#: rfc3315.c:166
+#: rfc3315.c:182
 #, c-format
 msgid "no address range available for DHCPv6 request via %s"
 msgstr ""
 
-#: rfc3315.c:303
+#: rfc3315.c:316
 #, c-format
 msgid "%u available DHCPv6 subnet: %s/%d"
 msgstr ""
 
-#: rfc3315.c:386
+#: rfc3315.c:399
 #, c-format
 msgid "%u vendor class: %u"
 msgstr ""
 
-#: rfc3315.c:434
+#: rfc3315.c:447
 #, c-format
 msgid "%u client MAC address: %s"
 msgstr ""
 
-#: rfc3315.c:673
-#, c-format
-msgid "unknown prefix-class %d"
-msgstr ""
-
-#: rfc3315.c:816 rfc3315.c:911
+#: rfc3315.c:762 rfc3315.c:859
 msgid "address unavailable"
 msgstr ""
 
-#: rfc3315.c:828 rfc3315.c:959 rfc3315.c:1292
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
 msgid "success"
 msgstr ""
 
-#: rfc3315.c:843 rfc3315.c:852 rfc3315.c:967 rfc3315.c:969
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
 msgid "no addresses available"
 msgstr ""
 
-#: rfc3315.c:946
+#: rfc3315.c:890
 msgid "not on link"
 msgstr ""
 
-#: rfc3315.c:1019 rfc3315.c:1204 rfc3315.c:1281
+#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
 msgid "no binding found"
 msgstr ""
 
-#: rfc3315.c:1057
+#: rfc3315.c:1002
 msgid "deprecated"
 msgstr ""
 
-#: rfc3315.c:1062
+#: rfc3315.c:1007
 msgid "address invalid"
 msgstr ""
 
-#: rfc3315.c:1109
+#: rfc3315.c:1057 rfc3315.c:1059
 msgid "confirm failed"
 msgstr ""
 
-#: rfc3315.c:1125
+#: rfc3315.c:1074
 msgid "all addresses still on link"
 msgstr ""
 
-#: rfc3315.c:1213
+#: rfc3315.c:1165
 msgid "release received"
 msgstr ""
 
-#: rfc3315.c:2140
+#: rfc3315.c:2130
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr ""
 
@@ -2048,76 +2142,76 @@ msgstr ""
 msgid "%u tags: %s"
 msgstr ""
 
-#: dhcp-common.c:407
+#: dhcp-common.c:444
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr ""
 
-#: dhcp-common.c:430
+#: dhcp-common.c:478
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr ""
 
-#: dhcp-common.c:491
+#: dhcp-common.c:542
 #, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr ""
 
-#: dhcp-common.c:612
+#: dhcp-common.c:665
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr ""
 
-#: dhcp-common.c:623
+#: dhcp-common.c:676
 #, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr ""
 
-#: dhcp-common.c:820
+#: dhcp-common.c:873
 msgid ", prefix deprecated"
 msgstr ""
 
-#: dhcp-common.c:823
+#: dhcp-common.c:876
 #, c-format
 msgid ", lease time "
 msgstr ""
 
-#: dhcp-common.c:865
+#: dhcp-common.c:918
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr ""
 
-#: dhcp-common.c:867
+#: dhcp-common.c:920
 #, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr ""
 
-#: dhcp-common.c:869
+#: dhcp-common.c:922
 #, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr ""
 
-#: dhcp-common.c:870
+#: dhcp-common.c:923
 #, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr ""
 
-#: dhcp-common.c:883
+#: dhcp-common.c:936
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr ""
 
-#: dhcp-common.c:886
+#: dhcp-common.c:939
 #, c-format
 msgid "router advertisement on %s%s"
 msgstr ""
 
-#: dhcp-common.c:897
+#: dhcp-common.c:950
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr ""
 
-#: dhcp-common.c:899
+#: dhcp-common.c:952
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr ""
@@ -2127,7 +2221,7 @@ msgstr ""
 msgid "cannot create ICMPv6 socket: %s"
 msgstr ""
 
-#: auth.c:449
+#: auth.c:439
 #, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr ""
@@ -2142,18 +2236,23 @@ msgstr ""
 msgid "failed to create IPset control socket: %s"
 msgstr ""
 
-#: ipset.c:233
+#: ipset.c:226
 #, c-format
 msgid "failed to update ipset %s: %s"
 msgstr ""
 
-#: dnssec.c:208
+#: dnssec.c:206
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
 msgstr ""
 
-#: blockdata.c:58
+#: dnssec.c:902
 #, c-format
-msgid "DNSSEC memory in use %u, max %u, allocated %u"
+msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
+msgstr ""
+
+#: blockdata.c:55
+#, c-format
+msgid "pool memory in use %u, max %u, allocated %u"
 msgstr ""
 
 #: tables.c:61
@@ -2185,12 +2284,12 @@ msgstr ""
 msgid "info: table created"
 msgstr ""
 
-#: tables.c:134
+#: tables.c:133
 #, c-format
 msgid "warning: DIOCR%sADDRS: %s"
 msgstr ""
 
-#: tables.c:138
+#: tables.c:137
 #, c-format
 msgid "%d addresses %s"
 msgstr ""
@@ -2229,3 +2328,62 @@ msgstr ""
 #, c-format
 msgid "inotify, new or changed file %s"
 msgstr ""
+
+#: dump.c:64
+#, c-format
+msgid "cannot create %s: %s"
+msgstr ""
+
+#: dump.c:70
+#, c-format
+msgid "bad header in %s"
+msgstr ""
+
+#: dump.c:201
+msgid "failed to write packet dump"
+msgstr ""
+
+#: dump.c:203
+#, c-format
+msgid "dumping UDP packet %u mask 0x%04x"
+msgstr ""
+
+#: ubus.c:52
+#, c-format
+msgid "UBus subscription callback: %s subscriber(s)"
+msgstr ""
+
+#: ubus.c:73
+#, c-format
+msgid "Cannot reconnect to UBus: %s"
+msgstr ""
+
+#: ubus.c:89
+msgid "Cannot initialize UBus: connection failed"
+msgstr ""
+
+#: ubus.c:102
+#, c-format
+msgid "Cannot add object to UBus: %s"
+msgstr ""
+
+#: ubus.c:112
+msgid "Connected to system UBus"
+msgstr ""
+
+#: ubus.c:122
+msgid "Cannot set UBus listeners: no connection"
+msgstr ""
+
+#: ubus.c:142
+msgid "Cannot poll UBus listeners: no connection"
+msgstr ""
+
+#: ubus.c:155
+msgid "Disconnecting from UBus"
+msgstr ""
+
+#: ubus.c:199
+#, c-format
+msgid "Failed to send UBus event: %s"
+msgstr ""
index 2718648..85d50d9 100644 (file)
--- a/po/no.po
+++ b/po/no.po
@@ -18,70 +18,70 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: cache.c:518
+#: cache.c:559
 msgid "Internal error in cache."
 msgstr ""
 
-#: cache.c:928
+#: cache.c:1081
 #, fuzzy, c-format
 msgid "failed to load names from %s: %s"
 msgstr "feilet å laste navn fra %s: %s"
 
-#: cache.c:954 dhcp.c:867
+#: cache.c:1103 dhcp.c:927
 #, c-format
 msgid "bad address at %s line %d"
 msgstr "dårlig adresse ved %s linje %d"
 
-#: cache.c:1007 dhcp.c:883
+#: cache.c:1156 dhcp.c:943
 #, c-format
 msgid "bad name at %s line %d"
 msgstr "dårlig navn ved %s linje %d"
 
-#: cache.c:1016 dhcp.c:958
+#: cache.c:1167 dhcp.c:1018
 #, c-format
 msgid "read %s - %d addresses"
 msgstr "les %s - %d adresser"
 
-#: cache.c:1129
+#: cache.c:1283
 msgid "cleared cache"
 msgstr "mellomlager tømt"
 
-#: cache.c:1158
+#: cache.c:1345
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr ""
 
-#: cache.c:1237
+#: cache.c:1391
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr ""
 
-#: cache.c:1261
+#: cache.c:1415
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr "gir ikke navnet %s til DHCP leien for %s fordi navnet eksisterer i %s med adressen %s"
 
-#: cache.c:1418
+#: cache.c:1663
 #, c-format
 msgid "time %lu"
 msgstr ""
 
-#: cache.c:1419
+#: cache.c:1664
 #, fuzzy, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr "mellomlager størrelse %d, %d/%d mellomlager innsettinger re-bruker mellomlager plasser som ikke er utløpt"
 
-#: cache.c:1421
+#: cache.c:1666
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr ""
 
-#: cache.c:1424
+#: cache.c:1669
 #, c-format
 msgid "queries for authoritative zones %u"
 msgstr ""
 
-#: cache.c:1450
+#: cache.c:1694
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr ""
@@ -96,687 +96,724 @@ msgstr "feilet 
 msgid "failed to allocate memory"
 msgstr "feilet å laste %d bytes"
 
-#: util.c:281 option.c:619
+#: util.c:281 option.c:641
 msgid "could not get memory"
 msgstr "kunne ikke få minne"
 
-#: util.c:291
+#: util.c:302
 #, fuzzy, c-format
 msgid "cannot create pipe: %s"
 msgstr "kan ikke lese %s: %s"
 
-#: util.c:299
+#: util.c:310
 #, fuzzy, c-format
 msgid "failed to allocate %d bytes"
 msgstr "feilet å laste %d bytes"
 
-#: util.c:468
+#: util.c:506
 #, c-format
 msgid "infinite"
 msgstr "uendelig"
 
-#: option.c:344
+#: option.c:358
 msgid "Specify local address(es) to listen on."
 msgstr "Spesifiser lokal(e) adresse(r) å lytte på."
 
-#: option.c:345
+#: option.c:359
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr "Returner ipaddr for alle verter i det spesifiserte domenet."
 
-#: option.c:346
+#: option.c:360
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr "Forfalsk revers oppslag for RFC1918 private adresse områder."
 
-#: option.c:347
+#: option.c:361
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr "Behandle ipaddr som NXDOMAIN (omgår Verisign wildcard)."
 
-#: option.c:348
+#: option.c:362
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr "Spesifiser størrelsen på mellomlager plassene (standard er %s)."
 
-#: option.c:349
+#: option.c:363
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr "Spesifiser konfigurasjonsfil (standard er %s)."
 
-#: option.c:350
+#: option.c:364
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr "IKKE legg (fork) som bakgrunnsprosess: kjør i debug modus."
 
-#: option.c:351
+#: option.c:365
 msgid "Do NOT forward queries with no domain part."
 msgstr "IKKE videresend oppslag som mangler domene del."
 
-#: option.c:352
+#: option.c:366
 msgid "Return self-pointing MX records for local hosts."
 msgstr "Returner selv-pekende MX post for lokale verter."
 
-#: option.c:353
+#: option.c:367
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr "Utvid enkle navn i /etc/hosts med domene-suffiks."
 
-#: option.c:354
+#: option.c:368
 msgid "Don't forward spurious DNS requests from Windows hosts."
 msgstr "Ikke videresend falske/uekte DNS forespørsler fra Windows verter."
 
-#: option.c:355
+#: option.c:369
 msgid "Enable DHCP in the range given with lease duration."
 msgstr "Aktiver DHCP i det gitte området med leie varighet"
 
-#: option.c:356
+#: option.c:370
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr "Skift til denne gruppen etter oppstart (standard er %s)."
 
-#: option.c:357
+#: option.c:371
 msgid "Set address or hostname for a specified machine."
 msgstr "Sett adresse eller vertsnavn for en spesifikk maskin."
 
-#: option.c:358
+#: option.c:372
 #, fuzzy
 msgid "Read DHCP host specs from file."
 msgstr "dårlig MX navn"
 
-#: option.c:359
+#: option.c:373
 msgid "Read DHCP option specs from file."
 msgstr ""
 
-#: option.c:360
+#: option.c:374
 #, fuzzy
 msgid "Read DHCP host specs from a directory."
 msgstr "dårlig MX navn"
 
-#: option.c:361
+#: option.c:375
 #, fuzzy
 msgid "Read DHCP options from a directory."
 msgstr "dårlig MX navn"
 
-#: option.c:362
+#: option.c:376
 msgid "Evaluate conditional tag expression."
 msgstr ""
 
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Do NOT load %s file."
 msgstr "IKKE last %s filen."
 
-#: option.c:364
+#: option.c:378
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr "Spesifiser en verts (hosts) fil som skal leses i tilleg til %s."
 
-#: option.c:365
+#: option.c:379
 #, fuzzy
 msgid "Read hosts files from a directory."
 msgstr "dårlig MX navn"
 
-#: option.c:366
+#: option.c:380
 msgid "Specify interface(s) to listen on."
 msgstr "Spesifiser nettverkskort det skal lyttes på."
 
-#: option.c:367
+#: option.c:381
 msgid "Specify interface(s) NOT to listen on."
 msgstr "Spesifiser nettverkskort det IKKE skal lyttes på."
 
-#: option.c:368
+#: option.c:382
 #, fuzzy
 msgid "Map DHCP user class to tag."
 msgstr "Map DHCP bruker klasse til opsjon sett."
 
-#: option.c:369
+#: option.c:383
 msgid "Map RFC3046 circuit-id to tag."
 msgstr ""
 
-#: option.c:370
+#: option.c:384
 msgid "Map RFC3046 remote-id to tag."
 msgstr ""
 
-#: option.c:371
+#: option.c:385
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr ""
 
-#: option.c:372
+#: option.c:386
 #, fuzzy
 msgid "Don't do DHCP for hosts with tag set."
 msgstr "Ikke utfør DHCP for klienter i opsjon sett."
 
-#: option.c:373
+#: option.c:387
 #, fuzzy
 msgid "Force broadcast replies for hosts with tag set."
 msgstr "Ikke utfør DHCP for klienter i opsjon sett."
 
-#: option.c:374
+#: option.c:388
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr "IKKE last (fork) som bakgrunnsprosess, IKKE kjør i debug modus."
 
-#: option.c:375
+#: option.c:389
 msgid "Assume we are the only DHCP server on the local network."
 msgstr "Anta at vi er den eneste DHCP tjeneren på det lokale nettverket."
 
-#: option.c:376
+#: option.c:390
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr "Spesifiser hvor DHCP leiene skal lagres (standard er %s)."
 
-#: option.c:377
+#: option.c:391
 msgid "Return MX records for local hosts."
 msgstr "Returner MX records for lokale verter."
 
-#: option.c:378
+#: option.c:392
 msgid "Specify an MX record."
 msgstr "Spesifiser en MX post."
 
-#: option.c:379
+#: option.c:393
 msgid "Specify BOOTP options to DHCP server."
 msgstr "Spesifiser BOOTP opsjoner til DHCP tjener."
 
-#: option.c:380
+#: option.c:394
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr "IKKE spør (poll) %s fil, les på nytt kun ved SIGHUP"
 
-#: option.c:381
+#: option.c:395
 msgid "Do NOT cache failed search results."
 msgstr "IKKE mellomlagre søkeresultater som feiler."
 
-#: option.c:382
+#: option.c:396
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr "Bruk navnetjenere kun som bestemt i rekkefølgen gitt i %s."
 
-#: option.c:383
+#: option.c:397
 #, fuzzy
 msgid "Specify options to be sent to DHCP clients."
 msgstr "Sett ekstra opsjoner som skal fordeles til DHCP klientene."
 
-#: option.c:384
+#: option.c:398
 msgid "DHCP option sent even if the client does not request it."
 msgstr ""
 
-#: option.c:385
+#: option.c:399
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr "Spesifiser lytteport for DNS oppslag (standard er 53)."
 
-#: option.c:386
+#: option.c:400
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr "Maksimal støttet UDP pakkestørrelse for EDNS.0 (standard er %s)."
 
-#: option.c:387
+#: option.c:401
 #, fuzzy
 msgid "Log DNS queries."
 msgstr "Logg oppslag."
 
-#: option.c:388
+#: option.c:402
 #, fuzzy
 msgid "Force the originating port for upstream DNS queries."
 msgstr "Tving bruk av opprinnelig port for oppstrøms oppslag."
 
-#: option.c:389
+#: option.c:403
 msgid "Do NOT read resolv.conf."
 msgstr "IKKE les resolv.conf."
 
-#: option.c:390
+#: option.c:404
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr "Spesifiser stien til resolv.conf (standard er %s)."
 
-#: option.c:391
+#: option.c:405
 #, fuzzy
 msgid "Specify path to file with server= options"
 msgstr "Spesifiser stien til PID fil. (standard er %s)."
 
-#: option.c:392
+#: option.c:406
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr "Spesifiser adressen(e) til oppstrøms tjenere med valgfrie domener."
 
-#: option.c:393
+#: option.c:407
 #, fuzzy
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr "Spesifiser adressen(e) til oppstrøms tjenere med valgfrie domener."
 
-#: option.c:394
+#: option.c:408
 msgid "Never forward queries to specified domains."
 msgstr "Aldri videresend oppslag til spesifiserte domener."
 
-#: option.c:395
+#: option.c:409
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr "Spesifiser domenet som skal tildeles i DHCP leien."
 
-#: option.c:396
+#: option.c:410
 msgid "Specify default target in an MX record."
 msgstr "Spesifiser default mål i en MX post."
 
-#: option.c:397
+#: option.c:411
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr "Spesifiser time-to-live i sekunder for svar fra /etc/hosts."
 
-#: option.c:398
+#: option.c:412
 #, fuzzy
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr "Spesifiser time-to-live i sekunder for svar fra /etc/hosts."
 
-#: option.c:399
+#: option.c:413
 #, fuzzy
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr "Spesifiser time-to-live i sekunder for svar fra /etc/hosts."
 
-#: option.c:400
+#: option.c:414
 #, fuzzy
 msgid "Specify time-to-live ceiling for cache."
 msgstr "Spesifiser time-to-live i sekunder for svar fra /etc/hosts."
 
-#: option.c:401
+#: option.c:415
 #, fuzzy
 msgid "Specify time-to-live floor for cache."
 msgstr "Spesifiser time-to-live i sekunder for svar fra /etc/hosts."
 
-#: option.c:402
+#: option.c:416
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr "Skift til denne bruker etter oppstart (standard er %s)."
 
-#: option.c:403
+#: option.c:417
 #, fuzzy
 msgid "Map DHCP vendor class to tag."
 msgstr "Map DHCP produsent klasse til opsjon sett."
 
-#: option.c:404
+#: option.c:418
 msgid "Display dnsmasq version and copyright information."
 msgstr "Vis dnsmasq versjon og copyright informasjon."
 
-#: option.c:405
+#: option.c:419
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr "Oversett IPv4 adresser fra oppstrøms tjenere."
 
-#: option.c:406
+#: option.c:420
 msgid "Specify a SRV record."
 msgstr "Spesifiser en SRV post."
 
-#: option.c:407
+#: option.c:421
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr ""
 
-#: option.c:408
+#: option.c:422
 #, fuzzy, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr "Spesifiser stien til PID fil. (standard er %s)."
 
-#: option.c:409
+#: option.c:423
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr "Spesifiser maksimum antall DHCP leier (standard er %s)"
 
-#: option.c:410
+#: option.c:424
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr "Svar DNS oppslag basert på nettverkskortet oppslaget ble sendt til."
 
-#: option.c:411
+#: option.c:425
 msgid "Specify TXT DNS record."
 msgstr "Spesifiser TXT DNS post."
 
-#: option.c:412
+#: option.c:426
 #, fuzzy
 msgid "Specify PTR DNS record."
 msgstr "Spesifiser TXT DNS post."
 
-#: option.c:413
+#: option.c:427
 msgid "Give DNS name to IPv4 address of interface."
 msgstr ""
 
-#: option.c:414
+#: option.c:428
 msgid "Bind only to interfaces in use."
 msgstr "Bind kun til nettverkskort som er i bruk."
 
-#: option.c:415
+#: option.c:429
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr "Les DHCP statisk vert informasjon fra %s."
 
-#: option.c:416
+#: option.c:430
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr "Aktiver DBus interface for å sette oppstrøms tjenere, osv."
 
-#: option.c:417
+#: option.c:431
+msgid "Enable the UBus interface."
+msgstr ""
+
+#: option.c:432
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr "Ikke lever DHCP på dette nettverkskortet, kun lever DNS."
 
-#: option.c:418
+#: option.c:433
 msgid "Enable dynamic address allocation for bootp."
 msgstr "Aktiver dynamisk adresse allokering for bootp."
 
-#: option.c:419
+#: option.c:434
 #, fuzzy
 msgid "Map MAC address (with wildcards) to option set."
 msgstr "Map DHCP produsent klasse til opsjon sett."
 
-#: option.c:420
+#: option.c:435
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr ""
 
-#: option.c:421
+#: option.c:436
+msgid "Specify extra networks sharing a broadcast domain for DHCP"
+msgstr ""
+
+#: option.c:437
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr ""
 
-#: option.c:422
+#: option.c:438
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:423
+#: option.c:439
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:424
+#: option.c:440
 msgid "Run lease-change scripts as this user."
 msgstr ""
 
-#: option.c:425
+#: option.c:441
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr ""
 
-#: option.c:426
+#: option.c:442
 msgid "Read configuration from all the files in this directory."
 msgstr ""
 
-#: option.c:427
+#: option.c:443
 #, fuzzy
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr "Skift til denne bruker etter oppstart (standard er %s)."
 
-#: option.c:428
+#: option.c:444
 msgid "Do not use leasefile."
 msgstr ""
 
-#: option.c:429
+#: option.c:445
 #, fuzzy, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr "Spesifiser maksimum antall DHCP leier (standard er %s)"
 
-#: option.c:430
+#: option.c:446
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr ""
 
-#: option.c:431
+#: option.c:447
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr ""
 
-#: option.c:432
+#: option.c:448
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr ""
 
-#: option.c:433
+#: option.c:449
 msgid "Enable integrated read-only TFTP server."
 msgstr ""
 
-#: option.c:434
+#: option.c:450
 msgid "Export files by TFTP only from the specified subtree."
 msgstr ""
 
-#: option.c:435
+#: option.c:451
 msgid "Add client IP or hardware address to tftp-root."
 msgstr ""
 
-#: option.c:436
+#: option.c:452
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr ""
 
-#: option.c:437
+#: option.c:453
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr ""
 
-#: option.c:438
+#: option.c:454
 #, fuzzy, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr "Spesifiser maksimum antall DHCP leier (standard er %s)"
 
-#: option.c:439
+#: option.c:455
 #, fuzzy
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr "Spesifiser maksimum antall DHCP leier (standard er %s)"
 
-#: option.c:440
+#: option.c:456
 msgid "Disable the TFTP blocksize extension."
 msgstr ""
 
-#: option.c:441
+#: option.c:457
 msgid "Convert TFTP filenames to lowercase"
 msgstr ""
 
-#: option.c:442
+#: option.c:458
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr ""
 
-#: option.c:443
+#: option.c:459
+msgid "Use only one port for TFTP server."
+msgstr ""
+
+#: option.c:460
 msgid "Extra logging for DHCP."
 msgstr ""
 
-#: option.c:444
+#: option.c:461
 msgid "Enable async. logging; optionally set queue length."
 msgstr ""
 
-#: option.c:445
+#: option.c:462
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr ""
 
-#: option.c:446
+#: option.c:463
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr ""
 
-#: option.c:447
+#: option.c:464
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr ""
 
-#: option.c:448
+#: option.c:465
 msgid "Always perform DNS queries to all servers."
 msgstr ""
 
-#: option.c:449
+#: option.c:466
 msgid "Set tag if client includes matching option in request."
 msgstr ""
 
-#: option.c:450
+#: option.c:467
+msgid "Set tag if client provides given name."
+msgstr ""
+
+#: option.c:468
 msgid "Use alternative ports for DHCP."
 msgstr ""
 
-#: option.c:451
+#: option.c:469
 #, fuzzy
 msgid "Specify NAPTR DNS record."
 msgstr "Spesifiser TXT DNS post."
 
-#: option.c:452
+#: option.c:470
 msgid "Specify lowest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:453
+#: option.c:471
 msgid "Specify highest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:454
+#: option.c:472
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr ""
 
-#: option.c:455
+#: option.c:473
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr ""
 
-#: option.c:456
+#: option.c:474
 msgid "Use these DHCP relays as full proxies."
 msgstr ""
 
-#: option.c:457
+#: option.c:475
 msgid "Relay DHCP requests to a remote server"
 msgstr ""
 
-#: option.c:458
+#: option.c:476
 msgid "Specify alias name for LOCAL DNS name."
 msgstr ""
 
-#: option.c:459
+#: option.c:477
 #, fuzzy
 msgid "Prompt to send to PXE clients."
 msgstr "Sett ekstra opsjoner som skal fordeles til DHCP klientene."
 
-#: option.c:460
+#: option.c:478
 msgid "Boot service for PXE menu."
 msgstr ""
 
-#: option.c:461
+#: option.c:479
 msgid "Check configuration syntax."
 msgstr ""
 
-#: option.c:462
+#: option.c:480
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr ""
 
-#: option.c:463
+#: option.c:481
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr ""
 
-#: option.c:464
+#: option.c:482
 #, fuzzy
 msgid "Add client identification to forwarded DNS queries."
 msgstr "Tving bruk av opprinnelig port for oppstrøms oppslag."
 
-#: option.c:465
+#: option.c:483
 #, fuzzy
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr "Oversett IPv4 adresser fra oppstrøms tjenere."
 
-#: option.c:466
+#: option.c:484
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr ""
 
-#: option.c:467
+#: option.c:485
+#, fuzzy
+msgid "Ignore client identifier option sent by DHCP clients."
+msgstr "Sett ekstra opsjoner som skal fordeles til DHCP klientene."
+
+#: option.c:486
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr ""
 
-#: option.c:468
+#: option.c:487
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr ""
 
-#: option.c:469
+#: option.c:488
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr ""
 
-#: option.c:470
+#: option.c:489
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr ""
 
-#: option.c:471
+#: option.c:490
 #, fuzzy
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr "Spesifiser en MX post."
 
-#: option.c:472
+#: option.c:491
+msgid "Specify certification authority authorization record"
+msgstr ""
+
+#: option.c:492
 #, fuzzy
 msgid "Specify arbitrary DNS resource record"
 msgstr "Spesifiser TXT DNS post."
 
-#: option.c:473
+#: option.c:493
 #, fuzzy
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr "ukjent tilknytning (interface) %s"
 
-#: option.c:474
+#: option.c:494
 msgid "Export local names to global DNS"
 msgstr ""
 
-#: option.c:475
+#: option.c:495
 msgid "Domain to export to global DNS"
 msgstr ""
 
-#: option.c:476
+#: option.c:496
 msgid "Set TTL for authoritative replies"
 msgstr ""
 
-#: option.c:477
+#: option.c:497
 msgid "Set authoritative zone information"
 msgstr ""
 
-#: option.c:478
+#: option.c:498
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr ""
 
-#: option.c:479
+#: option.c:499
 msgid "Peers which are allowed to do zone transfer"
 msgstr ""
 
-#: option.c:480
+#: option.c:500
 msgid "Specify ipsets to which matching domains should be added"
 msgstr ""
 
-#: option.c:481
+#: option.c:501
 msgid "Specify a domain and address range for synthesised names"
 msgstr ""
 
-#: option.c:482
+#: option.c:502
 msgid "Activate DNSSEC validation"
 msgstr ""
 
-#: option.c:483
+#: option.c:503
 msgid "Specify trust anchor key digest."
 msgstr ""
 
-#: option.c:484
+#: option.c:504
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr ""
 
-#: option.c:485
+#: option.c:505
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr ""
 
-#: option.c:486
+#: option.c:506
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr ""
 
-#: option.c:487
+#: option.c:507
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr ""
 
-#: option.c:489
-msgid "Specify DHCPv6 prefix class"
-msgstr ""
-
-#: option.c:491
+#: option.c:508
 msgid "Set MTU, priority, resend-interval and router-lifetime"
 msgstr ""
 
-#: option.c:492
+#: option.c:509
 msgid "Do not log routine DHCP."
 msgstr ""
 
-#: option.c:493
+#: option.c:510
 msgid "Do not log routine DHCPv6."
 msgstr ""
 
-#: option.c:494
+#: option.c:511
 msgid "Do not log RA."
 msgstr ""
 
-#: option.c:495
+#: option.c:512
 msgid "Accept queries only from directly-connected networks."
 msgstr ""
 
-#: option.c:496
+#: option.c:513
 msgid "Detect and remove DNS forwarding loops."
 msgstr ""
 
-#: option.c:497
+#: option.c:514
 msgid "Ignore DNS responses containing ipaddr."
 msgstr ""
 
-#: option.c:498
+#: option.c:515
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr ""
 
-#: option.c:499
+#: option.c:516
 msgid "Delay DHCP replies for at least number of seconds."
 msgstr ""
 
-#: option.c:703
+#: option.c:517
+msgid "Enables DHCPv4 Rapid Commit option."
+msgstr ""
+
+#: option.c:518
+msgid "Path to debug packet dump file"
+msgstr ""
+
+#: option.c:519
+msgid "Mask which packets to dump"
+msgstr ""
+
+#: option.c:520
+msgid "Call dhcp-script when lease expiry changes."
+msgstr ""
+
+#: option.c:725
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
@@ -785,341 +822,356 @@ msgstr ""
 "Bruk: dnsmasq [opsjoner]\n"
 "\n"
 
-#: option.c:705
+#: option.c:727
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr "Bruk korte opsjoner kun på kommandolinjen.\n"
 
-#: option.c:707
+#: option.c:729
 #, fuzzy, c-format
 msgid "Valid options are:\n"
 msgstr "Gyldige opsjoner er :\n"
 
-#: option.c:754 option.c:868
+#: option.c:776 option.c:884
 #, fuzzy
 msgid "bad address"
 msgstr "les %s - %d adresser"
 
-#: option.c:779 option.c:783
+#: option.c:799 option.c:803
 msgid "bad port"
 msgstr "dårlig port"
 
-#: option.c:797 option.c:826 option.c:861
+#: option.c:815 option.c:844 option.c:878
 msgid "interface binding not supported"
 msgstr ""
 
-#: option.c:821 option.c:856
+#: option.c:839 option.c:873
 msgid "interface can only be specified once"
 msgstr ""
 
-#: option.c:835 option.c:3809
+#: option.c:852 option.c:4042
 #, fuzzy
 msgid "bad interface name"
 msgstr "dårlig MX navn"
 
-#: option.c:1062
+#: option.c:1184
 msgid "unsupported encapsulation for IPv6 option"
 msgstr ""
 
-#: option.c:1076
+#: option.c:1198
 msgid "bad dhcp-option"
 msgstr "dårlig dhcp-opsjon"
 
-#: option.c:1144
+#: option.c:1270
 #, fuzzy
 msgid "bad IP address"
 msgstr "les %s - %d adresser"
 
-#: option.c:1147 option.c:1286 option.c:3079
+#: option.c:1273 option.c:1412 option.c:3297
 #, fuzzy
 msgid "bad IPv6 address"
 msgstr "les %s - %d adresser"
 
-#: option.c:1240
+#: option.c:1366
 #, fuzzy
 msgid "bad IPv4 address"
 msgstr "les %s - %d adresser"
 
-#: option.c:1313 option.c:1407
+#: option.c:1439 option.c:1533
 msgid "bad domain in dhcp-option"
 msgstr "dårlig domene i dhcp-opsjon"
 
-#: option.c:1445
+#: option.c:1571
 msgid "dhcp-option too long"
 msgstr "dhcp-opsjon for lang"
 
-#: option.c:1452
+#: option.c:1578
 msgid "illegal dhcp-match"
 msgstr ""
 
-#: option.c:1514
+#: option.c:1647
 msgid "illegal repeated flag"
 msgstr ""
 
-#: option.c:1522
+#: option.c:1655
 msgid "illegal repeated keyword"
 msgstr ""
 
-#: option.c:1593 option.c:4443
+#: option.c:1726 option.c:4764
 #, fuzzy, c-format
 msgid "cannot access directory %s: %s"
 msgstr "kan ikke lese %s: %s"
 
-#: option.c:1639 tftp.c:537
+#: option.c:1772 tftp.c:564 dump.c:68
 #, fuzzy, c-format
 msgid "cannot access %s: %s"
 msgstr "kan ikke lese %s: %s"
 
-#: option.c:1727
+#: option.c:1879
 msgid "setting log facility is not possible under Android"
 msgstr ""
 
-#: option.c:1736
+#: option.c:1888
 msgid "bad log facility"
 msgstr ""
 
-#: option.c:1789
+#: option.c:1941
 msgid "bad MX preference"
 msgstr "dårlig MX preferanse"
 
-#: option.c:1794
+#: option.c:1946
 msgid "bad MX name"
 msgstr "dårlig MX navn"
 
-#: option.c:1808
+#: option.c:1960
 msgid "bad MX target"
 msgstr "dårlig MX mål"
 
-#: option.c:1820
-msgid "cannot run scripts under uClinux"
-msgstr ""
-
-#: option.c:1822
+#: option.c:1980
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr ""
 
-#: option.c:1826
+#: option.c:1984
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr ""
 
-#: option.c:2095 option.c:2106 option.c:2143 option.c:2199 option.c:2482
+#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
 #, fuzzy
 msgid "bad prefix"
 msgstr "dårlig port"
 
-#: option.c:2504
+#: option.c:2658
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr ""
 
-#: option.c:2713
+#: option.c:2871
 #, fuzzy
 msgid "bad port range"
 msgstr "dårlig port"
 
-#: option.c:2739
+#: option.c:2897
 msgid "bad bridge-interface"
 msgstr ""
 
-#: option.c:2807
+#: option.c:2941
+msgid "bad shared-network"
+msgstr ""
+
+#: option.c:2996
 msgid "only one tag allowed"
 msgstr ""
 
-#: option.c:2827 option.c:2839 option.c:2948 option.c:2953 option.c:2992
+#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
 msgid "bad dhcp-range"
 msgstr "dårlig dhcp-område"
 
-#: option.c:2854
+#: option.c:3050
 msgid "inconsistent DHCP range"
 msgstr "ikke konsistent DHCP område"
 
-#: option.c:2916
+#: option.c:3115
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr ""
 
-#: option.c:2918
+#: option.c:3117
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr ""
 
-#: option.c:2922
+#: option.c:3120
 msgid "prefix length must be at least 64"
 msgstr ""
 
-#: option.c:2925
+#: option.c:3123
 #, fuzzy
 msgid "inconsistent DHCPv6 range"
 msgstr "ikke konsistent DHCP område"
 
-#: option.c:2936
+#: option.c:3142
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr ""
 
-#: option.c:3049 option.c:3097
+#: option.c:3262 option.c:3340
 #, fuzzy
 msgid "bad hex constant"
 msgstr "dårlig dhcp-vert"
 
-#: option.c:3071
-msgid "cannot match tags in --dhcp-host"
-msgstr ""
+#: option.c:3315
+#, fuzzy
+msgid "bad IPv6 prefix"
+msgstr "dårlig port"
 
-#: option.c:3119
+#: option.c:3362
 #, fuzzy, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr "dubliserte IP adresser i %s dhcp-config direktiv."
 
-#: option.c:3177
+#: option.c:3422
 #, fuzzy
 msgid "bad DHCP host name"
 msgstr "dårlig MX navn"
 
-#: option.c:3259
+#: option.c:3508
 #, fuzzy
 msgid "bad tag-if"
 msgstr "dårlig MX mål"
 
-#: option.c:3616 option.c:4039
+#: option.c:3851 option.c:4324
 msgid "invalid port number"
 msgstr "ugyldig portnummer"
 
-#: option.c:3678
+#: option.c:3907
 #, fuzzy
 msgid "bad dhcp-proxy address"
 msgstr "les %s - %d adresser"
 
-#: option.c:3704
+#: option.c:3935
 #, fuzzy
 msgid "Bad dhcp-relay"
 msgstr "dårlig dhcp-område"
 
-#: option.c:3745
+#: option.c:3979
 msgid "bad RA-params"
 msgstr ""
 
-#: option.c:3754
+#: option.c:3989
 msgid "bad DUID"
 msgstr ""
 
-#: option.c:3796
+#: option.c:4023
+#, fuzzy
+msgid "missing address in alias"
+msgstr "adresse i bruk"
+
+#: option.c:4029
 #, fuzzy
 msgid "invalid alias range"
 msgstr "ugyldig vekt"
 
-#: option.c:3850 option.c:3862
+#: option.c:4081 option.c:4097
 msgid "bad CNAME"
 msgstr ""
 
-#: option.c:3866
+#: option.c:4105
 msgid "duplicate CNAME"
 msgstr ""
 
-#: option.c:3889
+#: option.c:4132
 #, fuzzy
 msgid "bad PTR record"
 msgstr "dårlig SRV post"
 
-#: option.c:3920
+#: option.c:4167
 #, fuzzy
 msgid "bad NAPTR record"
 msgstr "dårlig SRV post"
 
-#: option.c:3954
+#: option.c:4203
 #, fuzzy
 msgid "bad RR record"
 msgstr "dårlig SRV post"
 
-#: option.c:3984
+#: option.c:4236
+#, fuzzy
+msgid "bad CAA record"
+msgstr "dårlig SRV post"
+
+#: option.c:4265
 msgid "bad TXT record"
 msgstr "dårlig TXT post"
 
-#: option.c:4025
+#: option.c:4308
 msgid "bad SRV record"
 msgstr "dårlig SRV post"
 
-#: option.c:4032
+#: option.c:4315
 msgid "bad SRV target"
 msgstr "dårlig SRV mål"
 
-#: option.c:4046
+#: option.c:4334
 msgid "invalid priority"
 msgstr "ugyldig prioritet"
 
-#: option.c:4049
+#: option.c:4339
 msgid "invalid weight"
 msgstr "ugyldig vekt"
 
-#: option.c:4073
+#: option.c:4362
 #, fuzzy
 msgid "Bad host-record"
 msgstr "dårlig SRV post"
 
-#: option.c:4097
+#: option.c:4402
 #, fuzzy
 msgid "Bad name in host-record"
 msgstr "dårlig navn i %s"
 
-#: option.c:4162
+#: option.c:4444
+msgid "bad value for dnssec-check-unsigned"
+msgstr ""
+
+#: option.c:4480
 #, fuzzy
 msgid "bad trust anchor"
 msgstr "dårlig port"
 
-#: option.c:4176
+#: option.c:4496
 msgid "bad HEX in trust anchor"
 msgstr ""
 
-#: option.c:4186
+#: option.c:4507
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr ""
 
-#: option.c:4246
+#: option.c:4567
 msgid "missing \""
 msgstr "mangler \""
 
-#: option.c:4303
+#: option.c:4624
 msgid "bad option"
 msgstr "dårlig opsjon"
 
-#: option.c:4305
+#: option.c:4626
 msgid "extraneous parameter"
 msgstr "overflødig parameter"
 
-#: option.c:4307
+#: option.c:4628
 msgid "missing parameter"
 msgstr "mangler parameter"
 
-#: option.c:4309
+#: option.c:4630
 #, fuzzy
 msgid "illegal option"
 msgstr "dårlig opsjon"
 
-#: option.c:4316
+#: option.c:4637
 msgid "error"
 msgstr "feil"
 
-#: option.c:4318
+#: option.c:4639
 #, fuzzy, c-format
 msgid " at line %d of %s"
 msgstr "%s på linje %d av %%s"
 
-#: option.c:4333 option.c:4580 option.c:4616
+#: option.c:4654 option.c:4939 option.c:4950
 #, fuzzy, c-format
 msgid "read %s"
 msgstr "leser %s"
 
-#: option.c:4396 option.c:4519 tftp.c:715
+#: option.c:4717 option.c:4840 tftp.c:754
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "kan ikke lese %s: %s"
 
-#: option.c:4688
+#: option.c:5027
 msgid "junk found in command line"
 msgstr ""
 
-#: option.c:4729
+#: option.c:5067
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr "Dnsmasq versjon %s %s\n"
 
-#: option.c:4730
+#: option.c:5068
 #, fuzzy, c-format
 msgid ""
 "Compile time options: %s\n"
@@ -1128,507 +1180,559 @@ msgstr ""
 "Kompileringsopsjoner %s\n"
 "\n"
 
-#: option.c:4731
+#: option.c:5069
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr "Denne programvaren kommer med ABSOLUTT INGEN GARANTI.\n"
 
-#: option.c:4732
+#: option.c:5070
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr "DNsmasq er fri programvare, du er velkommen til å redistribuere den\n"
 
-#: option.c:4733
+#: option.c:5071
 #, fuzzy, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr "under vilkårene gitt i GNU General Public License, versjon 2.\n"
 
-#: option.c:4744
+#: option.c:5088
 msgid "try --help"
 msgstr ""
 
-#: option.c:4746
+#: option.c:5090
 msgid "try -w"
 msgstr ""
 
-#: option.c:4748
+#: option.c:5092
 #, fuzzy, c-format
 msgid "bad command line options: %s"
 msgstr "dårlige kommandlinje opsjoner: %s."
 
-#: option.c:4818
+#: option.c:5161
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr ""
 
-#: option.c:4854
+#: option.c:5195
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr "klarer ikke å få vertsnavn: %s"
 
-#: option.c:4882
+#: option.c:5223
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr "kun en resolv.conf fil tillat i no-poll modus."
 
-#: option.c:4892
+#: option.c:5233
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr "må ha nøyaktig en resolv.conf å lese domene fra."
 
-#: option.c:4895 network.c:1623 dhcp.c:816
+#: option.c:5236 network.c:1594 dhcp.c:876
 #, fuzzy, c-format
 msgid "failed to read %s: %s"
 msgstr "feilet å lese %s: %s"
 
-#: option.c:4912
+#: option.c:5253
 #, c-format
 msgid "no search directive found in %s"
 msgstr "intet søke direktiv funnet i %s"
 
-#: option.c:4933
+#: option.c:5274
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr ""
 
-#: option.c:4942
+#: option.c:5283
 msgid "syntax check OK"
 msgstr ""
 
-#: forward.c:102
+#: forward.c:99
 #, fuzzy, c-format
 msgid "failed to send packet: %s"
 msgstr "feilet å lytte på socket: %s"
 
-#: forward.c:598
+#: forward.c:614
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr ""
 
-#: forward.c:652
+#: forward.c:677
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr "navnetjener %s nektet å gjøre et rekursivt oppslag"
 
-#: forward.c:684
+#: forward.c:709
 #, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr ""
 
-#: forward.c:870
+#: forward.c:961
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
 msgstr ""
 
-#: forward.c:1266 forward.c:1704
+#: forward.c:1370 forward.c:1830
 msgid "Ignoring query from non-local network"
 msgstr ""
 
-#: forward.c:2184
+#: forward.c:2321
 #, fuzzy, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr "Spesifiser maksimum antall DHCP leier (standard er %s)"
 
-#: network.c:720
+#: network.c:698
 #, fuzzy, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr "feilet å lage lytte socket: %s"
 
-#: network.c:1031
+#: network.c:1002
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr ""
 
-#: network.c:1038
+#: network.c:1009
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr ""
 
-#: network.c:1047
+#: network.c:1018
 #, fuzzy, c-format
 msgid "warning: using interface %s instead"
 msgstr "advarsel: nettverkskort %s eksisterer ikke for tiden"
 
-#: network.c:1056
+#: network.c:1027
 #, fuzzy, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr "benytter lokale adresser kun for %s %s"
 
-#: network.c:1114
+#: network.c:1085
 #, fuzzy, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr "feilet å binde DHCP tjener socket: %s"
 
-#: network.c:1119
+#: network.c:1090
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr ""
 
-#: network.c:1337
+#: network.c:1307
 #, fuzzy, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr "feilet å binde lytte socket for %s: %s"
 
-#: network.c:1528
+#: network.c:1499
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr "ignorerer navnetjener %s - lokal tilknytning"
 
-#: network.c:1539
+#: network.c:1510
 #, fuzzy, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr "ignorerer navnetjener %s - kan ikke lage/dinde socket: %s"
 
-#: network.c:1559
+#: network.c:1530
 msgid "(no DNSSEC)"
 msgstr ""
 
-#: network.c:1562
+#: network.c:1533
 msgid "unqualified"
 msgstr "ikke kvalifisert"
 
-#: network.c:1562
+#: network.c:1533
 msgid "names"
 msgstr ""
 
-#: network.c:1564
+#: network.c:1535
 msgid "default"
 msgstr ""
 
-#: network.c:1566
+#: network.c:1537
 msgid "domain"
 msgstr "domene"
 
-#: network.c:1572
-#, c-format
-msgid "using local addresses only for %s %s"
+#: network.c:1543
+#, fuzzy, c-format
+msgid "using only locally-known addresses for %s %s"
 msgstr "benytter lokale adresser kun for %s %s"
 
-#: network.c:1575
+#: network.c:1546
 #, fuzzy, c-format
 msgid "using standard nameservers for %s %s"
 msgstr "benytter navnetjener %s#%d for %s %s"
 
-#: network.c:1577
+#: network.c:1548
 #, fuzzy, c-format
 msgid "using nameserver %s#%d for %s %s %s"
 msgstr "benytter navnetjener %s#%d for %s %s"
 
-#: network.c:1581
+#: network.c:1552
 #, fuzzy, c-format
 msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr "benytter navnetjener %s#%d for %s %s"
 
-#: network.c:1584
+#: network.c:1555
 #, fuzzy, c-format
 msgid "using nameserver %s#%d(via %s)"
 msgstr "benytter navnetjener %s#%d"
 
-#: network.c:1586
+#: network.c:1557
 #, c-format
 msgid "using nameserver %s#%d"
 msgstr "benytter navnetjener %s#%d"
 
-#: network.c:1591
+#: network.c:1562
 #, fuzzy, c-format
 msgid "using %d more local addresses"
 msgstr "benytter navnetjener %s#%d"
 
-#: network.c:1593
+#: network.c:1564
 #, fuzzy, c-format
 msgid "using %d more nameservers"
 msgstr "benytter navnetjener %s#%d"
 
-#: dnsmasq.c:171
+#: dnsmasq.c:173
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr ""
 
-#: dnsmasq.c:186
+#: dnsmasq.c:188
 msgid "no root trust anchor provided for DNSSEC"
 msgstr ""
 
-#: dnsmasq.c:189
+#: dnsmasq.c:191
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr ""
 
-#: dnsmasq.c:191
+#: dnsmasq.c:193
 #, fuzzy
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr "DBus ikke tilgjengelig: sett HAVE_DBUS i src/config.h"
 
-#: dnsmasq.c:197
+#: dnsmasq.c:199
 #, fuzzy
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr "DBus ikke tilgjengelig: sett HAVE_DBUS i src/config.h"
 
-#: dnsmasq.c:202
+#: dnsmasq.c:204
 msgid "cannot use --conntrack AND --query-port"
 msgstr ""
 
-#: dnsmasq.c:205
+#: dnsmasq.c:207
 #, fuzzy
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr "DBus ikke tilgjengelig: sett HAVE_DBUS i src/config.h"
 
-#: dnsmasq.c:210
+#: dnsmasq.c:212
 msgid "asynchronous logging is not available under Solaris"
 msgstr ""
 
-#: dnsmasq.c:215
+#: dnsmasq.c:217
 msgid "asynchronous logging is not available under Android"
 msgstr ""
 
-#: dnsmasq.c:220
+#: dnsmasq.c:222
 #, fuzzy
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr "DBus ikke tilgjengelig: sett HAVE_DBUS i src/config.h"
 
-#: dnsmasq.c:225
+#: dnsmasq.c:227
 #, fuzzy
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr "DBus ikke tilgjengelig: sett HAVE_DBUS i src/config.h"
 
-#: dnsmasq.c:229
+#: dnsmasq.c:232
+#, fuzzy
+msgid "Ubus not available: set HAVE_UBUS in src/config.h"
+msgstr "DBus ikke tilgjengelig: sett HAVE_DBUS i src/config.h"
+
+#: dnsmasq.c:236
 msgid "max_port cannot be smaller than min_port"
 msgstr ""
 
-#: dnsmasq.c:236
+#: dnsmasq.c:243
+msgid "--auth-server required when an auth zone is defined."
+msgstr ""
+
+#: dnsmasq.c:248
 msgid "zone serial must be configured in --auth-soa"
 msgstr ""
 
-#: dnsmasq.c:254
+#: dnsmasq.c:268
 msgid "dhcp-range constructor not available on this platform"
 msgstr ""
 
-#: dnsmasq.c:300
+#: dnsmasq.c:332
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr ""
 
-#: dnsmasq.c:303
+#: dnsmasq.c:335
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr "feilet å finne liste av tilknytninger (interfaces): %s"
 
-#: dnsmasq.c:312
+#: dnsmasq.c:344
 #, c-format
 msgid "unknown interface %s"
 msgstr "ukjent tilknytning (interface) %s"
 
-#: dnsmasq.c:377 dnsmasq.c:1054
+#: dnsmasq.c:406
+#, fuzzy
+msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
+msgstr "DBus ikke tilgjengelig: sett HAVE_DBUS i src/config.h"
+
+#: dnsmasq.c:416 dnsmasq.c:1171
 #, c-format
 msgid "DBus error: %s"
 msgstr "DBus feil: %s"
 
-#: dnsmasq.c:380
+#: dnsmasq.c:419
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr "DBus ikke tilgjengelig: sett HAVE_DBUS i src/config.h"
 
-#: dnsmasq.c:410
+#: dnsmasq.c:429
+#, fuzzy
+msgid "UBus not available: set HAVE_UBUS in src/config.h"
+msgstr "DBus ikke tilgjengelig: sett HAVE_DBUS i src/config.h"
+
+#: dnsmasq.c:459
 #, c-format
 msgid "unknown user or group: %s"
 msgstr ""
 
-#: dnsmasq.c:465
+#: dnsmasq.c:535
+#, c-format
+msgid "process is missing required capability %s"
+msgstr ""
+
+#: dnsmasq.c:567
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr ""
 
-#: dnsmasq.c:730
+#: dnsmasq.c:815
 #, fuzzy, c-format
 msgid "started, version %s DNS disabled"
 msgstr "startet, versjon %s mellomlager deaktivert"
 
-#: dnsmasq.c:734
+#: dnsmasq.c:820
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr "startet, versjon %s mellomlager størrelse %d"
 
-#: dnsmasq.c:736
+#: dnsmasq.c:822
+msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
+msgstr ""
+
+#: dnsmasq.c:825
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr "startet, versjon %s mellomlager deaktivert"
 
-#: dnsmasq.c:739
+#: dnsmasq.c:828
 msgid "DNS service limited to local subnets"
 msgstr ""
 
-#: dnsmasq.c:742
+#: dnsmasq.c:831
 #, c-format
 msgid "compile time options: %s"
 msgstr "kompilerings opsjoner: %s"
 
-#: dnsmasq.c:751
+#: dnsmasq.c:840
 msgid "DBus support enabled: connected to system bus"
 msgstr "DBus støtte aktivert: koblet til system buss"
 
-#: dnsmasq.c:753
+#: dnsmasq.c:842
 msgid "DBus support enabled: bus connection pending"
 msgstr "DBus støtte aktivert: avventer buss tilkobling"
 
-#: dnsmasq.c:771
+#: dnsmasq.c:850
+#, fuzzy
+msgid "UBus support enabled: connected to system bus"
+msgstr "DBus støtte aktivert: koblet til system buss"
+
+#: dnsmasq.c:852
+#, fuzzy
+msgid "UBus support enabled: bus connection pending"
+msgstr "DBus støtte aktivert: avventer buss tilkobling"
+
+#: dnsmasq.c:872
+msgid "DNSSEC validation enabled but all unsigned answers are trusted"
+msgstr ""
+
+#: dnsmasq.c:874
 msgid "DNSSEC validation enabled"
 msgstr ""
 
-#: dnsmasq.c:775
+#: dnsmasq.c:878
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr ""
 
-#: dnsmasq.c:778
+#: dnsmasq.c:881
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr ""
 
-#: dnsmasq.c:783
+#: dnsmasq.c:884
+#, c-format
+msgid "configured with trust anchor for %s keytag %u"
+msgstr ""
+
+#: dnsmasq.c:890
 #, fuzzy, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr "feilet å laste navn fra %s: %s"
 
-#: dnsmasq.c:787
+#: dnsmasq.c:894
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr "setter --bind-interfaces opsjon på grunn av OS begrensninger"
 
-#: dnsmasq.c:799
+#: dnsmasq.c:906
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr "advarsel: nettverkskort %s eksisterer ikke for tiden"
 
-#: dnsmasq.c:804
+#: dnsmasq.c:911
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr ""
 
-#: dnsmasq.c:807
+#: dnsmasq.c:914
 #, fuzzy
 msgid "warning: no upstream servers configured"
 msgstr "setter oppstrøms tjener fra DBus"
 
-#: dnsmasq.c:811
+#: dnsmasq.c:918
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr ""
 
-#: dnsmasq.c:832
+#: dnsmasq.c:939
 msgid "IPv6 router advertisement enabled"
 msgstr ""
 
-#: dnsmasq.c:837
+#: dnsmasq.c:944
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr ""
 
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 msgid "root is "
 msgstr ""
 
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 #, fuzzy
 msgid "enabled"
 msgstr "deaktivert"
 
-#: dnsmasq.c:853
+#: dnsmasq.c:960
 msgid "secure mode"
 msgstr ""
 
-#: dnsmasq.c:856
+#: dnsmasq.c:961
+#, fuzzy
+msgid "single port mode"
+msgstr "ugyldig portnummer"
+
+#: dnsmasq.c:964
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:860
+#: dnsmasq.c:968
 #, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:886
+#: dnsmasq.c:994
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr ""
 
-#: dnsmasq.c:1056
+#: dnsmasq.c:1173
 msgid "connected to system DBus"
 msgstr "tilkoblet til system DBus"
 
-#: dnsmasq.c:1215
+#: dnsmasq.c:1345
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr ""
 
-#: dnsmasq.c:1218
+#: dnsmasq.c:1349
 #, fuzzy, c-format
 msgid "failed to create helper: %s"
 msgstr "feilet å lese %s: %s"
 
-#: dnsmasq.c:1221
+#: dnsmasq.c:1353
 #, c-format
 msgid "setting capabilities failed: %s"
 msgstr ""
 
-#: dnsmasq.c:1224
+#: dnsmasq.c:1357
 #, fuzzy, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr "feilet å laste navn fra %s: %s"
 
-#: dnsmasq.c:1227
+#: dnsmasq.c:1361
 #, fuzzy, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr "feilet å laste navn fra %s: %s"
 
-#: dnsmasq.c:1230
+#: dnsmasq.c:1365
 #, fuzzy, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr "feilet å lese %s: %s"
 
-#: dnsmasq.c:1233
+#: dnsmasq.c:1369
 #, fuzzy, c-format
 msgid "cannot open log %s: %s"
 msgstr "kan ikke åpne %s:%s"
 
-#: dnsmasq.c:1236
+#: dnsmasq.c:1373
 #, fuzzy, c-format
 msgid "failed to load Lua script: %s"
 msgstr "feilet å laste %s: %s"
 
-#: dnsmasq.c:1239
+#: dnsmasq.c:1377
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr ""
 
-#: dnsmasq.c:1242
+#: dnsmasq.c:1381
 #, fuzzy, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr "kan ikke åpne eller lage leie fil: %s"
 
-#: dnsmasq.c:1326
+#: dnsmasq.c:1465
 #, c-format
 msgid "script process killed by signal %d"
 msgstr ""
 
-#: dnsmasq.c:1330
+#: dnsmasq.c:1469
 #, c-format
 msgid "script process exited with status %d"
 msgstr ""
 
-#: dnsmasq.c:1334
+#: dnsmasq.c:1473
 #, fuzzy, c-format
 msgid "failed to execute %s: %s"
 msgstr "feilet å få tilgang til %s: %s"
 
-#: dnsmasq.c:1374
+#: dnsmasq.c:1513
 msgid "now checking DNSSEC signature timestamps"
 msgstr ""
 
-#: dnsmasq.c:1409 dnssec.c:160 dnssec.c:206
+#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
 #, fuzzy, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr "feilet å lese %s: %s"
 
-#: dnsmasq.c:1416
+#: dnsmasq.c:1560
 msgid "exiting on receipt of SIGTERM"
 msgstr "avslutter etter mottak av SIGTERM"
 
-#: dnsmasq.c:1444
+#: dnsmasq.c:1588
 #, fuzzy, c-format
 msgid "failed to access %s: %s"
 msgstr "feilet å få tilgang til %s: %s"
 
-#: dnsmasq.c:1474
+#: dnsmasq.c:1618
 #, c-format
 msgid "reading %s"
 msgstr "leser %s"
 
-#: dnsmasq.c:1485
+#: dnsmasq.c:1629
 #, fuzzy, c-format
 msgid "no servers found in %s, will retry"
 msgstr "intet søke direktiv funnet i %s"
@@ -1658,7 +1762,7 @@ msgstr "feilet 
 msgid "cannot create ICMP raw socket: %s."
 msgstr "kan ikke lage ICMP raw socket: %s"
 
-#: dhcp.c:252 dhcp6.c:173
+#: dhcp.c:252 dhcp6.c:180
 #, fuzzy, c-format
 msgid "unknown interface %s in bridge-interface"
 msgstr "ukjent tilknytning (interface) %s"
@@ -1668,331 +1772,337 @@ msgstr "ukjent tilknytning (interface) %s"
 msgid "DHCP packet received on %s which has no address"
 msgstr ""
 
-#: dhcp.c:427
+#: dhcp.c:428
 #, c-format
 msgid "ARP-cache injection failed: %s"
 msgstr ""
 
-#: dhcp.c:470
+#: dhcp.c:471
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr ""
 
-#: dhcp.c:531
+#: dhcp.c:526
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr "DHCP område %s -- %s er ikke konsistent med nettmaske %s"
 
-#: dhcp.c:854
+#: dhcp.c:914
 #, c-format
 msgid "bad line at %s line %d"
 msgstr "dårlig linje ved %s linje %d"
 
-#: dhcp.c:897
+#: dhcp.c:957
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr ""
 
-#: dhcp.c:1041 rfc3315.c:2149
+#: dhcp.c:1100 rfc3315.c:2139
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr ""
 
-#: lease.c:98
+#: lease.c:64
+#, c-format
+msgid "ignoring invalid line in lease database: %s %s %s %s ..."
+msgstr ""
+
+#: lease.c:101
+#, c-format
+msgid "ignoring invalid line in lease database, bad address: %s"
+msgstr ""
+
+#: lease.c:108
 msgid "too many stored leases"
 msgstr "for mange lagrede leier"
 
-#: lease.c:166
+#: lease.c:176
 #, fuzzy, c-format
 msgid "cannot open or create lease file %s: %s"
 msgstr "kan ikke åpne eller lage leie fil: %s"
 
-#: lease.c:175
-#, c-format
-msgid "failed to parse lease database, invalid line: %s %s %s %s ..."
-msgstr ""
+#: lease.c:185
+#, fuzzy
+msgid "failed to parse lease database cleanly"
+msgstr "feilet å lese %s: %s"
 
-#: lease.c:180
+#: lease.c:188
 #, fuzzy, c-format
 msgid "failed to read lease file %s: %s"
 msgstr "feilet å lese %s: %s"
 
-#: lease.c:196
+#: lease.c:204
 #, fuzzy, c-format
 msgid "cannot run lease-init script %s: %s"
 msgstr "kan ikke lese %s: %s"
 
-#: lease.c:202
+#: lease.c:210
 #, c-format
 msgid "lease-init script returned exit code %s"
 msgstr ""
 
-#: lease.c:373
+#: lease.c:381
 #, fuzzy, c-format
 msgid "failed to write %s: %s (retry in %us)"
 msgstr "feilet å lese %s: %s"
 
-#: lease.c:937
+#: lease.c:955
 #, c-format
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr ""
 
-#: rfc2131.c:347
+#: rfc2131.c:372
 #, c-format
 msgid "no address range available for DHCP request %s %s"
 msgstr "ingen adresse område tilgjengelig for DHCP krav %s %s"
 
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "with subnet selector"
 msgstr "med subnet velger"
 
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "via"
 msgstr "via"
 
-#: rfc2131.c:360
+#: rfc2131.c:385
 #, fuzzy, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr "ingen adresse område tilgjengelig for DHCP krav %s %s"
 
-#: rfc2131.c:363 rfc3315.c:306
+#: rfc2131.c:388 rfc3315.c:319
 #, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr ""
 
-#: rfc2131.c:474
+#: rfc2131.c:499
 #, fuzzy, c-format
 msgid "%u vendor class: %s"
 msgstr "DBus feil: %s"
 
-#: rfc2131.c:476
+#: rfc2131.c:501
 #, fuzzy, c-format
 msgid "%u user class: %s"
 msgstr "DBus feil: %s"
 
-#: rfc2131.c:510
+#: rfc2131.c:535
 msgid "disabled"
 msgstr "deaktivert"
 
-#: rfc2131.c:551 rfc2131.c:1006 rfc2131.c:1430 rfc3315.c:616 rfc3315.c:869
-#: rfc3315.c:1148
+#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1097
 msgid "ignored"
 msgstr "oversett"
 
-#: rfc2131.c:566 rfc2131.c:1239 rfc3315.c:919
+#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
 msgid "address in use"
 msgstr "adresse i bruk"
 
-#: rfc2131.c:580 rfc2131.c:1060
+#: rfc2131.c:605 rfc2131.c:1119
 msgid "no address available"
 msgstr "ingen adresse tilgjengelig"
 
-#: rfc2131.c:587 rfc2131.c:1202
+#: rfc2131.c:612 rfc2131.c:1273
 msgid "wrong network"
 msgstr "galt nettverk"
 
-#: rfc2131.c:602
+#: rfc2131.c:627
 msgid "no address configured"
 msgstr "ingen adresse konfigurert"
 
-#: rfc2131.c:608 rfc2131.c:1252
+#: rfc2131.c:633 rfc2131.c:1323
 msgid "no leases left"
 msgstr "ingen leier igjen"
 
-#: rfc2131.c:703 rfc3315.c:482
+#: rfc2131.c:734 rfc3315.c:499
 #, c-format
 msgid "%u client provides name: %s"
 msgstr ""
 
-#: rfc2131.c:808
+#: rfc2131.c:864
 msgid "PXE BIS not supported"
 msgstr ""
 
-#: rfc2131.c:974 rfc3315.c:1242
+#: rfc2131.c:1032 rfc3315.c:1197
 #, fuzzy, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr "deaktiverer DHCP statisk adresse %s"
 
-#: rfc2131.c:995
+#: rfc2131.c:1053
 msgid "unknown lease"
 msgstr "ukjent leie"
 
-#: rfc2131.c:1029
+#: rfc2131.c:1088
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr ""
 
-#: rfc2131.c:1039
+#: rfc2131.c:1098
 #, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr ""
 
-#: rfc2131.c:1042
+#: rfc2131.c:1101
 #, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr ""
 
-#: rfc2131.c:1058 rfc2131.c:1245
+#: rfc2131.c:1117 rfc2131.c:1316
 msgid "no unique-id"
 msgstr ""
 
-#: rfc2131.c:1140
+#: rfc2131.c:1209
 msgid "wrong server-ID"
 msgstr ""
 
-#: rfc2131.c:1159
+#: rfc2131.c:1228
 msgid "wrong address"
 msgstr "gal adresse"
 
-#: rfc2131.c:1177 rfc3315.c:1015
+#: rfc2131.c:1246 rfc3315.c:961
 msgid "lease not found"
 msgstr "leie ikke funnet"
 
-#: rfc2131.c:1210
+#: rfc2131.c:1281
 msgid "address not available"
 msgstr "adresse ikke tilgjengelig"
 
-#: rfc2131.c:1221
+#: rfc2131.c:1292
 msgid "static lease available"
 msgstr "statisk leie tilgjengelig"
 
-#: rfc2131.c:1225
+#: rfc2131.c:1296
 msgid "address reserved"
 msgstr "adresse reservert"
 
-#: rfc2131.c:1233
+#: rfc2131.c:1304
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr ""
 
-#: rfc2131.c:1757
+#: rfc2131.c:1845
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr ""
 
-#: rfc2131.c:1766
+#: rfc2131.c:1854
 #, fuzzy, c-format
 msgid "%u server name: %s"
 msgstr "DBus feil: %s"
 
-#: rfc2131.c:1774
+#: rfc2131.c:1862
 #, fuzzy, c-format
 msgid "%u next server: %s"
 msgstr "DBus feil: %s"
 
-#: rfc2131.c:1777
+#: rfc2131.c:1865
 #, c-format
 msgid "%u broadcast response"
 msgstr ""
 
-#: rfc2131.c:1840
+#: rfc2131.c:1928
 #, fuzzy, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr "kan ikke sende DHCP opsjon %d: ikke mer plass i pakken"
 
-#: rfc2131.c:2131
+#: rfc2131.c:2219
 msgid "PXE menu too large"
 msgstr ""
 
-#: rfc2131.c:2270 rfc3315.c:1515
+#: rfc2131.c:2358 rfc3315.c:1470
 #, fuzzy, c-format
 msgid "%u requested options: %s"
 msgstr "kompilerings opsjoner: %s"
 
-#: rfc2131.c:2587
+#: rfc2131.c:2675
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr ""
 
-#: rfc2131.c:2650
+#: rfc2131.c:2738
 #, c-format
 msgid "%u reply delay: %d"
 msgstr ""
 
-#: netlink.c:77
+#: netlink.c:76
 #, fuzzy, c-format
 msgid "cannot create netlink socket: %s"
 msgstr "kan ikke binde netlink socket: %s"
 
-#: netlink.c:355
+#: netlink.c:352
 #, fuzzy, c-format
 msgid "netlink returns error: %s"
 msgstr "DBus feil: %s"
 
-#: dbus.c:186
-msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
-msgstr "forsøk på å sette en IPv6 tjener adresse via DBus - ingen IPv6 støtte"
-
-#: dbus.c:439
+#: dbus.c:438
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:444
+#: dbus.c:443
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:690
+#: dbus.c:717
 msgid "setting upstream servers from DBus"
 msgstr "setter oppstrøms tjener fra DBus"
 
-#: dbus.c:737
+#: dbus.c:764
 msgid "could not register a DBus message handler"
 msgstr "kunne ikke registrere en DBus meldingshåndterer"
 
-#: bpf.c:265
+#: bpf.c:261
 #, c-format
 msgid "cannot create DHCP BPF socket: %s"
 msgstr "kan ikke lage DHCP BPF socket: %s"
 
-#: bpf.c:293
+#: bpf.c:289
 #, fuzzy, c-format
 msgid "DHCP request for unsupported hardware type (%d) received on %s"
 msgstr "DHCP krav for ikke støttet maskinvare type (%d) mottatt på %s"
 
-#: bpf.c:378
+#: bpf.c:374
 #, fuzzy, c-format
 msgid "cannot create PF_ROUTE socket: %s"
 msgstr "kan ikke lage DHCP socket: %s"
 
-#: bpf.c:399
+#: bpf.c:395
 msgid "Unknown protocol version from route socket"
 msgstr ""
 
-#: helper.c:154
+#: helper.c:150
 msgid "lease() function missing in Lua script"
 msgstr ""
 
-#: tftp.c:319
+#: tftp.c:347
 msgid "unable to get free port for TFTP"
 msgstr ""
 
-#: tftp.c:335
+#: tftp.c:363
 #, c-format
 msgid "unsupported request from %s"
 msgstr ""
 
-#: tftp.c:483
+#: tftp.c:510
 #, fuzzy, c-format
 msgid "file %s not found"
 msgstr "leie ikke funnet"
 
-#: tftp.c:592
-#, c-format
-msgid "error %d %s received from %s"
-msgstr ""
-
-#: tftp.c:634
+#: tftp.c:628
 #, fuzzy, c-format
 msgid "failed sending %s to %s"
 msgstr "feilet å lese %s: %s"
 
-#: tftp.c:634
+#: tftp.c:628
 #, c-format
 msgid "sent %s to %s"
 msgstr ""
 
+#: tftp.c:678
+#, c-format
+msgid "error %d %s received from %s"
+msgstr ""
+
 #: log.c:190
 #, c-format
 msgid "overflow: %d log entries lost"
@@ -2007,7 +2117,7 @@ msgstr ""
 msgid "FAILED to start up"
 msgstr "FEILET å starte opp"
 
-#: conntrack.c:65
+#: conntrack.c:63
 #, c-format
 msgid "Conntrack connection mark retrieval failed: %s"
 msgstr ""
@@ -2027,81 +2137,76 @@ msgstr "feilet 
 msgid "failed to bind DHCPv6 server socket: %s"
 msgstr "feilet å binde DHCP tjener socket: %s"
 
-#: rfc3315.c:157
+#: rfc3315.c:173
 #, fuzzy, c-format
 msgid "no address range available for DHCPv6 request from relay at %s"
 msgstr "ingen adresse område tilgjengelig for DHCP krav %s %s"
 
-#: rfc3315.c:166
+#: rfc3315.c:182
 #, fuzzy, c-format
 msgid "no address range available for DHCPv6 request via %s"
 msgstr "ingen adresse område tilgjengelig for DHCP krav %s %s"
 
-#: rfc3315.c:303
+#: rfc3315.c:316
 #, fuzzy, c-format
 msgid "%u available DHCPv6 subnet: %s/%d"
 msgstr "ingen adresse område tilgjengelig for DHCP krav %s %s"
 
-#: rfc3315.c:386
+#: rfc3315.c:399
 #, fuzzy, c-format
 msgid "%u vendor class: %u"
 msgstr "DBus feil: %s"
 
-#: rfc3315.c:434
+#: rfc3315.c:447
 #, fuzzy, c-format
 msgid "%u client MAC address: %s"
 msgstr "ingen tilknytning (interface) med adresse %s"
 
-#: rfc3315.c:673
-#, fuzzy, c-format
-msgid "unknown prefix-class %d"
-msgstr "ukjent leie"
-
-#: rfc3315.c:816 rfc3315.c:911
+#: rfc3315.c:762 rfc3315.c:859
 #, fuzzy
 msgid "address unavailable"
 msgstr "adresse ikke tilgjengelig"
 
-#: rfc3315.c:828 rfc3315.c:959 rfc3315.c:1292
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
 msgid "success"
 msgstr ""
 
-#: rfc3315.c:843 rfc3315.c:852 rfc3315.c:967 rfc3315.c:969
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
 #, fuzzy
 msgid "no addresses available"
 msgstr "ingen adresse tilgjengelig"
 
-#: rfc3315.c:946
+#: rfc3315.c:890
 msgid "not on link"
 msgstr ""
 
-#: rfc3315.c:1019 rfc3315.c:1204 rfc3315.c:1281
+#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
 msgid "no binding found"
 msgstr ""
 
-#: rfc3315.c:1057
+#: rfc3315.c:1002
 msgid "deprecated"
 msgstr ""
 
-#: rfc3315.c:1062
+#: rfc3315.c:1007
 #, fuzzy
 msgid "address invalid"
 msgstr "adresse i bruk"
 
-#: rfc3315.c:1109
+#: rfc3315.c:1057 rfc3315.c:1059
 msgid "confirm failed"
 msgstr ""
 
-#: rfc3315.c:1125
+#: rfc3315.c:1074
 #, fuzzy
 msgid "all addresses still on link"
 msgstr "dårlig adresse ved %s linje %d"
 
-#: rfc3315.c:1213
+#: rfc3315.c:1165
 msgid "release received"
 msgstr ""
 
-#: rfc3315.c:2140
+#: rfc3315.c:2130
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr ""
 
@@ -2115,76 +2220,76 @@ msgstr ""
 msgid "%u tags: %s"
 msgstr ""
 
-#: dhcp-common.c:407
+#: dhcp-common.c:444
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr ""
 
-#: dhcp-common.c:430
+#: dhcp-common.c:478
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr "dubliserte IP adresser i %s (%s) i dhcp-config direktiv"
 
-#: dhcp-common.c:491
+#: dhcp-common.c:542
 #, fuzzy, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr "feilet å sette SO_REUSEADDR på DHCP socket: %s"
 
-#: dhcp-common.c:612
+#: dhcp-common.c:665
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr ""
 
-#: dhcp-common.c:623
+#: dhcp-common.c:676
 #, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr ""
 
-#: dhcp-common.c:820
+#: dhcp-common.c:873
 msgid ", prefix deprecated"
 msgstr ""
 
-#: dhcp-common.c:823
+#: dhcp-common.c:876
 #, c-format
 msgid ", lease time "
 msgstr ""
 
-#: dhcp-common.c:865
+#: dhcp-common.c:918
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr ""
 
-#: dhcp-common.c:867
+#: dhcp-common.c:920
 #, fuzzy, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr "DHCP, statisk leie kun på %.0s%s, leie tid %s"
 
-#: dhcp-common.c:869
+#: dhcp-common.c:922
 #, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr ""
 
-#: dhcp-common.c:870
+#: dhcp-common.c:923
 #, fuzzy, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr "DHCP, IP område %s -- %s, leie tid %s"
 
-#: dhcp-common.c:883
+#: dhcp-common.c:936
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr ""
 
-#: dhcp-common.c:886
+#: dhcp-common.c:939
 #, fuzzy, c-format
 msgid "router advertisement on %s%s"
 msgstr "DHCP, statisk leie kun på %.0s%s, leie tid %s"
 
-#: dhcp-common.c:897
+#: dhcp-common.c:950
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr ""
 
-#: dhcp-common.c:899
+#: dhcp-common.c:952
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr ""
@@ -2194,7 +2299,7 @@ msgstr ""
 msgid "cannot create ICMPv6 socket: %s"
 msgstr "kan ikke lage DHCP socket: %s"
 
-#: auth.c:449
+#: auth.c:439
 #, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr ""
@@ -2209,18 +2314,23 @@ msgstr "feilet 
 msgid "failed to create IPset control socket: %s"
 msgstr "feilet å lage lytte socket: %s"
 
-#: ipset.c:233
+#: ipset.c:226
 #, fuzzy, c-format
 msgid "failed to update ipset %s: %s"
 msgstr "feilet å lese %s: %s"
 
-#: dnssec.c:208
+#: dnssec.c:206
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
 msgstr ""
 
-#: blockdata.c:58
+#: dnssec.c:902
+#, c-format
+msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
+msgstr ""
+
+#: blockdata.c:55
 #, c-format
-msgid "DNSSEC memory in use %u, max %u, allocated %u"
+msgid "pool memory in use %u, max %u, allocated %u"
 msgstr ""
 
 #: tables.c:61
@@ -2252,12 +2362,12 @@ msgstr "DBus feil: %s"
 msgid "info: table created"
 msgstr ""
 
-#: tables.c:134
+#: tables.c:133
 #, c-format
 msgid "warning: DIOCR%sADDRS: %s"
 msgstr ""
 
-#: tables.c:138
+#: tables.c:137
 #, fuzzy, c-format
 msgid "%d addresses %s"
 msgstr "les %s - %d adresser"
@@ -2297,6 +2407,74 @@ msgstr "kan ikke lese %s: %s"
 msgid "inotify, new or changed file %s"
 msgstr ""
 
+#: dump.c:64
+#, fuzzy, c-format
+msgid "cannot create %s: %s"
+msgstr "kan ikke lese %s: %s"
+
+#: dump.c:70
+#, fuzzy, c-format
+msgid "bad header in %s"
+msgstr "adresse i bruk"
+
+#: dump.c:201
+#, fuzzy
+msgid "failed to write packet dump"
+msgstr "feilet å lytte på socket: %s"
+
+#: dump.c:203
+#, c-format
+msgid "dumping UDP packet %u mask 0x%04x"
+msgstr ""
+
+#: ubus.c:52
+#, c-format
+msgid "UBus subscription callback: %s subscriber(s)"
+msgstr ""
+
+#: ubus.c:73
+#, fuzzy, c-format
+msgid "Cannot reconnect to UBus: %s"
+msgstr "kan ikke åpne %s:%s"
+
+#: ubus.c:89
+msgid "Cannot initialize UBus: connection failed"
+msgstr ""
+
+#: ubus.c:102
+#, fuzzy, c-format
+msgid "Cannot add object to UBus: %s"
+msgstr "kan ikke åpne %s:%s"
+
+#: ubus.c:112
+#, fuzzy
+msgid "Connected to system UBus"
+msgstr "tilkoblet til system DBus"
+
+#: ubus.c:122
+msgid "Cannot set UBus listeners: no connection"
+msgstr ""
+
+#: ubus.c:142
+msgid "Cannot poll UBus listeners: no connection"
+msgstr ""
+
+#: ubus.c:155
+msgid "Disconnecting from UBus"
+msgstr ""
+
+#: ubus.c:199
+#, fuzzy, c-format
+msgid "Failed to send UBus event: %s"
+msgstr "feilet å lytte på socket: %s"
+
+#~ msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
+#~ msgstr "forsøk på å sette en IPv6 tjener adresse via DBus - ingen IPv6 støtte"
+
+#, fuzzy
+#~ msgid "unknown prefix-class %d"
+#~ msgstr "ukjent leie"
+
 #, fuzzy
 #~ msgid "cannot cannonicalise resolv-file %s: %s"
 #~ msgstr "kan ikke åpne eller lage leie fil: %s"
index 33f0d5a..a947f03 100644 (file)
--- a/po/pl.po
+++ b/po/pl.po
@@ -21,70 +21,70 @@ msgstr ""
 "X-Generator: Poedit 1.8.7\n"
 "X-Language: pl_PL\n"
 
-#: cache.c:518
+#: cache.c:559
 msgid "Internal error in cache."
 msgstr "Wewnętrzny błąd w pamięci podręcznej."
 
-#: cache.c:928
+#: cache.c:1081
 #, c-format
 msgid "failed to load names from %s: %s"
 msgstr "nie potrafię wczytać nazw z %s: %s"
 
-#: cache.c:954 dhcp.c:867
+#: cache.c:1103 dhcp.c:927
 #, c-format
 msgid "bad address at %s line %d"
 msgstr "błędny adres w pliku %s, w linii %d"
 
-#: cache.c:1007 dhcp.c:883
+#: cache.c:1156 dhcp.c:943
 #, c-format
 msgid "bad name at %s line %d"
 msgstr "błędna nazwa w pliku %s, w linii %d"
 
-#: cache.c:1016 dhcp.c:958
+#: cache.c:1167 dhcp.c:1018
 #, c-format
 msgid "read %s - %d addresses"
 msgstr "wczytałem %s - %d adresów"
 
-#: cache.c:1129
+#: cache.c:1283
 msgid "cleared cache"
 msgstr "wyczyszczono pamięć podręczną"
 
-#: cache.c:1158
+#: cache.c:1345
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr "Nie znalazłem adresu IPv4 komputera %s"
 
-#: cache.c:1237
+#: cache.c:1391
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr "%s to nazwa CNAME, nie przypisuję jej dzierżawie DHCP %s"
 
-#: cache.c:1261
+#: cache.c:1415
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr "nazwa %s nie została nadana dzierżawie DHCP %s, ponieważ nazwa istnieje w %s i ma już adres %s"
 
-#: cache.c:1418
+#: cache.c:1663
 #, c-format
 msgid "time %lu"
 msgstr "czas %lu"
 
-#: cache.c:1419
+#: cache.c:1664
 #, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr "wielkość pamięci podręcznej: %d; %d z %d miejsc aktualnych wpisów użyto ponownie."
 
-#: cache.c:1421
+#: cache.c:1666
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr "%u zapytań przesłanych dalej, %u odpowiedzi udzielonych samodzielnie"
 
-#: cache.c:1424
+#: cache.c:1669
 #, c-format
 msgid "queries for authoritative zones %u"
 msgstr "zapytań do stref autorytatywnych %u"
 
-#: cache.c:1450
+#: cache.c:1694
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr "serwer %s#%d: %u zapytań wysłanych, %u ponowionych lub nieudanych"
@@ -98,662 +98,701 @@ msgstr "brak możliwości użycia generatora liczb losowych: %s"
 msgid "failed to allocate memory"
 msgstr "nie udało się przydzielić pamięci"
 
-#: util.c:281 option.c:619
+#: util.c:281 option.c:641
 msgid "could not get memory"
 msgstr "nie można dostać pamięci"
 
-#: util.c:291
+#: util.c:302
 #, c-format
 msgid "cannot create pipe: %s"
 msgstr "błąd podczas próby utworzenia potoku: %s"
 
-#: util.c:299
+#: util.c:310
 #, c-format
 msgid "failed to allocate %d bytes"
 msgstr "niemożliwość przydzielenia %d bajtów pamięci"
 
-#: util.c:468
+#: util.c:506
 #, c-format
 msgid "infinite"
 msgstr "nieskończona"
 
-#: option.c:344
+#: option.c:358
 msgid "Specify local address(es) to listen on."
 msgstr "Wskazanie adresów, na których należy nasłuchiwać."
 
-#: option.c:345
+#: option.c:359
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr "Zwracanie adresu IP dla wszystkich hostów we wskazanych domenach."
 
-#: option.c:346
+#: option.c:360
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr "Wyłączenie przekazywania zapytań odwrotnych dla prywatnych zakresów IP."
 
-#: option.c:347
+#: option.c:361
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr "Traktowanie adresu IP jako NXDOMAIN (unieważnia ,,Verisign wildcard'')."
 
-#: option.c:348
+#: option.c:362
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr "Wskazanie wielkości pamięci podręcznej (domyślnie: %s miejsc)."
 
-#: option.c:349
+#: option.c:363
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr "Wskazanie pliku konfiguracyjnego (domyślnie: %s)."
 
-#: option.c:350
+#: option.c:364
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr "NIE twórz procesu potomnego w tle: działanie w trybie debugowania."
 
-#: option.c:351
+#: option.c:365
 msgid "Do NOT forward queries with no domain part."
 msgstr "Wyłączenie przekazywania zapytań bez podanej części domenowej."
 
-#: option.c:352
+#: option.c:366
 msgid "Return self-pointing MX records for local hosts."
 msgstr "Zwracanie samowskazującego rekordu MX dla lokalnych hostów."
 
-#: option.c:353
+#: option.c:367
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr "Rozwijanie prostych nazw z /etc/hosts przyrostkiem domenowym."
 
-#: option.c:354
+#: option.c:368
 msgid "Don't forward spurious DNS requests from Windows hosts."
 msgstr "Wyłączenie przekazywania pozornych zapytań DNS z komputerów działających pod Windows."
 
-#: option.c:355
+#: option.c:369
 msgid "Enable DHCP in the range given with lease duration."
 msgstr "Włączenie serwera DHCP dla wskazanego zakresu adresów."
 
-#: option.c:356
+#: option.c:370
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr "Po uruchomieniu zmiana grupy procesu na podaną (domyślnie: %s)."
 
-#: option.c:357
+#: option.c:371
 msgid "Set address or hostname for a specified machine."
 msgstr "Ustawienie adresu lub nazwy dla wskazanego komputera."
 
-#: option.c:358
+#: option.c:372
 msgid "Read DHCP host specs from file."
 msgstr "Wskazanie pliku z wartościami 'dhcp-host='."
 
-#: option.c:359
+#: option.c:373
 msgid "Read DHCP option specs from file."
 msgstr "Wskazanie pliku z wartościami 'dhcp-option='."
 
-#: option.c:360
+#: option.c:374
 msgid "Read DHCP host specs from a directory."
 msgstr "Odczyt specyfikacji hostów dla DHCP z katalogu."
 
-#: option.c:361
+#: option.c:375
 msgid "Read DHCP options from a directory."
 msgstr "Odczyt opcji DHCP z katalogu."
 
-#: option.c:362
+#: option.c:376
 msgid "Evaluate conditional tag expression."
 msgstr "Warunkowe ustawianie znaczników."
 
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Do NOT load %s file."
 msgstr "NIE wczytywanie pliku %s."
 
-#: option.c:364
+#: option.c:378
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr "Wskazanie dodatkowego pliku 'hosts' oprócz %s."
 
-#: option.c:365
+#: option.c:379
 msgid "Read hosts files from a directory."
 msgstr "Odczyt pliku hostów z katalogu."
 
-#: option.c:366
+#: option.c:380
 msgid "Specify interface(s) to listen on."
 msgstr "Interfejsy, na których nasłuchiwać."
 
-#: option.c:367
+#: option.c:381
 msgid "Specify interface(s) NOT to listen on."
 msgstr "Interfejsy, na których NIE nasłuchiwać."
 
-#: option.c:368
+#: option.c:382
 msgid "Map DHCP user class to tag."
 msgstr "Przyporządkowanie znacznika w zależności od klasy użytkownika DHCP."
 
-#: option.c:369
+#: option.c:383
 msgid "Map RFC3046 circuit-id to tag."
 msgstr "Przyporządkowanie znacznika w zależności od numeru obwodu (w rozumieniu RFC3046)."
 
-#: option.c:370
+#: option.c:384
 msgid "Map RFC3046 remote-id to tag."
 msgstr "Przyporządkowanie znacznika w zależności od numeru agenta (w rozumieniu RFC3046)."
 
-#: option.c:371
+#: option.c:385
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr "Przyporządkowanie znacznika w zależności od numeru subskrybenta (w rozumieniu RFC3993)."
 
-#: option.c:372
+#: option.c:386
 msgid "Don't do DHCP for hosts with tag set."
 msgstr "Wyłączenie DHCP dla hostów z określonym znacznikiem."
 
-#: option.c:373
+#: option.c:387
 msgid "Force broadcast replies for hosts with tag set."
 msgstr "Wymuszenie odpowiedzi w trybie rozgłoszeniowym dla hostów z określonym znacznikiem."
 
-#: option.c:374
+#: option.c:388
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr "NIE twórz procesu potomnego w tle i NIE włączaj trybu debugowania."
 
-#: option.c:375
+#: option.c:389
 msgid "Assume we are the only DHCP server on the local network."
 msgstr "Zakładanie, że jesteśmy jedynym serwerem DHCP w sieci lokalnej."
 
-#: option.c:376
+#: option.c:390
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr "Ścieżka przechowywania pliku dzierżaw DHCP (domyślnie: %s)."
 
-#: option.c:377
+#: option.c:391
 msgid "Return MX records for local hosts."
 msgstr "Włączenie zwracania rekordu MX dla hostów lokalnych."
 
-#: option.c:378
+#: option.c:392
 msgid "Specify an MX record."
 msgstr "Specyfikacja rekordu MX."
 
-#: option.c:379
+#: option.c:393
 msgid "Specify BOOTP options to DHCP server."
 msgstr "Określenie opcji BOOTP serwera DHCP."
 
-#: option.c:380
+#: option.c:394
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr "Wyłączenie obserwowania pliku %s; ponowne odczytywanie tylko po odebraniu sygnału SIGHUP."
 
-#: option.c:381
+#: option.c:395
 msgid "Do NOT cache failed search results."
 msgstr "Wyłączenie przechowywania w pamięci podręcznej wyników nieudanych wyszukiwań."
 
-#: option.c:382
+#: option.c:396
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr "Odpytywanie serwerów nazw w kolejności ich wystąpienia w %s."
 
-#: option.c:383
+#: option.c:397
 msgid "Specify options to be sent to DHCP clients."
 msgstr "Specyfikacja opcji wysyłanej do klientów DHCP."
 
-#: option.c:384
+#: option.c:398
 msgid "DHCP option sent even if the client does not request it."
 msgstr "Opcja DHCP wysyłana nawet jeżeli klient o nią nie prosi."
 
-#: option.c:385
+#: option.c:399
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr "Wskazanie portu do nasłuchiwania zapytań DNS (domyślnie: 53)."
 
-#: option.c:386
+#: option.c:400
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr "Maksymalna obsługiwana wielkość pakietu EDNS.0 (domyślnie: %s)."
 
-#: option.c:387
+#: option.c:401
 msgid "Log DNS queries."
 msgstr "Włączenie spisywania zapytań DNS do logu."
 
-#: option.c:388
+#: option.c:402
 msgid "Force the originating port for upstream DNS queries."
 msgstr "Wymuszenie użycia wskazanego portu UDP do odpytywania nadrzędnych serwerów DNS i odbierania od nich odpowiedzi."
 
-#: option.c:389
+#: option.c:403
 msgid "Do NOT read resolv.conf."
 msgstr "Wyłączenie czytania pliku resolv.conf."
 
-#: option.c:390
+#: option.c:404
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr "Wskazanie położenia pliku resolv.conf (domyślnie: %s)."
 
-#: option.c:391
+#: option.c:405
 msgid "Specify path to file with server= options"
 msgstr "Wskazanie położenia pliku z opcjami server="
 
-#: option.c:392
+#: option.c:406
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr "Wskazywanie adresów serwerów nazw, opcjonalnie z przypisaniem do domeny."
 
-#: option.c:393
+#: option.c:407
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr "Wskazanie serwerów nazw do odwrotnej translacji adresów."
 
-#: option.c:394
+#: option.c:408
 msgid "Never forward queries to specified domains."
 msgstr "Wyłączenie przekazywania zapytań do wskazanych domen."
 
-#: option.c:395
+#: option.c:409
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr "Wskazanie domeny dla serwera DHCP."
 
-#: option.c:396
+#: option.c:410
 msgid "Specify default target in an MX record."
 msgstr "Określenie domyślnego celu w rekordzie MX."
 
-#: option.c:397
+#: option.c:411
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr "Określenie (w sekundach) czasu ważności odpowiedzi udzielonych na podstawie /etc/hosts (domyślnie 0)."
 
-#: option.c:398
+#: option.c:412
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr "Określenie (w sekundach) czasu ważności negatywnych odpowiedzi."
 
-#: option.c:399
+#: option.c:413
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr "Ograniczenie maksymalnego czasu ważności odpowiedzi (TTL) podawanego klientom [w sekundach]."
 
-#: option.c:400
+#: option.c:414
 msgid "Specify time-to-live ceiling for cache."
 msgstr "Określenie górnej granicy czasu ważności dla wpisów w pamięci podręcznej."
 
-#: option.c:401
+#: option.c:415
 msgid "Specify time-to-live floor for cache."
 msgstr "Określenie dolnej granicy czasu ważności dla wpisów w pamięci podręcznej."
 
-#: option.c:402
+#: option.c:416
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr "Zmiana użytkownika procesu na wskazanego (po uruchomieniu, domyślnie: %s)."
 
-#: option.c:403
+#: option.c:417
 msgid "Map DHCP vendor class to tag."
 msgstr "Przyporządkowanie znacznika w zależności od typu klienta DHCP."
 
-#: option.c:404
+#: option.c:418
 msgid "Display dnsmasq version and copyright information."
 msgstr "Wydrukowanie informacji o programie i ochronie praw autorskich."
 
-#: option.c:405
+#: option.c:419
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr "Tłumaczenie adresów IPv4 z serwerów nadrzędnych."
 
-#: option.c:406
+#: option.c:420
 msgid "Specify a SRV record."
 msgstr "Określenie rekordu SRV."
 
-#: option.c:407
+#: option.c:421
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr "Wyświetla ten komunikat. Chcąc przejrzeć listę dostępnych opcji DHCP użyj '--help dhcp' lub '--help dhcp6' ."
 
-#: option.c:408
+#: option.c:422
 #, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr "Określenie ścieżki do pliku PID (domyślnie: %s)."
 
-#: option.c:409
+#: option.c:423
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr "Maksymalna liczba dzierżaw DHCP (domyślnie: %s)."
 
-#: option.c:410
+#: option.c:424
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr "Uzależnienie odpowiedzi DNS od interfejsu, na którym odebrano zapytanie (wygodne dla serwerów kilku podsieci z różnymi adresami w /etc/hosts)."
 
-#: option.c:411
+#: option.c:425
 msgid "Specify TXT DNS record."
 msgstr "Specyfikacja rekordu DNS TXT."
 
-#: option.c:412
+#: option.c:426
 msgid "Specify PTR DNS record."
 msgstr "Specyfikacja rekordu DNS PTR."
 
-#: option.c:413
+#: option.c:427
 msgid "Give DNS name to IPv4 address of interface."
 msgstr "Zwraca nazwę domenową powiązaną z adresem interfejsu sieciowego."
 
-#: option.c:414
+#: option.c:428
 msgid "Bind only to interfaces in use."
 msgstr "Nasłuchiwanie tylko na wykorzystywanych interfejsach (umożliwia uruchomienie osobnych serwerów dla różnych kart)."
 
-#: option.c:415
+#: option.c:429
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr "Wczytanie przyporządkowań adresów z %s."
 
-#: option.c:416
+#: option.c:430
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr "Włączenie używania interfejsu DBus do informowania o zmianach konfiguracji."
 
-#: option.c:417
+#: option.c:431
+msgid "Enable the UBus interface."
+msgstr ""
+
+#: option.c:432
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr "Uruchomienie na wskazanym interfejsie tylko DNS-a, bez usług DHCP i TFTP."
 
-#: option.c:418
+#: option.c:433
 msgid "Enable dynamic address allocation for bootp."
 msgstr "Włączenie dynamicznego przydzielania adresów dla klientów BOOTP."
 
-#: option.c:419
+#: option.c:434
 msgid "Map MAC address (with wildcards) to option set."
 msgstr "Przyporządkowanie znacznika w zależności od adresu MAC (można używać uogólnień: *)."
 
-#: option.c:420
+#: option.c:435
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr "Traktowanie żądań DHCP odebranych na interfejsach alias, ..., jako odebranych na iface."
 
-#: option.c:421
+#: option.c:436
+msgid "Specify extra networks sharing a broadcast domain for DHCP"
+msgstr ""
+
+#: option.c:437
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr "Pominięcie sprawdzania za pomocą ICMP niezajętości adresu przed jego wydzierżawieniem."
 
-#: option.c:422
+#: option.c:438
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr "Skrypt powłoki uruchamiany po przyznaniu lub zwolnieniu adresu."
 
-#: option.c:423
+#: option.c:439
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr "Skrypt Lua uruchamiany po przyznaniu lub zwolnieniu adresu."
 
-#: option.c:424
+#: option.c:440
 msgid "Run lease-change scripts as this user."
 msgstr "Wskazanie użytkownika z którego uprawnieniami będą uruchamiane skrypty."
 
-#: option.c:425
+#: option.c:441
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr "Wywoływanie dhcp-script w reakcji na zmiany w tablicy ARP."
 
-#: option.c:426
+#: option.c:442
 msgid "Read configuration from all the files in this directory."
 msgstr "Wczytanie wszystkich plików ze wskazanego katalogu jako konfiguracyjnych."
 
-#: option.c:427
+#: option.c:443
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr "Wskazanie kanału syslog-a do którego mają trafiać komunikaty (domyślnie: DAEMON)"
 
-#: option.c:428
+#: option.c:444
 msgid "Do not use leasefile."
 msgstr "Nieużywanie bazy dzierżaw."
 
-#: option.c:429
+#: option.c:445
 #, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr "Maksymalna liczba jednocześnie obsługiwanych zapytań DNS (domyślnie: %s)"
 
-#: option.c:430
+#: option.c:446
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr "Czyszczenie pamięci podręcznej serwera nazw w przypadku ponownego odczytu %s."
 
-#: option.c:431
+#: option.c:447
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr "Nie zwracanie uwagi na nazwę podawaną przez klienta w przypadku dopasowania wszystkich wymienionych znaczników."
 
-#: option.c:432
+#: option.c:448
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr "Wyłączenie oszczędzania miejsca w pakiecie DHCP przez przesuwanie pól servername i filename do opcji DHCP. Wymusza prostszy tryb budowy pakietu rozwiązując problemy z nieprzystosowanymi klientami DHCP."
 
-#: option.c:433
+#: option.c:449
 msgid "Enable integrated read-only TFTP server."
 msgstr "Włączenie wbudowanego serwera TFTP (tylko do wysyłania)."
 
-#: option.c:434
+#: option.c:450
 msgid "Export files by TFTP only from the specified subtree."
 msgstr "Ograniczenie działania serwera TFTP do wskazanego katalogu i podkatalogów. Nazwy z .. są odrzucane, / odnosi się do wskazanego katalogu."
 
-#: option.c:435
+#: option.c:451
 #, fuzzy
 msgid "Add client IP or hardware address to tftp-root."
 msgstr "Doklejanie adresu IP klienta do głównego katalogu TFTP. Jeżeli wynikowy katalog nie istnieje, nadal wykorzystuje się tftp-root."
 
-#: option.c:436
+#: option.c:452
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr "Ograniczenie dostępu do plików przez TFTP do tych, których właścicielem jest użytkownik uruchamiający dnsmasq-a."
 
-#: option.c:437
+#: option.c:453
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr "Nieprzerywanie działania serwisu mimo braku dostępu do katalogów TFTP."
 
-#: option.c:438
+#: option.c:454
 #, fuzzy, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr "Maksymalna liczba jednocześnie obsługiwanych połączeń TFTP (domyślnie %s)."
 
-#: option.c:439
+#: option.c:455
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr "Ograniczenie MTU w komunikacji TFTP."
 
-#: option.c:440
+#: option.c:456
 msgid "Disable the TFTP blocksize extension."
 msgstr "Wyłączenie możliwości negocjowania wielkości bloku dla przesyłów przez TFTP."
 
-#: option.c:441
+#: option.c:457
 msgid "Convert TFTP filenames to lowercase"
 msgstr "Konwertowanie nazw plików żądanych przez TFTP do małych liter"
 
-#: option.c:442
+#: option.c:458
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr "Wskazanie zakresu portów do użytku TFTP."
 
-#: option.c:443
+#: option.c:459
+msgid "Use only one port for TFTP server."
+msgstr ""
+
+#: option.c:460
 msgid "Extra logging for DHCP."
 msgstr "Włączenie spisywania w logu operacji DHCP."
 
-#: option.c:444
+#: option.c:461
 msgid "Enable async. logging; optionally set queue length."
 msgstr "Włączenie asynchronicznego zapisywania do logu z ewentualnym wskazaniem długości kolejki."
 
-#: option.c:445
+#: option.c:462
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr "Odfiltrowywanie adresów wskazujących na komputery w sieciach wewnętrznych spośród odpowiedzi od zewnętrznych serwerów DNS."
 
-#: option.c:446
+#: option.c:463
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr "Zezwolenie na przekazywanie odpowiedzi w klasie 127.0.0.0/8. Dla serwerów RBL."
 
-#: option.c:447
+#: option.c:464
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr "Dezaktywacja zabezpieczenia przed atakami DNS-rebind dla wskazanych domen."
 
-#: option.c:448
+#: option.c:465
 msgid "Always perform DNS queries to all servers."
 msgstr "Jednoczesne odpytywanie wszystkich serwerów nadrzędnych; klientowi przekazywana jest pierwsza odpowiedź."
 
-#: option.c:449
+#: option.c:466
 msgid "Set tag if client includes matching option in request."
 msgstr "Ustawienie znacznika jeżeli w żądaniu DHCP pojawi się wskazana opcja, ewentualnie o konkretnej wartości."
 
-#: option.c:450
+#: option.c:467
+#, fuzzy
+msgid "Set tag if client provides given name."
+msgstr "Ustawienie znacznika jeżeli w żądaniu DHCP pojawi się wskazana opcja, ewentualnie o konkretnej wartości."
+
+#: option.c:468
 msgid "Use alternative ports for DHCP."
 msgstr "Użycie alternatywnych portów dla usługi DHCP."
 
-#: option.c:451
+#: option.c:469
 msgid "Specify NAPTR DNS record."
 msgstr "Specyfikacja rekordu DNS NAPTR."
 
-#: option.c:452
+#: option.c:470
 msgid "Specify lowest port available for DNS query transmission."
 msgstr "Ustawienie dolnej granicy numerów portów do przesyłania zapytań DNS."
 
-#: option.c:453
+#: option.c:471
 msgid "Specify highest port available for DNS query transmission."
 msgstr "Ograniczenie najwyższego numeru portu dla transmisji zapytań DNS."
 
-#: option.c:454
+#: option.c:472
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr "Przechowywanie w serwerze DNS dnsmasq-a tylko w pełni kwalifikowanych nazw zgłaszanych przez klientów DHCP."
 
-#: option.c:455
+#: option.c:473
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr "Generowanie nazw na podstawie MAC-adresów dla klientów bez nazwy."
 
-#: option.c:456
+#: option.c:474
 msgid "Use these DHCP relays as full proxies."
 msgstr "Traktowanie wskazanych serwerów pośredniczących DHCP jako działających w trybie \"pełnomocnika\" (full-proxy)."
 
-#: option.c:457
+#: option.c:475
 msgid "Relay DHCP requests to a remote server"
 msgstr "Przekazywanie żądań DHCP do zdalnego serwera"
 
-#: option.c:458
+#: option.c:476
 msgid "Specify alias name for LOCAL DNS name."
 msgstr "Wskazanie synonimu nazwy komputera lokalnego - znanego z /etc/hosts albo z DHCP."
 
-#: option.c:459
+#: option.c:477
 msgid "Prompt to send to PXE clients."
 msgstr "Zgłoszenie wysyłane klientom PXE."
 
-#: option.c:460
+#: option.c:478
 msgid "Boot service for PXE menu."
 msgstr "Składnik menu PXE (--> man)."
 
-#: option.c:461
+#: option.c:479
 msgid "Check configuration syntax."
 msgstr "Sprawdzenie składni."
 
-#: option.c:462
+#: option.c:480
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr "Przekazywanie MAC-adresu komputera pytającego w ruchu wychodzącym DNS."
 
-#: option.c:463
+#: option.c:481
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr "Zamieszczanie wskazanego adresu podsieci w przekazywanych zapytaniach DNS."
 
-#: option.c:464
+#: option.c:482
 msgid "Add client identification to forwarded DNS queries."
 msgstr "Zamieszczanie identyfikacji pytającego w przekazywanych zapytaniach DNS."
 
-#: option.c:465
+#: option.c:483
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr "Przekazywanie wyników weryfikacji DNSSEC z serwerów nadrzędnych."
 
-#: option.c:466
+#: option.c:484
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr "Zmiana sposobu przydzielania adresów IP na sekwencyjny."
 
-#: option.c:467
+#: option.c:485
+#, fuzzy
+msgid "Ignore client identifier option sent by DHCP clients."
+msgstr "Nie zwracanie uwagi na nazwę podawaną przez klienta w przypadku dopasowania wszystkich wymienionych znaczników."
+
+#: option.c:486
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr "Zachowanie znacznika połączenia z odebranego zapytania DNS w ruchu zewnętrznym."
 
-#: option.c:468
+#: option.c:487
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr "Zezwolenie klientom DHCP na uaktualnianie DDNS-ów."
 
-#: option.c:469
+#: option.c:488
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr "Załączenie anonsowania (RA) na interfejsach serwujących DHCPv6"
 
-#: option.c:470
+#: option.c:489
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr "Określenie DHCPv6 DUID"
 
-#: option.c:471
+#: option.c:490
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr "Określenie rekordów A/AAAA i PTR"
 
-#: option.c:472
+#: option.c:491
+msgid "Specify certification authority authorization record"
+msgstr ""
+
+#: option.c:492
 msgid "Specify arbitrary DNS resource record"
 msgstr "Określenie rekordu TXT"
 
-#: option.c:473
+#: option.c:493
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr "Dynamiczne podpinanie do interfejsów sieciowych"
 
-#: option.c:474
+#: option.c:494
 msgid "Export local names to global DNS"
 msgstr "Eksportowanie lokalnych nazw hostów do globalnego DNS-a"
 
-#: option.c:475
+#: option.c:495
 msgid "Domain to export to global DNS"
 msgstr "Domena pod którą będą eksportowane lokalne nazwy"
 
-#: option.c:476
+#: option.c:496
 msgid "Set TTL for authoritative replies"
 msgstr "Określenie TTL dla odpowiedzi autorytatywnych"
 
-#: option.c:477
+#: option.c:497
 #, fuzzy
 msgid "Set authoritative zone information"
 msgstr "Określenie danych strefy autorytatywnej (SOA)"
 
-#: option.c:478
+#: option.c:498
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr "Pomocnicze serwery autorytatywne dla forwardowanych domen"
 
-#: option.c:479
+#: option.c:499
 msgid "Peers which are allowed to do zone transfer"
 msgstr "Wskazanie serwerów uprawnionych do transferu stref"
 
-#: option.c:480
+#: option.c:500
 msgid "Specify ipsets to which matching domains should be added"
 msgstr "Wyszczególnienie ipset-ów, do których będą dopisywane adresy IP leżące we wskazanych domenach"
 
-#: option.c:481
+#: option.c:501
 msgid "Specify a domain and address range for synthesised names"
 msgstr "Wskazanie domeny i zakresu adresów dla generowanych nazw"
 
-#: option.c:482
+#: option.c:502
 msgid "Activate DNSSEC validation"
 msgstr "Uaktywnienie walidacji DNSSEC"
 
-#: option.c:483
+#: option.c:503
 msgid "Specify trust anchor key digest."
 msgstr "Wskazanie punktu zaufania dla uwierzytelniania DNSSEC."
 
-#: option.c:484
+#: option.c:504
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr "Akceptowanie nieuwiarygodnionych odpowiedzi DNSSEC (ustawienie bitu CD w zapytaniach)."
 
-#: option.c:485
+#: option.c:505
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr "Upewnianie się, że odpowiedzi bez DNSSEC pochodzą ze stref niepodpisanych."
 
-#: option.c:486
+#: option.c:506
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr "Wyłączenie sprawdzania sygnatur czasowych DNSSEC do pierwszego przeładowania pamięci podręcznej."
 
-#: option.c:487
+#: option.c:507
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr "Plik znacznika czasu do weryfikacji zegara systemowego dla potrzeb DNSSEC."
 
-#: option.c:489
-msgid "Specify DHCPv6 prefix class"
-msgstr "Określenie prefiksu klasy DHCPv6"
-
-#: option.c:491
+#: option.c:508
 #, fuzzy
 msgid "Set MTU, priority, resend-interval and router-lifetime"
 msgstr "Ustawianie priorytetu, okresu rozsyłania oraz czasu życia rutera (RA)."
 
-#: option.c:492
+#: option.c:509
 msgid "Do not log routine DHCP."
 msgstr "Wyłączenie logowania zwyczajnego DHCP."
 
-#: option.c:493
+#: option.c:510
 msgid "Do not log routine DHCPv6."
 msgstr "Wyłączenie logowania zwyczajnego DHCPv6."
 
-#: option.c:494
+#: option.c:511
 msgid "Do not log RA."
 msgstr "Wyłączenie logowania RA."
 
-#: option.c:495
+#: option.c:512
 msgid "Accept queries only from directly-connected networks."
 msgstr "Akceptowanie zapytań wyłącznie z sieci podpiętych bezpośrednio."
 
-#: option.c:496
+#: option.c:513
 msgid "Detect and remove DNS forwarding loops."
 msgstr "Wykrywanie i usuwanie pętli zapytań DNS."
 
-#: option.c:497
+#: option.c:514
 msgid "Ignore DNS responses containing ipaddr."
 msgstr "Ignorowanie odpowiedzi DNS zawierających ipaddr."
 
-#: option.c:498
+#: option.c:515
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr "Ustawienie TTL w odpowiedziach DNS dla adresów przydzielonych przez DHCP."
 
-#: option.c:499
+#: option.c:516
 msgid "Delay DHCP replies for at least number of seconds."
 msgstr ""
 
-#: option.c:703
+#: option.c:517
+msgid "Enables DHCPv4 Rapid Commit option."
+msgstr ""
+
+#: option.c:518
+msgid "Path to debug packet dump file"
+msgstr ""
+
+#: option.c:519
+msgid "Mask which packets to dump"
+msgstr ""
+
+#: option.c:520
+#, fuzzy
+msgid "Call dhcp-script when lease expiry changes."
+msgstr "Wywoływanie dhcp-script w reakcji na zmiany w tablicy ARP."
+
+#: option.c:725
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
@@ -762,320 +801,335 @@ msgstr ""
 "Użycie: dnsmasq [opcje]\n"
 "\n"
 
-#: option.c:705
+#: option.c:727
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr "W tym systemie w linii poleceń można używać wyłącznie jednoliterowych opcji.\n"
 
-#: option.c:707
+#: option.c:729
 #, c-format
 msgid "Valid options are:\n"
 msgstr "Dostępne opcje:\n"
 
-#: option.c:754 option.c:868
+#: option.c:776 option.c:884
 msgid "bad address"
 msgstr "zły adres"
 
-#: option.c:779 option.c:783
+#: option.c:799 option.c:803
 msgid "bad port"
 msgstr "nieprawidłowy numer portu"
 
-#: option.c:797 option.c:826 option.c:861
+#: option.c:815 option.c:844 option.c:878
 msgid "interface binding not supported"
 msgstr "nie ma możliwości dowiązywania do interfejsu"
 
-#: option.c:821 option.c:856
+#: option.c:839 option.c:873
 msgid "interface can only be specified once"
 msgstr ""
 
-#: option.c:835 option.c:3809
+#: option.c:852 option.c:4042
 msgid "bad interface name"
 msgstr "nieprawidłowa nazwa interfejsu"
 
-#: option.c:1062
+#: option.c:1184
 msgid "unsupported encapsulation for IPv6 option"
 msgstr "nieobsługiwany rodzaj enkapsulacji opcji IPv6"
 
-#: option.c:1076
+#: option.c:1198
 msgid "bad dhcp-option"
 msgstr "błąd w dhcp-option"
 
-#: option.c:1144
+#: option.c:1270
 msgid "bad IP address"
 msgstr "zły adres IP"
 
-#: option.c:1147 option.c:1286 option.c:3079
+#: option.c:1273 option.c:1412 option.c:3297
 msgid "bad IPv6 address"
 msgstr "zły adres IPv6"
 
-#: option.c:1240
+#: option.c:1366
 msgid "bad IPv4 address"
 msgstr "nieprawidłowy adres IPv4"
 
-#: option.c:1313 option.c:1407
+#: option.c:1439 option.c:1533
 msgid "bad domain in dhcp-option"
 msgstr "nieprawidłowa nazwa domeny w dhcp-option"
 
-#: option.c:1445
+#: option.c:1571
 msgid "dhcp-option too long"
 msgstr "zbyt długa dhcp-option (>255 znaków)"
 
-#: option.c:1452
+#: option.c:1578
 msgid "illegal dhcp-match"
 msgstr "niedopuszczalne dhcp-match"
 
-#: option.c:1514
+#: option.c:1647
 msgid "illegal repeated flag"
 msgstr "wielokrotne użycie opcji niedozwolone (pojawiła się wcześniej w linii poleceń)"
 
-#: option.c:1522
+#: option.c:1655
 msgid "illegal repeated keyword"
 msgstr "wielokrotne użycie opcji niedozwolone (pojawiła się wsześniej w pliku konfiguracyjnym)"
 
-#: option.c:1593 option.c:4443
+#: option.c:1726 option.c:4764
 #, c-format
 msgid "cannot access directory %s: %s"
 msgstr "brak dostępu do katalogu %s: %s"
 
-#: option.c:1639 tftp.c:537
+#: option.c:1772 tftp.c:564 dump.c:68
 #, c-format
 msgid "cannot access %s: %s"
 msgstr "brak dostępu do %s: %s"
 
-#: option.c:1727
+#: option.c:1879
 msgid "setting log facility is not possible under Android"
 msgstr "zmiana log-facility w systemie Android nie jest możliwa"
 
-#: option.c:1736
+#: option.c:1888
 msgid "bad log facility"
 msgstr "nierozpoznany znacznik logów"
 
-#: option.c:1789
+#: option.c:1941
 msgid "bad MX preference"
 msgstr "nieprawidłowa wartość preferencji MX"
 
-#: option.c:1794
+#: option.c:1946
 msgid "bad MX name"
 msgstr "nieprawidłowa nazwa MX"
 
-#: option.c:1808
+#: option.c:1960
 msgid "bad MX target"
 msgstr "nieprawidłowa wartość celu MX"
 
-#: option.c:1820
-msgid "cannot run scripts under uClinux"
-msgstr "w uClinuksie nie ma możliwości uruchamiania skryptów"
-
-#: option.c:1822
+#: option.c:1980
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr "żeby mieć możliwość używania skryptów wywoływanych przy zmianie dzierżawy, przekompiluj dnsmasq-a z włączoną flagą HAVE_SCRIPT"
 
-#: option.c:1826
+#: option.c:1984
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr "używanie skryptów Lua, wymaga skompilowania dnsmasq-a z flagą HAVE_LUASCRIPT"
 
-#: option.c:2095 option.c:2106 option.c:2143 option.c:2199 option.c:2482
+#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
 msgid "bad prefix"
 msgstr "zła maska"
 
-#: option.c:2504
+#: option.c:2658
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr "chcąc korzystać z ipsets przekompiluj dnsmasq-a z HAVE_IPSET"
 
-#: option.c:2713
+#: option.c:2871
 msgid "bad port range"
 msgstr "nieprawidłowy zakres numerów portów"
 
-#: option.c:2739
+#: option.c:2897
 msgid "bad bridge-interface"
 msgstr "nieprawidłowa nazwa urządzenia w bridge-interface"
 
-#: option.c:2807
+#: option.c:2941
+msgid "bad shared-network"
+msgstr ""
+
+#: option.c:2996
 msgid "only one tag allowed"
 msgstr "można wskazać tylko jeden znacznik sieci"
 
-#: option.c:2827 option.c:2839 option.c:2948 option.c:2953 option.c:2992
+#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
 msgid "bad dhcp-range"
 msgstr "nieprawidłowy zakres dhcp-range"
 
-#: option.c:2854
+#: option.c:3050
 msgid "inconsistent DHCP range"
 msgstr "niespójny zakres adresów DHCP"
 
-#: option.c:2916
+#: option.c:3115
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr "długość prefiksu musi wynosić dokładnie 64 dla podsieci RA"
 
-#: option.c:2918
+#: option.c:3117
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr "długość prefiksu musi wynosić dokładnie 64 dla konstruktorów podsieci"
 
-#: option.c:2922
+#: option.c:3120
 msgid "prefix length must be at least 64"
 msgstr "długość prefiksu musi wynosić co najmniej 64"
 
-#: option.c:2925
+#: option.c:3123
 msgid "inconsistent DHCPv6 range"
 msgstr "niespójny zakres adresów DHCPv6"
 
-#: option.c:2936
+#: option.c:3142
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr "prefiks musi wynosić zero z argumentem \"constructor:\""
 
-#: option.c:3049 option.c:3097
+#: option.c:3262 option.c:3340
 msgid "bad hex constant"
 msgstr "zapis niezgodny z formatem szesnastkowym"
 
-#: option.c:3071
-msgid "cannot match tags in --dhcp-host"
-msgstr "--dhcp-host nie dopuszcza dopasowywania na podstawie znaczników"
+#: option.c:3315
+#, fuzzy
+msgid "bad IPv6 prefix"
+msgstr "zła maska"
 
-#: option.c:3119
+#: option.c:3362
 #, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr "powtórzony adres IP %s w specyfikacji dhcp-host"
 
-#: option.c:3177
+#: option.c:3422
 msgid "bad DHCP host name"
 msgstr "niedopuszczalna nazwa komputera w dhcp-host"
 
-#: option.c:3259
+#: option.c:3508
 msgid "bad tag-if"
 msgstr "nieprawidłowa składnia 'tag-if'"
 
-#: option.c:3616 option.c:4039
+#: option.c:3851 option.c:4324
 msgid "invalid port number"
 msgstr "nieprawidłowy numer portu"
 
-#: option.c:3678
+#: option.c:3907
 msgid "bad dhcp-proxy address"
 msgstr "zły adres dhcp-proxy"
 
-#: option.c:3704
+#: option.c:3935
 msgid "Bad dhcp-relay"
 msgstr "zły dhcp-relay"
 
-#: option.c:3745
+#: option.c:3979
 msgid "bad RA-params"
 msgstr "nieprawidłowe argumenty RA"
 
-#: option.c:3754
+#: option.c:3989
 msgid "bad DUID"
 msgstr "zły DUID"
 
-#: option.c:3796
+#: option.c:4023
+#, fuzzy
+msgid "missing address in alias"
+msgstr "niepoprawny adres"
+
+#: option.c:4029
 msgid "invalid alias range"
 msgstr "nieprawidłowy zakres adresów w --alias"
 
-#: option.c:3850 option.c:3862
+#: option.c:4081 option.c:4097
 msgid "bad CNAME"
 msgstr "zła CNAME"
 
-#: option.c:3866
+#: option.c:4105
 msgid "duplicate CNAME"
 msgstr "powtórzona CNAME"
 
-#: option.c:3889
+#: option.c:4132
 msgid "bad PTR record"
 msgstr "nieprawidłowy zapis rekordu PTR"
 
-#: option.c:3920
+#: option.c:4167
 msgid "bad NAPTR record"
 msgstr "nieprawidłowy zapis rekordu NAPTR"
 
-#: option.c:3954
+#: option.c:4203
 msgid "bad RR record"
 msgstr "nieprawidłowy zapis rekordu RR"
 
-#: option.c:3984
+#: option.c:4236
+#, fuzzy
+msgid "bad CAA record"
+msgstr "nieprawidłowy zapis rekordu RR"
+
+#: option.c:4265
 msgid "bad TXT record"
 msgstr "nieprawidłowy zapis rekordu TXT"
 
-#: option.c:4025
+#: option.c:4308
 msgid "bad SRV record"
 msgstr "nieprawidłowy zapis rekordu SRV"
 
-#: option.c:4032
+#: option.c:4315
 msgid "bad SRV target"
 msgstr "nieprawidłowa wartość celu SRV"
 
-#: option.c:4046
+#: option.c:4334
 msgid "invalid priority"
 msgstr "nieprawidłowy priorytet"
 
-#: option.c:4049
+#: option.c:4339
 msgid "invalid weight"
 msgstr "nieprawidłowa waga"
 
-#: option.c:4073
+#: option.c:4362
 msgid "Bad host-record"
 msgstr "nieprawidłowy zapis host-record"
 
-#: option.c:4097
+#: option.c:4402
 msgid "Bad name in host-record"
 msgstr "niedopuszczalna nazwa w host-record"
 
-#: option.c:4162
+#: option.c:4444
+msgid "bad value for dnssec-check-unsigned"
+msgstr ""
+
+#: option.c:4480
 msgid "bad trust anchor"
 msgstr "nieprawidłowa specyfikacja punktu zaufania"
 
-#: option.c:4176
+#: option.c:4496
 msgid "bad HEX in trust anchor"
 msgstr "zły zapis szesnastkowy"
 
-#: option.c:4186
+#: option.c:4507
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr "nieobsługiwana opcja (sprawdź, czy obsługa DHCP/TFTP/DNSSEC/DBus została wkompilowana)"
 
-#: option.c:4246
+#: option.c:4567
 msgid "missing \""
 msgstr "brakuje \""
 
-#: option.c:4303
+#: option.c:4624
 msgid "bad option"
 msgstr "nieprawidłowa opcja"
 
-#: option.c:4305
+#: option.c:4626
 msgid "extraneous parameter"
 msgstr "nadwyżkowy parametr"
 
-#: option.c:4307
+#: option.c:4628
 msgid "missing parameter"
 msgstr "brak parametru"
 
-#: option.c:4309
+#: option.c:4630
 msgid "illegal option"
 msgstr "niedopuszczalna opcja"
 
-#: option.c:4316
+#: option.c:4637
 msgid "error"
 msgstr "błąd"
 
-#: option.c:4318
+#: option.c:4639
 #, c-format
 msgid " at line %d of %s"
 msgstr " w linii %d pliku %s"
 
-#: option.c:4333 option.c:4580 option.c:4616
+#: option.c:4654 option.c:4939 option.c:4950
 #, c-format
 msgid "read %s"
 msgstr "przeczytałem %s"
 
-#: option.c:4396 option.c:4519 tftp.c:715
+#: option.c:4717 option.c:4840 tftp.c:754
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "błąd odczytu z pliku %s: %s"
 
-#: option.c:4688
+#: option.c:5027
 msgid "junk found in command line"
 msgstr "jakieś śmieci w linii poleceń"
 
-#: option.c:4729
+#: option.c:5067
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr "Dnsmasq, wersja %s  %s\n"
 
-#: option.c:4730
+#: option.c:5068
 #, c-format
 msgid ""
 "Compile time options: %s\n"
@@ -1084,501 +1138,553 @@ msgstr ""
 "Wkompilowane opcje %s\n"
 "\n"
 
-#: option.c:4731
+#: option.c:5069
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr "Autor nie daje ŻADNYCH GWARANCJI egzekwowalnych prawnie.\n"
 
-#: option.c:4732
+#: option.c:5070
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr "Dnsmasq jest wolnym oprogramowaniem, możesz go rozprowadzać\n"
 
-#: option.c:4733
+#: option.c:5071
 #, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr "na warunkach określonych w GNU General Public Licence, w wersji 2 lub 3.\n"
 
-#: option.c:4744
+#: option.c:5088
 msgid "try --help"
 msgstr "spróbuj: --help"
 
-#: option.c:4746
+#: option.c:5090
 msgid "try -w"
 msgstr "spróbuj: -w"
 
-#: option.c:4748
+#: option.c:5092
 #, c-format
 msgid "bad command line options: %s"
 msgstr "nieprawidłowa opcja w linii poleceń %s"
 
-#: option.c:4818
+#: option.c:5161
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr ""
 
-#: option.c:4854
+#: option.c:5195
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr "nie można pobrać nazwy hosta: %s"
 
-#: option.c:4882
+#: option.c:5223
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr "w trybie no-poll można wskazać najwyżej jeden plik resolv.conf."
 
-#: option.c:4892
+#: option.c:5233
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr "musisz mieć dokładnie jeden plik resolv.conf do odczytu domen."
 
-#: option.c:4895 network.c:1623 dhcp.c:816
+#: option.c:5236 network.c:1594 dhcp.c:876
 #, c-format
 msgid "failed to read %s: %s"
 msgstr "nie udało się odczytać %s: %s"
 
-#: option.c:4912
+#: option.c:5253
 #, c-format
 msgid "no search directive found in %s"
 msgstr "brak wytycznych wyszukiwania w %s"
 
-#: option.c:4933
+#: option.c:5274
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr "w przypadku używania --dhcp-fqdn trzeba wskazać domyślną domenę"
 
-#: option.c:4942
+#: option.c:5283
 msgid "syntax check OK"
 msgstr "składnia sprawdzona, jest prawidłowa"
 
-#: forward.c:102
+#: forward.c:99
 #, c-format
 msgid "failed to send packet: %s"
 msgstr "wysyłanie pakietu nie powiodło się: %s"
 
-#: forward.c:598
+#: forward.c:614
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr "odrzucam odpowiedź DNS: nie zgadza się specyfikacja podsieci"
 
-#: forward.c:652
+#: forward.c:677
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr "serwer nazw %s odmawia wykonania zapytania rekurencyjnego"
 
-#: forward.c:684
+#: forward.c:709
 #, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr "prawdopodobnie wykryto atak DNS-rebind: %s"
 
-#: forward.c:870
+#: forward.c:961
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
 msgstr ""
 
-#: forward.c:1266 forward.c:1704
+#: forward.c:1370 forward.c:1830
 msgid "Ignoring query from non-local network"
 msgstr "Ignorowanie zapytań z sieci pozalokalnych."
 
-#: forward.c:2184
+#: forward.c:2321
 #, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr "Osiągnięto graniczną ilość jednocześnie obsługiwanych zapytań DNS (maks: %d)"
 
-#: network.c:720
+#: network.c:698
 #, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr "nie udało się otworzyć gniazda %s: %s"
 
-#: network.c:1031
+#: network.c:1002
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr "UWAGA: nasłuchiwanie na %s może przyjmować żądania przychodzące przez interfejsy inne niż %s"
 
-#: network.c:1038
+#: network.c:1009
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr "UWAGA: zastosowanie --bind-dynamic zamiast --bind-interfaces daje ochronę przed atakami wzmocnienia DNS"
 
-#: network.c:1047
+#: network.c:1018
 #, fuzzy, c-format
 msgid "warning: using interface %s instead"
 msgstr "uwaga: %s niedostępny"
 
-#: network.c:1056
+#: network.c:1027
 #, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr "uwaga: nie znaleziono adresu interfejsu %s"
 
-#: network.c:1114
+#: network.c:1085
 #, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr "interfejs %s nie pozwolił się przyłączyć do grupy rozgłoszeniowej DHCPv6: %s"
 
-#: network.c:1119
+#: network.c:1090
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr "spróbuj podwyższyć /proc/sys/net/core/optmem_max"
 
-#: network.c:1337
+#: network.c:1307
 #, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr "błąd przy przyznawaniu nazwy gniazdu serwera %s: %s"
 
-#: network.c:1528
+#: network.c:1499
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr "ignorowanie serwera nazw %s - interfejs lokalny"
 
-#: network.c:1539
+#: network.c:1510
 #, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr "ignorowanie serwera nazw %s - nie można utworzyć/dowiązać gniazda: %s"
 
-#: network.c:1559
+#: network.c:1530
 msgid "(no DNSSEC)"
 msgstr "(brak obsługi DNSSEC)"
 
-#: network.c:1562
+#: network.c:1533
 msgid "unqualified"
 msgstr "niekwalifikowane(-a)"
 
-#: network.c:1562
+#: network.c:1533
 msgid "names"
 msgstr "nazwy"
 
-#: network.c:1564
+#: network.c:1535
 msgid "default"
 msgstr "domyślne"
 
-#: network.c:1566
+#: network.c:1537
 msgid "domain"
 msgstr "domeny"
 
-#: network.c:1572
-#, c-format
-msgid "using local addresses only for %s %s"
+#: network.c:1543
+#, fuzzy, c-format
+msgid "using only locally-known addresses for %s %s"
 msgstr "używam adresów lokalnych tylko dla %s %s"
 
-#: network.c:1575
+#: network.c:1546
 #, c-format
 msgid "using standard nameservers for %s %s"
 msgstr "używam standardowych serwerów nazw dla %s %s"
 
-#: network.c:1577
+#: network.c:1548
 #, c-format
 msgid "using nameserver %s#%d for %s %s %s"
 msgstr "używam serwera nazw %s#%d dla %s %s %s"
 
-#: network.c:1581
+#: network.c:1552
 #, c-format
 msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr "NIE używam serwera nazw %s#%d - wykryto pętlę zapytań"
 
-#: network.c:1584
+#: network.c:1555
 #, c-format
 msgid "using nameserver %s#%d(via %s)"
 msgstr "używam serwera nazw %s#%d (przez %s)"
 
-#: network.c:1586
+#: network.c:1557
 #, c-format
 msgid "using nameserver %s#%d"
 msgstr "używam serwera nazw %s#%d"
 
-#: network.c:1591
+#: network.c:1562
 #, fuzzy, c-format
 msgid "using %d more local addresses"
 msgstr "używam o %d serwerów nazw więcej"
 
-#: network.c:1593
+#: network.c:1564
 #, c-format
 msgid "using %d more nameservers"
 msgstr "używam o %d serwerów nazw więcej"
 
-#: dnsmasq.c:171
+#: dnsmasq.c:173
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr "dhcp-hostsdir, dhcp-optsdir i hostsdir nie znajdują zastosowania na tej platformie"
 
-#: dnsmasq.c:186
+#: dnsmasq.c:188
 msgid "no root trust anchor provided for DNSSEC"
 msgstr "nie wskazano punktów zaufania dla DNSSEC"
 
-#: dnsmasq.c:189
+#: dnsmasq.c:191
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr "brak możliwości zmniejszenia pamięci podręcznej poniżej wielkości domyślnej w przypadku używania DNSSEC"
 
-#: dnsmasq.c:191
+#: dnsmasq.c:193
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr "obsługa DNSSEC niedostępna - ustaw HAVE_DNSSEC w src/config.h"
 
-#: dnsmasq.c:197
+#: dnsmasq.c:199
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr "Serwer TFTP nie został wkompilowany -- ustaw HAVE_TFTP w src/config.h"
 
-#: dnsmasq.c:202
+#: dnsmasq.c:204
 msgid "cannot use --conntrack AND --query-port"
 msgstr "--conntrack i --query-port wzajemnie się wykluczają"
 
-#: dnsmasq.c:205
+#: dnsmasq.c:207
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr "wsparcie przekazywania znaczników połączeń (conntrack) nie zostało wkompilowane - ustaw HAVE_CONNTRACK w src/config.h"
 
-#: dnsmasq.c:210
+#: dnsmasq.c:212
 msgid "asynchronous logging is not available under Solaris"
 msgstr "zapis do logów w trybie asynchronicznym nie jest dostępny w Solarisie"
 
-#: dnsmasq.c:215
+#: dnsmasq.c:217
 msgid "asynchronous logging is not available under Android"
 msgstr "zapis do logów w trybie asynchronicznym nie jest dostępny w Androidzie"
 
-#: dnsmasq.c:220
+#: dnsmasq.c:222
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr "tryb autorytatywny DNS-a niedostępny - ustaw HAVE_AUTH w src/config.h"
 
-#: dnsmasq.c:225
+#: dnsmasq.c:227
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr "wykrywanie pętli zapytań nie zostało wkompilowane - ustaw HAVE_LOOP w src/config.h"
 
-#: dnsmasq.c:229
+#: dnsmasq.c:232
+#, fuzzy
+msgid "Ubus not available: set HAVE_UBUS in src/config.h"
+msgstr "Obsługa DBus nie została wkompilowana -- ustaw HAVE_DBUS w src/config.h"
+
+#: dnsmasq.c:236
 msgid "max_port cannot be smaller than min_port"
 msgstr "max_port nie może być niższy niż min_port"
 
-#: dnsmasq.c:236
+#: dnsmasq.c:243
+msgid "--auth-server required when an auth zone is defined."
+msgstr ""
+
+#: dnsmasq.c:248
 msgid "zone serial must be configured in --auth-soa"
 msgstr "za pomocą --auth-soa musi zostać ustawiony numer seryjny strefy"
 
-#: dnsmasq.c:254
+#: dnsmasq.c:268
 msgid "dhcp-range constructor not available on this platform"
 msgstr "konstrukcja dhcp-range nie jest dostępna w tym systemie"
 
-#: dnsmasq.c:300
+#: dnsmasq.c:332
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr "--bind-interfaces i --bind-dynamic wzajemnie się wykluczają"
 
-#: dnsmasq.c:303
+#: dnsmasq.c:335
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr "błąd podczas tworzenia listy interfejsów sieciowych: %s"
 
-#: dnsmasq.c:312
+#: dnsmasq.c:344
 #, c-format
 msgid "unknown interface %s"
 msgstr "nieznany interfejs %s"
 
-#: dnsmasq.c:377 dnsmasq.c:1054
+#: dnsmasq.c:406
+#, fuzzy
+msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
+msgstr "Obsługa DBus nie została wkompilowana -- ustaw HAVE_DBUS w src/config.h"
+
+#: dnsmasq.c:416 dnsmasq.c:1171
 #, c-format
 msgid "DBus error: %s"
 msgstr "błąd DBus: %s"
 
-#: dnsmasq.c:380
+#: dnsmasq.c:419
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr "Obsługa DBus nie została wkompilowana -- ustaw HAVE_DBUS w src/config.h"
 
-#: dnsmasq.c:410
+#: dnsmasq.c:429
+#, fuzzy
+msgid "UBus not available: set HAVE_UBUS in src/config.h"
+msgstr "Obsługa DBus nie została wkompilowana -- ustaw HAVE_DBUS w src/config.h"
+
+#: dnsmasq.c:459
 #, c-format
 msgid "unknown user or group: %s"
 msgstr "nieznany użytkownik lub grupa: %s"
 
-#: dnsmasq.c:465
+#: dnsmasq.c:535
+#, c-format
+msgid "process is missing required capability %s"
+msgstr ""
+
+#: dnsmasq.c:567
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr "nie potrafię wejść do głównego katalogu: %s"
 
-#: dnsmasq.c:730
+#: dnsmasq.c:815
 #, c-format
 msgid "started, version %s DNS disabled"
 msgstr "uruchomiony, wersja %s, DNS wyłączony"
 
-#: dnsmasq.c:734
+#: dnsmasq.c:820
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr "uruchomiony, wersja %s, %d miejsc w pamięci podręcznej"
 
-#: dnsmasq.c:736
+#: dnsmasq.c:822
+msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
+msgstr ""
+
+#: dnsmasq.c:825
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr "uruchomiony, wersja %s, pamięć podręczna wyłączona"
 
-#: dnsmasq.c:739
+#: dnsmasq.c:828
 msgid "DNS service limited to local subnets"
 msgstr "usługa DNS ograniczona do lokalnych podsieci"
 
-#: dnsmasq.c:742
+#: dnsmasq.c:831
 #, c-format
 msgid "compile time options: %s"
 msgstr "opcje kompilacji: %s"
 
-#: dnsmasq.c:751
+#: dnsmasq.c:840
 msgid "DBus support enabled: connected to system bus"
 msgstr "obsługa DBus włączona, podłączono do serwera DBus"
 
-#: dnsmasq.c:753
+#: dnsmasq.c:842
 msgid "DBus support enabled: bus connection pending"
 msgstr "obsługa DBus włączona, trwa podłączanie do serwera DBus"
 
-#: dnsmasq.c:771
+#: dnsmasq.c:850
+#, fuzzy
+msgid "UBus support enabled: connected to system bus"
+msgstr "obsługa DBus włączona, podłączono do serwera DBus"
+
+#: dnsmasq.c:852
+#, fuzzy
+msgid "UBus support enabled: bus connection pending"
+msgstr "obsługa DBus włączona, trwa podłączanie do serwera DBus"
+
+#: dnsmasq.c:872
+msgid "DNSSEC validation enabled but all unsigned answers are trusted"
+msgstr ""
+
+#: dnsmasq.c:874
 msgid "DNSSEC validation enabled"
 msgstr "walidacja DNSSEC włączona"
 
-#: dnsmasq.c:775
+#: dnsmasq.c:878
 #, fuzzy
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr "sprawdzanie sygnatur czasowych DNSSEC wyłączone do czasu przeładowania pamięci podręcznej"
 
-#: dnsmasq.c:778
+#: dnsmasq.c:881
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr "sprawdzanie sygnatur czasowych DNSSEC wyłączone do czasu zsynchronizowania się zegara systemowego"
 
-#: dnsmasq.c:783
+#: dnsmasq.c:884
+#, c-format
+msgid "configured with trust anchor for %s keytag %u"
+msgstr ""
+
+#: dnsmasq.c:890
 #, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr "uwaga: nie udało się zmienić użytkownika pliku %s: %s"
 
-#: dnsmasq.c:787
+#: dnsmasq.c:894
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr "ustawiam --bind-interfaces z powodu ograniczeń systemu operacyjnego"
 
-#: dnsmasq.c:799
+#: dnsmasq.c:906
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr "uwaga: interfejs %s nie jest włączony"
 
-#: dnsmasq.c:804
+#: dnsmasq.c:911
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr "uwaga: ignoruję opcję resolv-file, ponieważ wybrano tryb no-resolv"
 
-#: dnsmasq.c:807
+#: dnsmasq.c:914
 msgid "warning: no upstream servers configured"
 msgstr "uwaga: nie wskazano nadrzędnych serwerów DNS"
 
-#: dnsmasq.c:811
+#: dnsmasq.c:918
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr "włączono asynchroniczny tryb zapisu do logów z kolejką na %d komunikatów"
 
-#: dnsmasq.c:832
+#: dnsmasq.c:939
 msgid "IPv6 router advertisement enabled"
 msgstr "anonsowanie rutera IPv6 włączone"
 
-#: dnsmasq.c:837
+#: dnsmasq.c:944
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr "DHCP, gniazda dowiązane na wyłączność interfejsowi %s"
 
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 msgid "root is "
 msgstr "z głównym katalogiem w "
 
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 msgid "enabled"
 msgstr "włączony"
 
-#: dnsmasq.c:853
+#: dnsmasq.c:960
 msgid "secure mode"
 msgstr "w trybie bezpiecznym"
 
-#: dnsmasq.c:856
+#: dnsmasq.c:961
+#, fuzzy
+msgid "single port mode"
+msgstr "nieprawidłowy numer portu"
+
+#: dnsmasq.c:964
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr "uwaga: %s niedostępny"
 
-#: dnsmasq.c:860
+#: dnsmasq.c:968
 #, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr "uwaga: katalog TFTP %s nie jest dostępny"
 
-#: dnsmasq.c:886
+#: dnsmasq.c:994
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr "ograniczam ilość jednoczesnych przesłań TFTP do %d"
 
-#: dnsmasq.c:1056
+#: dnsmasq.c:1173
 msgid "connected to system DBus"
 msgstr "podłączono do DBus-a"
 
-#: dnsmasq.c:1215
+#: dnsmasq.c:1345
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr "nie potrafię przełączyć się do pracy w tle: %s"
 
-#: dnsmasq.c:1218
+#: dnsmasq.c:1349
 #, c-format
 msgid "failed to create helper: %s"
 msgstr "nie udało się utworzyć procesu pomocniczego: %s"
 
-#: dnsmasq.c:1221
+#: dnsmasq.c:1353
 #, c-format
 msgid "setting capabilities failed: %s"
 msgstr "nie powiodło się ustawianie ograniczeń (capabilities): %s"
 
-#: dnsmasq.c:1224
+#: dnsmasq.c:1357
 #, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr "nie udało się zmienić użytkownika procesu na %s: %s"
 
-#: dnsmasq.c:1227
+#: dnsmasq.c:1361
 #, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr "nie udało się zmienić grupy procesu na %s: %s"
 
-#: dnsmasq.c:1230
+#: dnsmasq.c:1365
 #, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr "nie udało się otworzyć pliku z PID-em %s: %s"
 
-#: dnsmasq.c:1233
+#: dnsmasq.c:1369
 #, c-format
 msgid "cannot open log %s: %s"
 msgstr "nie udało się otworzyć logu %s: %s"
 
-#: dnsmasq.c:1236
+#: dnsmasq.c:1373
 #, c-format
 msgid "failed to load Lua script: %s"
 msgstr "nie udało się wczytać skryptu Lua: %s"
 
-#: dnsmasq.c:1239
+#: dnsmasq.c:1377
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr "katalog TFTP %s nie jest dostępny: %s"
 
-#: dnsmasq.c:1242
+#: dnsmasq.c:1381
 #, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr "nie potrafię utworzyć pliku znacznika czasu %s: %s"
 
-#: dnsmasq.c:1326
+#: dnsmasq.c:1465
 #, c-format
 msgid "script process killed by signal %d"
 msgstr "skrypt został zabity sygnałem %d"
 
-#: dnsmasq.c:1330
+#: dnsmasq.c:1469
 #, c-format
 msgid "script process exited with status %d"
 msgstr "skrypt zakończył się z kodem powrotu %d"
 
-#: dnsmasq.c:1334
+#: dnsmasq.c:1473
 #, c-format
 msgid "failed to execute %s: %s"
 msgstr "nie udało się uruchomić %s: %s"
 
-#: dnsmasq.c:1374
+#: dnsmasq.c:1513
 msgid "now checking DNSSEC signature timestamps"
 msgstr "trwa sprawdzanie sygnatur czasowych podpisów DNSSEC"
 
-#: dnsmasq.c:1409 dnssec.c:160 dnssec.c:206
+#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
 #, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr "nie udało się uaktualnić znacznika czasu pliku %s: %s"
 
-#: dnsmasq.c:1416
+#: dnsmasq.c:1560
 msgid "exiting on receipt of SIGTERM"
 msgstr "zakończyłem działanie z powodu odebrania SIGTERM"
 
-#: dnsmasq.c:1444
+#: dnsmasq.c:1588
 #, c-format
 msgid "failed to access %s: %s"
 msgstr "brak dostępu do %s: %s"
 
-#: dnsmasq.c:1474
+#: dnsmasq.c:1618
 #, c-format
 msgid "reading %s"
 msgstr "czytanie %s"
 
-#: dnsmasq.c:1485
+#: dnsmasq.c:1629
 #, c-format
 msgid "no servers found in %s, will retry"
 msgstr "w %s nie znalazłem serwerów, spróbuję ponownie później"
@@ -1608,7 +1714,7 @@ msgstr "błąd przy przyznawaniu nazwy gniazdu serwera DHCP: %s"
 msgid "cannot create ICMP raw socket: %s."
 msgstr "nie udało się utworzyć surowego gniazda ICMP: %s."
 
-#: dhcp.c:252 dhcp6.c:173
+#: dhcp.c:252 dhcp6.c:180
 #, c-format
 msgid "unknown interface %s in bridge-interface"
 msgstr "nieznany interfejs %s w bridge-u"
@@ -1618,331 +1724,337 @@ msgstr "nieznany interfejs %s w bridge-u"
 msgid "DHCP packet received on %s which has no address"
 msgstr "żądanie DHCP odebrano na interfejsie %s, który nie ma adresu"
 
-#: dhcp.c:427
+#: dhcp.c:428
 #, c-format
 msgid "ARP-cache injection failed: %s"
 msgstr "uzupełnienie pamięci podręcznej ARP nie powiodło się: %s"
 
-#: dhcp.c:470
+#: dhcp.c:471
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr "Błąd wysyłania pakietu DHCP do %s: %s"
 
-#: dhcp.c:531
+#: dhcp.c:526
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr "zakres adresów DHCP %s -- %s jest niespójny z maską sieci %s"
 
-#: dhcp.c:854
+#: dhcp.c:914
 #, c-format
 msgid "bad line at %s line %d"
 msgstr "zła zawartość pliku %s, w linii %d"
 
-#: dhcp.c:897
+#: dhcp.c:957
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr "w %s pomijam linię %d -- powtórzona nazwa lub adres IP"
 
-#: dhcp.c:1041 rfc3315.c:2149
+#: dhcp.c:1100 rfc3315.c:2139
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr "przekazywanie DHCP %s -> %s"
 
-#: lease.c:98
+#: lease.c:64
+#, c-format
+msgid "ignoring invalid line in lease database: %s %s %s %s ..."
+msgstr ""
+
+#: lease.c:101
+#, c-format
+msgid "ignoring invalid line in lease database, bad address: %s"
+msgstr ""
+
+#: lease.c:108
 msgid "too many stored leases"
 msgstr "zbyt duża ilość zapisanych dzierżaw"
 
-#: lease.c:166
+#: lease.c:176
 #, c-format
 msgid "cannot open or create lease file %s: %s"
 msgstr "nie potrafię otworzyć albo utworzyć pliku dzierżaw %s: %s"
 
-#: lease.c:175
-#, c-format
-msgid "failed to parse lease database, invalid line: %s %s %s %s ..."
-msgstr ""
+#: lease.c:185
+#, fuzzy
+msgid "failed to parse lease database cleanly"
+msgstr "nie udało się odczytać %s: %s"
 
-#: lease.c:180
+#: lease.c:188
 #, fuzzy, c-format
 msgid "failed to read lease file %s: %s"
 msgstr "nie udało się odczytać %s: %s"
 
-#: lease.c:196
+#: lease.c:204
 #, c-format
 msgid "cannot run lease-init script %s: %s"
 msgstr "nie potrafię uruchomić skryptu %s: %s"
 
-#: lease.c:202
+#: lease.c:210
 #, c-format
 msgid "lease-init script returned exit code %s"
 msgstr "skrypt zakończył się z kodem powrotu %s"
 
-#: lease.c:373
+#: lease.c:381
 #, c-format
 msgid "failed to write %s: %s (retry in %us)"
 msgstr "błąd zapisu do %s: %s (spróbuję ponownie za %us)"
 
-#: lease.c:937
+#: lease.c:955
 #, c-format
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr "Nie uwzględniam części domenowej (%s) dla komputera %s"
 
-#: rfc2131.c:347
+#: rfc2131.c:372
 #, c-format
 msgid "no address range available for DHCP request %s %s"
 msgstr "nie zdefiniowano zakresu adresów odpowiedniego dla żądania %s %s"
 
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "with subnet selector"
 msgstr "z wyborem podsieci"
 
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "via"
 msgstr "przez"
 
-#: rfc2131.c:360
+#: rfc2131.c:385
 #, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr "%u dostępna podsieć DHCP: %s/%s"
 
-#: rfc2131.c:363 rfc3315.c:306
+#: rfc2131.c:388 rfc3315.c:319
 #, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr "%u dostępny zakres adresów DHCP: %s -- %s"
 
-#: rfc2131.c:474
+#: rfc2131.c:499
 #, c-format
 msgid "%u vendor class: %s"
 msgstr "%u klasa dostawcy: %s"
 
-#: rfc2131.c:476
+#: rfc2131.c:501
 #, c-format
 msgid "%u user class: %s"
 msgstr "%u klasa użytkownika: %s"
 
-#: rfc2131.c:510
+#: rfc2131.c:535
 msgid "disabled"
 msgstr "wyłączony(a)"
 
-#: rfc2131.c:551 rfc2131.c:1006 rfc2131.c:1430 rfc3315.c:616 rfc3315.c:869
-#: rfc3315.c:1148
+#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1097
 msgid "ignored"
 msgstr "ignoruję"
 
-#: rfc2131.c:566 rfc2131.c:1239 rfc3315.c:919
+#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
 msgid "address in use"
 msgstr "adres jest w użyciu"
 
-#: rfc2131.c:580 rfc2131.c:1060
+#: rfc2131.c:605 rfc2131.c:1119
 msgid "no address available"
 msgstr "brak dostępnego adresu"
 
-#: rfc2131.c:587 rfc2131.c:1202
+#: rfc2131.c:612 rfc2131.c:1273
 msgid "wrong network"
 msgstr "nieprawidłowa sieć"
 
-#: rfc2131.c:602
+#: rfc2131.c:627
 msgid "no address configured"
 msgstr "brak skonfigurowanego adresu"
 
-#: rfc2131.c:608 rfc2131.c:1252
+#: rfc2131.c:633 rfc2131.c:1323
 msgid "no leases left"
 msgstr "brak wolnych dzierżaw"
 
-#: rfc2131.c:703 rfc3315.c:482
+#: rfc2131.c:734 rfc3315.c:499
 #, c-format
 msgid "%u client provides name: %s"
 msgstr "klient %u przedstawia się jako %s"
 
-#: rfc2131.c:808
+#: rfc2131.c:864
 msgid "PXE BIS not supported"
 msgstr "PXE BIS nie jest obsługiwane"
 
-#: rfc2131.c:974 rfc3315.c:1242
+#: rfc2131.c:1032 rfc3315.c:1197
 #, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr "wyłączam statyczne przypisanie adresu %s dla %s"
 
-#: rfc2131.c:995
+#: rfc2131.c:1053
 msgid "unknown lease"
 msgstr "nieznana dzierżawa"
 
-#: rfc2131.c:1029
+#: rfc2131.c:1088
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr "nie proponuję zakładanego w konfiguracji adresu %s, bo jest on już wydzierżawiony komputerowi %s"
 
-#: rfc2131.c:1039
+#: rfc2131.c:1098
 #, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr "nie proponuję zakładanego w konfiguracji adresu %s, bo używa go któryś z serwerów"
 
-#: rfc2131.c:1042
+#: rfc2131.c:1101
 #, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr "nie proponuję zakładanego w konfiguracji adresu %s, bo już poprzednio został odrzucony"
 
-#: rfc2131.c:1058 rfc2131.c:1245
+#: rfc2131.c:1117 rfc2131.c:1316
 msgid "no unique-id"
 msgstr "brak unikalnego id"
 
-#: rfc2131.c:1140
+#: rfc2131.c:1209
 msgid "wrong server-ID"
 msgstr "nieprawidłowy identyfikator serwera (server-ID)"
 
-#: rfc2131.c:1159
+#: rfc2131.c:1228
 msgid "wrong address"
 msgstr "błędny adres"
 
-#: rfc2131.c:1177 rfc3315.c:1015
+#: rfc2131.c:1246 rfc3315.c:961
 msgid "lease not found"
 msgstr "dzierżawa nieznaleziona"
 
-#: rfc2131.c:1210
+#: rfc2131.c:1281
 msgid "address not available"
 msgstr "adres niedostępny"
 
-#: rfc2131.c:1221
+#: rfc2131.c:1292
 msgid "static lease available"
 msgstr "dostępna statyczna dzierżawa"
 
-#: rfc2131.c:1225
+#: rfc2131.c:1296
 msgid "address reserved"
 msgstr "adres zarezerwowany"
 
-#: rfc2131.c:1233
+#: rfc2131.c:1304
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr "porzucam przypisanie do %s nazwy %s"
 
-#: rfc2131.c:1757
+#: rfc2131.c:1845
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr "%u nazwa pliku bootowania: %s"
 
-#: rfc2131.c:1766
+#: rfc2131.c:1854
 #, c-format
 msgid "%u server name: %s"
 msgstr "%u nazwa serwera: %s"
 
-#: rfc2131.c:1774
+#: rfc2131.c:1862
 #, c-format
 msgid "%u next server: %s"
 msgstr "%u następny serwer: %s"
 
-#: rfc2131.c:1777
+#: rfc2131.c:1865
 #, c-format
 msgid "%u broadcast response"
 msgstr "%u odpowiedź rozgłoszeniowa"
 
-#: rfc2131.c:1840
+#: rfc2131.c:1928
 #, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr "nie mam możliwości wysłania opcji %d DHCP/BOOTP: niedostateczna ilość miejsca w pakiecie"
 
-#: rfc2131.c:2131
+#: rfc2131.c:2219
 msgid "PXE menu too large"
 msgstr "menu PXE zbyt duże"
 
-#: rfc2131.c:2270 rfc3315.c:1515
+#: rfc2131.c:2358 rfc3315.c:1470
 #, c-format
 msgid "%u requested options: %s"
 msgstr "%u zażądano: %s"
 
-#: rfc2131.c:2587
+#: rfc2131.c:2675
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr "nie mogę wysłać opcji RFC3925: za długi łańcuch opcji przy numerze %d"
 
-#: rfc2131.c:2650
+#: rfc2131.c:2738
 #, c-format
 msgid "%u reply delay: %d"
 msgstr ""
 
-#: netlink.c:77
+#: netlink.c:76
 #, c-format
 msgid "cannot create netlink socket: %s"
 msgstr "nie potrafię utworzyć połączenia netlink %s"
 
-#: netlink.c:355
+#: netlink.c:352
 #, c-format
 msgid "netlink returns error: %s"
 msgstr "wystąpił błąd w połączeniu netlink %s"
 
-#: dbus.c:186
-msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
-msgstr "próba ustawienia adresu IPv6 serwera przez DBus, ale brak obsługi IPv6"
-
-#: dbus.c:439
+#: dbus.c:438
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr "opcja --%s została właśnie aktywowana za pomocą D-Bus"
 
-#: dbus.c:444
+#: dbus.c:443
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr "opcja --%s została właśnie dezaktywowana za pomocą D-Bus"
 
-#: dbus.c:690
+#: dbus.c:717
 msgid "setting upstream servers from DBus"
 msgstr "ustawiam adresy serwerów nadrzędnych na podstawie informacji odebranych z DBus"
 
-#: dbus.c:737
+#: dbus.c:764
 msgid "could not register a DBus message handler"
 msgstr "nie można zarejestrować uchwytu DBus"
 
-#: bpf.c:265
+#: bpf.c:261
 #, c-format
 msgid "cannot create DHCP BPF socket: %s"
 msgstr "nie potrafię utworzyć gniazda DHCP BPF: %s"
 
-#: bpf.c:293
+#: bpf.c:289
 #, c-format
 msgid "DHCP request for unsupported hardware type (%d) received on %s"
 msgstr "żądanie DHCP od urządzenia nieobsługiwanego typu (%d) odebrano na %s"
 
-#: bpf.c:378
+#: bpf.c:374
 #, c-format
 msgid "cannot create PF_ROUTE socket: %s"
 msgstr "nie udało się utworzyć gniazda PF_ROUTE: %s"
 
-#: bpf.c:399
+#: bpf.c:395
 msgid "Unknown protocol version from route socket"
 msgstr "Nieznana wersja protokołu."
 
-#: helper.c:154
+#: helper.c:150
 msgid "lease() function missing in Lua script"
 msgstr "w skrypcie Lua brak funkcji lease()"
 
-#: tftp.c:319
+#: tftp.c:347
 msgid "unable to get free port for TFTP"
 msgstr "brak wolnego portu dla usługi TFTP"
 
-#: tftp.c:335
+#: tftp.c:363
 #, c-format
 msgid "unsupported request from %s"
 msgstr "nieobsługiwane żądanie od komputera %s"
 
-#: tftp.c:483
+#: tftp.c:510
 #, c-format
 msgid "file %s not found"
 msgstr "plik %s nie został znaleziony"
 
-#: tftp.c:592
-#, c-format
-msgid "error %d %s received from %s"
-msgstr "błąd %d %s odebrano od %s"
-
-#: tftp.c:634
+#: tftp.c:628
 #, c-format
 msgid "failed sending %s to %s"
 msgstr "błąd wysyłania pliku %s do komputera %s"
 
-#: tftp.c:634
+#: tftp.c:628
 #, c-format
 msgid "sent %s to %s"
 msgstr "plik %s przesłano do %s"
 
+#: tftp.c:678
+#, c-format
+msgid "error %d %s received from %s"
+msgstr "błąd %d %s odebrano od %s"
+
 #: log.c:190
 #, c-format
 msgid "overflow: %d log entries lost"
@@ -1957,7 +2069,7 @@ msgstr "nie udało się zapisać komunikatów do %s"
 msgid "FAILED to start up"
 msgstr "BŁĄD: nie udało się uruchomić dnsmasq-a"
 
-#: conntrack.c:65
+#: conntrack.c:63
 #, c-format
 msgid "Conntrack connection mark retrieval failed: %s"
 msgstr "Nie udało się odcztać znacznika połączenia (conntrack): %s"
@@ -1977,77 +2089,72 @@ msgstr "nie udało się ustawić SO_REUSE{ADDR|PORT} gniazda DHCPv6: %s"
 msgid "failed to bind DHCPv6 server socket: %s"
 msgstr "dowiązywanie gniazda serwera DHCPv6 zakończone niepowodzeniem: %s"
 
-#: rfc3315.c:157
+#: rfc3315.c:173
 #, c-format
 msgid "no address range available for DHCPv6 request from relay at %s"
 msgstr "nie zdefiniowano zakresu adresów odpowiedniego dla żądania DHCPv6 przekazanego przez %s"
 
-#: rfc3315.c:166
+#: rfc3315.c:182
 #, c-format
 msgid "no address range available for DHCPv6 request via %s"
 msgstr "nie zdefiniowano zakresu adresów odpowiedniego dla żądania DHCPv6 od %s"
 
-#: rfc3315.c:303
+#: rfc3315.c:316
 #, c-format
 msgid "%u available DHCPv6 subnet: %s/%d"
 msgstr "%u dostępna podsieć DHCPv6: %s/%d"
 
-#: rfc3315.c:386
+#: rfc3315.c:399
 #, c-format
 msgid "%u vendor class: %u"
 msgstr "%u klasa dostawcy: %u"
 
-#: rfc3315.c:434
+#: rfc3315.c:447
 #, c-format
 msgid "%u client MAC address: %s"
 msgstr "adres MAC klienta %u: %s"
 
-#: rfc3315.c:673
-#, c-format
-msgid "unknown prefix-class %d"
-msgstr "nieznana klasa sieci %d"
-
-#: rfc3315.c:816 rfc3315.c:911
+#: rfc3315.c:762 rfc3315.c:859
 msgid "address unavailable"
 msgstr "adres niedostępny"
 
-#: rfc3315.c:828 rfc3315.c:959 rfc3315.c:1292
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
 msgid "success"
 msgstr "udane"
 
-#: rfc3315.c:843 rfc3315.c:852 rfc3315.c:967 rfc3315.c:969
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
 msgid "no addresses available"
 msgstr "brak wolnych adresów"
 
-#: rfc3315.c:946
+#: rfc3315.c:890
 msgid "not on link"
 msgstr "poza zasięgiem"
 
-#: rfc3315.c:1019 rfc3315.c:1204 rfc3315.c:1281
+#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
 msgid "no binding found"
 msgstr "brak powiązania"
 
-#: rfc3315.c:1057
+#: rfc3315.c:1002
 msgid "deprecated"
 msgstr "przestarzały"
 
-#: rfc3315.c:1062
+#: rfc3315.c:1007
 msgid "address invalid"
 msgstr "niepoprawny adres"
 
-#: rfc3315.c:1109
+#: rfc3315.c:1057 rfc3315.c:1059
 msgid "confirm failed"
 msgstr "brak potwierdzenia"
 
-#: rfc3315.c:1125
+#: rfc3315.c:1074
 msgid "all addresses still on link"
 msgstr "wszystkie adresy ciągle w użyciu"
 
-#: rfc3315.c:1213
+#: rfc3315.c:1165
 msgid "release received"
 msgstr "adres został zwolniony"
 
-#: rfc3315.c:2140
+#: rfc3315.c:2130
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr "Nie mogę rozesłać do serwerów DHCPv6 nie mając prawidłowego interfejsu"
 
@@ -2061,76 +2168,76 @@ msgstr "Pomijam powtórzoną dhcp-option %d"
 msgid "%u tags: %s"
 msgstr "%u cechy: %s"
 
-#: dhcp-common.c:407
+#: dhcp-common.c:444
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr "do komputera o nazwie %s pasuje więcej niż jeden adres, w odpowiedzi DHCP wysyłam %s"
 
-#: dhcp-common.c:430
+#: dhcp-common.c:478
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr "powtórzenie adresu IP %s (%s) w opcji dhcp-config"
 
-#: dhcp-common.c:491
+#: dhcp-common.c:542
 #, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr "nie udało się ustawić SO_BINDTODEVICE gniazda DHCP: %s"
 
-#: dhcp-common.c:612
+#: dhcp-common.c:665
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr "Znane opcje DHCP:\n"
 
-#: dhcp-common.c:623
+#: dhcp-common.c:676
 #, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr "Rozpoznawane opcje DHCPv6:\n"
 
-#: dhcp-common.c:820
+#: dhcp-common.c:873
 msgid ", prefix deprecated"
 msgstr ", przestarzały prefiks"
 
-#: dhcp-common.c:823
+#: dhcp-common.c:876
 #, c-format
 msgid ", lease time "
 msgstr ", czas dzierżawy "
 
-#: dhcp-common.c:865
+#: dhcp-common.c:918
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr "%s bezstanowy na %s%.0s%.0s%s"
 
-#: dhcp-common.c:867
+#: dhcp-common.c:920
 #, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr "%s, wyłącznie statyczne dzierżawy na %.0s%s%s%.0s"
 
-#: dhcp-common.c:869
+#: dhcp-common.c:922
 #, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr "%s, wykryto pośrednika na podsieci %.0s%s%.0s%.0s"
 
-#: dhcp-common.c:870
+#: dhcp-common.c:923
 #, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr "%s, zakres IP %s -- %s%s%.0s"
 
-#: dhcp-common.c:883
+#: dhcp-common.c:936
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr "pochodzące z DHCPv4 nazwy IPv6 na %s%s"
 
-#: dhcp-common.c:886
+#: dhcp-common.c:939
 #, c-format
 msgid "router advertisement on %s%s"
 msgstr "anonsowanie rutera na %s%s"
 
-#: dhcp-common.c:897
+#: dhcp-common.c:950
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr "przekazywanie DHCP z %s do %s za pomocą %s"
 
-#: dhcp-common.c:899
+#: dhcp-common.c:952
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr "przekazywanie DHCP z %s do %s"
@@ -2140,7 +2247,7 @@ msgstr "przekazywanie DHCP z %s do %s"
 msgid "cannot create ICMPv6 socket: %s"
 msgstr "nie udało się utworzyć gniazda dla ICMPv6: %s"
 
-#: auth.c:449
+#: auth.c:439
 #, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr "ignoruję żądanie transferu strefy od %s"
@@ -2155,19 +2262,24 @@ msgstr "niezgodna wersja jądra: %s"
 msgid "failed to create IPset control socket: %s"
 msgstr "nie powiodło się otwieranie gniazda sterującego IPset: %s"
 
-#: ipset.c:233
+#: ipset.c:226
 #, fuzzy, c-format
 msgid "failed to update ipset %s: %s"
 msgstr "nie udało się uaktualnić znacznika czasu pliku %s: %s"
 
-#: dnssec.c:208
+#: dnssec.c:206
 #, fuzzy
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
 msgstr "trwa sprawdzanie sygnatur czasowych podpisów DNSSEC"
 
-#: blockdata.c:58
+#: dnssec.c:902
 #, c-format
-msgid "DNSSEC memory in use %u, max %u, allocated %u"
+msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
+msgstr ""
+
+#: blockdata.c:55
+#, fuzzy, c-format
+msgid "pool memory in use %u, max %u, allocated %u"
 msgstr "DNSSEC: zużycie pamięci %u, maks. %u, przydzielona %u"
 
 #: tables.c:61
@@ -2199,12 +2311,12 @@ msgstr "błąd DBus: %s"
 msgid "info: table created"
 msgstr "info: tablica utworzona"
 
-#: tables.c:134
+#: tables.c:133
 #, c-format
 msgid "warning: DIOCR%sADDRS: %s"
 msgstr "uwaga: DIOCR%sADDRS: %s"
 
-#: tables.c:138
+#: tables.c:137
 #, c-format
 msgid "%d addresses %s"
 msgstr "%d adresów %s"
@@ -2244,6 +2356,82 @@ msgstr "zły katalog dynamiczny %s: %s"
 msgid "inotify, new or changed file %s"
 msgstr "inotify: pojawił się lub uległ zmianie plik %s"
 
+#: dump.c:64
+#, fuzzy, c-format
+msgid "cannot create %s: %s"
+msgstr "błąd odczytu z pliku %s: %s"
+
+#: dump.c:70
+#, fuzzy, c-format
+msgid "bad header in %s"
+msgstr "adres jest w użyciu"
+
+#: dump.c:201
+#, fuzzy
+msgid "failed to write packet dump"
+msgstr "wysyłanie pakietu nie powiodło się: %s"
+
+#: dump.c:203
+#, c-format
+msgid "dumping UDP packet %u mask 0x%04x"
+msgstr ""
+
+#: ubus.c:52
+#, c-format
+msgid "UBus subscription callback: %s subscriber(s)"
+msgstr ""
+
+#: ubus.c:73
+#, fuzzy, c-format
+msgid "Cannot reconnect to UBus: %s"
+msgstr "nie udało się otworzyć logu %s: %s"
+
+#: ubus.c:89
+msgid "Cannot initialize UBus: connection failed"
+msgstr ""
+
+#: ubus.c:102
+#, fuzzy, c-format
+msgid "Cannot add object to UBus: %s"
+msgstr "nie udało się otworzyć logu %s: %s"
+
+#: ubus.c:112
+#, fuzzy
+msgid "Connected to system UBus"
+msgstr "podłączono do DBus-a"
+
+#: ubus.c:122
+msgid "Cannot set UBus listeners: no connection"
+msgstr ""
+
+#: ubus.c:142
+msgid "Cannot poll UBus listeners: no connection"
+msgstr ""
+
+#: ubus.c:155
+msgid "Disconnecting from UBus"
+msgstr ""
+
+#: ubus.c:199
+#, fuzzy, c-format
+msgid "Failed to send UBus event: %s"
+msgstr "wysyłanie pakietu nie powiodło się: %s"
+
+#~ msgid "Specify DHCPv6 prefix class"
+#~ msgstr "Określenie prefiksu klasy DHCPv6"
+
+#~ msgid "cannot run scripts under uClinux"
+#~ msgstr "w uClinuksie nie ma możliwości uruchamiania skryptów"
+
+#~ msgid "cannot match tags in --dhcp-host"
+#~ msgstr "--dhcp-host nie dopuszcza dopasowywania na podstawie znaczników"
+
+#~ msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
+#~ msgstr "próba ustawienia adresu IPv6 serwera przez DBus, ale brak obsługi IPv6"
+
+#~ msgid "unknown prefix-class %d"
+#~ msgstr "nieznana klasa sieci %d"
+
 #~ msgid "bad TTL"
 #~ msgstr "zły TTL"
 
index cbaea31..217fd03 100644 (file)
@@ -16,70 +16,70 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
 
-#: cache.c:518
+#: cache.c:559
 msgid "Internal error in cache."
 msgstr ""
 
-#: cache.c:928
+#: cache.c:1081
 #, c-format
 msgid "failed to load names from %s: %s"
 msgstr ""
 
-#: cache.c:954 dhcp.c:867
+#: cache.c:1103 dhcp.c:927
 #, c-format
 msgid "bad address at %s line %d"
 msgstr ""
 
-#: cache.c:1007 dhcp.c:883
+#: cache.c:1156 dhcp.c:943
 #, c-format
 msgid "bad name at %s line %d"
 msgstr ""
 
-#: cache.c:1016 dhcp.c:958
+#: cache.c:1167 dhcp.c:1018
 #, c-format
 msgid "read %s - %d addresses"
 msgstr ""
 
-#: cache.c:1129
+#: cache.c:1283
 msgid "cleared cache"
 msgstr ""
 
-#: cache.c:1158
+#: cache.c:1345
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr ""
 
-#: cache.c:1237
+#: cache.c:1391
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr ""
 
-#: cache.c:1261
+#: cache.c:1415
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr ""
 
-#: cache.c:1418
+#: cache.c:1663
 #, c-format
 msgid "time %lu"
 msgstr ""
 
-#: cache.c:1419
+#: cache.c:1664
 #, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr ""
 
-#: cache.c:1421
+#: cache.c:1666
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr ""
 
-#: cache.c:1424
+#: cache.c:1669
 #, c-format
 msgid "queries for authoritative zones %u"
 msgstr ""
 
-#: cache.c:1450
+#: cache.c:1694
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr ""
@@ -93,1479 +93,1573 @@ msgstr ""
 msgid "failed to allocate memory"
 msgstr ""
 
-#: util.c:281 option.c:619
+#: util.c:281 option.c:641
 msgid "could not get memory"
 msgstr ""
 
-#: util.c:291
+#: util.c:302
 #, c-format
 msgid "cannot create pipe: %s"
 msgstr ""
 
-#: util.c:299
+#: util.c:310
 #, c-format
 msgid "failed to allocate %d bytes"
 msgstr ""
 
-#: util.c:468
+#: util.c:506
 #, c-format
 msgid "infinite"
 msgstr ""
 
-#: option.c:344
+#: option.c:358
 msgid "Specify local address(es) to listen on."
 msgstr ""
 
-#: option.c:345
+#: option.c:359
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr ""
 
-#: option.c:346
+#: option.c:360
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr ""
 
-#: option.c:347
+#: option.c:361
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr ""
 
-#: option.c:348
+#: option.c:362
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr ""
 
-#: option.c:349
+#: option.c:363
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr ""
 
-#: option.c:350
+#: option.c:364
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr ""
 
-#: option.c:351
+#: option.c:365
 msgid "Do NOT forward queries with no domain part."
 msgstr ""
 
-#: option.c:352
+#: option.c:366
 msgid "Return self-pointing MX records for local hosts."
 msgstr ""
 
-#: option.c:353
+#: option.c:367
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr ""
 
-#: option.c:354
+#: option.c:368
 msgid "Don't forward spurious DNS requests from Windows hosts."
 msgstr ""
 
-#: option.c:355
+#: option.c:369
 msgid "Enable DHCP in the range given with lease duration."
 msgstr ""
 
-#: option.c:356
+#: option.c:370
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr ""
 
-#: option.c:357
+#: option.c:371
 msgid "Set address or hostname for a specified machine."
 msgstr ""
 
-#: option.c:358
+#: option.c:372
 msgid "Read DHCP host specs from file."
 msgstr ""
 
-#: option.c:359
+#: option.c:373
 msgid "Read DHCP option specs from file."
 msgstr ""
 
-#: option.c:360
+#: option.c:374
 msgid "Read DHCP host specs from a directory."
 msgstr ""
 
-#: option.c:361
+#: option.c:375
 msgid "Read DHCP options from a directory."
 msgstr ""
 
-#: option.c:362
+#: option.c:376
 msgid "Evaluate conditional tag expression."
 msgstr ""
 
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Do NOT load %s file."
 msgstr ""
 
-#: option.c:364
+#: option.c:378
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr ""
 
-#: option.c:365
+#: option.c:379
 msgid "Read hosts files from a directory."
 msgstr ""
 
-#: option.c:366
+#: option.c:380
 msgid "Specify interface(s) to listen on."
 msgstr ""
 
-#: option.c:367
+#: option.c:381
 msgid "Specify interface(s) NOT to listen on."
 msgstr ""
 
-#: option.c:368
+#: option.c:382
 msgid "Map DHCP user class to tag."
 msgstr ""
 
-#: option.c:369
+#: option.c:383
 msgid "Map RFC3046 circuit-id to tag."
 msgstr ""
 
-#: option.c:370
+#: option.c:384
 msgid "Map RFC3046 remote-id to tag."
 msgstr ""
 
-#: option.c:371
+#: option.c:385
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr ""
 
-#: option.c:372
+#: option.c:386
 msgid "Don't do DHCP for hosts with tag set."
 msgstr ""
 
-#: option.c:373
+#: option.c:387
 msgid "Force broadcast replies for hosts with tag set."
 msgstr ""
 
-#: option.c:374
+#: option.c:388
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr ""
 
-#: option.c:375
+#: option.c:389
 msgid "Assume we are the only DHCP server on the local network."
 msgstr ""
 
-#: option.c:376
+#: option.c:390
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr ""
 
-#: option.c:377
+#: option.c:391
 msgid "Return MX records for local hosts."
 msgstr ""
 
-#: option.c:378
+#: option.c:392
 msgid "Specify an MX record."
 msgstr ""
 
-#: option.c:379
+#: option.c:393
 msgid "Specify BOOTP options to DHCP server."
 msgstr ""
 
-#: option.c:380
+#: option.c:394
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr ""
 
-#: option.c:381
+#: option.c:395
 msgid "Do NOT cache failed search results."
 msgstr ""
 
-#: option.c:382
+#: option.c:396
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr ""
 
-#: option.c:383
+#: option.c:397
 msgid "Specify options to be sent to DHCP clients."
 msgstr ""
 
-#: option.c:384
+#: option.c:398
 msgid "DHCP option sent even if the client does not request it."
 msgstr ""
 
-#: option.c:385
+#: option.c:399
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr ""
 
-#: option.c:386
+#: option.c:400
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr ""
 
-#: option.c:387
+#: option.c:401
 msgid "Log DNS queries."
 msgstr ""
 
-#: option.c:388
+#: option.c:402
 msgid "Force the originating port for upstream DNS queries."
 msgstr ""
 
-#: option.c:389
+#: option.c:403
 msgid "Do NOT read resolv.conf."
 msgstr ""
 
-#: option.c:390
+#: option.c:404
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr ""
 
-#: option.c:391
+#: option.c:405
 msgid "Specify path to file with server= options"
 msgstr ""
 
-#: option.c:392
+#: option.c:406
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr ""
 
-#: option.c:393
+#: option.c:407
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr ""
 
-#: option.c:394
+#: option.c:408
 msgid "Never forward queries to specified domains."
 msgstr ""
 
-#: option.c:395
+#: option.c:409
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr ""
 
-#: option.c:396
+#: option.c:410
 msgid "Specify default target in an MX record."
 msgstr ""
 
-#: option.c:397
+#: option.c:411
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr ""
 
-#: option.c:398
+#: option.c:412
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr ""
 
-#: option.c:399
+#: option.c:413
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr ""
 
-#: option.c:400
+#: option.c:414
 msgid "Specify time-to-live ceiling for cache."
 msgstr ""
 
-#: option.c:401
+#: option.c:415
 msgid "Specify time-to-live floor for cache."
 msgstr ""
 
-#: option.c:402
+#: option.c:416
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr ""
 
-#: option.c:403
+#: option.c:417
 msgid "Map DHCP vendor class to tag."
 msgstr ""
 
-#: option.c:404
+#: option.c:418
 msgid "Display dnsmasq version and copyright information."
 msgstr ""
 
-#: option.c:405
+#: option.c:419
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr ""
 
-#: option.c:406
+#: option.c:420
 msgid "Specify a SRV record."
 msgstr ""
 
-#: option.c:407
+#: option.c:421
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr ""
 
-#: option.c:408
+#: option.c:422
 #, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr ""
 
-#: option.c:409
+#: option.c:423
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr ""
 
-#: option.c:410
+#: option.c:424
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr ""
 
-#: option.c:411
+#: option.c:425
 msgid "Specify TXT DNS record."
 msgstr ""
 
-#: option.c:412
+#: option.c:426
 msgid "Specify PTR DNS record."
 msgstr ""
 
-#: option.c:413
+#: option.c:427
 msgid "Give DNS name to IPv4 address of interface."
 msgstr ""
 
-#: option.c:414
+#: option.c:428
 msgid "Bind only to interfaces in use."
 msgstr ""
 
-#: option.c:415
+#: option.c:429
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr ""
 
-#: option.c:416
+#: option.c:430
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr ""
 
-#: option.c:417
+#: option.c:431
+msgid "Enable the UBus interface."
+msgstr ""
+
+#: option.c:432
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr ""
 
-#: option.c:418
+#: option.c:433
 msgid "Enable dynamic address allocation for bootp."
 msgstr ""
 
-#: option.c:419
+#: option.c:434
 msgid "Map MAC address (with wildcards) to option set."
 msgstr ""
 
-#: option.c:420
+#: option.c:435
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr ""
 
-#: option.c:421
+#: option.c:436
+msgid "Specify extra networks sharing a broadcast domain for DHCP"
+msgstr ""
+
+#: option.c:437
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr ""
 
-#: option.c:422
+#: option.c:438
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:423
+#: option.c:439
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:424
+#: option.c:440
 msgid "Run lease-change scripts as this user."
 msgstr ""
 
-#: option.c:425
+#: option.c:441
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr ""
 
-#: option.c:426
+#: option.c:442
 msgid "Read configuration from all the files in this directory."
 msgstr ""
 
-#: option.c:427
+#: option.c:443
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr ""
 
-#: option.c:428
+#: option.c:444
 msgid "Do not use leasefile."
 msgstr ""
 
-#: option.c:429
+#: option.c:445
 #, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr ""
 
-#: option.c:430
+#: option.c:446
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr ""
 
-#: option.c:431
+#: option.c:447
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr ""
 
-#: option.c:432
+#: option.c:448
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr ""
 
-#: option.c:433
+#: option.c:449
 msgid "Enable integrated read-only TFTP server."
 msgstr ""
 
-#: option.c:434
+#: option.c:450
 msgid "Export files by TFTP only from the specified subtree."
 msgstr ""
 
-#: option.c:435
+#: option.c:451
 msgid "Add client IP or hardware address to tftp-root."
 msgstr ""
 
-#: option.c:436
+#: option.c:452
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr ""
 
-#: option.c:437
+#: option.c:453
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr ""
 
-#: option.c:438
+#: option.c:454
 #, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr ""
 
-#: option.c:439
+#: option.c:455
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr ""
 
-#: option.c:440
+#: option.c:456
 msgid "Disable the TFTP blocksize extension."
 msgstr ""
 
-#: option.c:441
+#: option.c:457
 msgid "Convert TFTP filenames to lowercase"
 msgstr ""
 
-#: option.c:442
+#: option.c:458
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr ""
 
-#: option.c:443
+#: option.c:459
+msgid "Use only one port for TFTP server."
+msgstr ""
+
+#: option.c:460
 msgid "Extra logging for DHCP."
 msgstr ""
 
-#: option.c:444
+#: option.c:461
 msgid "Enable async. logging; optionally set queue length."
 msgstr ""
 
-#: option.c:445
+#: option.c:462
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr ""
 
-#: option.c:446
+#: option.c:463
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr ""
 
-#: option.c:447
+#: option.c:464
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr ""
 
-#: option.c:448
+#: option.c:465
 msgid "Always perform DNS queries to all servers."
 msgstr ""
 
-#: option.c:449
+#: option.c:466
 msgid "Set tag if client includes matching option in request."
 msgstr ""
 
-#: option.c:450
+#: option.c:467
+msgid "Set tag if client provides given name."
+msgstr ""
+
+#: option.c:468
 msgid "Use alternative ports for DHCP."
 msgstr ""
 
-#: option.c:451
+#: option.c:469
 msgid "Specify NAPTR DNS record."
 msgstr ""
 
-#: option.c:452
+#: option.c:470
 msgid "Specify lowest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:453
+#: option.c:471
 msgid "Specify highest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:454
+#: option.c:472
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr ""
 
-#: option.c:455
+#: option.c:473
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr ""
 
-#: option.c:456
+#: option.c:474
 msgid "Use these DHCP relays as full proxies."
 msgstr ""
 
-#: option.c:457
+#: option.c:475
 msgid "Relay DHCP requests to a remote server"
 msgstr ""
 
-#: option.c:458
+#: option.c:476
 msgid "Specify alias name for LOCAL DNS name."
 msgstr ""
 
-#: option.c:459
+#: option.c:477
 msgid "Prompt to send to PXE clients."
 msgstr ""
 
-#: option.c:460
+#: option.c:478
 msgid "Boot service for PXE menu."
 msgstr ""
 
-#: option.c:461
+#: option.c:479
 msgid "Check configuration syntax."
 msgstr ""
 
-#: option.c:462
+#: option.c:480
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr ""
 
-#: option.c:463
+#: option.c:481
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr ""
 
-#: option.c:464
+#: option.c:482
 msgid "Add client identification to forwarded DNS queries."
 msgstr ""
 
-#: option.c:465
+#: option.c:483
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr ""
 
-#: option.c:466
+#: option.c:484
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr ""
 
-#: option.c:467
+#: option.c:485
+msgid "Ignore client identifier option sent by DHCP clients."
+msgstr ""
+
+#: option.c:486
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr ""
 
-#: option.c:468
+#: option.c:487
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr ""
 
-#: option.c:469
+#: option.c:488
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr ""
 
-#: option.c:470
+#: option.c:489
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr ""
 
-#: option.c:471
+#: option.c:490
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr ""
 
-#: option.c:472
+#: option.c:491
+msgid "Specify certification authority authorization record"
+msgstr ""
+
+#: option.c:492
 msgid "Specify arbitrary DNS resource record"
 msgstr ""
 
-#: option.c:473
+#: option.c:493
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr ""
 
-#: option.c:474
+#: option.c:494
 msgid "Export local names to global DNS"
 msgstr ""
 
-#: option.c:475
+#: option.c:495
 msgid "Domain to export to global DNS"
 msgstr ""
 
-#: option.c:476
+#: option.c:496
 msgid "Set TTL for authoritative replies"
 msgstr ""
 
-#: option.c:477
+#: option.c:497
 msgid "Set authoritative zone information"
 msgstr ""
 
-#: option.c:478
+#: option.c:498
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr ""
 
-#: option.c:479
+#: option.c:499
 msgid "Peers which are allowed to do zone transfer"
 msgstr ""
 
-#: option.c:480
+#: option.c:500
 msgid "Specify ipsets to which matching domains should be added"
 msgstr ""
 
-#: option.c:481
+#: option.c:501
 msgid "Specify a domain and address range for synthesised names"
 msgstr ""
 
-#: option.c:482
+#: option.c:502
 msgid "Activate DNSSEC validation"
 msgstr ""
 
-#: option.c:483
+#: option.c:503
 msgid "Specify trust anchor key digest."
 msgstr ""
 
-#: option.c:484
+#: option.c:504
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr ""
 
-#: option.c:485
+#: option.c:505
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr ""
 
-#: option.c:486
+#: option.c:506
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr ""
 
-#: option.c:487
+#: option.c:507
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr ""
 
-#: option.c:489
-msgid "Specify DHCPv6 prefix class"
-msgstr ""
-
-#: option.c:491
+#: option.c:508
 msgid "Set MTU, priority, resend-interval and router-lifetime"
 msgstr ""
 
-#: option.c:492
+#: option.c:509
 msgid "Do not log routine DHCP."
 msgstr ""
 
-#: option.c:493
+#: option.c:510
 msgid "Do not log routine DHCPv6."
 msgstr ""
 
-#: option.c:494
+#: option.c:511
 msgid "Do not log RA."
 msgstr ""
 
-#: option.c:495
+#: option.c:512
 msgid "Accept queries only from directly-connected networks."
 msgstr ""
 
-#: option.c:496
+#: option.c:513
 msgid "Detect and remove DNS forwarding loops."
 msgstr ""
 
-#: option.c:497
+#: option.c:514
 msgid "Ignore DNS responses containing ipaddr."
 msgstr ""
 
-#: option.c:498
+#: option.c:515
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr ""
 
-#: option.c:499
+#: option.c:516
 msgid "Delay DHCP replies for at least number of seconds."
 msgstr ""
 
-#: option.c:703
+#: option.c:517
+msgid "Enables DHCPv4 Rapid Commit option."
+msgstr ""
+
+#: option.c:518
+msgid "Path to debug packet dump file"
+msgstr ""
+
+#: option.c:519
+msgid "Mask which packets to dump"
+msgstr ""
+
+#: option.c:520
+msgid "Call dhcp-script when lease expiry changes."
+msgstr ""
+
+#: option.c:725
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
 "\n"
 msgstr ""
 
-#: option.c:705
+#: option.c:727
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr ""
 
-#: option.c:707
+#: option.c:729
 #, c-format
 msgid "Valid options are:\n"
 msgstr ""
 
-#: option.c:754 option.c:868
+#: option.c:776 option.c:884
 msgid "bad address"
 msgstr ""
 
-#: option.c:779 option.c:783
+#: option.c:799 option.c:803
 msgid "bad port"
 msgstr ""
 
-#: option.c:797 option.c:826 option.c:861
+#: option.c:815 option.c:844 option.c:878
 msgid "interface binding not supported"
 msgstr ""
 
-#: option.c:821 option.c:856
+#: option.c:839 option.c:873
 msgid "interface can only be specified once"
 msgstr ""
 
-#: option.c:835 option.c:3809
+#: option.c:852 option.c:4042
 msgid "bad interface name"
 msgstr ""
 
-#: option.c:1062
+#: option.c:1184
 msgid "unsupported encapsulation for IPv6 option"
 msgstr ""
 
-#: option.c:1076
+#: option.c:1198
 msgid "bad dhcp-option"
 msgstr ""
 
-#: option.c:1144
+#: option.c:1270
 msgid "bad IP address"
 msgstr ""
 
-#: option.c:1147 option.c:1286 option.c:3079
+#: option.c:1273 option.c:1412 option.c:3297
 msgid "bad IPv6 address"
 msgstr ""
 
-#: option.c:1240
+#: option.c:1366
 msgid "bad IPv4 address"
 msgstr ""
 
-#: option.c:1313 option.c:1407
+#: option.c:1439 option.c:1533
 msgid "bad domain in dhcp-option"
 msgstr ""
 
-#: option.c:1445
+#: option.c:1571
 msgid "dhcp-option too long"
 msgstr ""
 
-#: option.c:1452
+#: option.c:1578
 msgid "illegal dhcp-match"
 msgstr ""
 
-#: option.c:1514
+#: option.c:1647
 msgid "illegal repeated flag"
 msgstr ""
 
-#: option.c:1522
+#: option.c:1655
 msgid "illegal repeated keyword"
 msgstr ""
 
-#: option.c:1593 option.c:4443
+#: option.c:1726 option.c:4764
 #, c-format
 msgid "cannot access directory %s: %s"
 msgstr ""
 
-#: option.c:1639 tftp.c:537
+#: option.c:1772 tftp.c:564 dump.c:68
 #, c-format
 msgid "cannot access %s: %s"
 msgstr ""
 
-#: option.c:1727
+#: option.c:1879
 msgid "setting log facility is not possible under Android"
 msgstr ""
 
-#: option.c:1736
+#: option.c:1888
 msgid "bad log facility"
 msgstr ""
 
-#: option.c:1789
+#: option.c:1941
 msgid "bad MX preference"
 msgstr ""
 
-#: option.c:1794
+#: option.c:1946
 msgid "bad MX name"
 msgstr ""
 
-#: option.c:1808
+#: option.c:1960
 msgid "bad MX target"
 msgstr ""
 
-#: option.c:1820
-msgid "cannot run scripts under uClinux"
-msgstr ""
-
-#: option.c:1822
+#: option.c:1980
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr ""
 
-#: option.c:1826
+#: option.c:1984
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr ""
 
-#: option.c:2095 option.c:2106 option.c:2143 option.c:2199 option.c:2482
+#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
 msgid "bad prefix"
 msgstr ""
 
-#: option.c:2504
+#: option.c:2658
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr ""
 
-#: option.c:2713
+#: option.c:2871
 msgid "bad port range"
 msgstr ""
 
-#: option.c:2739
+#: option.c:2897
 msgid "bad bridge-interface"
 msgstr ""
 
-#: option.c:2807
+#: option.c:2941
+msgid "bad shared-network"
+msgstr ""
+
+#: option.c:2996
 msgid "only one tag allowed"
 msgstr ""
 
-#: option.c:2827 option.c:2839 option.c:2948 option.c:2953 option.c:2992
+#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
 msgid "bad dhcp-range"
 msgstr ""
 
-#: option.c:2854
+#: option.c:3050
 msgid "inconsistent DHCP range"
 msgstr ""
 
-#: option.c:2916
+#: option.c:3115
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr ""
 
-#: option.c:2918
+#: option.c:3117
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr ""
 
-#: option.c:2922
+#: option.c:3120
 msgid "prefix length must be at least 64"
 msgstr ""
 
-#: option.c:2925
+#: option.c:3123
 msgid "inconsistent DHCPv6 range"
 msgstr ""
 
-#: option.c:2936
+#: option.c:3142
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr ""
 
-#: option.c:3049 option.c:3097
+#: option.c:3262 option.c:3340
 msgid "bad hex constant"
 msgstr ""
 
-#: option.c:3071
-msgid "cannot match tags in --dhcp-host"
+#: option.c:3315
+msgid "bad IPv6 prefix"
 msgstr ""
 
-#: option.c:3119
+#: option.c:3362
 #, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr ""
 
-#: option.c:3177
+#: option.c:3422
 msgid "bad DHCP host name"
 msgstr ""
 
-#: option.c:3259
+#: option.c:3508
 msgid "bad tag-if"
 msgstr ""
 
-#: option.c:3616 option.c:4039
+#: option.c:3851 option.c:4324
 msgid "invalid port number"
 msgstr ""
 
-#: option.c:3678
+#: option.c:3907
 msgid "bad dhcp-proxy address"
 msgstr ""
 
-#: option.c:3704
+#: option.c:3935
 msgid "Bad dhcp-relay"
 msgstr ""
 
-#: option.c:3745
+#: option.c:3979
 msgid "bad RA-params"
 msgstr ""
 
-#: option.c:3754
+#: option.c:3989
 msgid "bad DUID"
 msgstr ""
 
-#: option.c:3796
+#: option.c:4023
+msgid "missing address in alias"
+msgstr ""
+
+#: option.c:4029
 msgid "invalid alias range"
 msgstr ""
 
-#: option.c:3850 option.c:3862
+#: option.c:4081 option.c:4097
 msgid "bad CNAME"
 msgstr ""
 
-#: option.c:3866
+#: option.c:4105
 msgid "duplicate CNAME"
 msgstr ""
 
-#: option.c:3889
+#: option.c:4132
 msgid "bad PTR record"
 msgstr ""
 
-#: option.c:3920
+#: option.c:4167
 msgid "bad NAPTR record"
 msgstr ""
 
-#: option.c:3954
+#: option.c:4203
 msgid "bad RR record"
 msgstr ""
 
-#: option.c:3984
+#: option.c:4236
+msgid "bad CAA record"
+msgstr ""
+
+#: option.c:4265
 msgid "bad TXT record"
 msgstr ""
 
-#: option.c:4025
+#: option.c:4308
 msgid "bad SRV record"
 msgstr ""
 
-#: option.c:4032
+#: option.c:4315
 msgid "bad SRV target"
 msgstr ""
 
-#: option.c:4046
+#: option.c:4334
 msgid "invalid priority"
 msgstr ""
 
-#: option.c:4049
+#: option.c:4339
 msgid "invalid weight"
 msgstr ""
 
-#: option.c:4073
+#: option.c:4362
 msgid "Bad host-record"
 msgstr ""
 
-#: option.c:4097
+#: option.c:4402
 msgid "Bad name in host-record"
 msgstr ""
 
-#: option.c:4162
+#: option.c:4444
+msgid "bad value for dnssec-check-unsigned"
+msgstr ""
+
+#: option.c:4480
 msgid "bad trust anchor"
 msgstr ""
 
-#: option.c:4176
+#: option.c:4496
 msgid "bad HEX in trust anchor"
 msgstr ""
 
-#: option.c:4186
+#: option.c:4507
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr ""
 
-#: option.c:4246
+#: option.c:4567
 msgid "missing \""
 msgstr ""
 
-#: option.c:4303
+#: option.c:4624
 msgid "bad option"
 msgstr ""
 
-#: option.c:4305
+#: option.c:4626
 msgid "extraneous parameter"
 msgstr ""
 
-#: option.c:4307
+#: option.c:4628
 msgid "missing parameter"
 msgstr ""
 
-#: option.c:4309
+#: option.c:4630
 msgid "illegal option"
 msgstr ""
 
-#: option.c:4316
+#: option.c:4637
 msgid "error"
 msgstr ""
 
-#: option.c:4318
+#: option.c:4639
 #, c-format
 msgid " at line %d of %s"
 msgstr ""
 
-#: option.c:4333 option.c:4580 option.c:4616
+#: option.c:4654 option.c:4939 option.c:4950
 #, c-format
 msgid "read %s"
 msgstr ""
 
-#: option.c:4396 option.c:4519 tftp.c:715
+#: option.c:4717 option.c:4840 tftp.c:754
 #, c-format
 msgid "cannot read %s: %s"
 msgstr ""
 
-#: option.c:4688
+#: option.c:5027
 msgid "junk found in command line"
 msgstr ""
 
-#: option.c:4729
+#: option.c:5067
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr ""
 
-#: option.c:4730
+#: option.c:5068
 #, c-format
 msgid ""
 "Compile time options: %s\n"
 "\n"
 msgstr ""
 
-#: option.c:4731
+#: option.c:5069
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr ""
 
-#: option.c:4732
+#: option.c:5070
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr ""
 
-#: option.c:4733
+#: option.c:5071
 #, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr ""
 
-#: option.c:4744
+#: option.c:5088
 msgid "try --help"
 msgstr ""
 
-#: option.c:4746
+#: option.c:5090
 msgid "try -w"
 msgstr ""
 
-#: option.c:4748
+#: option.c:5092
 #, c-format
 msgid "bad command line options: %s"
 msgstr ""
 
-#: option.c:4818
+#: option.c:5161
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr ""
 
-#: option.c:4854
+#: option.c:5195
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr ""
 
-#: option.c:4882
+#: option.c:5223
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr ""
 
-#: option.c:4892
+#: option.c:5233
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr ""
 
-#: option.c:4895 network.c:1623 dhcp.c:816
+#: option.c:5236 network.c:1594 dhcp.c:876
 #, c-format
 msgid "failed to read %s: %s"
 msgstr ""
 
-#: option.c:4912
+#: option.c:5253
 #, c-format
 msgid "no search directive found in %s"
 msgstr ""
 
-#: option.c:4933
+#: option.c:5274
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr ""
 
-#: option.c:4942
+#: option.c:5283
 msgid "syntax check OK"
 msgstr ""
 
-#: forward.c:102
+#: forward.c:99
 #, c-format
 msgid "failed to send packet: %s"
 msgstr ""
 
-#: forward.c:598
+#: forward.c:614
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr ""
 
-#: forward.c:652
+#: forward.c:677
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr ""
 
-#: forward.c:684
+#: forward.c:709
 #, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr ""
 
-#: forward.c:870
+#: forward.c:961
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
 msgstr ""
 
-#: forward.c:1266 forward.c:1704
+#: forward.c:1370 forward.c:1830
 msgid "Ignoring query from non-local network"
 msgstr ""
 
-#: forward.c:2184
+#: forward.c:2321
 #, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr ""
 
-#: network.c:720
+#: network.c:698
 #, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr ""
 
-#: network.c:1031
+#: network.c:1002
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr ""
 
-#: network.c:1038
+#: network.c:1009
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr ""
 
-#: network.c:1047
+#: network.c:1018
 #, c-format
 msgid "warning: using interface %s instead"
 msgstr ""
 
-#: network.c:1056
+#: network.c:1027
 #, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr ""
 
-#: network.c:1114
+#: network.c:1085
 #, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr ""
 
-#: network.c:1119
+#: network.c:1090
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr ""
 
-#: network.c:1337
+#: network.c:1307
 #, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr ""
 
-#: network.c:1528
+#: network.c:1499
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr ""
 
-#: network.c:1539
+#: network.c:1510
 #, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr ""
 
-#: network.c:1559
+#: network.c:1530
 msgid "(no DNSSEC)"
 msgstr ""
 
-#: network.c:1562
+#: network.c:1533
 msgid "unqualified"
 msgstr ""
 
-#: network.c:1562
+#: network.c:1533
 msgid "names"
 msgstr ""
 
-#: network.c:1564
+#: network.c:1535
 msgid "default"
 msgstr ""
 
-#: network.c:1566
+#: network.c:1537
 msgid "domain"
 msgstr ""
 
-#: network.c:1572
+#: network.c:1543
 #, c-format
-msgid "using local addresses only for %s %s"
+msgid "using only locally-known addresses for %s %s"
 msgstr ""
 
-#: network.c:1575
+#: network.c:1546
 #, c-format
 msgid "using standard nameservers for %s %s"
 msgstr ""
 
-#: network.c:1577
+#: network.c:1548
 #, c-format
 msgid "using nameserver %s#%d for %s %s %s"
 msgstr ""
 
-#: network.c:1581
+#: network.c:1552
 #, c-format
 msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr ""
 
-#: network.c:1584
+#: network.c:1555
 #, c-format
 msgid "using nameserver %s#%d(via %s)"
 msgstr ""
 
-#: network.c:1586
+#: network.c:1557
 #, c-format
 msgid "using nameserver %s#%d"
 msgstr ""
 
-#: network.c:1591
+#: network.c:1562
 #, c-format
 msgid "using %d more local addresses"
 msgstr ""
 
-#: network.c:1593
+#: network.c:1564
 #, c-format
 msgid "using %d more nameservers"
 msgstr ""
 
-#: dnsmasq.c:171
+#: dnsmasq.c:173
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr ""
 
-#: dnsmasq.c:186
+#: dnsmasq.c:188
 msgid "no root trust anchor provided for DNSSEC"
 msgstr ""
 
-#: dnsmasq.c:189
+#: dnsmasq.c:191
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr ""
 
-#: dnsmasq.c:191
+#: dnsmasq.c:193
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:197
+#: dnsmasq.c:199
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:202
+#: dnsmasq.c:204
 msgid "cannot use --conntrack AND --query-port"
 msgstr ""
 
-#: dnsmasq.c:205
+#: dnsmasq.c:207
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:210
+#: dnsmasq.c:212
 msgid "asynchronous logging is not available under Solaris"
 msgstr ""
 
-#: dnsmasq.c:215
+#: dnsmasq.c:217
 msgid "asynchronous logging is not available under Android"
 msgstr ""
 
-#: dnsmasq.c:220
+#: dnsmasq.c:222
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:225
+#: dnsmasq.c:227
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:229
-msgid "max_port cannot be smaller than min_port"
+#: dnsmasq.c:232
+msgid "Ubus not available: set HAVE_UBUS in src/config.h"
 msgstr ""
 
 #: dnsmasq.c:236
+msgid "max_port cannot be smaller than min_port"
+msgstr ""
+
+#: dnsmasq.c:243
+msgid "--auth-server required when an auth zone is defined."
+msgstr ""
+
+#: dnsmasq.c:248
 msgid "zone serial must be configured in --auth-soa"
 msgstr ""
 
-#: dnsmasq.c:254
+#: dnsmasq.c:268
 msgid "dhcp-range constructor not available on this platform"
 msgstr ""
 
-#: dnsmasq.c:300
+#: dnsmasq.c:332
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr ""
 
-#: dnsmasq.c:303
+#: dnsmasq.c:335
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr ""
 
-#: dnsmasq.c:312
+#: dnsmasq.c:344
 #, c-format
 msgid "unknown interface %s"
 msgstr ""
 
-#: dnsmasq.c:377 dnsmasq.c:1054
+#: dnsmasq.c:406
+msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
+msgstr ""
+
+#: dnsmasq.c:416 dnsmasq.c:1171
 #, c-format
 msgid "DBus error: %s"
 msgstr ""
 
-#: dnsmasq.c:380
+#: dnsmasq.c:419
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr ""
 
-#: dnsmasq.c:410
+#: dnsmasq.c:429
+msgid "UBus not available: set HAVE_UBUS in src/config.h"
+msgstr ""
+
+#: dnsmasq.c:459
 #, c-format
 msgid "unknown user or group: %s"
 msgstr ""
 
-#: dnsmasq.c:465
+#: dnsmasq.c:535
+#, c-format
+msgid "process is missing required capability %s"
+msgstr ""
+
+#: dnsmasq.c:567
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr ""
 
-#: dnsmasq.c:730
+#: dnsmasq.c:815
 #, c-format
 msgid "started, version %s DNS disabled"
 msgstr ""
 
-#: dnsmasq.c:734
+#: dnsmasq.c:820
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr ""
 
-#: dnsmasq.c:736
+#: dnsmasq.c:822
+msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
+msgstr ""
+
+#: dnsmasq.c:825
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr ""
 
-#: dnsmasq.c:739
+#: dnsmasq.c:828
 msgid "DNS service limited to local subnets"
 msgstr ""
 
-#: dnsmasq.c:742
+#: dnsmasq.c:831
 #, c-format
 msgid "compile time options: %s"
 msgstr ""
 
-#: dnsmasq.c:751
+#: dnsmasq.c:840
 msgid "DBus support enabled: connected to system bus"
 msgstr ""
 
-#: dnsmasq.c:753
+#: dnsmasq.c:842
 msgid "DBus support enabled: bus connection pending"
 msgstr ""
 
-#: dnsmasq.c:771
+#: dnsmasq.c:850
+msgid "UBus support enabled: connected to system bus"
+msgstr ""
+
+#: dnsmasq.c:852
+msgid "UBus support enabled: bus connection pending"
+msgstr ""
+
+#: dnsmasq.c:872
+msgid "DNSSEC validation enabled but all unsigned answers are trusted"
+msgstr ""
+
+#: dnsmasq.c:874
 msgid "DNSSEC validation enabled"
 msgstr ""
 
-#: dnsmasq.c:775
+#: dnsmasq.c:878
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr ""
 
-#: dnsmasq.c:778
+#: dnsmasq.c:881
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr ""
 
-#: dnsmasq.c:783
+#: dnsmasq.c:884
+#, c-format
+msgid "configured with trust anchor for %s keytag %u"
+msgstr ""
+
+#: dnsmasq.c:890
 #, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr ""
 
-#: dnsmasq.c:787
+#: dnsmasq.c:894
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr ""
 
-#: dnsmasq.c:799
+#: dnsmasq.c:906
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr ""
 
-#: dnsmasq.c:804
+#: dnsmasq.c:911
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr ""
 
-#: dnsmasq.c:807
+#: dnsmasq.c:914
 msgid "warning: no upstream servers configured"
 msgstr ""
 
-#: dnsmasq.c:811
+#: dnsmasq.c:918
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr ""
 
-#: dnsmasq.c:832
+#: dnsmasq.c:939
 msgid "IPv6 router advertisement enabled"
 msgstr ""
 
-#: dnsmasq.c:837
+#: dnsmasq.c:944
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr ""
 
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 msgid "root is "
 msgstr ""
 
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 msgid "enabled"
 msgstr ""
 
-#: dnsmasq.c:853
+#: dnsmasq.c:960
 msgid "secure mode"
 msgstr ""
 
-#: dnsmasq.c:856
+#: dnsmasq.c:961
+msgid "single port mode"
+msgstr ""
+
+#: dnsmasq.c:964
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:860
+#: dnsmasq.c:968
 #, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:886
+#: dnsmasq.c:994
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr ""
 
-#: dnsmasq.c:1056
+#: dnsmasq.c:1173
 msgid "connected to system DBus"
 msgstr ""
 
-#: dnsmasq.c:1215
+#: dnsmasq.c:1345
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr ""
 
-#: dnsmasq.c:1218
+#: dnsmasq.c:1349
 #, c-format
 msgid "failed to create helper: %s"
 msgstr ""
 
-#: dnsmasq.c:1221
+#: dnsmasq.c:1353
 #, c-format
 msgid "setting capabilities failed: %s"
 msgstr ""
 
-#: dnsmasq.c:1224
+#: dnsmasq.c:1357
 #, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1227
+#: dnsmasq.c:1361
 #, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1230
+#: dnsmasq.c:1365
 #, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1233
+#: dnsmasq.c:1369
 #, c-format
 msgid "cannot open log %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1236
+#: dnsmasq.c:1373
 #, c-format
 msgid "failed to load Lua script: %s"
 msgstr ""
 
-#: dnsmasq.c:1239
+#: dnsmasq.c:1377
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr ""
 
-#: dnsmasq.c:1242
+#: dnsmasq.c:1381
 #, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1326
+#: dnsmasq.c:1465
 #, c-format
 msgid "script process killed by signal %d"
 msgstr ""
 
-#: dnsmasq.c:1330
+#: dnsmasq.c:1469
 #, c-format
 msgid "script process exited with status %d"
 msgstr ""
 
-#: dnsmasq.c:1334
+#: dnsmasq.c:1473
 #, c-format
 msgid "failed to execute %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1374
+#: dnsmasq.c:1513
 msgid "now checking DNSSEC signature timestamps"
 msgstr ""
 
-#: dnsmasq.c:1409 dnssec.c:160 dnssec.c:206
+#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
 #, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1416
+#: dnsmasq.c:1560
 msgid "exiting on receipt of SIGTERM"
 msgstr ""
 
-#: dnsmasq.c:1444
+#: dnsmasq.c:1588
 #, c-format
 msgid "failed to access %s: %s"
 msgstr ""
 
-#: dnsmasq.c:1474
+#: dnsmasq.c:1618
 #, c-format
 msgid "reading %s"
 msgstr ""
 
-#: dnsmasq.c:1485
+#: dnsmasq.c:1629
 #, c-format
 msgid "no servers found in %s, will retry"
 msgstr ""
@@ -1595,7 +1689,7 @@ msgstr ""
 msgid "cannot create ICMP raw socket: %s."
 msgstr ""
 
-#: dhcp.c:252 dhcp6.c:173
+#: dhcp.c:252 dhcp6.c:180
 #, c-format
 msgid "unknown interface %s in bridge-interface"
 msgstr ""
@@ -1605,329 +1699,334 @@ msgstr ""
 msgid "DHCP packet received on %s which has no address"
 msgstr ""
 
-#: dhcp.c:427
+#: dhcp.c:428
 #, c-format
 msgid "ARP-cache injection failed: %s"
 msgstr ""
 
-#: dhcp.c:470
+#: dhcp.c:471
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr ""
 
-#: dhcp.c:531
+#: dhcp.c:526
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr ""
 
-#: dhcp.c:854
+#: dhcp.c:914
 #, c-format
 msgid "bad line at %s line %d"
 msgstr ""
 
-#: dhcp.c:897
+#: dhcp.c:957
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr ""
 
-#: dhcp.c:1041 rfc3315.c:2149
+#: dhcp.c:1100 rfc3315.c:2139
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr ""
 
-#: lease.c:98
+#: lease.c:64
+#, c-format
+msgid "ignoring invalid line in lease database: %s %s %s %s ..."
+msgstr ""
+
+#: lease.c:101
+#, c-format
+msgid "ignoring invalid line in lease database, bad address: %s"
+msgstr ""
+
+#: lease.c:108
 msgid "too many stored leases"
 msgstr ""
 
-#: lease.c:166
+#: lease.c:176
 #, c-format
 msgid "cannot open or create lease file %s: %s"
 msgstr ""
 
-#: lease.c:175
-#, c-format
-msgid "failed to parse lease database, invalid line: %s %s %s %s ..."
+#: lease.c:185
+msgid "failed to parse lease database cleanly"
 msgstr ""
 
-#: lease.c:180
+#: lease.c:188
 #, c-format
 msgid "failed to read lease file %s: %s"
 msgstr ""
 
-#: lease.c:196
+#: lease.c:204
 #, c-format
 msgid "cannot run lease-init script %s: %s"
 msgstr ""
 
-#: lease.c:202
+#: lease.c:210
 #, c-format
 msgid "lease-init script returned exit code %s"
 msgstr ""
 
-#: lease.c:373
+#: lease.c:381
 #, c-format
 msgid "failed to write %s: %s (retry in %us)"
 msgstr ""
 
-#: lease.c:937
+#: lease.c:955
 #, c-format
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr ""
 
-#: rfc2131.c:347
+#: rfc2131.c:372
 #, c-format
 msgid "no address range available for DHCP request %s %s"
 msgstr ""
 
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "with subnet selector"
 msgstr ""
 
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "via"
 msgstr ""
 
-#: rfc2131.c:360
+#: rfc2131.c:385
 #, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr ""
 
-#: rfc2131.c:363 rfc3315.c:306
+#: rfc2131.c:388 rfc3315.c:319
 #, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr ""
 
-#: rfc2131.c:474
+#: rfc2131.c:499
 #, c-format
 msgid "%u vendor class: %s"
 msgstr ""
 
-#: rfc2131.c:476
+#: rfc2131.c:501
 #, c-format
 msgid "%u user class: %s"
 msgstr ""
 
-#: rfc2131.c:510
+#: rfc2131.c:535
 msgid "disabled"
 msgstr ""
 
-#: rfc2131.c:551 rfc2131.c:1006 rfc2131.c:1430 rfc3315.c:616 rfc3315.c:869
-#: rfc3315.c:1148
+#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1097
 msgid "ignored"
 msgstr ""
 
-#: rfc2131.c:566 rfc2131.c:1239 rfc3315.c:919
+#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
 msgid "address in use"
 msgstr ""
 
-#: rfc2131.c:580 rfc2131.c:1060
+#: rfc2131.c:605 rfc2131.c:1119
 msgid "no address available"
 msgstr ""
 
-#: rfc2131.c:587 rfc2131.c:1202
+#: rfc2131.c:612 rfc2131.c:1273
 msgid "wrong network"
 msgstr ""
 
-#: rfc2131.c:602
+#: rfc2131.c:627
 msgid "no address configured"
 msgstr ""
 
-#: rfc2131.c:608 rfc2131.c:1252
+#: rfc2131.c:633 rfc2131.c:1323
 msgid "no leases left"
 msgstr ""
 
-#: rfc2131.c:703 rfc3315.c:482
+#: rfc2131.c:734 rfc3315.c:499
 #, c-format
 msgid "%u client provides name: %s"
 msgstr ""
 
-#: rfc2131.c:808
+#: rfc2131.c:864
 msgid "PXE BIS not supported"
 msgstr ""
 
-#: rfc2131.c:974 rfc3315.c:1242
+#: rfc2131.c:1032 rfc3315.c:1197
 #, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr ""
 
-#: rfc2131.c:995
+#: rfc2131.c:1053
 msgid "unknown lease"
 msgstr ""
 
-#: rfc2131.c:1029
+#: rfc2131.c:1088
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr ""
 
-#: rfc2131.c:1039
+#: rfc2131.c:1098
 #, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr ""
 
-#: rfc2131.c:1042
+#: rfc2131.c:1101
 #, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr ""
 
-#: rfc2131.c:1058 rfc2131.c:1245
+#: rfc2131.c:1117 rfc2131.c:1316
 msgid "no unique-id"
 msgstr ""
 
-#: rfc2131.c:1140
+#: rfc2131.c:1209
 msgid "wrong server-ID"
 msgstr ""
 
-#: rfc2131.c:1159
+#: rfc2131.c:1228
 msgid "wrong address"
 msgstr ""
 
-#: rfc2131.c:1177 rfc3315.c:1015
+#: rfc2131.c:1246 rfc3315.c:961
 msgid "lease not found"
 msgstr ""
 
-#: rfc2131.c:1210
+#: rfc2131.c:1281
 msgid "address not available"
 msgstr ""
 
-#: rfc2131.c:1221
+#: rfc2131.c:1292
 msgid "static lease available"
 msgstr ""
 
-#: rfc2131.c:1225
+#: rfc2131.c:1296
 msgid "address reserved"
 msgstr ""
 
-#: rfc2131.c:1233
+#: rfc2131.c:1304
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr ""
 
-#: rfc2131.c:1757
+#: rfc2131.c:1845
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr ""
 
-#: rfc2131.c:1766
+#: rfc2131.c:1854
 #, c-format
 msgid "%u server name: %s"
 msgstr ""
 
-#: rfc2131.c:1774
+#: rfc2131.c:1862
 #, c-format
 msgid "%u next server: %s"
 msgstr ""
 
-#: rfc2131.c:1777
+#: rfc2131.c:1865
 #, c-format
 msgid "%u broadcast response"
 msgstr ""
 
-#: rfc2131.c:1840
+#: rfc2131.c:1928
 #, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr ""
 
-#: rfc2131.c:2131
+#: rfc2131.c:2219
 msgid "PXE menu too large"
 msgstr ""
 
-#: rfc2131.c:2270 rfc3315.c:1515
+#: rfc2131.c:2358 rfc3315.c:1470
 #, c-format
 msgid "%u requested options: %s"
 msgstr ""
 
-#: rfc2131.c:2587
+#: rfc2131.c:2675
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr ""
 
-#: rfc2131.c:2650
+#: rfc2131.c:2738
 #, c-format
 msgid "%u reply delay: %d"
 msgstr ""
 
-#: netlink.c:77
+#: netlink.c:76
 #, c-format
 msgid "cannot create netlink socket: %s"
 msgstr ""
 
-#: netlink.c:355
+#: netlink.c:352
 #, c-format
 msgid "netlink returns error: %s"
 msgstr ""
 
-#: dbus.c:186
-msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
-msgstr ""
-
-#: dbus.c:439
+#: dbus.c:438
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:444
+#: dbus.c:443
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:690
+#: dbus.c:717
 msgid "setting upstream servers from DBus"
 msgstr ""
 
-#: dbus.c:737
+#: dbus.c:764
 msgid "could not register a DBus message handler"
 msgstr ""
 
-#: bpf.c:265
+#: bpf.c:261
 #, c-format
 msgid "cannot create DHCP BPF socket: %s"
 msgstr ""
 
-#: bpf.c:293
+#: bpf.c:289
 #, c-format
 msgid "DHCP request for unsupported hardware type (%d) received on %s"
 msgstr ""
 
-#: bpf.c:378
+#: bpf.c:374
 #, c-format
 msgid "cannot create PF_ROUTE socket: %s"
 msgstr ""
 
-#: bpf.c:399
+#: bpf.c:395
 msgid "Unknown protocol version from route socket"
 msgstr ""
 
-#: helper.c:154
+#: helper.c:150
 msgid "lease() function missing in Lua script"
 msgstr ""
 
-#: tftp.c:319
+#: tftp.c:347
 msgid "unable to get free port for TFTP"
 msgstr ""
 
-#: tftp.c:335
+#: tftp.c:363
 #, c-format
 msgid "unsupported request from %s"
 msgstr ""
 
-#: tftp.c:483
+#: tftp.c:510
 #, c-format
 msgid "file %s not found"
 msgstr ""
 
-#: tftp.c:592
+#: tftp.c:628
 #, c-format
-msgid "error %d %s received from %s"
+msgid "failed sending %s to %s"
 msgstr ""
 
-#: tftp.c:634
+#: tftp.c:628
 #, c-format
-msgid "failed sending %s to %s"
+msgid "sent %s to %s"
 msgstr ""
 
-#: tftp.c:634
+#: tftp.c:678
 #, c-format
-msgid "sent %s to %s"
+msgid "error %d %s received from %s"
 msgstr ""
 
 #: log.c:190
@@ -1944,7 +2043,7 @@ msgstr ""
 msgid "FAILED to start up"
 msgstr ""
 
-#: conntrack.c:65
+#: conntrack.c:63
 #, c-format
 msgid "Conntrack connection mark retrieval failed: %s"
 msgstr ""
@@ -1964,77 +2063,72 @@ msgstr ""
 msgid "failed to bind DHCPv6 server socket: %s"
 msgstr ""
 
-#: rfc3315.c:157
+#: rfc3315.c:173
 #, c-format
 msgid "no address range available for DHCPv6 request from relay at %s"
 msgstr ""
 
-#: rfc3315.c:166
+#: rfc3315.c:182
 #, c-format
 msgid "no address range available for DHCPv6 request via %s"
 msgstr ""
 
-#: rfc3315.c:303
+#: rfc3315.c:316
 #, c-format
 msgid "%u available DHCPv6 subnet: %s/%d"
 msgstr ""
 
-#: rfc3315.c:386
+#: rfc3315.c:399
 #, c-format
 msgid "%u vendor class: %u"
 msgstr ""
 
-#: rfc3315.c:434
+#: rfc3315.c:447
 #, c-format
 msgid "%u client MAC address: %s"
 msgstr ""
 
-#: rfc3315.c:673
-#, c-format
-msgid "unknown prefix-class %d"
-msgstr ""
-
-#: rfc3315.c:816 rfc3315.c:911
+#: rfc3315.c:762 rfc3315.c:859
 msgid "address unavailable"
 msgstr ""
 
-#: rfc3315.c:828 rfc3315.c:959 rfc3315.c:1292
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
 msgid "success"
 msgstr ""
 
-#: rfc3315.c:843 rfc3315.c:852 rfc3315.c:967 rfc3315.c:969
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
 msgid "no addresses available"
 msgstr ""
 
-#: rfc3315.c:946
+#: rfc3315.c:890
 msgid "not on link"
 msgstr ""
 
-#: rfc3315.c:1019 rfc3315.c:1204 rfc3315.c:1281
+#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
 msgid "no binding found"
 msgstr ""
 
-#: rfc3315.c:1057
+#: rfc3315.c:1002
 msgid "deprecated"
 msgstr ""
 
-#: rfc3315.c:1062
+#: rfc3315.c:1007
 msgid "address invalid"
 msgstr ""
 
-#: rfc3315.c:1109
+#: rfc3315.c:1057 rfc3315.c:1059
 msgid "confirm failed"
 msgstr ""
 
-#: rfc3315.c:1125
+#: rfc3315.c:1074
 msgid "all addresses still on link"
 msgstr ""
 
-#: rfc3315.c:1213
+#: rfc3315.c:1165
 msgid "release received"
 msgstr ""
 
-#: rfc3315.c:2140
+#: rfc3315.c:2130
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr ""
 
@@ -2048,76 +2142,76 @@ msgstr ""
 msgid "%u tags: %s"
 msgstr ""
 
-#: dhcp-common.c:407
+#: dhcp-common.c:444
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr ""
 
-#: dhcp-common.c:430
+#: dhcp-common.c:478
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr ""
 
-#: dhcp-common.c:491
+#: dhcp-common.c:542
 #, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr ""
 
-#: dhcp-common.c:612
+#: dhcp-common.c:665
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr ""
 
-#: dhcp-common.c:623
+#: dhcp-common.c:676
 #, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr ""
 
-#: dhcp-common.c:820
+#: dhcp-common.c:873
 msgid ", prefix deprecated"
 msgstr ""
 
-#: dhcp-common.c:823
+#: dhcp-common.c:876
 #, c-format
 msgid ", lease time "
 msgstr ""
 
-#: dhcp-common.c:865
+#: dhcp-common.c:918
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr ""
 
-#: dhcp-common.c:867
+#: dhcp-common.c:920
 #, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr ""
 
-#: dhcp-common.c:869
+#: dhcp-common.c:922
 #, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr ""
 
-#: dhcp-common.c:870
+#: dhcp-common.c:923
 #, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr ""
 
-#: dhcp-common.c:883
+#: dhcp-common.c:936
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr ""
 
-#: dhcp-common.c:886
+#: dhcp-common.c:939
 #, c-format
 msgid "router advertisement on %s%s"
 msgstr ""
 
-#: dhcp-common.c:897
+#: dhcp-common.c:950
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr ""
 
-#: dhcp-common.c:899
+#: dhcp-common.c:952
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr ""
@@ -2127,7 +2221,7 @@ msgstr ""
 msgid "cannot create ICMPv6 socket: %s"
 msgstr ""
 
-#: auth.c:449
+#: auth.c:439
 #, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr ""
@@ -2142,18 +2236,23 @@ msgstr ""
 msgid "failed to create IPset control socket: %s"
 msgstr ""
 
-#: ipset.c:233
+#: ipset.c:226
 #, c-format
 msgid "failed to update ipset %s: %s"
 msgstr ""
 
-#: dnssec.c:208
+#: dnssec.c:206
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
 msgstr ""
 
-#: blockdata.c:58
+#: dnssec.c:902
 #, c-format
-msgid "DNSSEC memory in use %u, max %u, allocated %u"
+msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
+msgstr ""
+
+#: blockdata.c:55
+#, c-format
+msgid "pool memory in use %u, max %u, allocated %u"
 msgstr ""
 
 #: tables.c:61
@@ -2185,12 +2284,12 @@ msgstr ""
 msgid "info: table created"
 msgstr ""
 
-#: tables.c:134
+#: tables.c:133
 #, c-format
 msgid "warning: DIOCR%sADDRS: %s"
 msgstr ""
 
-#: tables.c:138
+#: tables.c:137
 #, c-format
 msgid "%d addresses %s"
 msgstr ""
@@ -2229,3 +2328,62 @@ msgstr ""
 #, c-format
 msgid "inotify, new or changed file %s"
 msgstr ""
+
+#: dump.c:64
+#, c-format
+msgid "cannot create %s: %s"
+msgstr ""
+
+#: dump.c:70
+#, c-format
+msgid "bad header in %s"
+msgstr ""
+
+#: dump.c:201
+msgid "failed to write packet dump"
+msgstr ""
+
+#: dump.c:203
+#, c-format
+msgid "dumping UDP packet %u mask 0x%04x"
+msgstr ""
+
+#: ubus.c:52
+#, c-format
+msgid "UBus subscription callback: %s subscriber(s)"
+msgstr ""
+
+#: ubus.c:73
+#, c-format
+msgid "Cannot reconnect to UBus: %s"
+msgstr ""
+
+#: ubus.c:89
+msgid "Cannot initialize UBus: connection failed"
+msgstr ""
+
+#: ubus.c:102
+#, c-format
+msgid "Cannot add object to UBus: %s"
+msgstr ""
+
+#: ubus.c:112
+msgid "Connected to system UBus"
+msgstr ""
+
+#: ubus.c:122
+msgid "Cannot set UBus listeners: no connection"
+msgstr ""
+
+#: ubus.c:142
+msgid "Cannot poll UBus listeners: no connection"
+msgstr ""
+
+#: ubus.c:155
+msgid "Disconnecting from UBus"
+msgstr ""
+
+#: ubus.c:199
+#, c-format
+msgid "Failed to send UBus event: %s"
+msgstr ""
index f84d0bc..9d08ebb 100644 (file)
--- a/po/ro.po
+++ b/po/ro.po
@@ -15,71 +15,71 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: cache.c:518
+#: cache.c:559
 msgid "Internal error in cache."
 msgstr ""
 
 # for compatibility purposes the letters â, ă, ş, ţ and î can be written as their look-alike correspondent.
-#: cache.c:928
+#: cache.c:1081
 #, fuzzy, c-format
 msgid "failed to load names from %s: %s"
 msgstr "încărcarea numelor din %s: %s a eşuat"
 
-#: cache.c:954 dhcp.c:867
+#: cache.c:1103 dhcp.c:927
 #, c-format
 msgid "bad address at %s line %d"
 msgstr "adresă greşită în %s, linia %d"
 
-#: cache.c:1007 dhcp.c:883
+#: cache.c:1156 dhcp.c:943
 #, c-format
 msgid "bad name at %s line %d"
 msgstr "nume greşit în %s linia %d"
 
-#: cache.c:1016 dhcp.c:958
+#: cache.c:1167 dhcp.c:1018
 #, c-format
 msgid "read %s - %d addresses"
 msgstr "citesc %s - %d adrese"
 
-#: cache.c:1129
+#: cache.c:1283
 msgid "cleared cache"
 msgstr "memoria temporară a fost ştearsă"
 
-#: cache.c:1158
+#: cache.c:1345
 #, c-format
 msgid "No IPv4 address found for %s"
 msgstr ""
 
-#: cache.c:1237
+#: cache.c:1391
 #, c-format
 msgid "%s is a CNAME, not giving it to the DHCP lease of %s"
 msgstr ""
 
-#: cache.c:1261
+#: cache.c:1415
 #, c-format
 msgid "not giving name %s to the DHCP lease of %s because the name exists in %s with address %s"
 msgstr "nu pot da numele %s împrumutului de adresă DHCP a lui %s deoarece numeleexistă în %s cu adresa %s"
 
-#: cache.c:1418
+#: cache.c:1663
 #, c-format
 msgid "time %lu"
 msgstr ""
 
-#: cache.c:1419
+#: cache.c:1664
 #, fuzzy, c-format
 msgid "cache size %d, %d/%d cache insertions re-used unexpired cache entries."
 msgstr "cantitate de memorie temporară %d, %d/%d stocări temporare aureutilizat locaţii neexpirate."
 
-#: cache.c:1421
+#: cache.c:1666
 #, c-format
 msgid "queries forwarded %u, queries answered locally %u"
 msgstr ""
 
-#: cache.c:1424
+#: cache.c:1669
 #, c-format
 msgid "queries for authoritative zones %u"
 msgstr ""
 
-#: cache.c:1450
+#: cache.c:1694
 #, c-format
 msgid "server %s#%d: queries sent %u, retried or failed %u"
 msgstr ""
@@ -94,687 +94,724 @@ msgstr "ascultarea pe socket a eşuat: %s"
 msgid "failed to allocate memory"
 msgstr "nu pot încărca %d bytes"
 
-#: util.c:281 option.c:619
+#: util.c:281 option.c:641
 msgid "could not get memory"
 msgstr "nu am putut aloca memorie"
 
-#: util.c:291
+#: util.c:302
 #, fuzzy, c-format
 msgid "cannot create pipe: %s"
 msgstr "nu pot citi %s: %s"
 
-#: util.c:299
+#: util.c:310
 #, fuzzy, c-format
 msgid "failed to allocate %d bytes"
 msgstr "nu pot încărca %d bytes"
 
-#: util.c:468
+#: util.c:506
 #, c-format
 msgid "infinite"
 msgstr "infinit"
 
-#: option.c:344
+#: option.c:358
 msgid "Specify local address(es) to listen on."
 msgstr "Specificaţi adresele locale deservite."
 
-#: option.c:345
+#: option.c:359
 msgid "Return ipaddr for all hosts in specified domains."
 msgstr "Afişează adresele IP ale maşinilor în domeniul dat."
 
-#: option.c:346
+#: option.c:360
 msgid "Fake reverse lookups for RFC1918 private address ranges."
 msgstr "Simulează căutări după adresă pentru domenii de adresă private (RFC1918)."
 
-#: option.c:347
+#: option.c:361
 msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
 msgstr "Interpretează adresa IP ca NXDOMAIN (împotriva manipulărilor Verisign)"
 
-#: option.c:348
+#: option.c:362
 #, c-format
 msgid "Specify the size of the cache in entries (defaults to %s)."
 msgstr "Specifică mărimea înregistrărilor temporare (implicit e %s)."
 
-#: option.c:349
+#: option.c:363
 #, c-format
 msgid "Specify configuration file (defaults to %s)."
 msgstr "Specifică fişier de configurare (implicit e %s)."
 
-#: option.c:350
+#: option.c:364
 msgid "Do NOT fork into the background: run in debug mode."
 msgstr "NU porneşte în fundal: rulează în modul depanare."
 
-#: option.c:351
+#: option.c:365
 msgid "Do NOT forward queries with no domain part."
 msgstr "NU înainta cererile ce nu conţin domeniu DNS."
 
-#: option.c:352
+#: option.c:366
 msgid "Return self-pointing MX records for local hosts."
 msgstr "Răspunde cu înregistrări MX spre el însuşi pentru maşini locale."
 
-#: option.c:353
+#: option.c:367
 msgid "Expand simple names in /etc/hosts with domain-suffix."
 msgstr "Adaugă numelor simple din /etc/hosts numele domeniului ca sufix."
 
-#: option.c:354
+#: option.c:368
 msgid "Don't forward spurious DNS requests from Windows hosts."
 msgstr "Nu inainta cereri DNS defecte provenite de la maşini Windows."
 
-#: option.c:355
+#: option.c:369
 msgid "Enable DHCP in the range given with lease duration."
 msgstr "Activează DHCP în domeniul dat cu durată limitată de împrumut."
 
-#: option.c:356
+#: option.c:370
 #, c-format
 msgid "Change to this group after startup (defaults to %s)."
 msgstr "Rulează sub acest grup după pornire (implicit e %s)."
 
-#: option.c:357
+#: option.c:371
 msgid "Set address or hostname for a specified machine."
 msgstr "Schimbă adresa sau numele maşinii specificate."
 
-#: option.c:358
+#: option.c:372
 #, fuzzy
 msgid "Read DHCP host specs from file."
 msgstr "nume MX invalid"
 
-#: option.c:359
+#: option.c:373
 msgid "Read DHCP option specs from file."
 msgstr ""
 
-#: option.c:360
+#: option.c:374
 #, fuzzy
 msgid "Read DHCP host specs from a directory."
 msgstr "nume MX invalid"
 
-#: option.c:361
+#: option.c:375
 #, fuzzy
 msgid "Read DHCP options from a directory."
 msgstr "nume MX invalid"
 
-#: option.c:362
+#: option.c:376
 msgid "Evaluate conditional tag expression."
 msgstr ""
 
-#: option.c:363
+#: option.c:377
 #, c-format
 msgid "Do NOT load %s file."
 msgstr "Nu încarcă fişierul %s."
 
-#: option.c:364
+#: option.c:378
 #, c-format
 msgid "Specify a hosts file to be read in addition to %s."
 msgstr "Specifică spre citire un fişier hosts adiţional la %s."
 
-#: option.c:365
+#: option.c:379
 #, fuzzy
 msgid "Read hosts files from a directory."
 msgstr "nume MX invalid"
 
-#: option.c:366
+#: option.c:380
 msgid "Specify interface(s) to listen on."
 msgstr "Specifică interfeţele deservite."
 
-#: option.c:367
+#: option.c:381
 msgid "Specify interface(s) NOT to listen on."
 msgstr "Specifică interfeţele NE-deservite."
 
-#: option.c:368
+#: option.c:382
 #, fuzzy
 msgid "Map DHCP user class to tag."
 msgstr "Leagă clasa de utilizator DHCP cu grup de opţiuni."
 
-#: option.c:369
+#: option.c:383
 msgid "Map RFC3046 circuit-id to tag."
 msgstr ""
 
-#: option.c:370
+#: option.c:384
 msgid "Map RFC3046 remote-id to tag."
 msgstr ""
 
-#: option.c:371
+#: option.c:385
 msgid "Map RFC3993 subscriber-id to tag."
 msgstr ""
 
-#: option.c:372
+#: option.c:386
 #, fuzzy
 msgid "Don't do DHCP for hosts with tag set."
 msgstr "Nu furniza DHCP maşinilor din grupul de opţiuni."
 
-#: option.c:373
+#: option.c:387
 #, fuzzy
 msgid "Force broadcast replies for hosts with tag set."
 msgstr "Nu furniza DHCP maşinilor din grupul de opţiuni."
 
-#: option.c:374
+#: option.c:388
 msgid "Do NOT fork into the background, do NOT run in debug mode."
 msgstr "NU porneşte în fundal, NU rulează în modul depanare."
 
-#: option.c:375
+#: option.c:389
 msgid "Assume we are the only DHCP server on the local network."
 msgstr "Presupune că suntem singurul server DHCP din reţeaua locală."
 
-#: option.c:376
+#: option.c:390
 #, c-format
 msgid "Specify where to store DHCP leases (defaults to %s)."
 msgstr "Specifică fişierul de stocare a împrumuturilor DHCP (implicit e %s)."
 
-#: option.c:377
+#: option.c:391
 msgid "Return MX records for local hosts."
 msgstr "Răspunde cu întregistrări MX pentru maşini locale."
 
-#: option.c:378
+#: option.c:392
 msgid "Specify an MX record."
 msgstr "Specifică o înregistrare MX."
 
-#: option.c:379
+#: option.c:393
 msgid "Specify BOOTP options to DHCP server."
 msgstr "Specifică opţiuni BOOTP serverului DHCP."
 
-#: option.c:380
+#: option.c:394
 #, c-format
 msgid "Do NOT poll %s file, reload only on SIGHUP."
 msgstr "Nu încărca fişierul %s, citeşte-l doar la SIGHUP."
 
-#: option.c:381
+#: option.c:395
 msgid "Do NOT cache failed search results."
 msgstr "NU memora rezultatele de căutare DNS eşuatată."
 
-#: option.c:382
+#: option.c:396
 #, c-format
 msgid "Use nameservers strictly in the order given in %s."
 msgstr "Foloseşte servere DNS strict în ordinea dată în %s."
 
-#: option.c:383
+#: option.c:397
 #, fuzzy
 msgid "Specify options to be sent to DHCP clients."
 msgstr "Configurează opţiuni în plusce trebuie trimise clienţilor DHCP."
 
-#: option.c:384
+#: option.c:398
 msgid "DHCP option sent even if the client does not request it."
 msgstr ""
 
-#: option.c:385
+#: option.c:399
 msgid "Specify port to listen for DNS requests on (defaults to 53)."
 msgstr "Specifică numărul portului pentru cereri DNS (implicit e 53)."
 
-#: option.c:386
+#: option.c:400
 #, c-format
 msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
 msgstr "Marimea maximă a pachetului UDP pentru EDNS.0 (implicit e %s)."
 
-#: option.c:387
+#: option.c:401
 #, fuzzy
 msgid "Log DNS queries."
 msgstr "Înregistrează tranzacţiile."
 
-#: option.c:388
+#: option.c:402
 #, fuzzy
 msgid "Force the originating port for upstream DNS queries."
 msgstr "Forţează acest port pentru datele ce pleacă."
 
-#: option.c:389
+#: option.c:403
 msgid "Do NOT read resolv.conf."
 msgstr "NU citi fişierul resolv.conf"
 
-#: option.c:390
+#: option.c:404
 #, c-format
 msgid "Specify path to resolv.conf (defaults to %s)."
 msgstr "Specifică calea către resolv.conf (implicit e %s)."
 
-#: option.c:391
+#: option.c:405
 #, fuzzy
 msgid "Specify path to file with server= options"
 msgstr "Specifică o cale pentru fişierul PID. (implicit %s)."
 
-#: option.c:392
+#: option.c:406
 msgid "Specify address(es) of upstream servers with optional domains."
 msgstr "Specifică adresele server(elor) superioare cu domenii opţionale."
 
-#: option.c:393
+#: option.c:407
 #, fuzzy
 msgid "Specify address of upstream servers for reverse address queries"
 msgstr "Specifică adresele server(elor) superioare cu domenii opţionale."
 
-#: option.c:394
+#: option.c:408
 msgid "Never forward queries to specified domains."
 msgstr "Nu înaintează cererile spre domeniile specificate."
 
-#: option.c:395
+#: option.c:409
 msgid "Specify the domain to be assigned in DHCP leases."
 msgstr "Specifică domeniul de transmis prin DHCP."
 
-#: option.c:396
+#: option.c:410
 msgid "Specify default target in an MX record."
 msgstr "Specifică o ţintă într-o înregistrare MX."
 
-#: option.c:397
+#: option.c:411
 msgid "Specify time-to-live in seconds for replies from /etc/hosts."
 msgstr "Specifică TTL în secunde pentru răspunsurile din /etc/hosts."
 
-#: option.c:398
+#: option.c:412
 #, fuzzy
 msgid "Specify time-to-live in seconds for negative caching."
 msgstr "Specifică TTL în secunde pentru răspunsurile din /etc/hosts."
 
-#: option.c:399
+#: option.c:413
 #, fuzzy
 msgid "Specify time-to-live in seconds for maximum TTL to send to clients."
 msgstr "Specifică TTL în secunde pentru răspunsurile din /etc/hosts."
 
-#: option.c:400
+#: option.c:414
 #, fuzzy
 msgid "Specify time-to-live ceiling for cache."
 msgstr "Specifică TTL în secunde pentru răspunsurile din /etc/hosts."
 
-#: option.c:401
+#: option.c:415
 #, fuzzy
 msgid "Specify time-to-live floor for cache."
 msgstr "Specifică TTL în secunde pentru răspunsurile din /etc/hosts."
 
-#: option.c:402
+#: option.c:416
 #, c-format
 msgid "Change to this user after startup. (defaults to %s)."
 msgstr "Rulează sub acest utilizator după pornire. (implicit e %s)."
 
-#: option.c:403
+#: option.c:417
 #, fuzzy
 msgid "Map DHCP vendor class to tag."
 msgstr "Trimite opţiuni DHCP în funcţie de marca plăcii de reţea."
 
-#: option.c:404
+#: option.c:418
 msgid "Display dnsmasq version and copyright information."
 msgstr "Afişează versiunea dnsmasq şi drepturile de autor."
 
-#: option.c:405
+#: option.c:419
 msgid "Translate IPv4 addresses from upstream servers."
 msgstr "Traduce adresele IPv4 de la serverele DNS superioare."
 
-#: option.c:406
+#: option.c:420
 msgid "Specify a SRV record."
 msgstr "Specifică o înregistrare SRV."
 
-#: option.c:407
+#: option.c:421
 msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
 msgstr ""
 
-#: option.c:408
+#: option.c:422
 #, fuzzy, c-format
 msgid "Specify path of PID file (defaults to %s)."
 msgstr "Specifică o cale pentru fişierul PID. (implicit %s)."
 
-#: option.c:409
+#: option.c:423
 #, c-format
 msgid "Specify maximum number of DHCP leases (defaults to %s)."
 msgstr "Specifică numărul maxim de împrumuturi DHCP (implicit %s)."
 
-#: option.c:410
+#: option.c:424
 msgid "Answer DNS queries based on the interface a query was sent to."
 msgstr "Răspunde cererilor DNS în funcţie de interfaţa pe care a venit cererea."
 
-#: option.c:411
+#: option.c:425
 msgid "Specify TXT DNS record."
 msgstr "Specifică o înregistrare TXT."
 
-#: option.c:412
+#: option.c:426
 #, fuzzy
 msgid "Specify PTR DNS record."
 msgstr "Specifică o înregistrare TXT."
 
-#: option.c:413
+#: option.c:427
 msgid "Give DNS name to IPv4 address of interface."
 msgstr ""
 
-#: option.c:414
+#: option.c:428
 msgid "Bind only to interfaces in use."
 msgstr "Ascultă doar pe interfeţele active."
 
-#: option.c:415
+#: option.c:429
 #, c-format
 msgid "Read DHCP static host information from %s."
 msgstr "Citeşte informaţii DHCP statice despre maşină din %s."
 
-#: option.c:416
+#: option.c:430
 msgid "Enable the DBus interface for setting upstream servers, etc."
 msgstr "Activeaza interfaţa DBus pentru configurarea serverelor superioare."
 
-#: option.c:417
+#: option.c:431
+msgid "Enable the UBus interface."
+msgstr ""
+
+#: option.c:432
 msgid "Do not provide DHCP on this interface, only provide DNS."
 msgstr "Nu activează DHCP ci doar DNS pe această interfaţă."
 
-#: option.c:418
+#: option.c:433
 msgid "Enable dynamic address allocation for bootp."
 msgstr "Activează alocarea dinamică a adreselor pentru BOOTP."
 
-#: option.c:419
+#: option.c:434
 #, fuzzy
 msgid "Map MAC address (with wildcards) to option set."
 msgstr "Trimite opţiuni DHCP în funcţie de marca plăcii de reţea."
 
-#: option.c:420
+#: option.c:435
 msgid "Treat DHCP requests on aliases as arriving from interface."
 msgstr ""
 
-#: option.c:421
+#: option.c:436
+msgid "Specify extra networks sharing a broadcast domain for DHCP"
+msgstr ""
+
+#: option.c:437
 msgid "Disable ICMP echo address checking in the DHCP server."
 msgstr ""
 
-#: option.c:422
+#: option.c:438
 msgid "Shell script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:423
+#: option.c:439
 msgid "Lua script to run on DHCP lease creation and destruction."
 msgstr ""
 
-#: option.c:424
+#: option.c:440
 msgid "Run lease-change scripts as this user."
 msgstr ""
 
-#: option.c:425
+#: option.c:441
 msgid "Call dhcp-script with changes to local ARP table."
 msgstr ""
 
-#: option.c:426
+#: option.c:442
 msgid "Read configuration from all the files in this directory."
 msgstr ""
 
-#: option.c:427
+#: option.c:443
 #, fuzzy
 msgid "Log to this syslog facility or file. (defaults to DAEMON)"
 msgstr "Rulează sub acest utilizator după pornire. (implicit e %s)."
 
-#: option.c:428
+#: option.c:444
 msgid "Do not use leasefile."
 msgstr ""
 
-#: option.c:429
+#: option.c:445
 #, fuzzy, c-format
 msgid "Maximum number of concurrent DNS queries. (defaults to %s)"
 msgstr "Specifică numărul maxim de împrumuturi DHCP (implicit %s)."
 
-#: option.c:430
+#: option.c:446
 #, c-format
 msgid "Clear DNS cache when reloading %s."
 msgstr ""
 
-#: option.c:431
+#: option.c:447
 msgid "Ignore hostnames provided by DHCP clients."
 msgstr ""
 
-#: option.c:432
+#: option.c:448
 msgid "Do NOT reuse filename and server fields for extra DHCP options."
 msgstr ""
 
-#: option.c:433
+#: option.c:449
 msgid "Enable integrated read-only TFTP server."
 msgstr ""
 
-#: option.c:434
+#: option.c:450
 msgid "Export files by TFTP only from the specified subtree."
 msgstr ""
 
-#: option.c:435
+#: option.c:451
 msgid "Add client IP or hardware address to tftp-root."
 msgstr ""
 
-#: option.c:436
+#: option.c:452
 msgid "Allow access only to files owned by the user running dnsmasq."
 msgstr ""
 
-#: option.c:437
+#: option.c:453
 msgid "Do not terminate the service if TFTP directories are inaccessible."
 msgstr ""
 
-#: option.c:438
+#: option.c:454
 #, fuzzy, c-format
 msgid "Maximum number of concurrent TFTP transfers (defaults to %s)."
 msgstr "Specifică numărul maxim de împrumuturi DHCP (implicit %s)."
 
-#: option.c:439
+#: option.c:455
 #, fuzzy
 msgid "Maximum MTU to use for TFTP transfers."
 msgstr "Specifică numărul maxim de împrumuturi DHCP (implicit %s)."
 
-#: option.c:440
+#: option.c:456
 msgid "Disable the TFTP blocksize extension."
 msgstr ""
 
-#: option.c:441
+#: option.c:457
 msgid "Convert TFTP filenames to lowercase"
 msgstr ""
 
-#: option.c:442
+#: option.c:458
 msgid "Ephemeral port range for use by TFTP transfers."
 msgstr ""
 
-#: option.c:443
+#: option.c:459
+msgid "Use only one port for TFTP server."
+msgstr ""
+
+#: option.c:460
 msgid "Extra logging for DHCP."
 msgstr ""
 
-#: option.c:444
+#: option.c:461
 msgid "Enable async. logging; optionally set queue length."
 msgstr ""
 
-#: option.c:445
+#: option.c:462
 msgid "Stop DNS rebinding. Filter private IP ranges when resolving."
 msgstr ""
 
-#: option.c:446
+#: option.c:463
 msgid "Allow rebinding of 127.0.0.0/8, for RBL servers."
 msgstr ""
 
-#: option.c:447
+#: option.c:464
 msgid "Inhibit DNS-rebind protection on this domain."
 msgstr ""
 
-#: option.c:448
+#: option.c:465
 msgid "Always perform DNS queries to all servers."
 msgstr ""
 
-#: option.c:449
+#: option.c:466
 msgid "Set tag if client includes matching option in request."
 msgstr ""
 
-#: option.c:450
+#: option.c:467
+msgid "Set tag if client provides given name."
+msgstr ""
+
+#: option.c:468
 msgid "Use alternative ports for DHCP."
 msgstr ""
 
-#: option.c:451
+#: option.c:469
 #, fuzzy
 msgid "Specify NAPTR DNS record."
 msgstr "Specifică o înregistrare TXT."
 
-#: option.c:452
+#: option.c:470
 msgid "Specify lowest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:453
+#: option.c:471
 msgid "Specify highest port available for DNS query transmission."
 msgstr ""
 
-#: option.c:454
+#: option.c:472
 msgid "Use only fully qualified domain names for DHCP clients."
 msgstr ""
 
-#: option.c:455
+#: option.c:473
 msgid "Generate hostnames based on MAC address for nameless clients."
 msgstr ""
 
-#: option.c:456
+#: option.c:474
 msgid "Use these DHCP relays as full proxies."
 msgstr ""
 
-#: option.c:457
+#: option.c:475
 msgid "Relay DHCP requests to a remote server"
 msgstr ""
 
-#: option.c:458
+#: option.c:476
 msgid "Specify alias name for LOCAL DNS name."
 msgstr ""
 
-#: option.c:459
+#: option.c:477
 #, fuzzy
 msgid "Prompt to send to PXE clients."
 msgstr "Configurează opţiuni în plusce trebuie trimise clienţilor DHCP."
 
-#: option.c:460
+#: option.c:478
 msgid "Boot service for PXE menu."
 msgstr ""
 
-#: option.c:461
+#: option.c:479
 msgid "Check configuration syntax."
 msgstr ""
 
-#: option.c:462
+#: option.c:480
 msgid "Add requestor's MAC address to forwarded DNS queries."
 msgstr ""
 
-#: option.c:463
+#: option.c:481
 msgid "Add specified IP subnet to forwarded DNS queries."
 msgstr ""
 
-#: option.c:464
+#: option.c:482
 #, fuzzy
 msgid "Add client identification to forwarded DNS queries."
 msgstr "Forţează acest port pentru datele ce pleacă."
 
-#: option.c:465
+#: option.c:483
 #, fuzzy
 msgid "Proxy DNSSEC validation results from upstream nameservers."
 msgstr "Traduce adresele IPv4 de la serverele DNS superioare."
 
-#: option.c:466
+#: option.c:484
 msgid "Attempt to allocate sequential IP addresses to DHCP clients."
 msgstr ""
 
-#: option.c:467
+#: option.c:485
+#, fuzzy
+msgid "Ignore client identifier option sent by DHCP clients."
+msgstr "Configurează opţiuni în plusce trebuie trimise clienţilor DHCP."
+
+#: option.c:486
 msgid "Copy connection-track mark from queries to upstream connections."
 msgstr ""
 
-#: option.c:468
+#: option.c:487
 msgid "Allow DHCP clients to do their own DDNS updates."
 msgstr ""
 
-#: option.c:469
+#: option.c:488
 msgid "Send router-advertisements for interfaces doing DHCPv6"
 msgstr ""
 
-#: option.c:470
+#: option.c:489
 msgid "Specify DUID_EN-type DHCPv6 server DUID"
 msgstr ""
 
-#: option.c:471
+#: option.c:490
 #, fuzzy
 msgid "Specify host (A/AAAA and PTR) records"
 msgstr "Specifică o înregistrare MX."
 
-#: option.c:472
+#: option.c:491
+msgid "Specify certification authority authorization record"
+msgstr ""
+
+#: option.c:492
 #, fuzzy
 msgid "Specify arbitrary DNS resource record"
 msgstr "Specifică o înregistrare TXT."
 
-#: option.c:473
+#: option.c:493
 #, fuzzy
 msgid "Bind to interfaces in use - check for new interfaces"
 msgstr "interfaţă necunoscută %s"
 
-#: option.c:474
+#: option.c:494
 msgid "Export local names to global DNS"
 msgstr ""
 
-#: option.c:475
+#: option.c:495
 msgid "Domain to export to global DNS"
 msgstr ""
 
-#: option.c:476
+#: option.c:496
 msgid "Set TTL for authoritative replies"
 msgstr ""
 
-#: option.c:477
+#: option.c:497
 msgid "Set authoritative zone information"
 msgstr ""
 
-#: option.c:478
+#: option.c:498
 msgid "Secondary authoritative nameservers for forward domains"
 msgstr ""
 
-#: option.c:479
+#: option.c:499
 msgid "Peers which are allowed to do zone transfer"
 msgstr ""
 
-#: option.c:480
+#: option.c:500
 msgid "Specify ipsets to which matching domains should be added"
 msgstr ""
 
-#: option.c:481
+#: option.c:501
 msgid "Specify a domain and address range for synthesised names"
 msgstr ""
 
-#: option.c:482
+#: option.c:502
 msgid "Activate DNSSEC validation"
 msgstr ""
 
-#: option.c:483
+#: option.c:503
 msgid "Specify trust anchor key digest."
 msgstr ""
 
-#: option.c:484
+#: option.c:504
 msgid "Disable upstream checking for DNSSEC debugging."
 msgstr ""
 
-#: option.c:485
+#: option.c:505
 msgid "Ensure answers without DNSSEC are in unsigned zones."
 msgstr ""
 
-#: option.c:486
+#: option.c:506
 msgid "Don't check DNSSEC signature timestamps until first cache-reload"
 msgstr ""
 
-#: option.c:487
+#: option.c:507
 msgid "Timestamp file to verify system clock for DNSSEC"
 msgstr ""
 
-#: option.c:489
-msgid "Specify DHCPv6 prefix class"
-msgstr ""
-
-#: option.c:491
+#: option.c:508
 msgid "Set MTU, priority, resend-interval and router-lifetime"
 msgstr ""
 
-#: option.c:492
+#: option.c:509
 msgid "Do not log routine DHCP."
 msgstr ""
 
-#: option.c:493
+#: option.c:510
 msgid "Do not log routine DHCPv6."
 msgstr ""
 
-#: option.c:494
+#: option.c:511
 msgid "Do not log RA."
 msgstr ""
 
-#: option.c:495
+#: option.c:512
 msgid "Accept queries only from directly-connected networks."
 msgstr ""
 
-#: option.c:496
+#: option.c:513
 msgid "Detect and remove DNS forwarding loops."
 msgstr ""
 
-#: option.c:497
+#: option.c:514
 msgid "Ignore DNS responses containing ipaddr."
 msgstr ""
 
-#: option.c:498
+#: option.c:515
 msgid "Set TTL in DNS responses with DHCP-derived addresses."
 msgstr ""
 
-#: option.c:499
+#: option.c:516
 msgid "Delay DHCP replies for at least number of seconds."
 msgstr ""
 
-#: option.c:703
+#: option.c:517
+msgid "Enables DHCPv4 Rapid Commit option."
+msgstr ""
+
+#: option.c:518
+msgid "Path to debug packet dump file"
+msgstr ""
+
+#: option.c:519
+msgid "Mask which packets to dump"
+msgstr ""
+
+#: option.c:520
+msgid "Call dhcp-script when lease expiry changes."
+msgstr ""
+
+#: option.c:725
 #, c-format
 msgid ""
 "Usage: dnsmasq [options]\n"
@@ -783,341 +820,356 @@ msgstr ""
 "Utilizare: dnsmasq [opţiuni]\n"
 "\n"
 
-#: option.c:705
+#: option.c:727
 #, c-format
 msgid "Use short options only on the command line.\n"
 msgstr "Folosiţi opţiunile prescurtate doar în linie de comandă.\n"
 
-#: option.c:707
+#: option.c:729
 #, fuzzy, c-format
 msgid "Valid options are:\n"
 msgstr "Opţiunile valide sunt:\n"
 
-#: option.c:754 option.c:868
+#: option.c:776 option.c:884
 #, fuzzy
 msgid "bad address"
 msgstr "citesc %s - %d adrese"
 
-#: option.c:779 option.c:783
+#: option.c:799 option.c:803
 msgid "bad port"
 msgstr "port invalid"
 
-#: option.c:797 option.c:826 option.c:861
+#: option.c:815 option.c:844 option.c:878
 msgid "interface binding not supported"
 msgstr ""
 
-#: option.c:821 option.c:856
+#: option.c:839 option.c:873
 msgid "interface can only be specified once"
 msgstr ""
 
-#: option.c:835 option.c:3809
+#: option.c:852 option.c:4042
 #, fuzzy
 msgid "bad interface name"
 msgstr "nume MX invalid"
 
-#: option.c:1062
+#: option.c:1184
 msgid "unsupported encapsulation for IPv6 option"
 msgstr ""
 
-#: option.c:1076
+#: option.c:1198
 msgid "bad dhcp-option"
 msgstr "dhcp-option invalid"
 
-#: option.c:1144
+#: option.c:1270
 #, fuzzy
 msgid "bad IP address"
 msgstr "citesc %s - %d adrese"
 
-#: option.c:1147 option.c:1286 option.c:3079
+#: option.c:1273 option.c:1412 option.c:3297
 #, fuzzy
 msgid "bad IPv6 address"
 msgstr "citesc %s - %d adrese"
 
-#: option.c:1240
+#: option.c:1366
 #, fuzzy
 msgid "bad IPv4 address"
 msgstr "citesc %s - %d adrese"
 
-#: option.c:1313 option.c:1407
+#: option.c:1439 option.c:1533
 msgid "bad domain in dhcp-option"
 msgstr "domeniu DNS invalid în declaraţia dhcp-option"
 
-#: option.c:1445
+#: option.c:1571
 msgid "dhcp-option too long"
 msgstr "declararea dhcp-option este prea lungă"
 
-#: option.c:1452
+#: option.c:1578
 msgid "illegal dhcp-match"
 msgstr ""
 
-#: option.c:1514
+#: option.c:1647
 msgid "illegal repeated flag"
 msgstr ""
 
-#: option.c:1522
+#: option.c:1655
 msgid "illegal repeated keyword"
 msgstr ""
 
-#: option.c:1593 option.c:4443
+#: option.c:1726 option.c:4764
 #, fuzzy, c-format
 msgid "cannot access directory %s: %s"
 msgstr "nu pot citi %s: %s"
 
-#: option.c:1639 tftp.c:537
+#: option.c:1772 tftp.c:564 dump.c:68
 #, fuzzy, c-format
 msgid "cannot access %s: %s"
 msgstr "nu pot citi %s: %s"
 
-#: option.c:1727
+#: option.c:1879
 msgid "setting log facility is not possible under Android"
 msgstr ""
 
-#: option.c:1736
+#: option.c:1888
 msgid "bad log facility"
 msgstr ""
 
-#: option.c:1789
+#: option.c:1941
 msgid "bad MX preference"
 msgstr "preferinţă MX invalidă"
 
-#: option.c:1794
+#: option.c:1946
 msgid "bad MX name"
 msgstr "nume MX invalid"
 
-#: option.c:1808
+#: option.c:1960
 msgid "bad MX target"
 msgstr "ţintă MX invalidă"
 
-#: option.c:1820
-msgid "cannot run scripts under uClinux"
-msgstr ""
-
-#: option.c:1822
+#: option.c:1980
 msgid "recompile with HAVE_SCRIPT defined to enable lease-change scripts"
 msgstr ""
 
-#: option.c:1826
+#: option.c:1984
 msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
 msgstr ""
 
-#: option.c:2095 option.c:2106 option.c:2143 option.c:2199 option.c:2482
+#: option.c:2244 option.c:2255 option.c:2291 option.c:2344 option.c:2638
 #, fuzzy
 msgid "bad prefix"
 msgstr "port invalid"
 
-#: option.c:2504
+#: option.c:2658
 msgid "recompile with HAVE_IPSET defined to enable ipset directives"
 msgstr ""
 
-#: option.c:2713
+#: option.c:2871
 #, fuzzy
 msgid "bad port range"
 msgstr "port invalid"
 
-#: option.c:2739
+#: option.c:2897
 msgid "bad bridge-interface"
 msgstr ""
 
-#: option.c:2807
+#: option.c:2941
+msgid "bad shared-network"
+msgstr ""
+
+#: option.c:2996
 msgid "only one tag allowed"
 msgstr ""
 
-#: option.c:2827 option.c:2839 option.c:2948 option.c:2953 option.c:2992
+#: option.c:3017 option.c:3032 option.c:3157 option.c:3165 option.c:3205
 msgid "bad dhcp-range"
 msgstr "dhcp-range invalid"
 
-#: option.c:2854
+#: option.c:3050
 msgid "inconsistent DHCP range"
 msgstr "domeniu DHCP inconsistent"
 
-#: option.c:2916
+#: option.c:3115
 msgid "prefix length must be exactly 64 for RA subnets"
 msgstr ""
 
-#: option.c:2918
+#: option.c:3117
 msgid "prefix length must be exactly 64 for subnet constructors"
 msgstr ""
 
-#: option.c:2922
+#: option.c:3120
 msgid "prefix length must be at least 64"
 msgstr ""
 
-#: option.c:2925
+#: option.c:3123
 #, fuzzy
 msgid "inconsistent DHCPv6 range"
 msgstr "domeniu DHCP inconsistent"
 
-#: option.c:2936
+#: option.c:3142
 msgid "prefix must be zero with \"constructor:\" argument"
 msgstr ""
 
-#: option.c:3049 option.c:3097
+#: option.c:3262 option.c:3340
 #, fuzzy
 msgid "bad hex constant"
 msgstr "dhcp-host invalid"
 
-#: option.c:3071
-msgid "cannot match tags in --dhcp-host"
-msgstr ""
+#: option.c:3315
+#, fuzzy
+msgid "bad IPv6 prefix"
+msgstr "port invalid"
 
-#: option.c:3119
+#: option.c:3362
 #, fuzzy, c-format
 msgid "duplicate dhcp-host IP address %s"
 msgstr "adresă IP duplicat %s în declaraţia dhcp-config."
 
-#: option.c:3177
+#: option.c:3422
 #, fuzzy
 msgid "bad DHCP host name"
 msgstr "nume MX invalid"
 
-#: option.c:3259
+#: option.c:3508
 #, fuzzy
 msgid "bad tag-if"
 msgstr "ţintă MX invalidă"
 
-#: option.c:3616 option.c:4039
+#: option.c:3851 option.c:4324
 msgid "invalid port number"
 msgstr "număr de port invalid"
 
-#: option.c:3678
+#: option.c:3907
 #, fuzzy
 msgid "bad dhcp-proxy address"
 msgstr "citesc %s - %d adrese"
 
-#: option.c:3704
+#: option.c:3935
 #, fuzzy
 msgid "Bad dhcp-relay"
 msgstr "dhcp-range invalid"
 
-#: option.c:3745
+#: option.c:3979
 msgid "bad RA-params"
 msgstr ""
 
-#: option.c:3754
+#: option.c:3989
 msgid "bad DUID"
 msgstr ""
 
-#: option.c:3796
+#: option.c:4023
+#, fuzzy
+msgid "missing address in alias"
+msgstr "adresa este folosită"
+
+#: option.c:4029
 #, fuzzy
 msgid "invalid alias range"
 msgstr "pondere invalidă"
 
-#: option.c:3850 option.c:3862
+#: option.c:4081 option.c:4097
 msgid "bad CNAME"
 msgstr ""
 
-#: option.c:3866
+#: option.c:4105
 msgid "duplicate CNAME"
 msgstr ""
 
-#: option.c:3889
+#: option.c:4132
 #, fuzzy
 msgid "bad PTR record"
 msgstr "înregistrare SRV invalidă"
 
-#: option.c:3920
+#: option.c:4167
 #, fuzzy
 msgid "bad NAPTR record"
 msgstr "înregistrare SRV invalidă"
 
-#: option.c:3954
+#: option.c:4203
 #, fuzzy
 msgid "bad RR record"
 msgstr "înregistrare SRV invalidă"
 
-#: option.c:3984
+#: option.c:4236
+#, fuzzy
+msgid "bad CAA record"
+msgstr "înregistrare SRV invalidă"
+
+#: option.c:4265
 msgid "bad TXT record"
 msgstr "înregistrare TXT invalidă"
 
-#: option.c:4025
+#: option.c:4308
 msgid "bad SRV record"
 msgstr "înregistrare SRV invalidă"
 
-#: option.c:4032
+#: option.c:4315
 msgid "bad SRV target"
 msgstr "ţintă SRV invalidă"
 
-#: option.c:4046
+#: option.c:4334
 msgid "invalid priority"
 msgstr "prioritate invalidă"
 
-#: option.c:4049
+#: option.c:4339
 msgid "invalid weight"
 msgstr "pondere invalidă"
 
-#: option.c:4073
+#: option.c:4362
 #, fuzzy
 msgid "Bad host-record"
 msgstr "înregistrare SRV invalidă"
 
-#: option.c:4097
+#: option.c:4402
 #, fuzzy
 msgid "Bad name in host-record"
 msgstr "nume invalid în %s"
 
-#: option.c:4162
+#: option.c:4444
+msgid "bad value for dnssec-check-unsigned"
+msgstr ""
+
+#: option.c:4480
 #, fuzzy
 msgid "bad trust anchor"
 msgstr "port invalid"
 
-#: option.c:4176
+#: option.c:4496
 msgid "bad HEX in trust anchor"
 msgstr ""
 
-#: option.c:4186
+#: option.c:4507
 msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DNSSEC/DBus support)"
 msgstr ""
 
-#: option.c:4246
+#: option.c:4567
 msgid "missing \""
 msgstr "lipseşte \""
 
-#: option.c:4303
+#: option.c:4624
 msgid "bad option"
 msgstr "opţiune invalidă"
 
-#: option.c:4305
+#: option.c:4626
 msgid "extraneous parameter"
 msgstr "parametru nerecunoscut"
 
-#: option.c:4307
+#: option.c:4628
 msgid "missing parameter"
 msgstr "parametru lipsa"
 
-#: option.c:4309
+#: option.c:4630
 #, fuzzy
 msgid "illegal option"
 msgstr "opţiune invalidă"
 
-#: option.c:4316
+#: option.c:4637
 msgid "error"
 msgstr "eroare"
 
-#: option.c:4318
+#: option.c:4639
 #, fuzzy, c-format
 msgid " at line %d of %s"
 msgstr "%s la linia %d din %%s"
 
-#: option.c:4333 option.c:4580 option.c:4616
+#: option.c:4654 option.c:4939 option.c:4950
 #, fuzzy, c-format
 msgid "read %s"
 msgstr "citesc %s"
 
-#: option.c:4396 option.c:4519 tftp.c:715
+#: option.c:4717 option.c:4840 tftp.c:754
 #, c-format
 msgid "cannot read %s: %s"
 msgstr "nu pot citi %s: %s"
 
-#: option.c:4688
+#: option.c:5027
 msgid "junk found in command line"
 msgstr ""
 
-#: option.c:4729
+#: option.c:5067
 #, c-format
 msgid "Dnsmasq version %s  %s\n"
 msgstr "dnsmasq versiunea %s  %s\n"
 
-#: option.c:4730
+#: option.c:5068
 #, fuzzy, c-format
 msgid ""
 "Compile time options: %s\n"
@@ -1126,510 +1178,562 @@ msgstr ""
 "Opţiuni cu care a fost compilat %s\n"
 "\n"
 
-#: option.c:4731
+#: option.c:5069
 #, c-format
 msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
 msgstr "Acest program vine FĂRĂ NICI O GARANŢIE.\n"
 
-#: option.c:4732
+#: option.c:5070
 #, c-format
 msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
 msgstr "Dnsmasq este un program gratuit, sunteţi invitaţi să-l redistribuiţi\n"
 
-#: option.c:4733
+#: option.c:5071
 #, fuzzy, c-format
 msgid "under the terms of the GNU General Public License, version 2 or 3.\n"
 msgstr "în termenii Licenţei publice generale GNU, versiunea 2.\n"
 
-#: option.c:4744
+#: option.c:5088
 msgid "try --help"
 msgstr ""
 
-#: option.c:4746
+#: option.c:5090
 msgid "try -w"
 msgstr ""
 
-#: option.c:4748
+#: option.c:5092
 #, fuzzy, c-format
 msgid "bad command line options: %s"
 msgstr "opţiuni în linie de comandă invalide: %s."
 
-#: option.c:4818
+#: option.c:5161
 #, c-format
 msgid "CNAME loop involving %s"
 msgstr ""
 
-#: option.c:4854
+#: option.c:5195
 #, c-format
 msgid "cannot get host-name: %s"
 msgstr "nu pot citi numele maşinii: %s"
 
-#: option.c:4882
+#: option.c:5223
 msgid "only one resolv.conf file allowed in no-poll mode."
 msgstr "se permite un singur fişier resolv.conf în modul no-poll"
 
-#: option.c:4892
+#: option.c:5233
 msgid "must have exactly one resolv.conf to read domain from."
 msgstr "am nevoie de un singur resolv.conf din care să citesc numele domeniului."
 
-#: option.c:4895 network.c:1623 dhcp.c:816
+#: option.c:5236 network.c:1594 dhcp.c:876
 #, fuzzy, c-format
 msgid "failed to read %s: %s"
 msgstr "nu pot citi %s: %s"
 
-#: option.c:4912
+#: option.c:5253
 #, c-format
 msgid "no search directive found in %s"
 msgstr "nu s-a găsit nici un criteriu de căutare în %s"
 
-#: option.c:4933
+#: option.c:5274
 msgid "there must be a default domain when --dhcp-fqdn is set"
 msgstr ""
 
-#: option.c:4942
+#: option.c:5283
 msgid "syntax check OK"
 msgstr ""
 
-#: forward.c:102
+#: forward.c:99
 #, fuzzy, c-format
 msgid "failed to send packet: %s"
 msgstr "ascultarea pe socket a eşuat: %s"
 
-#: forward.c:598
+#: forward.c:614
 msgid "discarding DNS reply: subnet option mismatch"
 msgstr ""
 
-#: forward.c:652
+#: forward.c:677
 #, c-format
 msgid "nameserver %s refused to do a recursive query"
 msgstr "serverul DNS %s refuză interogările recursive"
 
-#: forward.c:684
+#: forward.c:709
 #, c-format
 msgid "possible DNS-rebind attack detected: %s"
 msgstr ""
 
-#: forward.c:870
+#: forward.c:961
 #, c-format
 msgid "reducing DNS packet size for nameserver %s to %d"
 msgstr ""
 
-#: forward.c:1266 forward.c:1704
+#: forward.c:1370 forward.c:1830
 msgid "Ignoring query from non-local network"
 msgstr ""
 
-#: forward.c:2184
+#: forward.c:2321
 #, fuzzy, c-format
 msgid "Maximum number of concurrent DNS queries reached (max: %d)"
 msgstr "Specifică numărul maxim de împrumuturi DHCP (implicit %s)."
 
-#: network.c:720
+#: network.c:698
 #, fuzzy, c-format
 msgid "failed to create listening socket for %s: %s"
 msgstr "creearea socket-ului de ascultare a eşuat: %s"
 
-#: network.c:1031
+#: network.c:1002
 #, c-format
 msgid "LOUD WARNING: listening on %s may accept requests via interfaces other than %s"
 msgstr ""
 
-#: network.c:1038
+#: network.c:1009
 msgid "LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"
 msgstr ""
 
-#: network.c:1047
+#: network.c:1018
 #, fuzzy, c-format
 msgid "warning: using interface %s instead"
 msgstr "atenţie: interfaţa %s nu există momentan"
 
-#: network.c:1056
+#: network.c:1027
 #, fuzzy, c-format
 msgid "warning: no addresses found for interface %s"
 msgstr "folosim adresele locale doar pentru %S %s"
 
-#: network.c:1114
+#: network.c:1085
 #, fuzzy, c-format
 msgid "interface %s failed to join DHCPv6 multicast group: %s"
 msgstr "activarea socket-ului server-ului DHCP a eşuat: %s"
 
-#: network.c:1119
+#: network.c:1090
 msgid "try increasing /proc/sys/net/core/optmem_max"
 msgstr ""
 
-#: network.c:1337
+#: network.c:1307
 #, fuzzy, c-format
 msgid "failed to bind server socket for %s: %s"
 msgstr "activarea socket-ului de ascultare pentru %s a eşuat: %s"
 
-#: network.c:1528
+#: network.c:1499
 #, c-format
 msgid "ignoring nameserver %s - local interface"
 msgstr "ignorăm serverul DNS %s - interfaţă locală"
 
-#: network.c:1539
+#: network.c:1510
 #, fuzzy, c-format
 msgid "ignoring nameserver %s - cannot make/bind socket: %s"
 msgstr "ignorăm serverul DNS %s - nu pot creea/activa socket-ul: %s"
 
-#: network.c:1559
+#: network.c:1530
 msgid "(no DNSSEC)"
 msgstr ""
 
-#: network.c:1562
+#: network.c:1533
 msgid "unqualified"
 msgstr "invalid"
 
-#: network.c:1562
+#: network.c:1533
 msgid "names"
 msgstr ""
 
-#: network.c:1564
+#: network.c:1535
 msgid "default"
 msgstr ""
 
-#: network.c:1566
+#: network.c:1537
 msgid "domain"
 msgstr "domeniu"
 
-#: network.c:1572
-#, c-format
-msgid "using local addresses only for %s %s"
+#: network.c:1543
+#, fuzzy, c-format
+msgid "using only locally-known addresses for %s %s"
 msgstr "folosim adresele locale doar pentru %S %s"
 
-#: network.c:1575
+#: network.c:1546
 #, fuzzy, c-format
 msgid "using standard nameservers for %s %s"
 msgstr "folosim serverul DNS %s#%d pentru %s %s"
 
-#: network.c:1577
+#: network.c:1548
 #, fuzzy, c-format
 msgid "using nameserver %s#%d for %s %s %s"
 msgstr "folosim serverul DNS %s#%d pentru %s %s"
 
-#: network.c:1581
+#: network.c:1552
 #, fuzzy, c-format
 msgid "NOT using nameserver %s#%d - query loop detected"
 msgstr "folosim serverul DNS %s#%d pentru %s %s"
 
-#: network.c:1584
+#: network.c:1555
 #, fuzzy, c-format
 msgid "using nameserver %s#%d(via %s)"
 msgstr "folosim serverul DNS %s#%d"
 
-#: network.c:1586
+#: network.c:1557
 #, c-format
 msgid "using nameserver %s#%d"
 msgstr "folosim serverul DNS %s#%d"
 
-#: network.c:1591
+#: network.c:1562
 #, fuzzy, c-format
 msgid "using %d more local addresses"
 msgstr "folosim serverul DNS %s#%d"
 
-#: network.c:1593
+#: network.c:1564
 #, fuzzy, c-format
 msgid "using %d more nameservers"
 msgstr "folosim serverul DNS %s#%d"
 
-#: dnsmasq.c:171
+#: dnsmasq.c:173
 msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
 msgstr ""
 
-#: dnsmasq.c:186
+#: dnsmasq.c:188
 msgid "no root trust anchor provided for DNSSEC"
 msgstr ""
 
-#: dnsmasq.c:189
+#: dnsmasq.c:191
 msgid "cannot reduce cache size from default when DNSSEC enabled"
 msgstr ""
 
-#: dnsmasq.c:191
+#: dnsmasq.c:193
 #, fuzzy
 msgid "DNSSEC not available: set HAVE_DNSSEC in src/config.h"
 msgstr "DBus nu este disponibil: puneţi HAVE_DBUS in src/config.h"
 
-#: dnsmasq.c:197
+#: dnsmasq.c:199
 #, fuzzy
 msgid "TFTP server not available: set HAVE_TFTP in src/config.h"
 msgstr "DBus nu este disponibil: puneţi HAVE_DBUS in src/config.h"
 
-#: dnsmasq.c:202
+#: dnsmasq.c:204
 msgid "cannot use --conntrack AND --query-port"
 msgstr ""
 
-#: dnsmasq.c:205
+#: dnsmasq.c:207
 #, fuzzy
 msgid "conntrack support not available: set HAVE_CONNTRACK in src/config.h"
 msgstr "DBus nu este disponibil: puneţi HAVE_DBUS in src/config.h"
 
-#: dnsmasq.c:210
+#: dnsmasq.c:212
 msgid "asynchronous logging is not available under Solaris"
 msgstr ""
 
-#: dnsmasq.c:215
+#: dnsmasq.c:217
 msgid "asynchronous logging is not available under Android"
 msgstr ""
 
-#: dnsmasq.c:220
+#: dnsmasq.c:222
 #, fuzzy
 msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
 msgstr "DBus nu este disponibil: puneţi HAVE_DBUS in src/config.h"
 
-#: dnsmasq.c:225
+#: dnsmasq.c:227
 #, fuzzy
 msgid "loop detection not available: set HAVE_LOOP in src/config.h"
 msgstr "DBus nu este disponibil: puneţi HAVE_DBUS in src/config.h"
 
-#: dnsmasq.c:229
+#: dnsmasq.c:232
+#, fuzzy
+msgid "Ubus not available: set HAVE_UBUS in src/config.h"
+msgstr "DBus nu este disponibil: puneţi HAVE_DBUS in src/config.h"
+
+#: dnsmasq.c:236
 msgid "max_port cannot be smaller than min_port"
 msgstr ""
 
-#: dnsmasq.c:236
+#: dnsmasq.c:243
+msgid "--auth-server required when an auth zone is defined."
+msgstr ""
+
+#: dnsmasq.c:248
 msgid "zone serial must be configured in --auth-soa"
 msgstr ""
 
-#: dnsmasq.c:254
+#: dnsmasq.c:268
 msgid "dhcp-range constructor not available on this platform"
 msgstr ""
 
-#: dnsmasq.c:300
+#: dnsmasq.c:332
 msgid "cannot set --bind-interfaces and --bind-dynamic"
 msgstr ""
 
-#: dnsmasq.c:303
+#: dnsmasq.c:335
 #, c-format
 msgid "failed to find list of interfaces: %s"
 msgstr "enumerarea interfeţelor a eşuat: %s"
 
-#: dnsmasq.c:312
+#: dnsmasq.c:344
 #, c-format
 msgid "unknown interface %s"
 msgstr "interfaţă necunoscută %s"
 
-#: dnsmasq.c:377 dnsmasq.c:1054
+#: dnsmasq.c:406
+#, fuzzy
+msgid "Packet dumps not available: set HAVE_DUMP in src/config.h"
+msgstr "DBus nu este disponibil: puneţi HAVE_DBUS in src/config.h"
+
+#: dnsmasq.c:416 dnsmasq.c:1171
 #, c-format
 msgid "DBus error: %s"
 msgstr "eroare DBus: %s"
 
-#: dnsmasq.c:380
+#: dnsmasq.c:419
 msgid "DBus not available: set HAVE_DBUS in src/config.h"
 msgstr "DBus nu este disponibil: puneţi HAVE_DBUS in src/config.h"
 
-#: dnsmasq.c:410
+#: dnsmasq.c:429
+#, fuzzy
+msgid "UBus not available: set HAVE_UBUS in src/config.h"
+msgstr "DBus nu este disponibil: puneţi HAVE_DBUS in src/config.h"
+
+#: dnsmasq.c:459
 #, c-format
 msgid "unknown user or group: %s"
 msgstr ""
 
-#: dnsmasq.c:465
+#: dnsmasq.c:535
+#, c-format
+msgid "process is missing required capability %s"
+msgstr ""
+
+#: dnsmasq.c:567
 #, c-format
 msgid "cannot chdir to filesystem root: %s"
 msgstr ""
 
-#: dnsmasq.c:730
+#: dnsmasq.c:815
 #, fuzzy, c-format
 msgid "started, version %s DNS disabled"
 msgstr "am pornit, versiunea %s memorie temporară dezactivată"
 
-#: dnsmasq.c:734
+#: dnsmasq.c:820
 #, c-format
 msgid "started, version %s cachesize %d"
 msgstr "am ponit, versiunea %s memorie temporară %d"
 
-#: dnsmasq.c:736
+#: dnsmasq.c:822
+msgid "cache size greater than 10000 may cause performance issues, and is unlikely to be useful."
+msgstr ""
+
+#: dnsmasq.c:825
 #, c-format
 msgid "started, version %s cache disabled"
 msgstr "am pornit, versiunea %s memorie temporară dezactivată"
 
-#: dnsmasq.c:739
+#: dnsmasq.c:828
 msgid "DNS service limited to local subnets"
 msgstr ""
 
-#: dnsmasq.c:742
+#: dnsmasq.c:831
 #, c-format
 msgid "compile time options: %s"
 msgstr "compilat cu opţiunile: %s"
 
-#: dnsmasq.c:751
+#: dnsmasq.c:840
 msgid "DBus support enabled: connected to system bus"
 msgstr "suportul DBus activ: sunt conectat la magistrala sistem"
 
-#: dnsmasq.c:753
+#: dnsmasq.c:842
 msgid "DBus support enabled: bus connection pending"
 msgstr "suportul DBus activ: aştept conexiunea la magistrală"
 
-#: dnsmasq.c:771
+#: dnsmasq.c:850
+#, fuzzy
+msgid "UBus support enabled: connected to system bus"
+msgstr "suportul DBus activ: sunt conectat la magistrala sistem"
+
+#: dnsmasq.c:852
+#, fuzzy
+msgid "UBus support enabled: bus connection pending"
+msgstr "suportul DBus activ: aştept conexiunea la magistrală"
+
+#: dnsmasq.c:872
+msgid "DNSSEC validation enabled but all unsigned answers are trusted"
+msgstr ""
+
+#: dnsmasq.c:874
 msgid "DNSSEC validation enabled"
 msgstr ""
 
-#: dnsmasq.c:775
+#: dnsmasq.c:878
 msgid "DNSSEC signature timestamps not checked until receipt of SIGINT"
 msgstr ""
 
-#: dnsmasq.c:778
+#: dnsmasq.c:881
 msgid "DNSSEC signature timestamps not checked until system time valid"
 msgstr ""
 
+#: dnsmasq.c:884
+#, c-format
+msgid "configured with trust anchor for %s keytag %u"
+msgstr ""
+
 # for compatibility purposes the letters â, ă, ş, ţ and î can be written as their look-alike correspondent.
-#: dnsmasq.c:783
+#: dnsmasq.c:890
 #, fuzzy, c-format
 msgid "warning: failed to change owner of %s: %s"
 msgstr "încărcarea numelor din %s: %s a eşuat"
 
-#: dnsmasq.c:787
+#: dnsmasq.c:894
 msgid "setting --bind-interfaces option because of OS limitations"
 msgstr "specific opţiunea --bind-interfaces din cauza limitărilor SO"
 
-#: dnsmasq.c:799
+#: dnsmasq.c:906
 #, c-format
 msgid "warning: interface %s does not currently exist"
 msgstr "atenţie: interfaţa %s nu există momentan"
 
-#: dnsmasq.c:804
+#: dnsmasq.c:911
 msgid "warning: ignoring resolv-file flag because no-resolv is set"
 msgstr ""
 
-#: dnsmasq.c:807
+#: dnsmasq.c:914
 #, fuzzy
 msgid "warning: no upstream servers configured"
 msgstr "configurăm serverele superioare prin Dbus"
 
-#: dnsmasq.c:811
+#: dnsmasq.c:918
 #, c-format
 msgid "asynchronous logging enabled, queue limit is %d messages"
 msgstr ""
 
-#: dnsmasq.c:832
+#: dnsmasq.c:939
 msgid "IPv6 router advertisement enabled"
 msgstr ""
 
-#: dnsmasq.c:837
+#: dnsmasq.c:944
 #, c-format
 msgid "DHCP, sockets bound exclusively to interface %s"
 msgstr ""
 
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 msgid "root is "
 msgstr ""
 
-#: dnsmasq.c:851
+#: dnsmasq.c:958
 #, fuzzy
 msgid "enabled"
 msgstr "dezactivat"
 
-#: dnsmasq.c:853
+#: dnsmasq.c:960
 msgid "secure mode"
 msgstr ""
 
-#: dnsmasq.c:856
+#: dnsmasq.c:961
+#, fuzzy
+msgid "single port mode"
+msgstr "număr de port invalid"
+
+#: dnsmasq.c:964
 #, c-format
 msgid "warning: %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:860
+#: dnsmasq.c:968
 #, c-format
 msgid "warning: TFTP directory %s inaccessible"
 msgstr ""
 
-#: dnsmasq.c:886
+#: dnsmasq.c:994
 #, c-format
 msgid "restricting maximum simultaneous TFTP transfers to %d"
 msgstr ""
 
-#: dnsmasq.c:1056
+#: dnsmasq.c:1173
 msgid "connected to system DBus"
 msgstr "magistrala sistem Dbus conectată"
 
-#: dnsmasq.c:1215
+#: dnsmasq.c:1345
 #, c-format
 msgid "cannot fork into background: %s"
 msgstr ""
 
-#: dnsmasq.c:1218
+#: dnsmasq.c:1349
 #, fuzzy, c-format
 msgid "failed to create helper: %s"
 msgstr "nu pot citi %s: %s"
 
-#: dnsmasq.c:1221
+#: dnsmasq.c:1353
 #, c-format
 msgid "setting capabilities failed: %s"
 msgstr ""
 
 # for compatibility purposes the letters â, ă, ş, ţ and î can be written as their look-alike correspondent.
-#: dnsmasq.c:1224
+#: dnsmasq.c:1357
 #, fuzzy, c-format
 msgid "failed to change user-id to %s: %s"
 msgstr "încărcarea numelor din %s: %s a eşuat"
 
 # for compatibility purposes the letters â, ă, ş, ţ and î can be written as their look-alike correspondent.
-#: dnsmasq.c:1227
+#: dnsmasq.c:1361
 #, fuzzy, c-format
 msgid "failed to change group-id to %s: %s"
 msgstr "încărcarea numelor din %s: %s a eşuat"
 
-#: dnsmasq.c:1230
+#: dnsmasq.c:1365
 #, fuzzy, c-format
 msgid "failed to open pidfile %s: %s"
 msgstr "nu pot citi %s: %s"
 
-#: dnsmasq.c:1233
+#: dnsmasq.c:1369
 #, fuzzy, c-format
 msgid "cannot open log %s: %s"
 msgstr "nu pot deschide %s:%s"
 
-#: dnsmasq.c:1236
+#: dnsmasq.c:1373
 #, fuzzy, c-format
 msgid "failed to load Lua script: %s"
 msgstr "nu pot încărca %s: %s"
 
-#: dnsmasq.c:1239
+#: dnsmasq.c:1377
 #, c-format
 msgid "TFTP directory %s inaccessible: %s"
 msgstr ""
 
-#: dnsmasq.c:1242
+#: dnsmasq.c:1381
 #, fuzzy, c-format
 msgid "cannot create timestamp file %s: %s"
 msgstr "nu pot creea sau deschide fişierul cu împrumuturi: %s"
 
-#: dnsmasq.c:1326
+#: dnsmasq.c:1465
 #, c-format
 msgid "script process killed by signal %d"
 msgstr ""
 
-#: dnsmasq.c:1330
+#: dnsmasq.c:1469
 #, c-format
 msgid "script process exited with status %d"
 msgstr ""
 
-#: dnsmasq.c:1334
+#: dnsmasq.c:1473
 #, fuzzy, c-format
 msgid "failed to execute %s: %s"
 msgstr "accesarea serverului %s a eşuat: %s"
 
-#: dnsmasq.c:1374
+#: dnsmasq.c:1513
 msgid "now checking DNSSEC signature timestamps"
 msgstr ""
 
-#: dnsmasq.c:1409 dnssec.c:160 dnssec.c:206
+#: dnsmasq.c:1548 dnssec.c:160 dnssec.c:204
 #, fuzzy, c-format
 msgid "failed to update mtime on %s: %s"
 msgstr "nu pot citi %s: %s"
 
-#: dnsmasq.c:1416
+#: dnsmasq.c:1560
 msgid "exiting on receipt of SIGTERM"
 msgstr "am primit SIGTERM, am terminat"
 
-#: dnsmasq.c:1444
+#: dnsmasq.c:1588
 #, fuzzy, c-format
 msgid "failed to access %s: %s"
 msgstr "accesarea serverului %s a eşuat: %s"
 
-#: dnsmasq.c:1474
+#: dnsmasq.c:1618
 #, c-format
 msgid "reading %s"
 msgstr "citesc %s"
 
-#: dnsmasq.c:1485
+#: dnsmasq.c:1629
 #, fuzzy, c-format
 msgid "no servers found in %s, will retry"
 msgstr "nu s-a găsit nici un criteriu de căutare în %s"
@@ -1659,7 +1763,7 @@ msgstr "activarea socket-ului server-ului DHCP a eşuat: %s"
 msgid "cannot create ICMP raw socket: %s."
 msgstr "nu pot creea socket ICMP raw: %s."
 
-#: dhcp.c:252 dhcp6.c:173
+#: dhcp.c:252 dhcp6.c:180
 #, fuzzy, c-format
 msgid "unknown interface %s in bridge-interface"
 msgstr "interfaţă necunoscută %s"
@@ -1669,331 +1773,337 @@ msgstr "interfaţă necunoscută %s"
 msgid "DHCP packet received on %s which has no address"
 msgstr ""
 
-#: dhcp.c:427
+#: dhcp.c:428
 #, c-format
 msgid "ARP-cache injection failed: %s"
 msgstr ""
 
-#: dhcp.c:470
+#: dhcp.c:471
 #, c-format
 msgid "Error sending DHCP packet to %s: %s"
 msgstr ""
 
-#: dhcp.c:531
+#: dhcp.c:526
 #, c-format
 msgid "DHCP range %s -- %s is not consistent with netmask %s"
 msgstr "domeniu DHCP %s -- %s nu este consistent cu masca de reţea %s"
 
-#: dhcp.c:854
+#: dhcp.c:914
 #, c-format
 msgid "bad line at %s line %d"
 msgstr "linie invalidă în %s rândul %d"
 
-#: dhcp.c:897
+#: dhcp.c:957
 #, c-format
 msgid "ignoring %s line %d, duplicate name or IP address"
 msgstr ""
 
-#: dhcp.c:1041 rfc3315.c:2149
+#: dhcp.c:1100 rfc3315.c:2139
 #, c-format
 msgid "DHCP relay %s -> %s"
 msgstr ""
 
-#: lease.c:98
+#: lease.c:64
+#, c-format
+msgid "ignoring invalid line in lease database: %s %s %s %s ..."
+msgstr ""
+
+#: lease.c:101
+#, c-format
+msgid "ignoring invalid line in lease database, bad address: %s"
+msgstr ""
+
+#: lease.c:108
 msgid "too many stored leases"
 msgstr "prea multe împrumuturi stocate"
 
-#: lease.c:166
+#: lease.c:176
 #, fuzzy, c-format
 msgid "cannot open or create lease file %s: %s"
 msgstr "nu pot creea sau deschide fişierul cu împrumuturi: %s"
 
-#: lease.c:175
-#, c-format
-msgid "failed to parse lease database, invalid line: %s %s %s %s ..."
-msgstr ""
+#: lease.c:185
+#, fuzzy
+msgid "failed to parse lease database cleanly"
+msgstr "nu pot citi %s: %s"
 
-#: lease.c:180
+#: lease.c:188
 #, fuzzy, c-format
 msgid "failed to read lease file %s: %s"
 msgstr "nu pot citi %s: %s"
 
-#: lease.c:196
+#: lease.c:204
 #, fuzzy, c-format
 msgid "cannot run lease-init script %s: %s"
 msgstr "nu pot citi %s: %s"
 
-#: lease.c:202
+#: lease.c:210
 #, c-format
 msgid "lease-init script returned exit code %s"
 msgstr ""
 
-#: lease.c:373
+#: lease.c:381
 #, fuzzy, c-format
 msgid "failed to write %s: %s (retry in %us)"
 msgstr "nu pot citi %s: %s"
 
-#: lease.c:937
+#: lease.c:955
 #, c-format
 msgid "Ignoring domain %s for DHCP host name %s"
 msgstr ""
 
-#: rfc2131.c:347
+#: rfc2131.c:372
 #, c-format
 msgid "no address range available for DHCP request %s %s"
 msgstr "nici un domeniu de adrese disponibil pentru cererea DHCP %s %s"
 
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "with subnet selector"
 msgstr "cu selectorul de subreţea"
 
-#: rfc2131.c:348
+#: rfc2131.c:373
 msgid "via"
 msgstr "prin"
 
-#: rfc2131.c:360
+#: rfc2131.c:385
 #, fuzzy, c-format
 msgid "%u available DHCP subnet: %s/%s"
 msgstr "nici un domeniu de adrese disponibil pentru cererea DHCP %s %s"
 
-#: rfc2131.c:363 rfc3315.c:306
+#: rfc2131.c:388 rfc3315.c:319
 #, c-format
 msgid "%u available DHCP range: %s -- %s"
 msgstr ""
 
-#: rfc2131.c:474
+#: rfc2131.c:499
 #, fuzzy, c-format
 msgid "%u vendor class: %s"
 msgstr "eroare DBus: %s"
 
-#: rfc2131.c:476
+#: rfc2131.c:501
 #, fuzzy, c-format
 msgid "%u user class: %s"
 msgstr "eroare DBus: %s"
 
-#: rfc2131.c:510
+#: rfc2131.c:535
 msgid "disabled"
 msgstr "dezactivat"
 
-#: rfc2131.c:551 rfc2131.c:1006 rfc2131.c:1430 rfc3315.c:616 rfc3315.c:869
-#: rfc3315.c:1148
+#: rfc2131.c:576 rfc2131.c:1065 rfc2131.c:1509 rfc3315.c:632 rfc3315.c:815
+#: rfc3315.c:1097
 msgid "ignored"
 msgstr "ignorat"
 
-#: rfc2131.c:566 rfc2131.c:1239 rfc3315.c:919
+#: rfc2131.c:591 rfc2131.c:1310 rfc3315.c:867
 msgid "address in use"
 msgstr "adresa este folosită"
 
-#: rfc2131.c:580 rfc2131.c:1060
+#: rfc2131.c:605 rfc2131.c:1119
 msgid "no address available"
 msgstr "nici o adresă disponibilă"
 
-#: rfc2131.c:587 rfc2131.c:1202
+#: rfc2131.c:612 rfc2131.c:1273
 msgid "wrong network"
 msgstr "reţea greşită"
 
-#: rfc2131.c:602
+#: rfc2131.c:627
 msgid "no address configured"
 msgstr "adresă lipsă"
 
-#: rfc2131.c:608 rfc2131.c:1252
+#: rfc2131.c:633 rfc2131.c:1323
 msgid "no leases left"
 msgstr "nu mai am de unde să împrumut"
 
-#: rfc2131.c:703 rfc3315.c:482
+#: rfc2131.c:734 rfc3315.c:499
 #, c-format
 msgid "%u client provides name: %s"
 msgstr ""
 
-#: rfc2131.c:808
+#: rfc2131.c:864
 msgid "PXE BIS not supported"
 msgstr ""
 
-#: rfc2131.c:974 rfc3315.c:1242
+#: rfc2131.c:1032 rfc3315.c:1197
 #, fuzzy, c-format
 msgid "disabling DHCP static address %s for %s"
 msgstr "dezactivăm adresele DHCP statice %s"
 
-#: rfc2131.c:995
+#: rfc2131.c:1053
 msgid "unknown lease"
 msgstr "împrumut necunoscut"
 
-#: rfc2131.c:1029
+#: rfc2131.c:1088
 #, c-format
 msgid "not using configured address %s because it is leased to %s"
 msgstr ""
 
-#: rfc2131.c:1039
+#: rfc2131.c:1098
 #, c-format
 msgid "not using configured address %s because it is in use by the server or relay"
 msgstr ""
 
-#: rfc2131.c:1042
+#: rfc2131.c:1101
 #, c-format
 msgid "not using configured address %s because it was previously declined"
 msgstr ""
 
-#: rfc2131.c:1058 rfc2131.c:1245
+#: rfc2131.c:1117 rfc2131.c:1316
 msgid "no unique-id"
 msgstr ""
 
-#: rfc2131.c:1140
+#: rfc2131.c:1209
 msgid "wrong server-ID"
 msgstr ""
 
-#: rfc2131.c:1159
+#: rfc2131.c:1228
 msgid "wrong address"
 msgstr "adresă greşită"
 
-#: rfc2131.c:1177 rfc3315.c:1015
+#: rfc2131.c:1246 rfc3315.c:961
 msgid "lease not found"
 msgstr "împrumutul nu a fost găsit"
 
-#: rfc2131.c:1210
+#: rfc2131.c:1281
 msgid "address not available"
 msgstr "adresă indisponibilă"
 
-#: rfc2131.c:1221
+#: rfc2131.c:1292
 msgid "static lease available"
 msgstr "împrumut static este disponibil"
 
-#: rfc2131.c:1225
+#: rfc2131.c:1296
 msgid "address reserved"
 msgstr "adresă rezervată"
 
-#: rfc2131.c:1233
+#: rfc2131.c:1304
 #, c-format
 msgid "abandoning lease to %s of %s"
 msgstr ""
 
-#: rfc2131.c:1757
+#: rfc2131.c:1845
 #, c-format
 msgid "%u bootfile name: %s"
 msgstr ""
 
-#: rfc2131.c:1766
+#: rfc2131.c:1854
 #, fuzzy, c-format
 msgid "%u server name: %s"
 msgstr "eroare DBus: %s"
 
-#: rfc2131.c:1774
+#: rfc2131.c:1862
 #, fuzzy, c-format
 msgid "%u next server: %s"
 msgstr "eroare DBus: %s"
 
-#: rfc2131.c:1777
+#: rfc2131.c:1865
 #, c-format
 msgid "%u broadcast response"
 msgstr ""
 
-#: rfc2131.c:1840
+#: rfc2131.c:1928
 #, fuzzy, c-format
 msgid "cannot send DHCP/BOOTP option %d: no space left in packet"
 msgstr "nu pot trimite opţiunea DHCP %d: nu mai este loc în pachet"
 
-#: rfc2131.c:2131
+#: rfc2131.c:2219
 msgid "PXE menu too large"
 msgstr ""
 
-#: rfc2131.c:2270 rfc3315.c:1515
+#: rfc2131.c:2358 rfc3315.c:1470
 #, fuzzy, c-format
 msgid "%u requested options: %s"
 msgstr "compilat cu opţiunile: %s"
 
-#: rfc2131.c:2587
+#: rfc2131.c:2675
 #, c-format
 msgid "cannot send RFC3925 option: too many options for enterprise number %d"
 msgstr ""
 
-#: rfc2131.c:2650
+#: rfc2131.c:2738
 #, c-format
 msgid "%u reply delay: %d"
 msgstr ""
 
-#: netlink.c:77
+#: netlink.c:76
 #, fuzzy, c-format
 msgid "cannot create netlink socket: %s"
 msgstr "nu pot să activez socket-ul netlink: %s"
 
-#: netlink.c:355
+#: netlink.c:352
 #, fuzzy, c-format
 msgid "netlink returns error: %s"
 msgstr "eroare DBus: %s"
 
-#: dbus.c:186
-msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
-msgstr "incerc să configurez un server IPv6 prin Dbus - nu este suport IPv6"
-
-#: dbus.c:439
+#: dbus.c:438
 #, c-format
 msgid "Enabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:444
+#: dbus.c:443
 #, c-format
 msgid "Disabling --%s option from D-Bus"
 msgstr ""
 
-#: dbus.c:690
+#: dbus.c:717
 msgid "setting upstream servers from DBus"
 msgstr "configurăm serverele superioare prin Dbus"
 
-#: dbus.c:737
+#: dbus.c:764
 msgid "could not register a DBus message handler"
 msgstr "nu pot activa o interfaţă de mesaje DBus"
 
-#: bpf.c:265
+#: bpf.c:261
 #, c-format
 msgid "cannot create DHCP BPF socket: %s"
 msgstr "nu pot creea socket DHCP BPF: %s"
 
-#: bpf.c:293
+#: bpf.c:289
 #, fuzzy, c-format
 msgid "DHCP request for unsupported hardware type (%d) received on %s"
 msgstr "cerere DHCP pentru dispozitiv nesuportat (%d) recepţionată prin %s"
 
-#: bpf.c:378
+#: bpf.c:374
 #, fuzzy, c-format
 msgid "cannot create PF_ROUTE socket: %s"
 msgstr "nu pot creea socket DHCP: %s"
 
-#: bpf.c:399
+#: bpf.c:395
 msgid "Unknown protocol version from route socket"
 msgstr ""
 
-#: helper.c:154
+#: helper.c:150
 msgid "lease() function missing in Lua script"
 msgstr ""
 
-#: tftp.c:319
+#: tftp.c:347
 msgid "unable to get free port for TFTP"
 msgstr ""
 
-#: tftp.c:335
+#: tftp.c:363
 #, c-format
 msgid "unsupported request from %s"
 msgstr ""
 
-#: tftp.c:483
+#: tftp.c:510
 #, fuzzy, c-format
 msgid "file %s not found"
 msgstr "împrumutul nu a fost găsit"
 
-#: tftp.c:592
-#, c-format
-msgid "error %d %s received from %s"
-msgstr ""
-
-#: tftp.c:634
+#: tftp.c:628
 #, fuzzy, c-format
 msgid "failed sending %s to %s"
 msgstr "nu pot citi %s: %s"
 
-#: tftp.c:634
+#: tftp.c:628
 #, c-format
 msgid "sent %s to %s"
 msgstr ""
 
+#: tftp.c:678
+#, c-format
+msgid "error %d %s received from %s"
+msgstr ""
+
 #: log.c:190
 #, c-format
 msgid "overflow: %d log entries lost"
@@ -2008,7 +2118,7 @@ msgstr ""
 msgid "FAILED to start up"
 msgstr "pornirea A EŞUAT"
 
-#: conntrack.c:65
+#: conntrack.c:63
 #, c-format
 msgid "Conntrack connection mark retrieval failed: %s"
 msgstr ""
@@ -2028,81 +2138,76 @@ msgstr "configurarea SO_REUSEADDR pe socket-ul DHCP a eşuat: %s"
 msgid "failed to bind DHCPv6 server socket: %s"
 msgstr "activarea socket-ului server-ului DHCP a eşuat: %s"
 
-#: rfc3315.c:157
+#: rfc3315.c:173
 #, fuzzy, c-format
 msgid "no address range available for DHCPv6 request from relay at %s"
 msgstr "nici un domeniu de adrese disponibil pentru cererea DHCP %s %s"
 
-#: rfc3315.c:166
+#: rfc3315.c:182
 #, fuzzy, c-format
 msgid "no address range available for DHCPv6 request via %s"
 msgstr "nici un domeniu de adrese disponibil pentru cererea DHCP %s %s"
 
-#: rfc3315.c:303
+#: rfc3315.c:316
 #, fuzzy, c-format
 msgid "%u available DHCPv6 subnet: %s/%d"
 msgstr "nici un domeniu de adrese disponibil pentru cererea DHCP %s %s"
 
-#: rfc3315.c:386
+#: rfc3315.c:399
 #, fuzzy, c-format
 msgid "%u vendor class: %u"
 msgstr "eroare DBus: %s"
 
-#: rfc3315.c:434
+#: rfc3315.c:447
 #, fuzzy, c-format
 msgid "%u client MAC address: %s"
 msgstr "nu exista interfaţă pentru adresa %s"
 
-#: rfc3315.c:673
-#, fuzzy, c-format
-msgid "unknown prefix-class %d"
-msgstr "împrumut necunoscut"
-
-#: rfc3315.c:816 rfc3315.c:911
+#: rfc3315.c:762 rfc3315.c:859
 #, fuzzy
 msgid "address unavailable"
 msgstr "adresă indisponibilă"
 
-#: rfc3315.c:828 rfc3315.c:959 rfc3315.c:1292
+#: rfc3315.c:774 rfc3315.c:903 rfc3315.c:1247
 msgid "success"
 msgstr ""
 
-#: rfc3315.c:843 rfc3315.c:852 rfc3315.c:967 rfc3315.c:969
+#: rfc3315.c:789 rfc3315.c:798 rfc3315.c:911 rfc3315.c:913
 #, fuzzy
 msgid "no addresses available"
 msgstr "nici o adresă disponibilă"
 
-#: rfc3315.c:946
+#: rfc3315.c:890
 msgid "not on link"
 msgstr ""
 
-#: rfc3315.c:1019 rfc3315.c:1204 rfc3315.c:1281
+#: rfc3315.c:965 rfc3315.c:1156 rfc3315.c:1236
 msgid "no binding found"
 msgstr ""
 
-#: rfc3315.c:1057
+#: rfc3315.c:1002
 msgid "deprecated"
 msgstr ""
 
-#: rfc3315.c:1062
+#: rfc3315.c:1007
 #, fuzzy
 msgid "address invalid"
 msgstr "adresa este folosită"
 
-#: rfc3315.c:1109
+#: rfc3315.c:1057 rfc3315.c:1059
 msgid "confirm failed"
 msgstr ""
 
-#: rfc3315.c:1125
+#: rfc3315.c:1074
 #, fuzzy
 msgid "all addresses still on link"
 msgstr "adresă greşită în %s, linia %d"
 
-#: rfc3315.c:1213
+#: rfc3315.c:1165
 msgid "release received"
 msgstr ""
 
-#: rfc3315.c:2140
+#: rfc3315.c:2130
 msgid "Cannot multicast to DHCPv6 server without correct interface"
 msgstr ""
 
@@ -2116,76 +2221,76 @@ msgstr ""
 msgid "%u tags: %s"
 msgstr ""
 
-#: dhcp-common.c:407
+#: dhcp-common.c:444
 #, c-format
 msgid "%s has more than one address in hostsfile, using %s for DHCP"
 msgstr ""
 
-#: dhcp-common.c:430
+#: dhcp-common.c:478
 #, c-format
 msgid "duplicate IP address %s (%s) in dhcp-config directive"
 msgstr "adresă IP duplicat %s (%s) în declaraţia dhcp-config."
 
-#: dhcp-common.c:491
+#: dhcp-common.c:542
 #, fuzzy, c-format
 msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
 msgstr "configurarea SO_REUSEADDR pe socket-ul DHCP a eşuat: %s"
 
-#: dhcp-common.c:612
+#: dhcp-common.c:665
 #, c-format
 msgid "Known DHCP options:\n"
 msgstr ""
 
-#: dhcp-common.c:623
+#: dhcp-common.c:676
 #, c-format
 msgid "Known DHCPv6 options:\n"
 msgstr ""
 
-#: dhcp-common.c:820
+#: dhcp-common.c:873
 msgid ", prefix deprecated"
 msgstr ""
 
-#: dhcp-common.c:823
+#: dhcp-common.c:876
 #, c-format
 msgid ", lease time "
 msgstr ""
 
-#: dhcp-common.c:865
+#: dhcp-common.c:918
 #, c-format
 msgid "%s stateless on %s%.0s%.0s%s"
 msgstr ""
 
-#: dhcp-common.c:867
+#: dhcp-common.c:920
 #, fuzzy, c-format
 msgid "%s, static leases only on %.0s%s%s%.0s"
 msgstr "DHCP, împrumuturi statice doar către  %.0s%s, timpul reînoirii %s"
 
-#: dhcp-common.c:869
+#: dhcp-common.c:922
 #, c-format
 msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
 msgstr ""
 
-#: dhcp-common.c:870
+#: dhcp-common.c:923
 #, fuzzy, c-format
 msgid "%s, IP range %s -- %s%s%.0s"
 msgstr "DHCP, domeniu IP %s -- %s, timpul reînoirii %s"
 
-#: dhcp-common.c:883
+#: dhcp-common.c:936
 #, c-format
 msgid "DHCPv4-derived IPv6 names on %s%s"
 msgstr ""
 
-#: dhcp-common.c:886
+#: dhcp-common.c:939
 #, fuzzy, c-format
 msgid "router advertisement on %s%s"
 msgstr "DHCP, împrumuturi statice doar către  %.0s%s, timpul reînoirii %s"
 
-#: dhcp-common.c:897
+#: dhcp-common.c:950
 #, c-format
 msgid "DHCP relay from %s to %s via %s"
 msgstr ""
 
-#: dhcp-common.c:899
+#: dhcp-common.c:952
 #, c-format
 msgid "DHCP relay from %s to %s"
 msgstr ""
@@ -2195,7 +2300,7 @@ msgstr ""
 msgid "cannot create ICMPv6 socket: %s"
 msgstr "nu pot creea socket DHCP: %s"
 
-#: auth.c:449
+#: auth.c:439
 #, c-format
 msgid "ignoring zone transfer request from %s"
 msgstr ""
@@ -2210,18 +2315,23 @@ msgstr "activarea socket-ului server-ului DHCP a eşuat: %s"
 msgid "failed to create IPset control socket: %s"
 msgstr "creearea socket-ului de ascultare a eşuat: %s"
 
-#: ipset.c:233
+#: ipset.c:226
 #, fuzzy, c-format
 msgid "failed to update ipset %s: %s"
 msgstr "nu pot citi %s: %s"
 
-#: dnssec.c:208
+#: dnssec.c:206
 msgid "system time considered valid, now checking DNSSEC signature timestamps."
 msgstr ""
 
-#: blockdata.c:58
+#: dnssec.c:902
+#, c-format
+msgid "Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"
+msgstr ""
+
+#: blockdata.c:55
 #, c-format
-msgid "DNSSEC memory in use %u, max %u, allocated %u"
+msgid "pool memory in use %u, max %u, allocated %u"
 msgstr ""
 
 #: tables.c:61
@@ -2253,12 +2363,12 @@ msgstr "eroare DBus: %s"
 msgid "info: table created"
 msgstr ""
 
-#: tables.c:134
+#: tables.c:133
 #, c-format
 msgid "warning: DIOCR%sADDRS: %s"
 msgstr ""
 
-#: tables.c:138
+#: tables.c:137
 #, fuzzy, c-format
 msgid "%d addresses %s"
 msgstr "citesc %s - %d adrese"
@@ -2298,6 +2408,74 @@ msgstr "nu pot citi %s: %s"
 msgid "inotify, new or changed file %s"
 msgstr ""
 
+#: dump.c:64
+#, fuzzy, c-format
+msgid "cannot create %s: %s"
+msgstr "nu pot citi %s: %s"
+
+#: dump.c:70
+#, fuzzy, c-format
+msgid "bad header in %s"
+msgstr "adresa este folosită"
+
+#: dump.c:201
+#, fuzzy
+msgid "failed to write packet dump"
+msgstr "ascultarea pe socket a eşuat: %s"
+
+#: dump.c:203
+#, c-format
+msgid "dumping UDP packet %u mask 0x%04x"
+msgstr ""
+
+#: ubus.c:52
+#, c-format
+msgid "UBus subscription callback: %s subscriber(s)"
+msgstr ""
+
+#: ubus.c:73
+#, fuzzy, c-format
+msgid "Cannot reconnect to UBus: %s"
+msgstr "nu pot deschide %s:%s"
+
+#: ubus.c:89
+msgid "Cannot initialize UBus: connection failed"
+msgstr ""
+
+#: ubus.c:102
+#, fuzzy, c-format
+msgid "Cannot add object to UBus: %s"
+msgstr "nu pot deschide %s:%s"
+
+#: ubus.c:112
+#, fuzzy
+msgid "Connected to system UBus"
+msgstr "magistrala sistem Dbus conectată"
+
+#: ubus.c:122
+msgid "Cannot set UBus listeners: no connection"
+msgstr ""
+
+#: ubus.c:142
+msgid "Cannot poll UBus listeners: no connection"
+msgstr ""
+
+#: ubus.c:155
+msgid "Disconnecting from UBus"
+msgstr ""
+
+#: ubus.c:199
+#, fuzzy, c-format
+msgid "Failed to send UBus event: %s"
+msgstr "ascultarea pe socket a eşuat: %s"
+
+#~ msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
+#~ msgstr "incerc să configurez un server IPv6 prin Dbus - nu este suport IPv6"
+
+#, fuzzy
+#~ msgid "unknown prefix-class %d"
+#~ msgstr "împrumut necunoscut"
+
 #, fuzzy
 #~ msgid "cannot cannonicalise resolv-file %s: %s"
 #~ msgstr "nu pot creea sau deschide fişierul cu împrumuturi: %s"
index 8beaed4..3329d6d 100644 (file)
--- a/src/arp.c
+++ b/src/arp.c
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -28,7 +28,7 @@ struct arp_record {
   unsigned short hwlen, status;
   int family;
   unsigned char hwaddr[DHCP_CHADDR_MAX]; 
-  struct all_addr addr;
+  union all_addr addr;
   struct arp_record *next;
 };
 
@@ -44,11 +44,6 @@ static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *p
   if (maclen > DHCP_CHADDR_MAX)
     return 1;
 
-#ifndef HAVE_IPV6
-  if (family != AF_INET)
-    return 1;
-#endif
-
   /* Look for existing entry */
   for (arp = arps; arp; arp = arp->next)
     {
@@ -57,16 +52,14 @@ static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *p
       
       if (family == AF_INET)
        {
-         if (arp->addr.addr.addr4.s_addr != ((struct in_addr *)addrp)->s_addr)
+         if (arp->addr.addr4.s_addr != ((struct in_addr *)addrp)->s_addr)
            continue;
        }
-#ifdef HAVE_IPV6
       else
        {
-         if (!IN6_ARE_ADDR_EQUAL(&arp->addr.addr.addr6, (struct in6_addr *)addrp))
+         if (!IN6_ARE_ADDR_EQUAL(&arp->addr.addr6, (struct in6_addr *)addrp))
            continue;
        }
-#endif
 
       if (arp->status == ARP_EMPTY)
        {
@@ -102,11 +95,9 @@ static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *p
       arp->family = family;
       memcpy(arp->hwaddr, mac, maclen);
       if (family == AF_INET)
-       arp->addr.addr.addr4.s_addr = ((struct in_addr *)addrp)->s_addr;
-#ifdef HAVE_IPV6
+       arp->addr.addr4.s_addr = ((struct in_addr *)addrp)->s_addr;
       else
-       memcpy(&arp->addr.addr.addr6, addrp, IN6ADDRSZ);
-#endif
+       memcpy(&arp->addr.addr6, addrp, IN6ADDRSZ);
     }
   
   return 1;
@@ -133,14 +124,12 @@ int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now)
            continue;
            
          if (arp->family == AF_INET &&
-             arp->addr.addr.addr4.s_addr != addr->in.sin_addr.s_addr)
+             arp->addr.addr4.s_addr != addr->in.sin_addr.s_addr)
            continue;
            
-#ifdef HAVE_IPV6
          if (arp->family == AF_INET6 && 
-             !IN6_ARE_ADDR_EQUAL(&arp->addr.addr.addr6, &addr->in6.sin6_addr))
+             !IN6_ARE_ADDR_EQUAL(&arp->addr.addr6, &addr->in6.sin6_addr))
            continue;
-#endif
          
          /* Only accept positive entries unless in lazy mode. */
          if (arp->status != ARP_EMPTY || lazy || updated)
@@ -202,11 +191,9 @@ int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now)
       arp->hwlen = 0;
 
       if (addr->sa.sa_family == AF_INET)
-       arp->addr.addr.addr4.s_addr = addr->in.sin_addr.s_addr;
-#ifdef HAVE_IPV6
+       arp->addr.addr4.s_addr = addr->in.sin_addr.s_addr;
       else
-       memcpy(&arp->addr.addr.addr6, &addr->in6.sin6_addr, IN6ADDRSZ);
-#endif
+       memcpy(&arp->addr.addr6, &addr->in6.sin6_addr, IN6ADDRSZ);
     }
          
    return 0;
index 6ad051d..b2fcd4b 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
 
 #ifdef HAVE_AUTH
 
-static struct addrlist *find_addrlist(struct addrlist *list, int flag, struct all_addr *addr_u)
+static struct addrlist *find_addrlist(struct addrlist *list, int flag, union all_addr *addr_u)
 {
   do {
     if (!(list->flags & ADDRLIST_IPV6))
       {
-       struct in_addr netmask, addr = addr_u->addr.addr4;
+       struct in_addr netmask, addr = addr_u->addr4;
        
        if (!(flag & F_IPV4))
          continue;
        
        netmask.s_addr = htonl(~(in_addr_t)0 << (32 - list->prefixlen));
        
-       if  (is_same_net(addr, list->addr.addr.addr4, netmask))
+       if  (is_same_net(addr, list->addr.addr4, netmask))
          return list;
       }
-#ifdef HAVE_IPV6
-    else if (is_same_net6(&(addr_u->addr.addr6), &list->addr.addr.addr6, list->prefixlen))
+    else if (is_same_net6(&(addr_u->addr6), &list->addr.addr6, list->prefixlen))
       return list;
-#endif
     
   } while ((list = list->next));
   
   return NULL;
 }
 
-static struct addrlist *find_subnet(struct auth_zone *zone, int flag, struct all_addr *addr_u)
+static struct addrlist *find_subnet(struct auth_zone *zone, int flag, union all_addr *addr_u)
 {
   if (!zone->subnet)
     return NULL;
@@ -51,7 +49,7 @@ static struct addrlist *find_subnet(struct auth_zone *zone, int flag, struct all
   return find_addrlist(zone->subnet, flag, addr_u);
 }
 
-static struct addrlist *find_exclude(struct auth_zone *zone, int flag, struct all_addr *addr_u)
+static struct addrlist *find_exclude(struct auth_zone *zone, int flag, union all_addr *addr_u)
 {
   if (!zone->exclude)
     return NULL;
@@ -59,7 +57,7 @@ static struct addrlist *find_exclude(struct auth_zone *zone, int flag, struct al
   return find_addrlist(zone->exclude, flag, addr_u);
 }
 
-static int filter_zone(struct auth_zone *zone, int flag, struct all_addr *addr_u)
+static int filter_zone(struct auth_zone *zone, int flag, union all_addr *addr_u)
 {
   if (find_exclude(zone, flag, addr_u))
     return 0;
@@ -103,7 +101,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
 {
   char *name = daemon->namebuff;
   unsigned char *p, *ansp;
-  int qtype, qclass;
+  int qtype, qclass, rc;
   int nameoffset, axfroffset = 0;
   int q, anscount = 0, authcount = 0;
   struct crec *crecp;
@@ -115,7 +113,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
   struct txt_record *txt;
   struct interface_name *intr;
   struct naptr *na;
-  struct all_addr addr;
+  union all_addr addr;
   struct cname *a, *candidate;
   unsigned int wclen;
   
@@ -131,7 +129,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
 
   for (q = ntohs(header->qdcount); q != 0; q--)
     {
-      unsigned short flag = 0;
+      unsigned int flag = 0;
       int found = 0;
       int cname_wildcard = 0;
   
@@ -180,7 +178,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
                struct addrlist *addrlist;
                
                for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
-                 if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr)
+                 if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr4.s_addr == addrlist->addr.addr4.s_addr)
                    break;
                
                if (addrlist)
@@ -189,14 +187,13 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
                  while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
                    intr = intr->next;
              }
-#ifdef HAVE_IPV6
          else if (flag == F_IPV6)
            for (intr = daemon->int_names; intr; intr = intr->next)
              {
                struct addrlist *addrlist;
                
                for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
-                 if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6))
+                 if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr6, &addrlist->addr.addr6))
                    break;
                
                if (addrlist)
@@ -205,7 +202,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
                  while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
                    intr = intr->next;
              }
-#endif
          
          if (intr)
            {
@@ -283,11 +279,11 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
        }
 
       for (rec = daemon->mxnames; rec; rec = rec->next)
-       if (!rec->issrv && hostname_isequal(name, rec->name))
+       if (!rec->issrv && (rc = hostname_issubdomain(name, rec->name)))
          {
            nxdomain = 0;
                 
-           if (qtype == T_MX)
+           if (rc == 2 && qtype == T_MX)
              {
                found = 1;
                log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>"); 
@@ -298,11 +294,11 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
          }
       
       for (move = NULL, up = &daemon->mxnames, rec = daemon->mxnames; rec; rec = rec->next)
-       if (rec->issrv && hostname_isequal(name, rec->name))
+       if (rec->issrv && (rc = hostname_issubdomain(name, rec->name)))
          {
            nxdomain = 0;
            
-           if (qtype == T_SRV)
+           if (rc == 2 && qtype == T_SRV)
              {
                found = 1;
                log_query(F_CONFIG | F_RRNAME, name, NULL, "<SRV>"); 
@@ -333,13 +329,13 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
        }
 
       for (txt = daemon->rr; txt; txt = txt->next)
-       if (hostname_isequal(name, txt->name))
+       if ((rc = hostname_issubdomain(name, txt->name)))
          {
            nxdomain = 0;
-           if (txt->class == qtype)
+           if (rc == 2 && txt->class == qtype)
              {
                found = 1;
-               log_query(F_CONFIG | F_RRNAME, name, NULL, "<RR>"); 
+               log_query(F_CONFIG | F_RRNAME, name, NULL, querystr(NULL, txt->class)); 
                if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
                                        NULL, txt->class, C_IN, "t", txt->len, txt->txt))
                  anscount++;
@@ -347,10 +343,10 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
          }
       
       for (txt = daemon->txt; txt; txt = txt->next)
-       if (txt->class == C_IN && hostname_isequal(name, txt->name))
+       if (txt->class == C_IN && (rc = hostname_issubdomain(name, txt->name)))
          {
            nxdomain = 0;
-           if (qtype == T_TXT)
+           if (rc == 2 && qtype == T_TXT)
              {
                found = 1;
                log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>"); 
@@ -361,10 +357,10 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
          }
 
        for (na = daemon->naptr; na; na = na->next)
-        if (hostname_isequal(name, na->name))
+        if ((rc = hostname_issubdomain(name, na->name)))
           {
             nxdomain = 0;
-            if (qtype == T_NAPTR)
+            if (rc == 2 && qtype == T_NAPTR)
               {
                 found = 1;
                 log_query(F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>");
@@ -378,27 +374,24 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
        if (qtype == T_A)
         flag = F_IPV4;
        
-#ifdef HAVE_IPV6
        if (qtype == T_AAAA)
         flag = F_IPV6;
-#endif
        
        for (intr = daemon->int_names; intr; intr = intr->next)
-        if (hostname_isequal(name, intr->name))
+        if ((rc = hostname_issubdomain(name, intr->name)))
           {
             struct addrlist *addrlist;
             
             nxdomain = 0;
             
-            if (flag)
+            if (rc == 2 && flag)
               for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)  
                 if (((addrlist->flags & ADDRLIST_IPV6)  ? T_AAAA : T_A) == qtype &&
                     (local_query || filter_zone(zone, flag, &addrlist->addr)))
                   {
-#ifdef HAVE_IPV6
                     if (addrlist->flags & ADDRLIST_REVONLY)
                       continue;
-#endif
+
                     found = 1;
                     log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
                     if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
@@ -424,27 +417,24 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
              
              if (peer_addr->sa.sa_family == AF_INET)
                peer_addr->in.sin_port = 0;
-#ifdef HAVE_IPV6
              else
                {
                  peer_addr->in6.sin6_port = 0; 
                  peer_addr->in6.sin6_scope_id = 0;
                }
-#endif
              
              for (peers = daemon->auth_peers; peers; peers = peers->next)
                if (sockaddr_isequal(peer_addr, &peers->addr))
                  break;
              
-             /* Refuse all AXFR unless --auth-sec-servers is set */
-             if ((!peers && daemon->auth_peers) || !daemon->secondary_forward_server)
+             /* Refuse all AXFR unless --auth-sec-servers or auth-peers is set */
+             if ((!daemon->secondary_forward_server && !daemon->auth_peers) ||
+                 (daemon->auth_peers && !peers)) 
                {
                  if (peer_addr->sa.sa_family == AF_INET)
                    inet_ntop(AF_INET, &peer_addr->in.sin_addr, daemon->addrbuff, ADDRSTRLEN);
-#ifdef HAVE_IPV6
                  else
                    inet_ntop(AF_INET6, &peer_addr->in6.sin6_addr, daemon->addrbuff, ADDRSTRLEN); 
-#endif
                  
                  my_syslog(LOG_WARNING, _("ignoring zone transfer request from %s"), daemon->addrbuff);
                  return 0;
@@ -478,10 +468,10 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
                  { 
                    nxdomain = 0;
                    if ((crecp->flags & flag) && 
-                       (local_query || filter_zone(zone, flag, &(crecp->addr.addr))))
+                       (local_query || filter_zone(zone, flag, &(crecp->addr))))
                      {
                        *cut = '.'; /* restore domain part */
-                       log_query(crecp->flags, name, &crecp->addr.addr, record_source(crecp->uid));
+                       log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid));
                        *cut  = 0; /* remove domain part */
                        found = 1;
                        if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
@@ -501,9 +491,9 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
            do
              { 
                 nxdomain = 0;
-                if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr.addr))))
+                if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr))))
                   {
-                    log_query(crecp->flags, name, &crecp->addr.addr, record_source(crecp->uid));
+                    log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid));
                     found = 1;
                     if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
                                             daemon->auth_ttl, NULL, qtype, C_IN, 
@@ -566,6 +556,8 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
              
              goto cname_restart;
            }
+         else if (cache_find_non_terminal(name, now))
+           nxdomain = 0;
 
          log_query(flag | F_NEG | (nxdomain ? F_NXDOMAIN : 0) | F_FORWARD | F_AUTH, name, NULL, NULL);
        }
@@ -588,7 +580,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
 
          if (!(subnet->flags & ADDRLIST_IPV6))
            {
-             in_addr_t a = ntohl(subnet->addr.addr.addr4.s_addr) >> 8;
+             in_addr_t a = ntohl(subnet->addr.addr4.s_addr) >> 8;
              char *p = name;
              
              if (subnet->prefixlen >= 24)
@@ -600,7 +592,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
              p += sprintf(p, "%u.in-addr.arpa", a & 0xff);
              
            }
-#ifdef HAVE_IPV6
          else
            {
              char *p = name;
@@ -608,13 +599,12 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
              
              for (i = subnet->prefixlen-1; i >= 0; i -= 4)
                { 
-                 int dig = ((unsigned char *)&subnet->addr.addr.addr6)[i>>3];
+                 int dig = ((unsigned char *)&subnet->addr.addr6)[i>>3];
                  p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
                }
              p += sprintf(p, "ip6.arpa");
              
            }
-#endif
        }
       
       /* handle NS and SOA in auth section or for explicit queries */
@@ -638,16 +628,20 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
        {
          struct name_list *secondary;
          
-         newoffset = ansp - (unsigned char *)header;
-         if (add_resource_record(header, limit, &trunc, -offset, &ansp, 
-                                 daemon->auth_ttl, NULL, T_NS, C_IN, "d", offset == 0 ? authname : NULL, daemon->authserver))
+         /* Only include the machine running dnsmasq if it's acting as an auth server */
+         if (daemon->authinterface)
            {
-             if (offset == 0) 
-               offset = newoffset;
-             if (ns) 
-               anscount++;
-             else
-               authcount++;
+             newoffset = ansp - (unsigned char *)header;
+             if (add_resource_record(header, limit, &trunc, -offset, &ansp, 
+                                     daemon->auth_ttl, NULL, T_NS, C_IN, "d", offset == 0 ? authname : NULL, daemon->authserver))
+               {
+                 if (offset == 0) 
+                   offset = newoffset;
+                 if (ns) 
+                   anscount++;
+                 else
+                   authcount++;
+               }
            }
 
          if (!subnet)
@@ -751,14 +745,12 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
                                          daemon->auth_ttl, NULL, T_A, C_IN, "4", cut ? intr->name : NULL, &addrlist->addr))
                    anscount++;
                
-#ifdef HAVE_IPV6
                for (addrlist = intr->addr; addrlist; addrlist = addrlist->next) 
                  if ((addrlist->flags & ADDRLIST_IPV6) && 
                      (local_query || filter_zone(zone, F_IPV6, &addrlist->addr)) &&
                      add_resource_record(header, limit, &trunc, -axfroffset, &ansp, 
                                          daemon->auth_ttl, NULL, T_AAAA, C_IN, "6", cut ? intr->name : NULL, &addrlist->addr))
                    anscount++;
-#endif             
                
                /* restore config data */
                if (cut)
@@ -795,38 +787,26 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
                    {
                      char *cache_name = cache_get_name(crecp);
                      if (!strchr(cache_name, '.') && 
-                         (local_query || filter_zone(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr))))
-                       {
-                         qtype = T_A;
-#ifdef HAVE_IPV6
-                         if (crecp->flags & F_IPV6)
-                           qtype = T_AAAA;
-#endif
-                         if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp, 
-                                                 daemon->auth_ttl, NULL, qtype, C_IN, 
-                                                 (crecp->flags & F_IPV4) ? "4" : "6", cache_name, &crecp->addr))
-                           anscount++;
-                       }
+                         (local_query || filter_zone(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr))) &&
+                         add_resource_record(header, limit, &trunc, -axfroffset, &ansp, 
+                                             daemon->auth_ttl, NULL, (crecp->flags & F_IPV6) ? T_AAAA : T_A, C_IN, 
+                                             (crecp->flags & F_IPV4) ? "4" : "6", cache_name, &crecp->addr))
+                       anscount++;
                    }
                  
                  if ((crecp->flags & F_HOSTS) || (((crecp->flags & F_DHCP) && option_bool(OPT_DHCP_FQDN))))
                    {
                      strcpy(name, cache_get_name(crecp));
                      if (in_zone(zone, name, &cut) && 
-                         (local_query || filter_zone(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr))))
+                         (local_query || filter_zone(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr))))
                        {
-                         qtype = T_A;
-#ifdef HAVE_IPV6
-                         if (crecp->flags & F_IPV6)
-                           qtype = T_AAAA;
-#endif
-                          if (cut)
-                            *cut = 0;
-
-                          if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp, 
-                                                  daemon->auth_ttl, NULL, qtype, C_IN, 
-                                                  (crecp->flags & F_IPV4) ? "4" : "6", cut ? name : NULL, &crecp->addr))
-                            anscount++;
+                         if (cut)
+                           *cut = 0;
+
+                         if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp, 
+                                                 daemon->auth_ttl, NULL, (crecp->flags & F_IPV6) ? T_AAAA : T_A, C_IN, 
+                                                 (crecp->flags & F_IPV4) ? "4" : "6", cut ? name : NULL, &crecp->addr))
+                           anscount++;
                        }
                    }
                }
@@ -860,6 +840,9 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
       header->hb4 &= ~HB4_RA;
     }
 
+  /* data is never DNSSEC signed. */
+  header->hb4 &= ~HB4_AD;
+
   /* authoritative */
   if (auth)
     header->hb3 |= HB3_AA;
index 72f0575..f33b28e 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -16,8 +16,6 @@
 
 #include "dnsmasq.h"
 
-#ifdef HAVE_DNSSEC
-
 static struct blockdata *keyblock_free;
 static unsigned int blockdata_count, blockdata_hwm, blockdata_alloced;
 
@@ -54,14 +52,13 @@ void blockdata_init(void)
 
 void blockdata_report(void)
 {
-  if (option_bool(OPT_DNSSEC_VALID))
-    my_syslog(LOG_INFO, _("DNSSEC memory in use %u, max %u, allocated %u"), 
-             blockdata_count * sizeof(struct blockdata),  
-             blockdata_hwm * sizeof(struct blockdata),  
-             blockdata_alloced * sizeof(struct blockdata));
+  my_syslog(LOG_INFO, _("pool memory in use %u, max %u, allocated %u"), 
+           blockdata_count * sizeof(struct blockdata),  
+           blockdata_hwm * sizeof(struct blockdata),  
+           blockdata_alloced * sizeof(struct blockdata));
 } 
 
-struct blockdata *blockdata_alloc(char *data, size_t len)
+static struct blockdata *blockdata_alloc_real(int fd, char *data, size_t len)
 {
   struct blockdata *block, *ret = NULL;
   struct blockdata **prev = &ret;
@@ -89,8 +86,17 @@ struct blockdata *blockdata_alloc(char *data, size_t len)
        blockdata_hwm = blockdata_count; 
       
       blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len;
-      memcpy(block->key, data, blen);
-      data += blen;
+      if (data)
+       {
+         memcpy(block->key, data, blen);
+         data += blen;
+       }
+      else if (!read_write(fd, block->key, blen, 1))
+       {
+         /* failed read free partial chain */
+         blockdata_free(ret);
+         return NULL;
+       }
       len -= blen;
       *prev = block;
       prev = &block->next;
@@ -100,6 +106,10 @@ struct blockdata *blockdata_alloc(char *data, size_t len)
   return ret;
 }
 
+struct blockdata *blockdata_alloc(char *data, size_t len)
+{
+  return blockdata_alloc_real(0, data, len);
+}
 
 void blockdata_free(struct blockdata *blocks)
 {
@@ -148,5 +158,20 @@ void *blockdata_retrieve(struct blockdata *block, size_t len, void *data)
 
   return data;
 }
-#endif
+
+
+void blockdata_write(struct blockdata *block, size_t len, int fd)
+{
+  for (; len > 0 && block; block = block->next)
+    {
+      size_t blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len;
+      read_write(fd, block->key, blen, 0);
+      len -= blen;
+    }
+}
+
+struct blockdata *blockdata_read(int fd, size_t len)
+{
+  return blockdata_alloc_real(fd, NULL, len);
+}
+
index 49a11bf..0ac1c8f 100644 (file)
--- a/src/bpf.c
+++ b/src/bpf.c
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -31,9 +31,7 @@
 #  include <net/if_var.h> 
 #endif
 #include <netinet/in_var.h>
-#ifdef HAVE_IPV6
-#  include <netinet6/in6_var.h>
-#endif
+#include <netinet6/in6_var.h>
 
 #ifndef SA_SIZE
 #define SA_SIZE(sa)                                             \
@@ -44,7 +42,7 @@
 
 #ifdef HAVE_BSD_NETWORK
 static int del_family = 0;
-static struct all_addr del_addr;
+static union all_addr del_addr;
 #endif
 
 #if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
@@ -121,7 +119,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
   if (getifaddrs(&head) == -1)
     return 0;
 
-#if defined(HAVE_BSD_NETWORK) && defined(HAVE_IPV6)
+#if defined(HAVE_BSD_NETWORK)
   if (family == AF_INET6)
     fd = socket(PF_INET6, SOCK_DGRAM, 0);
 #endif
@@ -141,7 +139,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
              struct in_addr addr, netmask, broadcast;
              addr = ((struct sockaddr_in *) addrs->ifa_addr)->sin_addr;
 #ifdef HAVE_BSD_NETWORK
-             if (del_family == AF_INET && del_addr.addr.addr4.s_addr == addr.s_addr)
+             if (del_family == AF_INET && del_addr.addr4.s_addr == addr.s_addr)
                continue;
 #endif
              netmask = ((struct sockaddr_in *) addrs->ifa_netmask)->sin_addr;
@@ -152,7 +150,6 @@ int iface_enumerate(int family, void *parm, int (*callback)())
              if (!((*callback)(addr, iface_index, NULL, netmask, broadcast, parm)))
                goto err;
            }
-#ifdef HAVE_IPV6
          else if (family == AF_INET6)
            {
              struct in6_addr *addr = &((struct sockaddr_in6 *) addrs->ifa_addr)->sin6_addr;
@@ -162,14 +159,14 @@ int iface_enumerate(int family, void *parm, int (*callback)())
              u32 valid = 0xffffffff, preferred = 0xffffffff;
              int flags = 0;
 #ifdef HAVE_BSD_NETWORK
-             if (del_family == AF_INET6 && IN6_ARE_ADDR_EQUAL(&del_addr.addr.addr6, addr))
+             if (del_family == AF_INET6 && IN6_ARE_ADDR_EQUAL(&del_addr.addr6, addr))
                continue;
 #endif
 #if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
              struct in6_ifreq ifr6;
 
              memset(&ifr6, 0, sizeof(ifr6));
-             strncpy(ifr6.ifr_name, addrs->ifa_name, sizeof(ifr6.ifr_name));
+             safe_strncpy(ifr6.ifr_name, addrs->ifa_name, sizeof(ifr6.ifr_name));
              
              ifr6.ifr_addr = *((struct sockaddr_in6 *) addrs->ifa_addr);
              if (fd != -1 && ioctl(fd, SIOCGIFAFLAG_IN6, &ifr6) != -1)
@@ -219,7 +216,6 @@ int iface_enumerate(int family, void *parm, int (*callback)())
                                (int) preferred, (int)valid, parm)))
                goto err;             
            }
-#endif /* HAVE_IPV6 */
 
 #ifdef HAVE_DHCP6      
          else if (family == AF_LINK)
@@ -426,11 +422,9 @@ void route_sock(void)
               {
                 del_family = sa->sa_family;
                 if (del_family == AF_INET)
-                  del_addr.addr.addr4 = ((struct sockaddr_in *)sa)->sin_addr;
-#ifdef HAVE_IPV6
+                  del_addr.addr4 = ((struct sockaddr_in *)sa)->sin_addr;
                 else if (del_family == AF_INET6)
-                  del_addr.addr.addr6 = ((struct sockaddr_in6 *)sa)->sin6_addr;
-#endif
+                  del_addr.addr6 = ((struct sockaddr_in6 *)sa)->sin6_addr;
                 else
                   del_family = 0;
               }
index 8b1b560..2f2c519 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -21,10 +21,14 @@ static struct crec *cache_head = NULL, *cache_tail = NULL, **hash_table = NULL;
 static struct crec *dhcp_spare = NULL;
 #endif
 static struct crec *new_chain = NULL;
-static int cache_inserted = 0, cache_live_freed = 0, insert_error;
+static int insert_error;
 static union bigname *big_free = NULL;
 static int bignames_left, hash_size;
 
+static void make_non_terminals(struct crec *source);
+static struct crec *really_insert(char *name, union all_addr *addr, unsigned short class,
+                                 time_t now,  unsigned long ttl, unsigned int flags);
+
 /* type->string mapping: this is also used by the name-hash function as a mixing table. */
 static const struct {
   unsigned int type;
@@ -68,7 +72,8 @@ static const struct {
   { 252, "AXFR" },
   { 253, "MAILB" },
   { 254, "MAILA" },
-  { 255, "ANY" }
+  { 255, "ANY" },
+  { 257, "CAA" }
 };
 
 static void cache_free(struct crec *crecp);
@@ -77,17 +82,20 @@ static void cache_link(struct crec *crecp);
 static void rehash(int size);
 static void cache_hash(struct crec *crecp);
 
-static unsigned int next_uid(void)
+void next_uid(struct crec *crecp)
 {
   static unsigned int uid = 0;
 
-  uid++;
-  
-  /* uid == 0 used to indicate CNAME to interface name. */
-  if (uid == SRC_INTERFACE)
-    uid++;
+  if (crecp->uid == UID_NONE)
+    {
+      uid++;
   
-  return uid;
+      /* uid == 0 used to indicate CNAME to interface name. */
+      if (uid == UID_NONE)
+       uid++;
+      
+      crecp->uid = uid;
+    }
 }
 
 void cache_init(void)
@@ -105,7 +113,7 @@ void cache_init(void)
        {
          cache_link(crecp);
          crecp->flags = 0;
-         crecp->uid = next_uid();
+         crecp->uid = UID_NONE;
        }
     }
   
@@ -190,21 +198,26 @@ static void cache_hash(struct crec *crecp)
   *up = crecp;
 }
 
-#ifdef HAVE_DNSSEC
 static void cache_blockdata_free(struct crec *crecp)
 {
-  if (crecp->flags & F_DNSKEY)
-    blockdata_free(crecp->addr.key.keydata);
-  else if ((crecp->flags & F_DS) && !(crecp->flags & F_NEG))
-    blockdata_free(crecp->addr.ds.keydata);
-}
+  if (!(crecp->flags & F_NEG))
+    {
+      if (crecp->flags & F_SRV)
+       blockdata_free(crecp->addr.srv.target);
+#ifdef HAVE_DNSSEC
+      else if (crecp->flags & F_DNSKEY)
+       blockdata_free(crecp->addr.key.keydata);
+      else if (crecp->flags & F_DS)
+       blockdata_free(crecp->addr.ds.keydata);
 #endif
+    }
+}
 
 static void cache_free(struct crec *crecp)
 {
   crecp->flags &= ~F_FORWARD;
   crecp->flags &= ~F_REVERSE;
-  crecp->uid = next_uid(); /* invalidate CNAMES pointing to this. */
+  crecp->uid = UID_NONE; /* invalidate CNAMES pointing to this. */
 
   if (cache_tail)
     cache_tail->next = crecp;
@@ -222,9 +235,7 @@ static void cache_free(struct crec *crecp)
       crecp->flags &= ~F_BIGNAME;
     }
 
-#ifdef HAVE_DNSSEC
   cache_blockdata_free(crecp);
-#endif
 }    
 
 /* insert a new cache entry at the head of the list (youngest entry) */
@@ -265,10 +276,10 @@ char *cache_get_name(struct crec *crecp)
 
 char *cache_get_cname_target(struct crec *crecp)
 {
-  if (crecp->addr.cname.uid != SRC_INTERFACE)
+  if (crecp->addr.cname.is_name_ptr)
+     return crecp->addr.cname.target.name;
+  else
     return cache_get_name(crecp->addr.cname.target.cache);
-
-  return crecp->addr.cname.target.int_name->name;
 }
 
 
@@ -298,13 +309,13 @@ struct crec *cache_enumerate(int init)
 
 static int is_outdated_cname_pointer(struct crec *crecp)
 {
-  if (!(crecp->flags & F_CNAME) || crecp->addr.cname.uid == SRC_INTERFACE)
+  if (!(crecp->flags & F_CNAME) || crecp->addr.cname.is_name_ptr)
     return 0;
   
   /* NB. record may be reused as DS or DNSKEY, where uid is 
      overloaded for something completely different */
   if (crecp->addr.cname.target.cache && 
-      (crecp->addr.cname.target.cache->flags & (F_IPV4 | F_IPV6 | F_CNAME)) &&
+      !(crecp->addr.cname.target.cache->flags & (F_DNSKEY | F_DS)) &&
       crecp->addr.cname.uid == crecp->addr.cname.target.cache->uid)
     return 0;
   
@@ -322,7 +333,8 @@ static int is_expired(time_t now, struct crec *crecp)
   return 1;
 }
 
-static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t now, unsigned short flags)
+static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned short class, time_t now,
+                                   unsigned int flags, struct crec **target_crec, unsigned int *target_uid)
 {
   /* Scan and remove old entries.
      If (flags & F_FORWARD) then remove any forward entries for name and any expired
@@ -335,34 +347,38 @@ static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t no
      to a cache entry if the name exists in the cache as a HOSTS or DHCP entry (these are never deleted)
 
      We take advantage of the fact that hash chains have stuff in the order <reverse>,<other>,<immortal>
-     so that when we hit an entry which isn't reverse and is immortal, we're done. */
+     so that when we hit an entry which isn't reverse and is immortal, we're done. 
+
+     If we free a crec which is a CNAME target, return the entry and uid in target_crec and target_uid.
+     This entry will get re-used with the same name, to preserve CNAMEs. */
  
   struct crec *crecp, **up;
+
+  (void)class;
   
   if (flags & F_FORWARD)
     {
       for (up = hash_bucket(name), crecp = *up; crecp; crecp = crecp->hash_next)
        {
-         if (is_expired(now, crecp) || is_outdated_cname_pointer(crecp))
-           { 
-             *up = crecp->hash_next;
-             if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
-               {
-                 cache_unlink(crecp);
-                 cache_free(crecp);
-               }
-             continue;
-           } 
-       
          if ((crecp->flags & F_FORWARD) && hostname_isequal(cache_get_name(crecp), name))
            {
              /* Don't delete DNSSEC in favour of a CNAME, they can co-exist */
-             if ((flags & crecp->flags & (F_IPV4 | F_IPV6)) || 
+             if ((flags & crecp->flags & (F_IPV4 | F_IPV6 | F_SRV)) || 
                  (((crecp->flags | flags) & F_CNAME) && !(crecp->flags & (F_DNSKEY | F_DS))))
                {
                  if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))
                    return crecp;
                  *up = crecp->hash_next;
+                 /* If this record is for the name we're inserting and is the target
+                    of a CNAME record. Make the new record for the same name, in the same
+                    crec, with the same uid to avoid breaking the existing CNAME. */
+                 if (crecp->uid != UID_NONE)
+                   {
+                     if (target_crec)
+                       *target_crec = crecp;
+                     if (target_uid)
+                       *target_uid = crecp->uid;
+                   }
                  cache_unlink(crecp);
                  cache_free(crecp);
                  continue;
@@ -370,7 +386,7 @@ static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t no
              
 #ifdef HAVE_DNSSEC
              /* Deletion has to be class-sensitive for DS and DNSKEY */
-             if ((flags & crecp->flags & (F_DNSKEY | F_DS)) && crecp->uid == addr->addr.dnssec.class)
+             if ((flags & crecp->flags & (F_DNSKEY | F_DS)) && crecp->uid == class)
                {
                  if (crecp->flags & F_CONFIG)
                    return crecp;
@@ -381,17 +397,26 @@ static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t no
                }
 #endif
            }
+
+         if (is_expired(now, crecp) || is_outdated_cname_pointer(crecp))
+           { 
+             *up = crecp->hash_next;
+             if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
+               {
+                 cache_unlink(crecp);
+                 cache_free(crecp);
+               }
+             continue;
+           } 
+         
          up = &crecp->hash_next;
        }
     }
   else
     {
       int i;
-#ifdef HAVE_IPV6
       int addrlen = (flags & F_IPV6) ? IN6ADDRSZ : INADDRSZ;
-#else
-      int addrlen = INADDRSZ;
-#endif 
+
       for (i = 0; i < hash_size; i++)
        for (crecp = hash_table[i], up = &hash_table[i]; 
             crecp && ((crecp->flags & F_REVERSE) || !(crecp->flags & F_IMMORTAL));
@@ -408,7 +433,7 @@ static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t no
          else if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) &&
                   (flags & crecp->flags & F_REVERSE) && 
                   (flags & crecp->flags & (F_IPV4 | F_IPV6)) &&
-                  memcmp(&crecp->addr.addr, addr, addrlen) == 0)
+                  memcmp(&crecp->addr, addr, addrlen) == 0)
            {
              *up = crecp->hash_next;
              cache_unlink(crecp);
@@ -443,131 +468,158 @@ void cache_start_insert(void)
   new_chain = NULL;
   insert_error = 0;
 }
-struct crec *cache_insert(char *name, struct all_addr *addr, 
-                         time_t now,  unsigned long ttl, unsigned short flags)
-{
-  struct crec *new;
-  union bigname *big_name = NULL;
-  int freed_all = flags & F_REVERSE;
-  int free_avail = 0;
 
-  /* Don't log DNSSEC records here, done elsewhere */
-  if (flags & (F_IPV4 | F_IPV6 | F_CNAME))
+struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class,
+                         time_t now,  unsigned long ttl, unsigned int flags)
+{
+#ifdef HAVE_DNSSEC
+  if (flags & (F_DNSKEY | F_DS)) 
+    {
+      /* The DNSSEC validation process works by getting needed records into the
+        cache, then retrying the validation until they are all in place.
+        This can be messed up by very short TTLs, and _really_ messed up by
+        zero TTLs, so we force the TTL to be at least long enough to do a validation.
+        Ideally, we should use some kind of reference counting so that records are
+        locked until the validation that asked for them is complete, but this
+        is much easier, and just as effective. */
+      if (ttl < DNSSEC_MIN_TTL)
+       ttl = DNSSEC_MIN_TTL;
+    }
+  else
+#endif
     {
+      /* Don't log DNSSEC records here, done elsewhere */
       log_query(flags | F_UPSTREAM, name, addr, NULL);
-      /* Don't mess with TTL for DNSSEC records. */
       if (daemon->max_cache_ttl != 0 && daemon->max_cache_ttl < ttl)
        ttl = daemon->max_cache_ttl;
       if (daemon->min_cache_ttl != 0 && daemon->min_cache_ttl > ttl)
        ttl = daemon->min_cache_ttl;
-    }
+    }  
+  
+  return really_insert(name, addr, class, now, ttl, flags);
+}
 
+
+static struct crec *really_insert(char *name, union all_addr *addr, unsigned short class,
+                                 time_t now,  unsigned long ttl, unsigned int flags)
+{
+  struct crec *new, *target_crec = NULL;
+  union bigname *big_name = NULL;
+  int freed_all = flags & F_REVERSE;
+  int free_avail = 0;
+  unsigned int target_uid;
+  
   /* if previous insertion failed give up now. */
   if (insert_error)
     return NULL;
+
+  /* we don't cache zero-TTL records. */
+  if (ttl == 0)
+    {
+      insert_error = 1;
+      return NULL;
+    }
   
   /* First remove any expired entries and entries for the name/address we
      are currently inserting. */
-  if ((new = cache_scan_free(name, addr, now, flags)))
+  if ((new = cache_scan_free(name, addr, class, now, flags, &target_crec, &target_uid)))
     {
       /* We're trying to insert a record over one from 
         /etc/hosts or DHCP, or other config. If the 
-        existing record is for an A or AAAA and
+        existing record is for an A or AAAA or CNAME and
         the record we're trying to insert is the same, 
         just drop the insert, but don't error the whole process. */
       if ((flags & (F_IPV4 | F_IPV6)) && (flags & F_FORWARD) && addr)
        {
          if ((flags & F_IPV4) && (new->flags & F_IPV4) &&
-             new->addr.addr.addr.addr4.s_addr == addr->addr.addr4.s_addr)
+             new->addr.addr4.s_addr == addr->addr4.s_addr)
            return new;
-#ifdef HAVE_IPV6
          else if ((flags & F_IPV6) && (new->flags & F_IPV6) &&
-                  IN6_ARE_ADDR_EQUAL(&new->addr.addr.addr.addr6, &addr->addr.addr6))
+                  IN6_ARE_ADDR_EQUAL(&new->addr.addr6, &addr->addr6))
            return new;
-#endif
        }
-      
+
       insert_error = 1;
       return NULL;
     }
   
   /* Now get a cache entry from the end of the LRU list */
-  while (1) {
-    if (!(new = cache_tail)) /* no entries left - cache is too small, bail */
-      {
-       insert_error = 1;
-       return NULL;
-      }
-    
-    /* End of LRU list is still in use: if we didn't scan all the hash
-       chains for expired entries do that now. If we already tried that
-       then it's time to start spilling things. */
-    
-    if (new->flags & (F_FORWARD | F_REVERSE))
-      { 
-       /* If free_avail set, we believe that an entry has been freed.
-          Bugs have been known to make this not true, resulting in
-          a tight loop here. If that happens, abandon the
-          insert. Once in this state, all inserts will probably fail. */
-       if (free_avail)
-         {
-           static int warned = 0;
-           if (!warned)
-             {
-               my_syslog(LOG_ERR, _("Internal error in cache."));
-               warned = 1;
-             }
-           insert_error = 1;
-           return NULL;
-         }
-               
-       if (freed_all)
-         {
-           struct all_addr free_addr = new->addr.addr;;
+  if (!target_crec)
+    while (1) {
+      if (!(new = cache_tail)) /* no entries left - cache is too small, bail */
+       {
+         insert_error = 1;
+         return NULL;
+       }
+      
+      /* Free entry at end of LRU list, use it. */
+      if (!(new->flags & (F_FORWARD | F_REVERSE)))
+       break;
 
-#ifdef HAVE_DNSSEC
-           /* For DNSSEC records, addr holds class. */
-           if (new->flags & (F_DS | F_DNSKEY))
-             free_addr.addr.dnssec.class = new->uid;
-#endif
-           
-           free_avail = 1; /* Must be free space now. */
-           cache_scan_free(cache_get_name(new), &free_addr, now, new->flags);
-           cache_live_freed++;
-         }
-       else
-         {
-           cache_scan_free(NULL, NULL, now, 0);
-           freed_all = 1;
-         }
-       continue;
-      }
-    /* Check if we need to and can allocate extra memory for a long name.
-       If that fails, give up now, always succeed for DNSSEC records. */
-    if (name && (strlen(name) > SMALLDNAME-1))
-      {
-       if (big_free)
-         { 
-           big_name = big_free;
-           big_free = big_free->next;
-         }
-       else if ((bignames_left == 0 && !(flags & (F_DS | F_DNSKEY))) ||
-                !(big_name = (union bigname *)whine_malloc(sizeof(union bigname))))
-         {
-           insert_error = 1;
-           return NULL;
-         }
-       else if (bignames_left != 0)
-         bignames_left--;
-       
-      }
+      /* End of LRU list is still in use: if we didn't scan all the hash
+        chains for expired entries do that now. If we already tried that
+        then it's time to start spilling things. */
+      
+      /* If free_avail set, we believe that an entry has been freed.
+        Bugs have been known to make this not true, resulting in
+        a tight loop here. If that happens, abandon the
+        insert. Once in this state, all inserts will probably fail. */
+      if (free_avail)
+       {
+         static int warned = 0;
+         if (!warned)
+           {
+             my_syslog(LOG_ERR, _("Internal error in cache."));
+             warned = 1;
+           }
+         insert_error = 1;
+         return NULL;
+       }
+      
+      if (freed_all)
+       {
+         /* For DNSSEC records, uid holds class. */
+         free_avail = 1; /* Must be free space now. */
+         cache_scan_free(cache_get_name(new), &new->addr, new->uid, now, new->flags, NULL, NULL);
+         daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED]++;
+       }
+      else
+       {
+         cache_scan_free(NULL, NULL, class, now, 0, NULL, NULL);
+         freed_all = 1;
+       }
+    }
+      
+  /* Check if we need to and can allocate extra memory for a long name.
+     If that fails, give up now, always succeed for DNSSEC records. */
+  if (name && (strlen(name) > SMALLDNAME-1))
+    {
+      if (big_free)
+       { 
+         big_name = big_free;
+         big_free = big_free->next;
+       }
+      else if ((bignames_left == 0 && !(flags & (F_DS | F_DNSKEY))) ||
+              !(big_name = (union bigname *)whine_malloc(sizeof(union bigname))))
+       {
+         insert_error = 1;
+         return NULL;
+       }
+      else if (bignames_left != 0)
+       bignames_left--;
+      
+    }
 
-    /* Got the rest: finally grab entry. */
-    cache_unlink(new);
-    break;
-  }
+  /* If we freed a cache entry for our name which was a CNAME target, use that.
+     and preserve the uid, so that existing CNAMES are not broken. */
+  if (target_crec)
+    {
+      new = target_crec;
+      new->uid = target_uid;
+    }
+  
+  /* Got the rest: finally grab entry. */
+  cache_unlink(new);
   
   new->flags = flags;
   if (big_name)
@@ -581,15 +633,13 @@ struct crec *cache_insert(char *name, struct all_addr *addr,
   else
     *cache_get_name(new) = 0;
 
-  if (addr)
-    {
 #ifdef HAVE_DNSSEC
-      if (flags & (F_DS | F_DNSKEY))
-       new->uid = addr->addr.dnssec.class;
-      else
+  if (flags & (F_DS | F_DNSKEY))
+    new->uid = class;
 #endif
-       new->addr.addr = *addr; 
-    }
+
+  if (addr)
+    new->addr = *addr; 
 
   new->ttd = now + (time_t)ttl;
   new->next = new_chain;
@@ -614,13 +664,161 @@ void cache_end_insert(void)
        {
          cache_hash(new_chain);
          cache_link(new_chain);
-         cache_inserted++;
+         daemon->metrics[METRIC_DNS_CACHE_INSERTED]++;
+
+         /* If we're a child process, send this cache entry up the pipe to the master.
+            The marshalling process is rather nasty. */
+         if (daemon->pipe_to_parent != -1)
+           {
+             char *name = cache_get_name(new_chain);
+             ssize_t m = strlen(name);
+             unsigned int flags = new_chain->flags;
+#ifdef HAVE_DNSSEC
+             u16 class = new_chain->uid;
+#endif
+             
+             read_write(daemon->pipe_to_parent, (unsigned char *)&m, sizeof(m), 0);
+             read_write(daemon->pipe_to_parent, (unsigned char *)name, m, 0);
+             read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->ttd, sizeof(new_chain->ttd), 0);
+             read_write(daemon->pipe_to_parent, (unsigned  char *)&flags, sizeof(flags), 0);
+
+             if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS | F_SRV))
+               read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr, sizeof(new_chain->addr), 0);
+             if (flags & F_SRV)
+               {
+                 /* A negative SRV entry is possible and has no data, obviously. */
+                 if (!(flags & F_NEG))
+                   blockdata_write(new_chain->addr.srv.target, new_chain->addr.srv.targetlen, daemon->pipe_to_parent);
+               }
+#ifdef HAVE_DNSSEC
+             if (flags & F_DNSKEY)
+               {
+                 read_write(daemon->pipe_to_parent, (unsigned char *)&class, sizeof(class), 0);
+                 blockdata_write(new_chain->addr.key.keydata, new_chain->addr.key.keylen, daemon->pipe_to_parent);
+               }
+             else if (flags & F_DS)
+               {
+                 read_write(daemon->pipe_to_parent, (unsigned char *)&class, sizeof(class), 0);
+                 /* A negative DS entry is possible and has no data, obviously. */
+                 if (!(flags & F_NEG))
+                   blockdata_write(new_chain->addr.ds.keydata, new_chain->addr.ds.keylen, daemon->pipe_to_parent);
+               }
+#endif
+           }
        }
+      
       new_chain = tmp;
     }
+
+  /* signal end of cache insert in master process */
+  if (daemon->pipe_to_parent != -1)
+    {
+      ssize_t m = -1;
+      read_write(daemon->pipe_to_parent, (unsigned char *)&m, sizeof(m), 0);
+    }
+      
   new_chain = NULL;
 }
 
+
+/* A marshalled cache entry arrives on fd, read, unmarshall and insert into cache of master process. */
+int cache_recv_insert(time_t now, int fd)
+{
+  ssize_t m;
+  union all_addr addr;
+  unsigned long ttl;
+  time_t ttd;
+  unsigned int flags;
+  struct crec *crecp = NULL;
+  
+  cache_start_insert();
+  
+  while(1)
+    {
+      if (!read_write(fd, (unsigned char *)&m, sizeof(m), 1))
+       return 0;
+      
+      if (m == -1)
+       {
+         cache_end_insert();
+         return 1;
+       }
+
+      if (!read_write(fd, (unsigned char *)daemon->namebuff, m, 1) ||
+         !read_write(fd, (unsigned char *)&ttd, sizeof(ttd), 1) ||
+         !read_write(fd, (unsigned char *)&flags, sizeof(flags), 1))
+       return 0;
+
+      daemon->namebuff[m] = 0;
+
+      ttl = difftime(ttd, now);
+      
+      if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS | F_SRV))
+       {
+         unsigned short class = C_IN;
+
+         if (!read_write(fd, (unsigned char *)&addr, sizeof(addr), 1))
+           return 0;
+
+         if ((flags & F_SRV) && !(flags & F_NEG) && !(addr.srv.target = blockdata_read(fd, addr.srv.targetlen)))
+           return 0;
+       
+#ifdef HAVE_DNSSEC
+          if (flags & F_DNSKEY)
+            {
+              if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1) ||
+                  !(addr.key.keydata = blockdata_read(fd, addr.key.keylen)))
+                return 0;
+            }
+          else  if (flags & F_DS)
+            {
+               if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1) ||
+                   (!(flags & F_NEG) && !(addr.key.keydata = blockdata_read(fd, addr.key.keylen))))
+                 return 0;
+            }
+#endif
+              
+         crecp = really_insert(daemon->namebuff, &addr, class, now, ttl, flags);
+       }
+      else if (flags & F_CNAME)
+       {
+         struct crec *newc = really_insert(daemon->namebuff, NULL, C_IN, now, ttl, flags);
+         /* This relies on the fact that the target of a CNAME immediately precedes
+            it because of the order of extraction in extract_addresses, and
+            the order reversal on the new_chain. */
+         if (newc)
+           {
+              newc->addr.cname.is_name_ptr = 0;
+              
+              if (!crecp)
+                newc->addr.cname.target.cache = NULL;
+              else
+               {
+                 next_uid(crecp);
+                 newc->addr.cname.target.cache = crecp;
+                 newc->addr.cname.uid = crecp->uid;
+               }
+           }
+       }
+    }
+}
+       
+int cache_find_non_terminal(char *name, time_t now)
+{
+  struct crec *crecp;
+
+  for (crecp = *hash_bucket(name); crecp; crecp = crecp->hash_next)
+    if (!is_outdated_cname_pointer(crecp) &&
+       !is_expired(now, crecp) &&
+       (crecp->flags & F_FORWARD) &&
+       !(crecp->flags & F_NXDOMAIN) && 
+       hostname_isequal(name, cache_get_name(crecp)))
+      return 1;
+
+  return 0;
+}
+
 struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsigned int prot)
 {
   struct crec *ans;
@@ -635,7 +833,7 @@ struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsi
       /* first search, look for relevant entries and push to top of list
         also free anything which has expired */
       struct crec *next, **up, **insert = NULL, **chainp = &ans;
-      unsigned short ins_flags = 0;
+      unsigned int ins_flags = 0;
       
       for (up = hash_bucket(name), crecp = *up; crecp; crecp = next)
        {
@@ -708,15 +906,11 @@ struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsi
   return NULL;
 }
 
-struct crec *cache_find_by_addr(struct crec *crecp, struct all_addr *addr, 
+struct crec *cache_find_by_addr(struct crec *crecp, union all_addr *addr, 
                                time_t now, unsigned int prot)
 {
   struct crec *ans;
-#ifdef HAVE_IPV6
   int addrlen = (prot == F_IPV6) ? IN6ADDRSZ : INADDRSZ;
-#else
-  int addrlen = INADDRSZ;
-#endif
   
   if (crecp) /* iterating */
     ans = crecp->next;
@@ -736,7 +930,7 @@ struct crec *cache_find_by_addr(struct crec *crecp, struct all_addr *addr,
           if (!is_expired(now, crecp))
             {      
               if ((crecp->flags & prot) &&
-                  memcmp(&crecp->addr.addr, addr, addrlen) == 0)
+                  memcmp(&crecp->addr, addr, addrlen) == 0)
                 {          
                   if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))
                     {
@@ -767,51 +961,26 @@ struct crec *cache_find_by_addr(struct crec *crecp, struct all_addr *addr,
   if (ans && 
       (ans->flags & F_REVERSE) &&
       (ans->flags & prot) &&
-      memcmp(&ans->addr.addr, addr, addrlen) == 0)
+      memcmp(&ans->addr, addr, addrlen) == 0)
     return ans;
   
   return NULL;
 }
 
-static void add_hosts_cname(struct crec *target)
-{
-  struct crec *crec;
-  struct cname *a;
-  
-  for (a = daemon->cnames; a; a = a->next)
-    if (a->alias[1] != '*' &&
-       hostname_isequal(cache_get_name(target), a->target) &&
-       (crec = whine_malloc(sizeof(struct crec))))
-      {
-       crec->flags = F_FORWARD | F_IMMORTAL | F_NAMEP | F_CONFIG | F_CNAME;
-       crec->ttd = a->ttl;
-       crec->name.namep = a->alias;
-       crec->addr.cname.target.cache = target;
-       crec->addr.cname.uid = target->uid;
-       crec->uid = next_uid();
-       cache_hash(crec);
-       add_hosts_cname(crec); /* handle chains */
-      }
-}
-  
-static void add_hosts_entry(struct crec *cache, struct all_addr *addr, int addrlen, 
+static void add_hosts_entry(struct crec *cache, union all_addr *addr, int addrlen, 
                            unsigned int index, struct crec **rhash, int hashsz)
 {
   struct crec *lookup = cache_find_by_name(NULL, cache_get_name(cache), 0, cache->flags & (F_IPV4 | F_IPV6));
-  int i, nameexists = 0;
+  int i;
   unsigned int j; 
 
   /* Remove duplicates in hosts files. */
-  if (lookup && (lookup->flags & F_HOSTS))
+  if (lookup && (lookup->flags & F_HOSTS) && memcmp(&lookup->addr, addr, addrlen) == 0)
     {
-      nameexists = 1;
-      if (memcmp(&lookup->addr.addr, addr, addrlen) == 0)
-       {
-         free(cache);
-         return;
-       }
+      free(cache);
+      return;
     }
-  
+    
   /* Ensure there is only one address -> name mapping (first one trumps) 
      We do this by steam here, The entries are kept in hash chains, linked
      by ->next (which is unused at this point) held in hash buckets in
@@ -837,7 +1006,7 @@ static void add_hosts_entry(struct crec *cache, struct all_addr *addr, int addrl
       
       for (lookup = rhash[j]; lookup; lookup = lookup->next)
        if ((lookup->flags & cache->flags & (F_IPV4 | F_IPV6)) &&
-           memcmp(&lookup->addr.addr, addr, addrlen) == 0)
+           memcmp(&lookup->addr, addr, addrlen) == 0)
          {
            cache->flags &= ~F_REVERSE;
            break;
@@ -859,12 +1028,9 @@ static void add_hosts_entry(struct crec *cache, struct all_addr *addr, int addrl
     }
 
   cache->uid = index;
-  memcpy(&cache->addr.addr, addr, addrlen);  
+  memcpy(&cache->addr, addr, addrlen);  
   cache_hash(cache);
-  
-  /* don't need to do alias stuff for second and subsequent addresses. */
-  if (!nameexists)
-    add_hosts_cname(cache);
+  make_non_terminals(cache);
 }
 
 static int eatspace(FILE *f)
@@ -887,7 +1053,7 @@ static int eatspace(FILE *f)
        }
 
       if (c == '\n')
-       nl = 1;
+       nl++;
     }
 }
         
@@ -898,7 +1064,7 @@ static int gettok(FILE *f, char *token)
   while (1)
     {
       if ((c = getc(f)) == EOF)
-       return (count == 0) ? EOF : 1;
+       return (count == 0) ? -1 : 1;
 
       if (isspace(c) || c == '#')
        {
@@ -918,9 +1084,9 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr
 {  
   FILE *f = fopen(filename, "r");
   char *token = daemon->namebuff, *domain_suffix = NULL;
-  int addr_count = 0, name_count = cache_size, lineno = 0;
-  unsigned short flags = 0;
-  struct all_addr addr;
+  int addr_count = 0, name_count = cache_size, lineno = 1;
+  unsigned int flags = 0;
+  union all_addr addr;
   int atnl, addrlen = 0;
 
   if (!f)
@@ -929,31 +1095,28 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr
       return cache_size;
     }
   
-  eatspace(f);
+  lineno += eatspace(f);
   
-  while ((atnl = gettok(f, token)) != EOF)
+  while ((atnl = gettok(f, token)) != -1)
     {
-      lineno++;
-      
       if (inet_pton(AF_INET, token, &addr) > 0)
        {
          flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4;
          addrlen = INADDRSZ;
-         domain_suffix = get_domain(addr.addr.addr4);
+         domain_suffix = get_domain(addr.addr4);
        }
-#ifdef HAVE_IPV6
       else if (inet_pton(AF_INET6, token, &addr) > 0)
        {
          flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV6;
          addrlen = IN6ADDRSZ;
-         domain_suffix = get_domain6(&addr.addr.addr6);
+         domain_suffix = get_domain6(&addr.addr6);
        }
-#endif
       else
        {
          my_syslog(LOG_ERR, _("bad address at %s line %d"), filename, lineno); 
          while (atnl == 0)
            atnl = gettok(f, token);
+         lineno += atnl;
          continue;
        }
       
@@ -972,7 +1135,7 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr
          int fqdn, nomem;
          char *canon;
          
-         if ((atnl = gettok(f, token)) == EOF)
+         if ((atnl = gettok(f, token)) == -1)
            break;
 
          fqdn = !!strchr(token, '.');
@@ -981,8 +1144,7 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr
            {
              /* If set, add a version of the name with a default domain appended */
              if (option_bool(OPT_EXPAND) && domain_suffix && !fqdn && 
-                 (cache = whine_malloc(sizeof(struct crec) + 
-                                       strlen(canon)+2+strlen(domain_suffix)-SMALLDNAME)))
+                 (cache = whine_malloc(SIZEOF_BARE_CREC + strlen(canon) + 2 + strlen(domain_suffix))))
                {
                  strcpy(cache->name.sname, canon);
                  strcat(cache->name.sname, ".");
@@ -992,7 +1154,7 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr
                  add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz);
                  name_count++;
                }
-             if ((cache = whine_malloc(sizeof(struct crec) + strlen(canon)+1-SMALLDNAME)))
+             if ((cache = whine_malloc(SIZEOF_BARE_CREC + strlen(canon) + 1)))
                {
                  strcpy(cache->name.sname, canon);
                  cache->flags = flags;
@@ -1006,6 +1168,8 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr
          else if (!nomem)
            my_syslog(LOG_ERR, _("bad name at %s line %d"), filename, lineno); 
        }
+
+      lineno += atnl;
     } 
 
   fclose(f);
@@ -1026,19 +1190,24 @@ void cache_reload(void)
   struct host_record *hr;
   struct name_list *nl;
   struct cname *a;
+  struct crec lrec;
+  struct mx_srv_record *mx;
+  struct txt_record *txt;
   struct interface_name *intr;
+  struct ptr_record *ptr;
+  struct naptr *naptr;
 #ifdef HAVE_DNSSEC
   struct ds_config *ds;
 #endif
 
-  cache_inserted = cache_live_freed = 0;
+  daemon->metrics[METRIC_DNS_CACHE_INSERTED] = 0;
+  daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED] = 0;
   
   for (i=0; i<hash_size; i++)
     for (cache = hash_table[i], up = &hash_table[i]; cache; cache = tmp)
       {
-#ifdef HAVE_DNSSEC
        cache_blockdata_free(cache);
-#endif
+
        tmp = cache->hash_next;
        if (cache->flags & (F_HOSTS | F_CONFIG))
          {
@@ -1059,26 +1228,24 @@ void cache_reload(void)
          up = &cache->hash_next;
       }
   
-  /* Add CNAMEs to interface_names to the cache */
+  /* Add locally-configured CNAMEs to the cache */
   for (a = daemon->cnames; a; a = a->next)
-    for (intr = daemon->int_names; intr; intr = intr->next)
-      if (a->alias[1] != '*' &&
-         hostname_isequal(a->target, intr->name) &&
-         ((cache = whine_malloc(sizeof(struct crec)))))
-       {
-         cache->flags = F_FORWARD | F_NAMEP | F_CNAME | F_IMMORTAL | F_CONFIG;
-         cache->ttd = a->ttl;
-         cache->name.namep = a->alias;
-         cache->addr.cname.target.int_name = intr;
-         cache->addr.cname.uid = SRC_INTERFACE;
-         cache->uid = next_uid();
-         cache_hash(cache);
-         add_hosts_cname(cache); /* handle chains */
-       }
-
+    if (a->alias[1] != '*' &&
+       ((cache = whine_malloc(SIZEOF_POINTER_CREC))))
+      {
+       cache->flags = F_FORWARD | F_NAMEP | F_CNAME | F_IMMORTAL | F_CONFIG;
+       cache->ttd = a->ttl;
+       cache->name.namep = a->alias;
+       cache->addr.cname.target.name = a->target;
+       cache->addr.cname.is_name_ptr = 1;
+       cache->uid = UID_NONE;
+       cache_hash(cache);
+       make_non_terminals(cache);
+      }
+  
 #ifdef HAVE_DNSSEC
   for (ds = daemon->ds; ds; ds = ds->next)
-    if ((cache = whine_malloc(sizeof(struct crec))) &&
+    if ((cache = whine_malloc(SIZEOF_POINTER_CREC)) &&
        (cache->addr.ds.keydata = blockdata_alloc(ds->digest, ds->digestlen)))
       {
        cache->flags = F_FORWARD | F_IMMORTAL | F_DS | F_CONFIG | F_NAMEP;
@@ -1090,6 +1257,7 @@ void cache_reload(void)
        cache->addr.ds.digest = ds->digest_type;
        cache->uid = ds->class;
        cache_hash(cache);
+       make_non_terminals(cache);
       }
 #endif
   
@@ -1103,24 +1271,23 @@ void cache_reload(void)
   for (hr = daemon->host_records; hr; hr = hr->next)
     for (nl = hr->names; nl; nl = nl->next)
       {
-       if (hr->addr.s_addr != 0 &&
-           (cache = whine_malloc(sizeof(struct crec))))
+       if ((hr->flags & HR_4) &&
+           (cache = whine_malloc(SIZEOF_POINTER_CREC)))
          {
            cache->name.namep = nl->name;
            cache->ttd = hr->ttl;
            cache->flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4 | F_NAMEP | F_CONFIG;
-           add_hosts_entry(cache, (struct all_addr *)&hr->addr, INADDRSZ, SRC_CONFIG, (struct crec **)daemon->packet, revhashsz);
+           add_hosts_entry(cache, (union all_addr *)&hr->addr, INADDRSZ, SRC_CONFIG, (struct crec **)daemon->packet, revhashsz);
          }
-#ifdef HAVE_IPV6
-       if (!IN6_IS_ADDR_UNSPECIFIED(&hr->addr6) &&
-           (cache = whine_malloc(sizeof(struct crec))))
+
+       if ((hr->flags & HR_6) &&
+           (cache = whine_malloc(SIZEOF_POINTER_CREC)))
          {
            cache->name.namep = nl->name;
            cache->ttd = hr->ttl;
            cache->flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV6 | F_NAMEP | F_CONFIG;
-           add_hosts_entry(cache, (struct all_addr *)&hr->addr6, IN6ADDRSZ, SRC_CONFIG, (struct crec **)daemon->packet, revhashsz);
+           add_hosts_entry(cache, (union all_addr *)&hr->addr6, IN6ADDRSZ, SRC_CONFIG, (struct crec **)daemon->packet, revhashsz);
          }
-#endif
       }
        
   if (option_bool(OPT_NO_HOSTS) && !daemon->addn_hosts)
@@ -1138,7 +1305,40 @@ void cache_reload(void)
        if (!(ah->flags & AH_INACTIVE))
          total_size = read_hostsfile(ah->fname, ah->index, total_size, (struct crec **)daemon->packet, revhashsz);
     }
+  
+  /* Make non-terminal records for all locally-define RRs */
+  lrec.flags = F_FORWARD | F_CONFIG | F_NAMEP | F_IMMORTAL;
+  
+  for (txt = daemon->txt; txt; txt = txt->next)
+    {
+      lrec.name.namep = txt->name;
+      make_non_terminals(&lrec);
+    }
 
+  for (naptr = daemon->naptr; naptr; naptr = naptr->next)
+    {
+      lrec.name.namep = naptr->name;
+      make_non_terminals(&lrec);
+    }
+
+  for (mx = daemon->mxnames; mx; mx = mx->next)
+    {
+      lrec.name.namep = mx->name;
+      make_non_terminals(&lrec);
+    }
+
+  for (intr = daemon->int_names; intr; intr = intr->next)
+    {
+      lrec.name.namep = intr->name;
+      make_non_terminals(&lrec);
+    }
+  
+  for (ptr = daemon->ptr; ptr; ptr = ptr->next)
+    {
+      lrec.name.namep = ptr->name;
+      make_non_terminals(&lrec);
+    }
+  
 #ifdef HAVE_INOTIFY
   set_dynamic_inotify(AH_HOSTS, total_size, (struct crec **)daemon->packet, revhashsz);
 #endif
@@ -1153,7 +1353,7 @@ struct in_addr a_record_from_hosts(char *name, time_t now)
   
   while ((crecp = cache_find_by_name(crecp, name, now, F_IPV4)))
     if (crecp->flags & F_HOSTS)
-      return *(struct in_addr *)&crecp->addr;
+      return crecp->addr.addr4;
 
   my_syslog(MS_DHCP | LOG_WARNING, _("No IPv4 address found for %s"), name);
   
@@ -1178,52 +1378,19 @@ void cache_unhash_dhcp(void)
        up = &cache->hash_next;
 }
 
-static void add_dhcp_cname(struct crec *target, time_t ttd)
-{
-  struct crec *aliasc;
-  struct cname *a;
-  
-  for (a = daemon->cnames; a; a = a->next)
-    if (a->alias[1] != '*' &&
-       hostname_isequal(cache_get_name(target), a->target))
-      {
-       if ((aliasc = dhcp_spare))
-         dhcp_spare = dhcp_spare->next;
-       else /* need new one */
-         aliasc = whine_malloc(sizeof(struct crec));
-       
-       if (aliasc)
-         {
-           aliasc->flags = F_FORWARD | F_NAMEP | F_DHCP | F_CNAME | F_CONFIG;
-           if (ttd == 0)
-             aliasc->flags |= F_IMMORTAL;
-           else
-             aliasc->ttd = ttd;
-           aliasc->name.namep = a->alias;
-           aliasc->addr.cname.target.cache = target;
-           aliasc->addr.cname.uid = target->uid;
-           aliasc->uid = next_uid();
-           cache_hash(aliasc);
-           add_dhcp_cname(aliasc, ttd);
-         }
-      }
-}
-
 void cache_add_dhcp_entry(char *host_name, int prot,
-                         struct all_addr *host_address, time_t ttd) 
+                         union all_addr *host_address, time_t ttd) 
 {
   struct crec *crec = NULL, *fail_crec = NULL;
-  unsigned short flags = F_IPV4;
+  unsigned int flags = F_IPV4;
   int in_hosts = 0;
   size_t addrlen = sizeof(struct in_addr);
 
-#ifdef HAVE_IPV6
   if (prot == AF_INET6)
     {
       flags = F_IPV6;
       addrlen = sizeof(struct in6_addr);
     }
-#endif
   
   inet_ntop(prot, host_address, daemon->addrbuff, ADDRSTRLEN);
   
@@ -1236,14 +1403,14 @@ void cache_add_dhcp_entry(char *host_name, int prot,
            my_syslog(MS_DHCP | LOG_WARNING, 
                      _("%s is a CNAME, not giving it to the DHCP lease of %s"),
                      host_name, daemon->addrbuff);
-         else if (memcmp(&crec->addr.addr, host_address, addrlen) == 0)
+         else if (memcmp(&crec->addr, host_address, addrlen) == 0)
            in_hosts = 1;
          else
            fail_crec = crec;
        }
       else if (!(crec->flags & F_DHCP))
        {
-         cache_scan_free(host_name, NULL, 0, crec->flags & (flags | F_CNAME | F_FORWARD));
+         cache_scan_free(host_name, NULL, C_IN, 0, crec->flags & (flags | F_CNAME | F_FORWARD), NULL, NULL);
          /* scan_free deletes all addresses associated with name */
          break;
        }
@@ -1256,7 +1423,7 @@ void cache_add_dhcp_entry(char *host_name, int prot,
   /* Name in hosts, address doesn't match */
   if (fail_crec)
     {
-      inet_ntop(prot, &fail_crec->addr.addr, daemon->namebuff, MAXDNAME);
+      inet_ntop(prot, &fail_crec->addr, daemon->namebuff, MAXDNAME);
       my_syslog(MS_DHCP | LOG_WARNING, 
                _("not giving name %s to the DHCP lease of %s because "
                  "the name exists in %s with address %s"), 
@@ -1265,12 +1432,12 @@ void cache_add_dhcp_entry(char *host_name, int prot,
       return;
     }    
   
-  if ((crec = cache_find_by_addr(NULL, (struct all_addr *)host_address, 0, flags)))
+  if ((crec = cache_find_by_addr(NULL, (union all_addr *)host_address, 0, flags)))
     {
       if (crec->flags & F_NEG)
        {
          flags |= F_REVERSE;
-         cache_scan_free(NULL, (struct all_addr *)host_address, 0, flags);
+         cache_scan_free(NULL, (union all_addr *)host_address, C_IN, 0, flags, NULL, NULL);
        }
     }
   else
@@ -1279,7 +1446,7 @@ void cache_add_dhcp_entry(char *host_name, int prot,
   if ((crec = dhcp_spare))
     dhcp_spare = dhcp_spare->next;
   else /* need new one */
-    crec = whine_malloc(sizeof(struct crec));
+    crec = whine_malloc(SIZEOF_POINTER_CREC);
   
   if (crec) /* malloc may fail */
     {
@@ -1288,16 +1455,108 @@ void cache_add_dhcp_entry(char *host_name, int prot,
        crec->flags |= F_IMMORTAL;
       else
        crec->ttd = ttd;
-      crec->addr.addr = *host_address;
+      crec->addr = *host_address;
       crec->name.namep = host_name;
-      crec->uid = next_uid();
+      crec->uid = UID_NONE;
       cache_hash(crec);
-
-      add_dhcp_cname(crec, ttd);
+      make_non_terminals(crec);
     }
 }
 #endif
 
+/* Called when we put a local or DHCP name into the cache.
+   Creates empty cache entries for subnames (ie,
+   for three.two.one, for two.one and one), without
+   F_IPV4 or F_IPV6 or F_CNAME set. These convert
+   NXDOMAIN answers to NoData ones. */
+static void make_non_terminals(struct crec *source)
+{
+  char *name = cache_get_name(source);
+  struct crec *crecp, *tmp, **up;
+  int type = F_HOSTS | F_CONFIG;
+#ifdef HAVE_DHCP
+  if (source->flags & F_DHCP)
+    type = F_DHCP;
+#endif
+  
+  /* First delete any empty entries for our new real name. Note that
+     we only delete empty entries deriving from DHCP for a new DHCP-derived
+     entry and vice-versa for HOSTS and CONFIG. This ensures that 
+     non-terminals from DHCP go when we reload DHCP and 
+     for HOSTS/CONFIG when we re-read. */
+  for (up = hash_bucket(name), crecp = *up; crecp; crecp = tmp)
+    {
+      tmp = crecp->hash_next;
+
+      if (!is_outdated_cname_pointer(crecp) &&
+         (crecp->flags & F_FORWARD) &&
+         (crecp->flags & type) &&
+         !(crecp->flags & (F_IPV4 | F_IPV6 | F_CNAME | F_SRV | F_DNSKEY | F_DS)) && 
+         hostname_isequal(name, cache_get_name(crecp)))
+       {
+         *up = crecp->hash_next;
+#ifdef HAVE_DHCP
+         if (type & F_DHCP)
+           {
+             crecp->next = dhcp_spare;
+             dhcp_spare = crecp;
+           }
+         else
+#endif
+           free(crecp);
+         break;
+       }
+      else
+        up = &crecp->hash_next;
+    }
+     
+  while ((name = strchr(name, '.')))
+    {
+      name++;
+
+      /* Look for one existing, don't need another */
+      for (crecp = *hash_bucket(name); crecp; crecp = crecp->hash_next)
+       if (!is_outdated_cname_pointer(crecp) &&
+           (crecp->flags & F_FORWARD) &&
+           (crecp->flags & type) &&
+           hostname_isequal(name, cache_get_name(crecp)))
+         break;
+      
+      if (crecp)
+       {
+         /* If the new name expires later, transfer that time to
+            empty non-terminal entry. */
+         if (!(crecp->flags & F_IMMORTAL))
+           {
+             if (source->flags & F_IMMORTAL)
+               crecp->flags |= F_IMMORTAL;
+             else if (difftime(crecp->ttd, source->ttd) < 0)
+               crecp->ttd = source->ttd;
+           }
+         continue;
+       }
+      
+#ifdef HAVE_DHCP
+      if ((source->flags & F_DHCP) && dhcp_spare)
+       {
+         crecp = dhcp_spare;
+         dhcp_spare = dhcp_spare->next;
+       }
+      else
+#endif
+       crecp = whine_malloc(SIZEOF_POINTER_CREC);
+
+      if (crecp)
+       {
+         crecp->flags = (source->flags | F_NAMEP) & ~(F_IPV4 | F_IPV6 | F_CNAME | F_SRV | F_DNSKEY | F_DS | F_REVERSE);
+         crecp->ttd = source->ttd;
+         crecp->name.namep = name;
+         
+         cache_hash(crecp);
+       }
+    }
+}
+
 #ifndef NO_ID
 int cache_make_stat(struct txt_record *t)
 { 
@@ -1319,24 +1578,24 @@ int cache_make_stat(struct txt_record *t)
       break;
 
     case TXT_STAT_INSERTS:
-      sprintf(buff+1, "%d", cache_inserted);
+      sprintf(buff+1, "%d", daemon->metrics[METRIC_DNS_CACHE_INSERTED]);
       break;
 
     case TXT_STAT_EVICTIONS:
-      sprintf(buff+1, "%d", cache_live_freed);
+      sprintf(buff+1, "%d", daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED]);
       break;
 
     case TXT_STAT_MISSES:
-      sprintf(buff+1, "%u", daemon->queries_forwarded);
+      sprintf(buff+1, "%u", daemon->metrics[METRIC_DNS_QUERIES_FORWARDED]);
       break;
 
     case TXT_STAT_HITS:
-      sprintf(buff+1, "%u", daemon->local_answer);
+      sprintf(buff+1, "%u", daemon->metrics[METRIC_DNS_LOCAL_ANSWERED]);
       break;
 
 #ifdef HAVE_AUTH
     case TXT_STAT_AUTH:
-      sprintf(buff+1, "%u", daemon->auth_answer);
+      sprintf(buff+1, "%u", daemon->metrics[METRIC_DNS_AUTH_ANSWERED]);
       break;
 #endif
 
@@ -1413,19 +1672,17 @@ static char *sanitise(char *name)
 void dump_cache(time_t now)
 {
   struct server *serv, *serv1;
-  char *t = "";
 
   my_syslog(LOG_INFO, _("time %lu"), (unsigned long)now);
   my_syslog(LOG_INFO, _("cache size %d, %d/%d cache insertions re-used unexpired cache entries."), 
-           daemon->cachesize, cache_live_freed, cache_inserted);
+           daemon->cachesize, daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED], daemon->metrics[METRIC_DNS_CACHE_INSERTED]);
   my_syslog(LOG_INFO, _("queries forwarded %u, queries answered locally %u"), 
-           daemon->queries_forwarded, daemon->local_answer);
+           daemon->metrics[METRIC_DNS_QUERIES_FORWARDED], daemon->metrics[METRIC_DNS_LOCAL_ANSWERED]);
 #ifdef HAVE_AUTH
-  my_syslog(LOG_INFO, _("queries for authoritative zones %u"), daemon->auth_answer);
+  my_syslog(LOG_INFO, _("queries for authoritative zones %u"), daemon->metrics[METRIC_DNS_AUTH_ANSWERED]);
 #endif
-#ifdef HAVE_DNSSEC
+
   blockdata_report();
-#endif
 
   /* sum counts from different records for same server */
   for (serv = daemon->servers; serv; serv = serv->next)
@@ -1459,6 +1716,7 @@ void dump_cache(time_t now)
       for (i=0; i<hash_size; i++)
        for (cache = hash_table[i]; cache; cache = cache->hash_next)
          {
+           char *t = " ";
            char *a = daemon->addrbuff, *p = daemon->namebuff, *n = cache_get_name(cache);
            *a = 0;
            if (strlen(n) == 0 && !(cache->flags & F_REVERSE))
@@ -1466,6 +1724,17 @@ void dump_cache(time_t now)
            p += sprintf(p, "%-30.30s ", sanitise(n));
            if ((cache->flags & F_CNAME) && !is_outdated_cname_pointer(cache))
              a = sanitise(cache_get_cname_target(cache));
+           else if ((cache->flags & F_SRV) && !(cache->flags & F_NEG))
+             {
+               int targetlen = cache->addr.srv.targetlen;
+               ssize_t len = sprintf(a, "%u %u %u ", cache->addr.srv.priority,
+                                     cache->addr.srv.weight, cache->addr.srv.srvport);
+
+               if (targetlen > (40 - len))
+                 targetlen = 40 - len;
+               blockdata_retrieve(cache->addr.srv.target, targetlen, a + len);
+               a[len + targetlen] = 0;         
+             }
 #ifdef HAVE_DNSSEC
            else if (cache->flags & F_DS)
              {
@@ -1481,11 +1750,9 @@ void dump_cache(time_t now)
              { 
                a = daemon->addrbuff;
                if (cache->flags & F_IPV4)
-                 inet_ntop(AF_INET, &cache->addr.addr, a, ADDRSTRLEN);
-#ifdef HAVE_IPV6
+                 inet_ntop(AF_INET, &cache->addr, a, ADDRSTRLEN);
                else if (cache->flags & F_IPV6)
-                 inet_ntop(AF_INET6, &cache->addr.addr, a, ADDRSTRLEN);
-#endif
+                 inet_ntop(AF_INET6, &cache->addr, a, ADDRSTRLEN);
              }
 
            if (cache->flags & F_IPV4)
@@ -1494,6 +1761,8 @@ void dump_cache(time_t now)
              t = "6";
            else if (cache->flags & F_CNAME)
              t = "C";
+           else if (cache->flags & F_SRV)
+             t = "V";
 #ifdef HAVE_DNSSEC
            else if (cache->flags & F_DS)
              t = "S";
@@ -1559,9 +1828,13 @@ char *querystr(char *desc, unsigned short type)
        break;
       }
 
-  len += 3; /* braces, terminator */
-  len += strlen(desc);
-
+  if (desc)
+    {
+       len += 2; /* braces */
+       len += strlen(desc);
+    }
+  len++; /* terminator */
+  
   if (!buff || bufflen < len)
     {
       if (buff)
@@ -1575,16 +1848,26 @@ char *querystr(char *desc, unsigned short type)
 
   if (buff)
     {
-      if (types)
-       sprintf(buff, "%s[%s]", desc, types);
+      if (desc)
+       {
+         if (types)
+           sprintf(buff, "%s[%s]", desc, types);
+         else
+           sprintf(buff, "%s[type=%d]", desc, type);
+       }
       else
-       sprintf(buff, "%s[type=%d]", desc, type);
+       {
+         if (types)
+           sprintf(buff, "<%s>", types);
+         else
+           sprintf(buff, "type=%d", type);
+       }
     }
-
+  
   return buff ? buff : "";
 }
 
-void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg)
+void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg)
 {
   char *source, *dest = daemon->addrbuff;
   char *verb = "is";
@@ -1597,16 +1880,24 @@ void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg)
   if (addr)
     {
       if (flags & F_KEYTAG)
-       sprintf(daemon->addrbuff, arg, addr->addr.log.keytag, addr->addr.log.algo, addr->addr.log.digest);
-      else
+       sprintf(daemon->addrbuff, arg, addr->log.keytag, addr->log.algo, addr->log.digest);
+      else if (flags & F_RCODE)
        {
-#ifdef HAVE_IPV6
-         inet_ntop(flags & F_IPV4 ? AF_INET : AF_INET6,
-                   addr, daemon->addrbuff, ADDRSTRLEN);
-#else
-         strncpy(daemon->addrbuff, inet_ntoa(addr->addr.addr4), ADDRSTRLEN);  
-#endif
+         unsigned int rcode = addr->log.rcode;
+
+          if (rcode == SERVFAIL)
+            dest = "SERVFAIL";
+          else if (rcode == REFUSED)
+            dest = "REFUSED";
+          else if (rcode == NOTIMP)
+            dest = "not implemented";
+          else
+            sprintf(daemon->addrbuff, "%u", rcode);
        }
+      else
+       inet_ntop(flags & F_IPV4 ? AF_INET : AF_INET6,
+                 addr, daemon->addrbuff, ADDRSTRLEN);
+      
     }
   else
     dest = arg;
@@ -1633,6 +1924,8 @@ void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg)
     }
   else if (flags & F_CNAME)
     dest = "<CNAME>";
+  else if (flags & F_SRV)
+    dest = "<SRV>";
   else if (flags & F_RRNAME)
     dest = arg;
     
index ecefb87..7187ffa 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
 #define DHCP_PACKET_MAX 16384 /* hard limit on DHCP packet size */
 #define SMALLDNAME 50 /* most domain names are smaller than this */
 #define CNAME_CHAIN 10 /* chains longer than this atr dropped for loop protection */
+#define DNSSEC_MIN_TTL 60 /* DNSKEY and DS records in cache last at least this long */
 #define HOSTSFILE "/etc/hosts"
 #define ETHERSFILE "/etc/ethers"
-#define DEFLEASE 3600 /* default lease time, 1 hour */
+#define DEFLEASE 3600 /* default DHCPv4 lease time, one hour */
+#define DEFLEASE6 (3600*24) /* default lease time for DHCPv6. One day. */
 #define CHUSER "nobody"
 #define CHGRP "dip"
 #define TFTP_MAX_CONNECTIONS 50 /* max simultaneous connections */
@@ -50,6 +52,7 @@
 #define RANDFILE "/dev/urandom"
 #define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq" /* Default - may be overridden by config */
 #define DNSMASQ_PATH "/uk/org/thekelleys/dnsmasq"
+#define DNSMASQ_UBUS_NAME "dnsmasq" /* Default - may be overridden by config */
 #define AUTH_TTL 600 /* default TTL for auth DNS */
 #define SOA_REFRESH 1200 /* SOA refresh default */
 #define SOA_RETRY 180 /* SOA retry default */
@@ -94,6 +97,9 @@ HAVE_DBUS
    support some methods to allow (re)configuration of the upstream DNS 
    servers via DBus.
 
+HAVE_UBUS
+   define this if you want to link against libubus
+
 HAVE_IDN
    define this if you want international domain name 2003 support.
    
@@ -117,6 +123,9 @@ HAVE_AUTH
 HAVE_DNSSEC
    include DNSSEC validator.
 
+HAVE_DUMPFILE
+   include code to dump packets to a libpcap-format file for debugging.
+
 HAVE_LOOP
    include functionality to probe for and remove DNS forwarding loops.
 
@@ -125,17 +134,17 @@ HAVE_INOTIFY
 
 NO_ID
    Don't report *.bind CHAOS info to clients, forward such requests upstream instead.
-NO_IPV6
 NO_TFTP
 NO_DHCP
 NO_DHCP6
 NO_SCRIPT
 NO_LARGEFILE
 NO_AUTH
+NO_DUMPFILE
 NO_INOTIFY
    these are available to explicitly disable compile time options which would 
-   otherwise be enabled automatically (HAVE_IPV6, >2Gb file sizes) or 
-   which are enabled  by default in the distributed source tree. Building dnsmasq
+   otherwise be enabled automatically or which are enabled  by default 
+   in the distributed source tree. Building dnsmasq
    with something like "make COPTS=-DNO_SCRIPT" will do the trick.
 NO_GMP
    Don't use and link against libgmp, Useful if nettle is built with --enable-mini-gmp.
@@ -164,6 +173,7 @@ RESOLVFILE
 #define HAVE_AUTH
 #define HAVE_IPSET 
 #define HAVE_LOOP
+#define HAVE_DUMPFILE
 
 /* Build options which require external libraries.
    
@@ -232,27 +242,13 @@ HAVE_SOCKADDR_SA_LEN
    defined if struct sockaddr has sa_len field (*BSD) 
 */
 
-/* Must precede __linux__ since uClinux defines __linux__ too. */
-#if defined(__uClinux__)
-#define HAVE_LINUX_NETWORK
-#define HAVE_GETOPT_LONG
-#undef HAVE_SOCKADDR_SA_LEN
-/* Never use fork() on uClinux. Note that this is subtly different from the
-   --keep-in-foreground option, since it also  suppresses forking new 
-   processes for TCP connections and disables the call-a-script on leasechange
-   system. It's intended for use on MMU-less kernels. */
-#define NO_FORK
-
-#elif defined(__UCLIBC__)
+#if defined(__UCLIBC__)
 #define HAVE_LINUX_NETWORK
 #if defined(__UCLIBC_HAS_GNU_GETOPT__) || \
    ((__UCLIBC_MAJOR__==0) && (__UCLIBC_MINOR__==9) && (__UCLIBC_SUBLEVEL__<21))
 #    define HAVE_GETOPT_LONG
 #endif
 #undef HAVE_SOCKADDR_SA_LEN
-#if !defined(__ARCH_HAS_MMU__) && !defined(__UCLIBC_HAS_MMU__)
-#  define NO_FORK
-#endif
 #if defined(__UCLIBC_HAS_IPV6__)
 #  ifndef IPV6_V6ONLY
 #    define IPV6_V6ONLY 26
@@ -280,11 +276,16 @@ HAVE_SOCKADDR_SA_LEN
 #define HAVE_BSD_NETWORK
 #define HAVE_GETOPT_LONG
 #define HAVE_SOCKADDR_SA_LEN
+#define NO_IPSET
 /* Define before sys/socket.h is included so we get socklen_t */
 #define _BSD_SOCKLEN_T_
 /* Select the RFC_3542 version of the IPv6 socket API. 
    Define before netinet6/in6.h is included. */
-#define __APPLE_USE_RFC_3542 
+#define __APPLE_USE_RFC_3542
+/* Required for Mojave. */
+#ifndef SOL_TCP
+#  define SOL_TCP IPPROTO_TCP
+#endif
 #define NO_IPSET
 
 #elif defined(__NetBSD__)
@@ -300,29 +301,9 @@ HAVE_SOCKADDR_SA_LEN
  
 #endif
 
-/* Decide if we're going to support IPv6 */
-/* We assume that systems which don't have IPv6
-   headers don't have ntop and pton either */
-
-#if defined(INET6_ADDRSTRLEN) && defined(IPV6_V6ONLY)
-#  define HAVE_IPV6
-#  define ADDRSTRLEN INET6_ADDRSTRLEN
-#else
-#  if !defined(INET_ADDRSTRLEN)
-#      define INET_ADDRSTRLEN 16 /* 4*3 + 3 dots + NULL */
-#  endif
-#  undef HAVE_IPV6
-#  define ADDRSTRLEN INET_ADDRSTRLEN
-#endif
-
-
 /* rules to implement compile-time option dependencies and 
    the NO_XXX flags */
 
-#ifdef NO_IPV6
-#undef HAVE_IPV6
-#endif
-
 #ifdef NO_TFTP
 #undef HAVE_TFTP
 #endif
@@ -332,7 +313,7 @@ HAVE_SOCKADDR_SA_LEN
 #undef HAVE_DHCP6
 #endif
 
-#if defined(NO_DHCP6) || !defined(HAVE_IPV6)
+#if defined(NO_DHCP6)
 #undef HAVE_DHCP6
 #endif
 
@@ -341,7 +322,7 @@ HAVE_SOCKADDR_SA_LEN
 #define HAVE_DHCP
 #endif
 
-#if defined(NO_SCRIPT) || defined(NO_FORK)
+#if defined(NO_SCRIPT)
 #undef HAVE_SCRIPT
 #undef HAVE_LUASCRIPT
 #endif
@@ -363,6 +344,10 @@ HAVE_SOCKADDR_SA_LEN
 #undef HAVE_LOOP
 #endif
 
+#ifdef NO_DUMPFILE
+#undef HAVE_DUMPFILE
+#endif
+
 #if defined (HAVE_LINUX_NETWORK) && !defined(NO_INOTIFY)
 #define HAVE_INOTIFY
 #endif
@@ -373,9 +358,6 @@ HAVE_SOCKADDR_SA_LEN
 #ifdef DNSMASQ_COMPILE_OPTS
 
 static char *compile_opts = 
-#ifndef HAVE_IPV6
-"no-"
-#endif
 "IPv6 "
 #ifndef HAVE_GETOPT_LONG
 "no-"
@@ -384,13 +366,14 @@ static char *compile_opts =
 #ifdef HAVE_BROKEN_RTC
 "no-RTC "
 #endif
-#ifdef NO_FORK
-"no-MMU "
-#endif
 #ifndef HAVE_DBUS
 "no-"
 #endif
 "DBus "
+#ifndef HAVE_UBUS
+"no-"
+#endif
+"UBus "
 #ifndef LOCALEDIR
 "no-"
 #endif
@@ -451,8 +434,11 @@ static char *compile_opts =
 #ifndef HAVE_INOTIFY
 "no-"
 #endif
-"inotify";
-
+"inotify "
+#ifndef HAVE_DUMPFILE
+"no-"
+#endif
+"dumpfile";
 
 #endif
 
index 2929f8c..33f5ceb 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -24,7 +24,7 @@ static int gotit = 0; /* yuck */
 
 static int callback(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data);
 
-int get_incoming_mark(union mysockaddr *peer_addr, struct all_addr *local_addr, int istcp, unsigned int *markp)
+int get_incoming_mark(union mysockaddr *peer_addr, union all_addr *local_addr, int istcp, unsigned int *markp)
 {
   struct nf_conntrack *ct;
   struct nfct_handle *h;
@@ -36,21 +36,19 @@ int get_incoming_mark(union mysockaddr *peer_addr, struct all_addr *local_addr,
       nfct_set_attr_u8(ct, ATTR_L4PROTO, istcp ? IPPROTO_TCP : IPPROTO_UDP);
       nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(daemon->port));
       
-#ifdef HAVE_IPV6
       if (peer_addr->sa.sa_family == AF_INET6)
        {
          nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET6);
          nfct_set_attr(ct, ATTR_IPV6_SRC, peer_addr->in6.sin6_addr.s6_addr);
          nfct_set_attr_u16(ct, ATTR_PORT_SRC, peer_addr->in6.sin6_port);
-         nfct_set_attr(ct, ATTR_IPV6_DST, local_addr->addr.addr6.s6_addr);
+         nfct_set_attr(ct, ATTR_IPV6_DST, local_addr->addr6.s6_addr);
        }
       else
-#endif
        {
          nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET);
          nfct_set_attr_u32(ct, ATTR_IPV4_SRC, peer_addr->in.sin_addr.s_addr);
          nfct_set_attr_u16(ct, ATTR_PORT_SRC, peer_addr->in.sin_port);
-         nfct_set_attr_u32(ct, ATTR_IPV4_DST, local_addr->addr.addr4.s_addr);
+         nfct_set_attr_u32(ct, ATTR_IPV4_DST, local_addr->addr4.s_addr);
        }
       
       
index ebb871e..ca63111 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
 #ifdef HAVE_DNSSEC
 
 #include <nettle/rsa.h>
-#include <nettle/dsa.h>
 #include <nettle/ecdsa.h>
 #include <nettle/ecc-curve.h>
 #include <nettle/eddsa.h>
+#if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR >= 6
+#  include <nettle/gostdsa.h>
+#endif
 #include <nettle/nettle-meta.h>
 #include <nettle/bignum.h>
 
@@ -207,8 +209,6 @@ static int dnsmasq_rsa_verify(struct blockdata *key_data, unsigned int key_len,
   
   switch (algo)
     {
-    case 1:
-      return nettle_rsa_md5_verify_digest(key, digest, sig_mpz);
     case 5: case 7:
       return nettle_rsa_sha1_verify_digest(key, digest, sig_mpz);
     case 8:
@@ -220,50 +220,6 @@ static int dnsmasq_rsa_verify(struct blockdata *key_data, unsigned int key_len,
   return 0;
 }  
 
-static int dnsmasq_dsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
-                             unsigned char *digest, size_t digest_len, int algo)
-{
-  unsigned char *p;
-  unsigned int t;
-
-  static mpz_t y;
-  static struct dsa_params *params = NULL;
-  static struct dsa_signature *sig_struct;
-  
-  (void)digest_len;
-
-  if (params == NULL)
-    {
-      if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature))) || 
-         !(params = whine_malloc(sizeof(struct dsa_params)))) 
-       return 0;
-      
-      mpz_init(y);
-      nettle_dsa_params_init(params);
-      nettle_dsa_signature_init(sig_struct);
-    }
-  
-  if ((sig_len < 41) || !(p = blockdata_retrieve(key_data, key_len, NULL)))
-    return 0;
-  
-  t = *p++;
-  
-  if (key_len < (213 + (t * 24)))
-    return 0;
-  
-  mpz_import(params->q, 20, 1, 1, 0, 0, p); p += 20;
-  mpz_import(params->p, 64 + (t*8), 1, 1, 0, 0, p); p += 64 + (t*8);
-  mpz_import(params->g, 64 + (t*8), 1, 1, 0, 0, p); p += 64 + (t*8);
-  mpz_import(y, 64 + (t*8), 1, 1, 0, 0, p); p += 64 + (t*8);
-  
-  mpz_import(sig_struct->r, 20, 1, 1, 0, 0, sig+1);
-  mpz_import(sig_struct->s, 20, 1, 1, 0, 0, sig+21);
-  
-  (void)algo;
-  
-  return nettle_dsa_verify(params, y, digest_len, digest, sig_struct);
-} 
 static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len, 
                                unsigned char *sig, size_t sig_len,
                                unsigned char *digest, size_t digest_len, int algo)
@@ -275,6 +231,10 @@ static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len
   static struct ecc_point *key_256 = NULL, *key_384 = NULL;
   static mpz_t x, y;
   static struct dsa_signature *sig_struct;
+#if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR < 4
+#define nettle_get_secp_256r1() (&nettle_secp_256r1)
+#define nettle_get_secp_384r1() (&nettle_secp_384r1)
+#endif
   
   if (!sig_struct)
     {
@@ -294,7 +254,7 @@ static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len
          if (!(key_256 = whine_malloc(sizeof(struct ecc_point))))
            return 0;
          
-         nettle_ecc_point_init(key_256, &nettle_secp_256r1);
+         nettle_ecc_point_init(key_256, nettle_get_secp_256r1());
        }
       
       key = key_256;
@@ -307,7 +267,7 @@ static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len
          if (!(key_384 = whine_malloc(sizeof(struct ecc_point))))
            return 0;
          
-         nettle_ecc_point_init(key_384, &nettle_secp_384r1);
+         nettle_ecc_point_init(key_384, nettle_get_secp_384r1());
        }
       
       key = key_384;
@@ -334,15 +294,54 @@ static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len
   return nettle_ecdsa_verify(key, digest_len, digest, sig_struct);
 }
 
+#if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR >= 6
+static int dnsmasq_gostdsa_verify(struct blockdata *key_data, unsigned int key_len, 
+                                 unsigned char *sig, size_t sig_len,
+                                 unsigned char *digest, size_t digest_len, int algo)
+{
+  unsigned char *p;
+  
+  static struct ecc_point *gost_key = NULL;
+  static mpz_t x, y;
+  static struct dsa_signature *sig_struct;
+
+  if (algo != 12 ||
+      sig_len != 64 || key_len != 64 ||
+      !(p = blockdata_retrieve(key_data, key_len, NULL)))
+    return 0;
+  
+  if (!sig_struct)
+    {
+      if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature))) ||
+         !(gost_key = whine_malloc(sizeof(struct ecc_point))))
+       return 0;
+      
+      nettle_dsa_signature_init(sig_struct);
+      nettle_ecc_point_init(gost_key, nettle_get_gost_gc256b());
+      mpz_init(x);
+      mpz_init(y);
+    }
+    
+  mpz_import(x, 32 , 1, 1, 0, 0, p);
+  mpz_import(y, 32 , 1, 1, 0, 0, p + 32);
+
+  if (!ecc_point_set(gost_key, x, y))
+    return 0;
+  
+  mpz_import(sig_struct->r, 32, 1, 1, 0, 0, sig);
+  mpz_import(sig_struct->s, 32, 1, 1, 0, 0, sig + 32);
+  
+  return nettle_gostdsa_verify(gost_key, digest_len, digest, sig_struct);
+}
+#endif
+
 static int dnsmasq_eddsa_verify(struct blockdata *key_data, unsigned int key_len, 
                                unsigned char *sig, size_t sig_len,
                                unsigned char *digest, size_t digest_len, int algo)
 {
   unsigned char *p;
    
-  if (key_len != ED25519_KEY_SIZE ||
-      sig_len != ED25519_SIGNATURE_SIZE ||
-      digest_len != sizeof(struct null_hash_digest) ||
+  if (digest_len != sizeof(struct null_hash_digest) ||
       !(p = blockdata_retrieve(key_data, key_len, NULL)))
     return 0;
   
@@ -353,13 +352,27 @@ static int dnsmasq_eddsa_verify(struct blockdata *key_data, unsigned int key_len
   switch (algo)
     {
     case 15:
+      if (key_len != ED25519_KEY_SIZE ||
+         sig_len != ED25519_SIGNATURE_SIZE)
+       return 0;
+
       return ed25519_sha512_verify(p,
                                   ((struct null_hash_digest *)digest)->len,
                                   ((struct null_hash_digest *)digest)->buff,
                                   sig);
+      
+#if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR >= 6
     case 16:
-      /* Ed448 when available */
-      return 0;
+      if (key_len != ED448_KEY_SIZE ||
+         sig_len != ED448_SIGNATURE_SIZE)
+       return 0;
+
+      return ed448_shake256_verify(p,
+                                  ((struct null_hash_digest *)digest)->len,
+                                  ((struct null_hash_digest *)digest)->buff,
+                                  sig);
+#endif
+
     }
 
   return 0;
@@ -369,19 +382,21 @@ static int (*verify_func(int algo))(struct blockdata *key_data, unsigned int key
                             unsigned char *digest, size_t digest_len, int algo)
 {
     
-  /* Enure at runtime that we have support for this digest */
+  /* Ensure at runtime that we have support for this digest */
   if (!hash_find(algo_digest_name(algo)))
     return NULL;
   
   /* This switch defines which sig algorithms we support, can't introspect Nettle for that. */
   switch (algo)
     {
-    case 1: case 5: case 7: case 8: case 10:
+    case 5: case 7: case 8: case 10:
       return dnsmasq_rsa_verify;
+
+#if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR >= 6
+    case 12:
+      return dnsmasq_gostdsa_verify;
+#endif
       
-    case 3: case 6: 
-      return dnsmasq_dsa_verify;
-    
     case 13: case 14:
       return dnsmasq_ecdsa_verify;
 
@@ -432,17 +447,17 @@ char *algo_digest_name(int algo)
     {
     case 1: return NULL;          /* RSA/MD5 - Must Not Implement.  RFC 6944 para 2.3. */
     case 2: return NULL;          /* Diffie-Hellman */
-    case 3: return "sha1";        /* DSA/SHA1 */ 
+    case 3: return NULL; ;        /* DSA/SHA1 - Must Not Implement. RFC 8624 section 3.1 */ 
     case 5: return "sha1";        /* RSA/SHA1 */
-    case 6: return "sha1";        /* DSA-NSEC3-SHA1 */
+    case 6: return NULL;          /* DSA-NSEC3-SHA1 - Must Not Implement. RFC 8624 section 3.1 */
     case 7: return "sha1";        /* RSASHA1-NSEC3-SHA1 */
     case 8: return "sha256";      /* RSA/SHA-256 */
     case 10: return "sha512";     /* RSA/SHA-512 */
-    case 12: return NULL;         /* ECC-GOST */
+    case 12: return "gosthash94"; /* ECC-GOST */
     case 13: return "sha256";     /* ECDSAP256SHA256 */
     case 14: return "sha384";     /* ECDSAP384SHA384 */        
     case 15: return "null_hash";  /* ED25519 */
-    case 16: return NULL;         /* ED448 */
+    case 16: return "null_hash";  /* ED448 */
     default: return NULL;
     }
 }
index 6a78b20..6def129 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -85,6 +85,9 @@ const char* introspection_xml_template =
 "       <arg name=\"success\" type=\"b\" direction=\"out\"/>\n"
 "    </method>\n"
 #endif
+"    <method name=\"GetMetrics\">\n"
+"      <arg name=\"metrics\" direction=\"out\" type=\"a{su}\"/>\n"
+"    </method>\n"
 "  </interface>\n"
 "</node>\n";
 
@@ -182,9 +185,6 @@ static void dbus_read_servers(DBusMessage *message)
                }
            }
 
-#ifndef HAVE_IPV6
-         my_syslog(LOG_WARNING, _("attempt to set an IPv6 server address via DBus - no IPv6 support"));
-#else
          if (i == sizeof(struct in6_addr))
            {
              memcpy(&addr.in6.sin6_addr, p, sizeof(struct in6_addr));
@@ -199,7 +199,6 @@ static void dbus_read_servers(DBusMessage *message)
               source_addr.in6.sin6_port = htons(daemon->query_port);
              skip = 0;
            }
-#endif
        }
       else
        /* At the end */
@@ -238,7 +237,7 @@ static DBusMessage *dbus_reply_server_loop(DBusMessage *message)
   for (serv = daemon->servers; serv; serv = serv->next)
     if (serv->flags & SERV_LOOP)
       {
-       prettyprint_addr(&serv->addr, daemon->addrbuff);
+       (void)prettyprint_addr(&serv->addr, daemon->addrbuff);
        dbus_message_iter_append_basic (&args_iter, DBUS_TYPE_STRING, &daemon->addrbuff);
       }
   
@@ -457,7 +456,7 @@ static DBusMessage *dbus_add_lease(DBusMessage* message)
   int clid_len, hostname_len, hw_len, hw_type;
   dbus_uint32_t expires, ia_id;
   dbus_bool_t is_temporary;
-  struct all_addr addr;
+  union all_addr addr;
   time_t now = dnsmasq_time();
   unsigned char dhcp_chaddr[DHCP_CHADDR_MAX];
 
@@ -527,20 +526,20 @@ static DBusMessage *dbus_add_lease(DBusMessage* message)
 
   dbus_message_iter_get_basic(&iter, &is_temporary);
 
-  if (inet_pton(AF_INET, ipaddr, &addr.addr.addr4))
+  if (inet_pton(AF_INET, ipaddr, &addr.addr4))
     {
       if (ia_id != 0 || is_temporary)
        return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
                                      "ia_id and is_temporary must be zero for IPv4 lease");
       
-      if (!(lease = lease_find_by_addr(addr.addr.addr4)))
-       lease = lease4_allocate(addr.addr.addr4);
+      if (!(lease = lease_find_by_addr(addr.addr4)))
+       lease = lease4_allocate(addr.addr4);
     }
 #ifdef HAVE_DHCP6
-  else if (inet_pton(AF_INET6, ipaddr, &addr.addr.addr6))
+  else if (inet_pton(AF_INET6, ipaddr, &addr.addr6))
     {
-      if (!(lease = lease6_find_by_addr(&addr.addr.addr6, 128, 0)))
-       lease = lease6_allocate(&addr.addr.addr6,
+      if (!(lease = lease6_find_by_addr(&addr.addr6, 128, 0)))
+       lease = lease6_allocate(&addr.addr6,
                                is_temporary ? LEASE_TA : LEASE_NA);
       lease_set_iaid(lease, ia_id);
     }
@@ -571,7 +570,7 @@ static DBusMessage *dbus_del_lease(DBusMessage* message)
   DBusMessageIter iter;
   const char *ipaddr;
   DBusMessage *reply;
-  struct all_addr addr;
+  union all_addr addr;
   dbus_bool_t ret = 1;
   time_t now = dnsmasq_time();
 
@@ -585,11 +584,11 @@ static DBusMessage *dbus_del_lease(DBusMessage* message)
    
   dbus_message_iter_get_basic(&iter, &ipaddr);
 
-  if (inet_pton(AF_INET, ipaddr, &addr.addr.addr4))
-    lease = lease_find_by_addr(addr.addr.addr4);
+  if (inet_pton(AF_INET, ipaddr, &addr.addr4))
+    lease = lease_find_by_addr(addr.addr4);
 #ifdef HAVE_DHCP6
-  else if (inet_pton(AF_INET6, ipaddr, &addr.addr.addr6))
-    lease = lease6_find_by_addr(&addr.addr.addr6, 128, 0);
+  else if (inet_pton(AF_INET6, ipaddr, &addr.addr6))
+    lease = lease6_find_by_addr(&addr.addr6, 128, 0);
 #endif
   else
     return dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
@@ -613,6 +612,30 @@ static DBusMessage *dbus_del_lease(DBusMessage* message)
 }
 #endif
 
+static DBusMessage *dbus_get_metrics(DBusMessage* message)
+{
+  DBusMessage *reply = dbus_message_new_method_return(message);
+  DBusMessageIter array, dict, iter;
+  int i;
+
+  dbus_message_iter_init_append(reply, &iter);
+  dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{su}", &array);
+
+  for (i = 0; i < __METRIC_MAX; i++) {
+    const char *key     = get_metric_name(i);
+    dbus_uint32_t value = daemon->metrics[i];
+
+    dbus_message_iter_open_container(&array, DBUS_TYPE_DICT_ENTRY, NULL, &dict);
+    dbus_message_iter_append_basic(&dict, DBUS_TYPE_STRING, &key);
+    dbus_message_iter_append_basic(&dict, DBUS_TYPE_UINT32, &value);
+    dbus_message_iter_close_container(&array, &dict);
+  }
+
+  dbus_message_iter_close_container(&iter, &array);
+
+  return reply;
+}
+
 DBusHandlerResult message_handler(DBusConnection *connection, 
                                  DBusMessage *message, 
                                  void *user_data)
@@ -680,6 +703,10 @@ DBusHandlerResult message_handler(DBusConnection *connection,
       reply = dbus_del_lease(message);
     }
 #endif
+  else if (strcmp(method, "GetMetrics") == 0)
+    {
+      reply = dbus_get_metrics(message);
+    }
   else if (strcmp(method, "ClearCache") == 0)
     clear_cache = 1;
   else
index d9719d1..eae9886 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -38,7 +38,7 @@ void dhcp_common_init(void)
 
 ssize_t recv_dhcp_packet(int fd, struct msghdr *msg)
 {  
-  ssize_t sz;
+  ssize_t sz, new_sz;
  
   while (1)
     {
@@ -65,9 +65,18 @@ ssize_t recv_dhcp_packet(int fd, struct msghdr *msg)
        }
     }
   
-  while ((sz = recvmsg(fd, msg, 0)) == -1 && errno == EINTR);
+  while ((new_sz = recvmsg(fd, msg, 0)) == -1 && errno == EINTR);
+
+  /* Some kernels seem to ignore MSG_PEEK, and dequeue the packet anyway. 
+     If that happens we get EAGAIN here because the socket is non-blocking.
+     Use the result of the original testing recvmsg as long as the buffer
+     was big enough. There's a small race here that may lose the odd packet,
+     but it's UDP anyway. */
+  
+  if (new_sz == -1 && (errno == EWOULDBLOCK || errno == EAGAIN))
+    new_sz = sz;
   
-  return (msg->msg_flags & MSG_TRUNC) ? -1 : sz;
+  return (msg->msg_flags & MSG_TRUNC) ? -1 : new_sz;
 }
 
 struct dhcp_netid *run_tag_if(struct dhcp_netid *tags)
@@ -271,35 +280,45 @@ static int is_config_in_context(struct dhcp_context *context, struct dhcp_config
 {
   if (!context) /* called via find_config() from lease_update_from_configs() */
     return 1; 
-
-  if (!(config->flags & (CONFIG_ADDR | CONFIG_ADDR6)))
-    return 1;
   
 #ifdef HAVE_DHCP6
-  if ((context->flags & CONTEXT_V6) && (config->flags & CONFIG_WILDCARD))
-    return 1;
-#endif
+  if (context->flags & CONTEXT_V6)
+    {
+       struct addrlist *addr_list;
 
-  for (; context; context = context->current)
-#ifdef HAVE_DHCP6
-    if (context->flags & CONTEXT_V6) 
-      {
-       if ((config->flags & CONFIG_ADDR6) && is_same_net6(&config->addr6, &context->start6, context->prefix))
-         return 1;
-      }
-    else 
+       if (!(config->flags & CONFIG_ADDR6))
+        return 1;
+       
+        for (; context; context = context->current)
+         for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
+           {
+             if ((addr_list->flags & ADDRLIST_WILDCARD) && context->prefix == 64)
+               return 1;
+             
+             if (is_same_net6(&addr_list->addr.addr6, &context->start6, context->prefix))
+               return 1;
+           }
+    }
+  else
 #endif
-      if ((config->flags & CONFIG_ADDR) && is_same_net(config->addr, context->start, context->netmask))
+    {
+      if (!(config->flags & CONFIG_ADDR))
        return 1;
+      
+      for (; context; context = context->current)
+       if ((config->flags & CONFIG_ADDR) && is_same_net(config->addr, context->start, context->netmask))
+         return 1;
+    }
 
   return 0;
 }
 
-struct dhcp_config *find_config(struct dhcp_config *configs,
-                               struct dhcp_context *context,
-                               unsigned char *clid, int clid_len,
-                               unsigned char *hwaddr, int hw_len, 
-                               int hw_type, char *hostname)
+static struct dhcp_config *find_config_match(struct dhcp_config *configs,
+                                            struct dhcp_context *context,
+                                            unsigned char *clid, int clid_len,
+                                            unsigned char *hwaddr, int hw_len, 
+                                            int hw_type, char *hostname,
+                                            struct dhcp_netid *tags, int tag_not_needed)
 {
   int count, new;
   struct dhcp_config *config, *candidate; 
@@ -311,7 +330,9 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
        {
          if (config->clid_len == clid_len && 
              memcmp(config->clid, clid, clid_len) == 0 &&
-             is_config_in_context(context, config))
+             is_config_in_context(context, config) &&
+             match_netid(config->filter, tags, tag_not_needed))
+           
            return config;
          
          /* dhcpcd prefixes ASCII client IDs by zero which is wrong, but we try and
@@ -319,7 +340,8 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
             see lease_update_from_configs() */
          if ((!context || !(context->flags & CONTEXT_V6)) && *clid == 0 && config->clid_len == clid_len-1  &&
              memcmp(config->clid, clid+1, clid_len-1) == 0 &&
-             is_config_in_context(context, config))
+             is_config_in_context(context, config) &&
+             match_netid(config->filter, tags, tag_not_needed))
            return config;
        }
   
@@ -327,14 +349,16 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
   if (hwaddr)
     for (config = configs; config; config = config->next)
       if (config_has_mac(config, hwaddr, hw_len, hw_type) &&
-         is_config_in_context(context, config))
+         is_config_in_context(context, config) &&
+         match_netid(config->filter, tags, tag_not_needed))
        return config;
   
   if (hostname && context)
     for (config = configs; config; config = config->next)
       if ((config->flags & CONFIG_NAME) && 
          hostname_isequal(config->hostname, hostname) &&
-         is_config_in_context(context, config))
+         is_config_in_context(context, config) &&
+         match_netid(config->filter, tags, tag_not_needed))
        return config;
 
   
@@ -343,7 +367,8 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
 
   /* use match with fewest wildcard octets */
   for (candidate = NULL, count = 0, config = configs; config; config = config->next)
-    if (is_config_in_context(context, config))
+    if (is_config_in_context(context, config) &&
+       match_netid(config->filter, tags, tag_not_needed))
       for (conf_addr = config->hwaddr; conf_addr; conf_addr = conf_addr->next)
        if (conf_addr->wildcard_mask != 0 &&
            conf_addr->hwaddr_len == hw_len &&  
@@ -357,6 +382,21 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
   return candidate;
 }
 
+/* Find tagged configs first. */
+struct dhcp_config *find_config(struct dhcp_config *configs,
+                               struct dhcp_context *context,
+                               unsigned char *clid, int clid_len,
+                               unsigned char *hwaddr, int hw_len, 
+                               int hw_type, char *hostname, struct dhcp_netid *tags)
+{
+  struct dhcp_config *ret = find_config_match(configs, context, clid, clid_len, hwaddr, hw_len, hw_type, hostname, tags, 0);
+
+  if (!ret)
+    ret = find_config_match(configs, context, clid, clid_len, hwaddr, hw_len, hw_type, hostname, tags, 1);
+
+  return ret;
+}
+
 void dhcp_update_configs(struct dhcp_config *configs)
 {
   /* Some people like to keep all static IP addresses in /etc/hosts.
@@ -371,8 +411,14 @@ void dhcp_update_configs(struct dhcp_config *configs)
   int prot = AF_INET;
 
   for (config = configs; config; config = config->next)
+  {
     if (config->flags & CONFIG_ADDR_HOSTS)
-      config->flags &= ~(CONFIG_ADDR | CONFIG_ADDR6 | CONFIG_ADDR_HOSTS);
+      config->flags &= ~(CONFIG_ADDR | CONFIG_ADDR_HOSTS);
+#ifdef HAVE_DHCP6
+    if (config->flags & CONFIG_ADDR6_HOSTS)
+      config->flags &= ~(CONFIG_ADDR6 | CONFIG_ADDR6_HOSTS);
+#endif
+  }
 
 #ifdef HAVE_DHCP6 
  again:  
@@ -403,30 +449,41 @@ void dhcp_update_configs(struct dhcp_config *configs)
                  crec = cache_find_by_name(crec, config->hostname, 0, cacheflags);
                if (!crec)
                  continue; /* should be never */
-               inet_ntop(prot, &crec->addr.addr, daemon->addrbuff, ADDRSTRLEN);
+               inet_ntop(prot, &crec->addr, daemon->addrbuff, ADDRSTRLEN);
                my_syslog(MS_DHCP | LOG_WARNING, _("%s has more than one address in hostsfile, using %s for DHCP"), 
                          config->hostname, daemon->addrbuff);
              }
            
            if (prot == AF_INET && 
-               (!(conf_tmp = config_find_by_address(configs, crec->addr.addr.addr.addr4)) || conf_tmp == config))
+               (!(conf_tmp = config_find_by_address(configs, crec->addr.addr4)) || conf_tmp == config))
              {
-               config->addr = crec->addr.addr.addr.addr4;
+               config->addr = crec->addr.addr4;
                config->flags |= CONFIG_ADDR | CONFIG_ADDR_HOSTS;
                continue;
              }
 
 #ifdef HAVE_DHCP6
            if (prot == AF_INET6 && 
-               (!(conf_tmp = config_find_by_address6(configs, &crec->addr.addr.addr.addr6, 128, 0)) || conf_tmp == config))
+               (!(conf_tmp = config_find_by_address6(configs, NULL, 0, &crec->addr.addr6)) || conf_tmp == config))
              {
-               memcpy(&config->addr6, &crec->addr.addr.addr.addr6, IN6ADDRSZ);
-               config->flags |= CONFIG_ADDR6 | CONFIG_ADDR_HOSTS;
+               /* host must have exactly one address if comming from /etc/hosts. */
+               if (!config->addr6 && (config->addr6 = whine_malloc(sizeof(struct addrlist))))
+                 {
+                   config->addr6->next = NULL;
+                   config->addr6->flags = 0;
+                 }
+
+               if (config->addr6 && !config->addr6->next && !(config->addr6->flags & (ADDRLIST_WILDCARD|ADDRLIST_PREFIX)))
+                 {
+                   memcpy(&config->addr6->addr.addr6, &crec->addr.addr6, IN6ADDRSZ);
+                   config->flags |= CONFIG_ADDR6 | CONFIG_ADDR6_HOSTS;
+                 }
+           
                continue;
              }
 #endif
 
-           inet_ntop(prot, &crec->addr.addr, daemon->addrbuff, ADDRSTRLEN);
+           inet_ntop(prot, &crec->addr, daemon->addrbuff, ADDRSTRLEN);
            my_syslog(MS_DHCP | LOG_WARNING, _("duplicate IP address %s (%s) in dhcp-config directive"), 
                      daemon->addrbuff, config->hostname);
            
@@ -485,8 +542,11 @@ char *whichdevice(void)
  
 void  bindtodevice(char *device, int fd)
 {
+  size_t len = strlen(device)+1;
+  if (len > IFNAMSIZ)
+    len = IFNAMSIZ;
   /* only allowed by root. */
-  if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, device, IFNAMSIZ) == -1 &&
+  if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, device, len) == -1 &&
       errno != EPERM)
     die(_("failed to set SO_BINDTODEVICE on DHCP socket: %s"), NULL, EC_BADNET);
 }
@@ -556,6 +616,7 @@ static const struct opttab_t {
   { "nntp-server", 71, OT_ADDR_LIST }, 
   { "irc-server", 74, OT_ADDR_LIST }, 
   { "user-class", 77, 0 },
+  { "rapid-commit", 80, 0 },
   { "FQDN", 81, OT_INTERNAL },
   { "agent-id", 82, OT_INTERNAL },
   { "client-arch", 93, 2 | OT_DEC },
@@ -566,6 +627,7 @@ static const struct opttab_t {
   { "sip-server", 120, 0 },
   { "classless-static-route", 121, 0 },
   { "vendor-id-encap", 125, 0 },
+  { "tftp-server-address", 150, OT_ADDR_LIST },
   { "server-ip-address", 255, OT_ADDR_LIST }, /* special, internal only, sets siaddr */
   { NULL, 0, 0 }
 };
@@ -596,7 +658,7 @@ static const struct opttab_t opttab6[] = {
   { "sntp-server", 31,  OT_ADDR_LIST },
   { "information-refresh-time", 32, OT_TIME },
   { "FQDN", 39, OT_INTERNAL | OT_RFC1035_NAME },
-  { "ntp-server", 56,  0 },
+  { "ntp-server", 56, 0 /* OT_ADDR_LIST | OT_RFC1035_NAME */ },
   { "bootfile-url", 59, OT_NAME },
   { "bootfile-param", 60, OT_CSTRING },
   { NULL, 0, 0 }
@@ -689,7 +751,7 @@ char *option_string(int prot, unsigned int opt, unsigned char *val, int opt_len,
            
            if (ot[o].size & OT_ADDR_LIST) 
              {
-               struct all_addr addr;
+               union all_addr addr;
                int addr_len = INADDRSZ;
 
 #ifdef HAVE_DHCP6
index a4a3535..e9007c8 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -54,6 +54,7 @@
 #define OPTION_SNAME             66
 #define OPTION_FILENAME          67
 #define OPTION_USER_CLASS        77
+#define OPTION_RAPID_COMMIT      80
 #define OPTION_CLIENT_FQDN       81
 #define OPTION_AGENT_ID          82
 #define OPTION_ARCH              93
index 5a8daec..bea4688 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -232,7 +232,7 @@ void dhcp_packet(time_t now, int pxe_fd)
   
 #ifdef HAVE_LINUX_NETWORK
   /* ARP fiddling uses original interface even if we pretend to use a different one. */
-  strncpy(arp_req.arp_dev, ifr.ifr_name, 16);
+  safe_strncpy(arp_req.arp_dev, ifr.ifr_name, sizeof(arp_req.arp_dev));
 #endif 
 
   /* If the interface on which the DHCP request was received is an
@@ -255,7 +255,7 @@ void dhcp_packet(time_t now, int pxe_fd)
              }
            else 
              {
-               strncpy(ifr.ifr_name,  bridge->iface, IF_NAMESIZE);
+               safe_strncpy(ifr.ifr_name,  bridge->iface, sizeof(ifr.ifr_name));
                break;
              }
          }
@@ -279,7 +279,7 @@ void dhcp_packet(time_t now, int pxe_fd)
       is_relay_reply = 1; 
       iov.iov_len = sz;
 #ifdef HAVE_LINUX_NETWORK
-      strncpy(arp_req.arp_dev, ifr.ifr_name, 16);
+      safe_strncpy(arp_req.arp_dev, ifr.ifr_name, sizeof(arp_req.arp_dev));
 #endif 
     }
   else
@@ -310,7 +310,7 @@ void dhcp_packet(time_t now, int pxe_fd)
       parm.relay_local.s_addr = 0;
       parm.ind = iface_index;
       
-      if (!iface_check(AF_INET, (struct all_addr *)&iface_addr, ifr.ifr_name, NULL))
+      if (!iface_check(AF_INET, (union all_addr *)&iface_addr, ifr.ifr_name, NULL))
        {
          /* If we failed to match the primary address of the interface, see if we've got a --listen-address
             for a secondary */
@@ -401,7 +401,8 @@ void dhcp_packet(time_t now, int pxe_fd)
       pkt = (struct in_pktinfo *)CMSG_DATA(cmptr);
       pkt->ipi_ifindex = rcvd_iface_index;
       pkt->ipi_spec_dst.s_addr = 0;
-      msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+      msg.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
+      cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
       cmptr->cmsg_level = IPPROTO_IP;
       cmptr->cmsg_type = IP_PKTINFO;
 
@@ -507,33 +508,83 @@ static int check_listen_addrs(struct in_addr local, int if_index, char *label,
 
    Note that the current chain may be superseded later for configured hosts or those coming via gateways. */
 
-static int complete_context(struct in_addr local, int if_index, char *label,
-                           struct in_addr netmask, struct in_addr broadcast, void *vparam)
+static void guess_range_netmask(struct in_addr addr, struct in_addr netmask)
 {
   struct dhcp_context *context;
-  struct dhcp_relay *relay;
-  struct iface_param *param = vparam;
 
-  (void)label;
-  
   for (context = daemon->dhcp; context; context = context->next)
-    {
-      if (!(context->flags & CONTEXT_NETMASK) &&
-         (is_same_net(local, context->start, netmask) ||
-          is_same_net(local, context->end, netmask)))
+    if (!(context->flags & CONTEXT_NETMASK) &&
+       (is_same_net(addr, context->start, netmask) ||
+        is_same_net(addr, context->end, netmask)))
       { 
        if (context->netmask.s_addr != netmask.s_addr &&
-           !(is_same_net(local, context->start, netmask) &&
-             is_same_net(local, context->end, netmask)))
+           !(is_same_net(addr, context->start, netmask) &&
+             is_same_net(addr, context->end, netmask)))
          {
            strcpy(daemon->dhcp_buff, inet_ntoa(context->start));
            strcpy(daemon->dhcp_buff2, inet_ntoa(context->end));
            my_syslog(MS_DHCP | LOG_WARNING, _("DHCP range %s -- %s is not consistent with netmask %s"),
                      daemon->dhcp_buff, daemon->dhcp_buff2, inet_ntoa(netmask));
          }     
-       context->netmask = netmask;
+       context->netmask = netmask;
       }
+}
+
+static int complete_context(struct in_addr local, int if_index, char *label,
+                           struct in_addr netmask, struct in_addr broadcast, void *vparam)
+{
+  struct dhcp_context *context;
+  struct dhcp_relay *relay;
+  struct iface_param *param = vparam;
+  struct shared_network *share;
+  
+  (void)label;
+
+  for (share = daemon->shared_networks; share; share = share->next)
+    {
       
+#ifdef HAVE_DHCP6
+      if (share->shared_addr.s_addr == 0)
+       continue;
+#endif
+      
+      if (share->if_index != 0)
+       {
+         if (share->if_index != if_index)
+           continue;
+       }
+      else
+       {
+         if (share->match_addr.s_addr != local.s_addr)
+           continue;
+       }
+
+      for (context = daemon->dhcp; context; context = context->next)
+       {
+         if (context->netmask.s_addr != 0 &&
+             is_same_net(share->shared_addr, context->start, context->netmask) &&
+             is_same_net(share->shared_addr, context->end, context->netmask))
+           {
+             /* link it onto the current chain if we've not seen it before */
+             if (context->current == context)
+               {
+                 /* For a shared network, we have no way to guess what the default route should be. */
+                 context->router.s_addr = 0;
+                 context->local = local; /* Use configured address for Server Identifier */
+                 context->current = param->current;
+                 param->current = context;
+               }
+             
+             if (!(context->flags & CONTEXT_BRDCAST))
+               context->broadcast.s_addr  = context->start.s_addr | ~context->netmask.s_addr;
+           }           
+       }
+    }
+
+  guess_range_netmask(local, netmask);
+  
+  for (context = daemon->dhcp; context; context = context->next)
+    {
       if (context->netmask.s_addr != 0 &&
          is_same_net(local, context->start, context->netmask) &&
          is_same_net(local, context->end, context->netmask))
@@ -558,7 +609,7 @@ static int complete_context(struct in_addr local, int if_index, char *label,
     }
 
   for (relay = daemon->relay4; relay; relay = relay->next)
-    if (if_index == param->ind && relay->local.addr.addr4.s_addr == local.s_addr && relay->current == relay &&
+    if (if_index == param->ind && relay->local.addr4.s_addr == local.s_addr && relay->current == relay &&
        (param->relay_local.s_addr == 0 || param->relay_local.s_addr == local.s_addr))
       {
        relay->current = param->relay;
@@ -678,7 +729,7 @@ struct ping_result *do_icmp_ping(time_t now, struct in_addr addr, unsigned int h
   if ((count >= max) || option_bool(OPT_NO_PING) || loopback)
     {
       /* overloaded, or configured not to check, loopback interface, return "not in use" */
-      dummy.hash = 0;
+      dummy.hash = hash;
       return &dummy;
     }
   else if (icmp_ping(addr))
@@ -765,24 +816,33 @@ int address_allocate(struct dhcp_context *context,
                (!IN_CLASSC(ntohl(addr.s_addr)) || 
                 ((ntohl(addr.s_addr) & 0xff) != 0xff && ((ntohl(addr.s_addr) & 0xff) != 0x0))))
              {
-               struct ping_result *r;
-               
-               if ((r = do_icmp_ping(now, addr, j, loopback)))
-                 {
-                   /* consec-ip mode: we offered this address for another client
-                      (different hash) recently, don't offer it to this one. */
-                   if (!option_bool(OPT_CONSEC_ADDR) || r->hash == j)
-                     {
-                       *addrp = addr;
-                       return 1;
-                     }
-                 }
+               /* in consec-ip mode, skip addresses equal to
+                  the number of addresses rejected by clients. This
+                  should avoid the same client being offered the same
+                  address after it has rjected it. */
+               if (option_bool(OPT_CONSEC_ADDR) && c->addr_epoch)
+                 c->addr_epoch--;
                else
                  {
-                   /* address in use: perturb address selection so that we are
-                      less likely to try this address again. */
-                   if (!option_bool(OPT_CONSEC_ADDR))
-                     c->addr_epoch++;
+                   struct ping_result *r;
+                   
+                   if ((r = do_icmp_ping(now, addr, j, loopback)))
+                     {
+                       /* consec-ip mode: we offered this address for another client
+                          (different hash) recently, don't offer it to this one. */
+                       if (!option_bool(OPT_CONSEC_ADDR) || r->hash == j)
+                         {
+                           *addrp = addr;
+                           return 1;
+                         }
+                     }
+                   else
+                     {
+                       /* address in use: perturb address selection so that we are
+                          less likely to try this address again. */
+                       if (!option_bool(OPT_CONSEC_ADDR))
+                         c->addr_epoch++;
+                     }
                  }
              }
            
@@ -971,7 +1031,7 @@ char *host_from_dns(struct in_addr addr)
   if (daemon->port == 0)
     return NULL; /* DNS disabled. */
   
-  lookup = cache_find_by_addr(NULL, (struct all_addr *)&addr, 0, F_IPV4);
+  lookup = cache_find_by_addr(NULL, (union all_addr *)&addr, 0, F_IPV4);
 
   if (lookup && (lookup->flags & F_HOSTS))
     {
@@ -988,8 +1048,7 @@ char *host_from_dns(struct in_addr addr)
       if (!legal_hostname(hostname))
        return NULL;
       
-      strncpy(daemon->dhcp_buff, hostname, 256);
-      daemon->dhcp_buff[255] = 0;
+      safe_strncpy(daemon->dhcp_buff, hostname, 256);
       strip_hostname(daemon->dhcp_buff);
 
       return daemon->dhcp_buff;
@@ -1001,25 +1060,25 @@ char *host_from_dns(struct in_addr addr)
 static int  relay_upstream4(struct dhcp_relay *relay, struct dhcp_packet *mess, size_t sz, int iface_index)
 {
   /* ->local is same value for all relays on ->current chain */
-  struct all_addr from;
+  union all_addr from;
   
   if (mess->op != BOOTREQUEST)
     return 0;
 
   /* source address == relay address */
-  from.addr.addr4 = relay->local.addr.addr4;
+  from.addr4 = relay->local.addr4;
   
   /* already gatewayed ? */
   if (mess->giaddr.s_addr)
     {
       /* if so check if by us, to stomp on loops. */
-      if (mess->giaddr.s_addr == relay->local.addr.addr4.s_addr)
+      if (mess->giaddr.s_addr == relay->local.addr4.s_addr)
        return 1;
     }
   else
     {
       /* plug in our address */
-      mess->giaddr.s_addr = relay->local.addr.addr4.s_addr;
+      mess->giaddr.s_addr = relay->local.addr4.s_addr;
     }
 
   if ((mess->hops++) > 20)
@@ -1030,7 +1089,7 @@ static int  relay_upstream4(struct dhcp_relay *relay, struct dhcp_packet *mess,
       union mysockaddr to;
       
       to.sa.sa_family = AF_INET;
-      to.in.sin_addr = relay->server.addr.addr4;
+      to.in.sin_addr = relay->server.addr4;
       to.in.sin_port = htons(daemon->dhcp_server_port);
       
       send_from(daemon->dhcpfd, 0, (char *)mess, sz, &to, &from, 0);
@@ -1038,7 +1097,7 @@ static int  relay_upstream4(struct dhcp_relay *relay, struct dhcp_packet *mess,
       if (option_bool(OPT_LOG_OPTS))
        {
          inet_ntop(AF_INET, &relay->local, daemon->addrbuff, ADDRSTRLEN);
-         my_syslog(MS_DHCP | LOG_INFO, _("DHCP relay %s -> %s"), daemon->addrbuff, inet_ntoa(relay->server.addr.addr4));
+         my_syslog(MS_DHCP | LOG_INFO, _("DHCP relay %s -> %s"), daemon->addrbuff, inet_ntoa(relay->server.addr4));
        }
       
       /* Save this for replies */
@@ -1058,7 +1117,7 @@ static struct dhcp_relay *relay_reply4(struct dhcp_packet *mess, char *arrival_i
 
   for (relay = daemon->relay4; relay; relay = relay->next)
     {
-      if (mess->giaddr.s_addr == relay->local.addr.addr4.s_addr)
+      if (mess->giaddr.s_addr == relay->local.addr4.s_addr)
        {
          if (!relay->interface || wildcard_match(relay->interface, arrival_interface))
            return relay->iface_index != 0 ? relay : NULL;
index fee5d28..48b027b 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
 #define OPTION6_REMOTE_ID       37
 #define OPTION6_SUBSCRIBER_ID   38
 #define OPTION6_FQDN            39
+#define OPTION6_NTP_SERVER      56
 #define OPTION6_CLIENT_MAC      79
 
-/* replace this with the real number when allocated.
-   defining this also enables the relevant code. */ 
-/* #define OPTION6_PREFIX_CLASS    99 */
-
+#define NTP_SUBOPTION_SRV_ADDR  1
+#define NTP_SUBOPTION_MC_ADDR   2
+#define NTP_SUBOPTION_SRV_FQDN  3
 
 #define DHCP6SUCCESS     0
 #define DHCP6UNSPEC      1
index 0853664..096e2e1 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -135,7 +135,14 @@ void dhcp6_packet(time_t now)
   if (!indextoname(daemon->dhcp6fd, if_index, ifr.ifr_name))
     return;
 
-  if ((port = relay_reply6(&from, sz, ifr.ifr_name)) == 0)
+  if ((port = relay_reply6(&from, sz, ifr.ifr_name)) != 0)
+    {
+      from.sin6_port = htons(port);
+      while (retry_send(sendto(daemon->dhcp6fd, daemon->outpacket.iov_base, 
+                              save_counter(-1), 0, (struct sockaddr *)&from, 
+                              sizeof(from))));
+    }
+  else
     {
       struct dhcp_bridge *bridge, *alias;
 
@@ -233,21 +240,23 @@ void dhcp6_packet(time_t now)
       port = dhcp6_reply(parm.current, if_index, ifr.ifr_name, &parm.fallback, 
                         &parm.ll_addr, &parm.ula_addr, sz, &from.sin6_addr, now);
       
+      /* The port in the source address of the original request should
+        be correct, but at least once client sends from the server port,
+        so we explicitly send to the client port to a client, and the
+        server port to a relay. */
+      if (port != 0)
+       {
+         from.sin6_port = htons(port);
+         while (retry_send(sendto(daemon->dhcp6fd, daemon->outpacket.iov_base, 
+                                  save_counter(-1), 0, (struct sockaddr *)&from, 
+                                  sizeof(from))));
+       }
+
+      /* These need to be called _after_ we send DHCPv6 packet, since lease_update_file()
+        may trigger sending an RA packet, which overwrites our buffer. */
       lease_update_file(now);
       lease_update_dns(0);
     }
-                         
-  /* The port in the source address of the original request should
-     be correct, but at least once client sends from the server port,
-     so we explicitly send to the client port to a client, and the
-     server port to a relay. */
-  if (port != 0)
-    {
-      from.sin6_port = htons(port);
-      while (retry_send(sendto(daemon->dhcp6fd, daemon->outpacket.iov_base, 
-                              save_counter(0), 0, (struct sockaddr *)&from, 
-                              sizeof(from))));
-    }
 }
 
 void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac, unsigned int *maclenp, unsigned int *mactypep, time_t now)
@@ -299,106 +308,136 @@ static int complete_context6(struct in6_addr *local,  int prefix,
                             unsigned int valid, void *vparam)
 {
   struct dhcp_context *context;
+  struct shared_network *share;
   struct dhcp_relay *relay;
   struct iface_param *param = vparam;
   struct iname *tmp;
  
   (void)scope; /* warning */
   
-  if (if_index == param->ind)
-    {
-      if (IN6_IS_ADDR_LINKLOCAL(local))
-       param->ll_addr = *local;
-      else if (IN6_IS_ADDR_ULA(local))
-       param->ula_addr = *local;
-
-      if (!IN6_IS_ADDR_LOOPBACK(local) &&
-         !IN6_IS_ADDR_LINKLOCAL(local) &&
-         !IN6_IS_ADDR_MULTICAST(local))
-       {
-         /* if we have --listen-address config, see if the 
-            arrival interface has a matching address. */
-         for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
-           if (tmp->addr.sa.sa_family == AF_INET6 &&
-               IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, local))
-             param->addr_match = 1;
-         
-         /* Determine a globally address on the arrival interface, even
-            if we have no matching dhcp-context, because we're only
-            allocating on remote subnets via relays. This
-            is used as a default for the DNS server option. */
-         param->fallback = *local;
-         
-         for (context = daemon->dhcp6; context; context = context->next)
-           {
-             if ((context->flags & CONTEXT_DHCP) &&
-                 !(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
-                 prefix <= context->prefix &&
-                 is_same_net6(local, &context->start6, context->prefix) &&
-                 is_same_net6(local, &context->end6, context->prefix))
-               {
-                 
-                 
-                 /* link it onto the current chain if we've not seen it before */
-                 if (context->current == context)
-                   {
-                     struct dhcp_context *tmp, **up;
-                     
-                     /* use interface values only for constructed contexts */
-                     if (!(context->flags & CONTEXT_CONSTRUCTED))
-                       preferred = valid = 0xffffffff;
-                     else if (flags & IFACE_DEPRECATED)
-                       preferred = 0;
-                     
-                     if (context->flags & CONTEXT_DEPRECATE)
-                       preferred = 0;
-                     
-                     /* order chain, longest preferred time first */
-                     for (up = &param->current, tmp = param->current; tmp; tmp = tmp->current)
-                       if (tmp->preferred <= preferred)
-                         break;
-                       else
-                         up = &tmp->current;
-                     
-                     context->current = *up;
-                     *up = context;
-                     context->local6 = *local;
-                     context->preferred = preferred;
-                     context->valid = valid;
-                   }
-               }
-           }
-       }
-
-      for (relay = daemon->relay6; relay; relay = relay->next)
-       if (IN6_ARE_ADDR_EQUAL(local, &relay->local.addr.addr6) && relay->current == relay &&
-           (IN6_IS_ADDR_UNSPECIFIED(&param->relay_local) || IN6_ARE_ADDR_EQUAL(local, &param->relay_local)))
+  if (if_index != param->ind)
+    return 1;
+  
+  if (IN6_IS_ADDR_LINKLOCAL(local))
+    param->ll_addr = *local;
+  else if (IN6_IS_ADDR_ULA(local))
+    param->ula_addr = *local;
+      
+  if (IN6_IS_ADDR_LOOPBACK(local) ||
+      IN6_IS_ADDR_LINKLOCAL(local) ||
+      IN6_IS_ADDR_MULTICAST(local))
+    return 1;
+  
+  /* if we have --listen-address config, see if the 
+     arrival interface has a matching address. */
+  for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
+    if (tmp->addr.sa.sa_family == AF_INET6 &&
+       IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, local))
+      param->addr_match = 1;
+  
+  /* Determine a globally address on the arrival interface, even
+     if we have no matching dhcp-context, because we're only
+     allocating on remote subnets via relays. This
+     is used as a default for the DNS server option. */
+  param->fallback = *local;
+  
+  for (context = daemon->dhcp6; context; context = context->next)
+    if ((context->flags & CONTEXT_DHCP) &&
+       !(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
+       prefix <= context->prefix &&
+       context->current == context)
+      {
+       if (is_same_net6(local, &context->start6, context->prefix) &&
+           is_same_net6(local, &context->end6, context->prefix))
          {
-           relay->current = param->relay;
-           param->relay = relay;
-           param->relay_local = *local;
+           struct dhcp_context *tmp, **up;
+           
+           /* use interface values only for constructed contexts */
+           if (!(context->flags & CONTEXT_CONSTRUCTED))
+             preferred = valid = 0xffffffff;
+           else if (flags & IFACE_DEPRECATED)
+             preferred = 0;
+                   
+           if (context->flags & CONTEXT_DEPRECATE)
+             preferred = 0;
+           
+           /* order chain, longest preferred time first */
+           for (up = &param->current, tmp = param->current; tmp; tmp = tmp->current)
+             if (tmp->preferred <= preferred)
+               break;
+             else
+               up = &tmp->current;
+           
+           context->current = *up;
+           *up = context;
+           context->local6 = *local;
+           context->preferred = preferred;
+           context->valid = valid;
          }
-      
-    }          
- return 1;
+       else
+         {
+           for (share = daemon->shared_networks; share; share = share->next)
+             {
+               /* IPv4 shared_address - ignore */
+               if (share->shared_addr.s_addr != 0)
+                 continue;
+                       
+               if (share->if_index != 0)
+                 {
+                   if (share->if_index != if_index)
+                     continue;
+                 }
+               else
+                 {
+                   if (!IN6_ARE_ADDR_EQUAL(&share->match_addr6, local))
+                     continue;
+                 }
+               
+               if (is_same_net6(&share->shared_addr6, &context->start6, context->prefix) &&
+                   is_same_net6(&share->shared_addr6, &context->end6, context->prefix))
+                 {
+                   context->current = param->current;
+                   param->current = context;
+                   context->local6 = *local;
+                   context->preferred = context->flags & CONTEXT_DEPRECATE ? 0 :0xffffffff;
+                   context->valid = 0xffffffff;
+                 }
+             }
+         }      
+      }
+
+  for (relay = daemon->relay6; relay; relay = relay->next)
+    if (IN6_ARE_ADDR_EQUAL(local, &relay->local.addr6) && relay->current == relay &&
+       (IN6_IS_ADDR_UNSPECIFIED(&param->relay_local) || IN6_ARE_ADDR_EQUAL(local, &param->relay_local)))
+      {
+       relay->current = param->relay;
+       param->relay = relay;
+       param->relay_local = *local;
+      }
+     
+  return 1;
 }
 
-struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct in6_addr *net, int prefix, u64 addr)
+struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct in6_addr *net, int prefix,  struct in6_addr *addr)
 {
   struct dhcp_config *config;
   
   for (config = configs; config; config = config->next)
-    if ((config->flags & CONFIG_ADDR6) &&
-       is_same_net6(&config->addr6, net, prefix) &&
-       (prefix == 128 || addr6part(&config->addr6) == addr))
-      return config;
+    if (config->flags & CONFIG_ADDR6)
+      {
+       struct addrlist *addr_list;
+       
+       for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
+         if ((!net || is_same_net6(&addr_list->addr.addr6, net, prefix) || ((addr_list->flags & ADDRLIST_WILDCARD) && prefix == 64)) &&
+             is_same_net6(&addr_list->addr.addr6, addr, (addr_list->flags & ADDRLIST_PREFIX) ? addr_list->prefixlen : 128))
+           return config;
+      }
   
   return NULL;
 }
 
 struct dhcp_context *address6_allocate(struct dhcp_context *context,  unsigned char *clid, int clid_len, int temp_addr,
-                                      int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans)   
+                                      unsigned int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans)
 {
   /* Find a free address: exclude anything in use and anything allocated to
      a particular hwaddr/clientid/hostname in our configuration.
@@ -431,8 +470,15 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context,  unsigned c
       else
        { 
          if (!temp_addr && option_bool(OPT_CONSEC_ADDR))
-           /* seed is largest extant lease addr in this context */
-           start = lease_find_max_addr6(c) + serial;
+           {
+             /* seed is largest extant lease addr in this context,
+                skip addresses equal to the number of addresses rejected
+                by clients. This should avoid the same client being offered the same
+                address after it has rjected it. */
+             start = lease_find_max_addr6(c) + 1 + serial + c->addr_epoch;
+             if (c->addr_epoch)
+               c->addr_epoch--;
+           }
          else
            {
              u64 range = 1 + addr6part(&c->end6) - addr6part(&c->start6);
@@ -453,16 +499,15 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context,  unsigned c
            for (d = context; d; d = d->current)
              if (addr == addr6part(&d->local6))
                break;
+           
+           *ans = c->start6;
+           setaddr6part (ans, addr);
 
            if (!d &&
                !lease6_find_by_addr(&c->start6, c->prefix, addr) && 
-               !config_find_by_address6(daemon->dhcp_conf, &c->start6, c->prefix, addr))
-             {
-               *ans = c->start6;
-               setaddr6part (ans, addr);
-               return c;
-             }
-       
+               !config_find_by_address6(daemon->dhcp_conf, &c->start6, c->prefix, ans))
+             return c;
+           
            addr++;
            
            if (addr  == addr6part(&c->end6) + 1)
@@ -516,27 +561,6 @@ struct dhcp_context *address6_valid(struct dhcp_context *context,
   return NULL;
 }
 
-int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr)
-{
-  if (!config || !(config->flags & CONFIG_ADDR6))
-    return 0;
-
-  if ((config->flags & CONFIG_WILDCARD) && context->prefix == 64)
-    {
-      *addr = context->start6;
-      setaddr6part(addr, addr6part(&config->addr6));
-      return 1;
-    }
-  
-  if (is_same_net6(&context->start6, &config->addr6, context->prefix))
-    {
-      *addr = config->addr6;
-      return 1;
-    }
-  
-  return 0;
-}
-
 void make_duid(time_t now)
 {
   (void)now;
@@ -617,7 +641,8 @@ static int construct_worker(struct in6_addr *local, int prefix,
   char ifrn_name[IFNAMSIZ];
   struct in6_addr start6, end6;
   struct dhcp_context *template, *context;
-
+  struct iname *tmp;
+  
   (void)scope;
   (void)flags;
   (void)valid;
@@ -636,17 +661,30 @@ static int construct_worker(struct in6_addr *local, int prefix,
   if (flags & IFACE_DEPRECATED)
     return 1;
 
-  if (!indextoname(daemon->icmp6fd, if_index, ifrn_name))
-    return 0;
+  /* Ignore interfaces where we're not doing RA/DHCP6 */
+  if (!indextoname(daemon->icmp6fd, if_index, ifrn_name) ||
+      !iface_check(AF_LOCAL, NULL, ifrn_name, NULL))
+    return 1;
   
+  for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
+    if (tmp->name && wildcard_match(tmp->name, ifrn_name))
+      return 1;
+
   for (template = daemon->dhcp6; template; template = template->next)
-    if (!(template->flags & CONTEXT_TEMPLATE))
+    if (!(template->flags & (CONTEXT_TEMPLATE | CONTEXT_CONSTRUCTED)))
       {
        /* non-template entries, just fill in interface and local addresses */
        if (prefix <= template->prefix &&
            is_same_net6(local, &template->start6, template->prefix) &&
            is_same_net6(local, &template->end6, template->prefix))
          {
+           /* First time found, do fast RA. */
+           if (template->if_index == 0)
+             {
+               ra_start_unsolicited(param->now, template);
+               param->newone = 1;
+             }
+           
            template->if_index = if_index;
            template->local6 = *local;
          }
@@ -661,24 +699,33 @@ static int construct_worker(struct in6_addr *local, int prefix,
        setaddr6part(&end6, addr6part(&template->end6));
        
        for (context = daemon->dhcp6; context; context = context->next)
-         if ((context->flags & CONTEXT_CONSTRUCTED) &&
+         if (!(context->flags & CONTEXT_TEMPLATE) &&
              IN6_ARE_ADDR_EQUAL(&start6, &context->start6) &&
              IN6_ARE_ADDR_EQUAL(&end6, &context->end6))
            {
-             int flags = context->flags;
-             context->flags &= ~(CONTEXT_GC | CONTEXT_OLD);
-             if (flags & CONTEXT_OLD)
+             /* If there's an absolute address context covering this address
+                then don't construct one as well. */
+             if (!(context->flags & CONTEXT_CONSTRUCTED))
+               break;
+             
+             if (context->if_index == if_index)
                {
-                 /* address went, now it's back */
-                 log_context(AF_INET6, context); 
-                 /* fast RAs for a while */
-                 ra_start_unsolicited(param->now, context);
-                 param->newone = 1; 
-                 /* Add address to name again */
-                 if (context->flags & CONTEXT_RA_NAME)
-                   param->newname = 1;
+                 int cflags = context->flags;
+                 context->flags &= ~(CONTEXT_GC | CONTEXT_OLD);
+                 if (cflags & CONTEXT_OLD)
+                   {
+                     /* address went, now it's back, and on the same interface */
+                     log_context(AF_INET6, context); 
+                     /* fast RAs for a while */
+                     ra_start_unsolicited(param->now, context);
+                     param->newone = 1; 
+                     /* Add address to name again */
+                     if (context->flags & CONTEXT_RA_NAME)
+                       param->newname = 1;
+                   
+                   }
+                 break;
                }
-             break;
            }
        
        if (!context && (context = whine_malloc(sizeof (struct dhcp_context))))
index 4958830..8edb9f3 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -76,6 +76,7 @@
 #define T_AXFR          252
 #define T_MAILB                253     
 #define T_ANY          255
+#define T_CAA           257
 
 #define EDNS0_OPTION_MAC            65001 /* dyndns.org temporary assignment */
 #define EDNS0_OPTION_CLIENT_SUBNET  8     /* IANA */
index ce44809..2306c48 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -52,8 +52,13 @@ int main (int argc, char **argv)
 #if defined(HAVE_LINUX_NETWORK)
   cap_user_header_t hdr = NULL;
   cap_user_data_t data = NULL;
+  int need_cap_net_admin = 0;
+  int need_cap_net_raw = 0;
+  int need_cap_net_bind_service = 0;
   char *bound_device = NULL;
   int did_bind = 0;
+  struct server *serv;
+  char *netlink_warn;
 #endif 
 #if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
   struct dhcp_context *context;
@@ -85,11 +90,15 @@ int main (int argc, char **argv)
   sigaction(SIGPIPE, &sigact, NULL);
 
   umask(022); /* known umask, create leases and pid files as 0644 */
+
   rand_init(); /* Must precede read_opts() */
   
   read_opts(argc, argv, compile_opts);
  
+#ifdef HAVE_LINUX_NETWORK
+  daemon->kernel_version = kernel_version();
+#endif
+
   if (daemon->edns_pktsz < PACKETSZ)
     daemon->edns_pktsz = PACKETSZ;
 
@@ -122,7 +131,7 @@ int main (int argc, char **argv)
       daemon->workspacename = safe_malloc(MAXDNAME * 2);
       /* one char flag per possible RR in answer section (may get extended). */
       daemon->rr_status_sz = 64;
-      daemon->rr_status = safe_malloc(daemon->rr_status_sz);
+      daemon->rr_status = safe_malloc(sizeof(*daemon->rr_status) * daemon->rr_status_sz);
     }
 #endif
 
@@ -134,20 +143,18 @@ int main (int argc, char **argv)
     }
 #endif
   
-  /* Close any file descriptors we inherited apart from std{in|out|err} 
-     
-     Ensure that at least stdin, stdout and stderr (fd 0, 1, 2) exist,
+  /* Ensure that at least stdin, stdout and stderr (fd 0, 1, 2) exist,
      otherwise file descriptors we create can end up being 0, 1, or 2 
      and then get accidentally closed later when we make 0, 1, and 2 
      open to /dev/null. Normally we'll be started with 0, 1 and 2 open, 
      but it's not guaranteed. By opening /dev/null three times, we 
      ensure that we're not using those fds for real stuff. */
-  for (i = 0; i < max_fd; i++)
-    if (i != STDOUT_FILENO && i != STDERR_FILENO && i != STDIN_FILENO)
-      close(i);
-    else
-      open("/dev/null", O_RDWR); 
-
+  for (i = 0; i < 3; i++)
+    open("/dev/null", O_RDWR); 
+  
+  /* Close any file descriptors we inherited apart from std{in|out|err} */
+  close_fds(max_fd, -1, -1, -1);
+  
 #ifndef HAVE_LINUX_NETWORK
 #  if !(defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && defined(IP_SENDSRCADDR))
   if (!option_bool(OPT_NOWILD))
@@ -216,7 +223,7 @@ int main (int argc, char **argv)
 #endif
 
 #ifndef HAVE_AUTH
-  if (daemon->authserver)
+  if (daemon->auth_zones)
     die(_("authoritative DNS not available: set HAVE_AUTH in src/config.h"), NULL, EC_BADCONF);
 #endif
 
@@ -225,18 +232,30 @@ int main (int argc, char **argv)
     die(_("loop detection not available: set HAVE_LOOP in src/config.h"), NULL, EC_BADCONF);
 #endif
 
+#ifndef HAVE_UBUS
+  if (option_bool(OPT_UBUS))
+    die(_("Ubus not available: set HAVE_UBUS in src/config.h"), NULL, EC_BADCONF);
+#endif
+  
   if (daemon->max_port < daemon->min_port)
     die(_("max_port cannot be smaller than min_port"), NULL, EC_BADCONF);
 
   now = dnsmasq_time();
 
-  /* Create a serial at startup if not configured. */
-  if (daemon->authinterface && daemon->soa_sn == 0)
+  if (daemon->auth_zones)
+    {
+      if (!daemon->authserver)
+       die(_("--auth-server required when an auth zone is defined."), NULL, EC_BADCONF);
+
+      /* Create a serial at startup if not configured. */
 #ifdef HAVE_BROKEN_RTC
-    die(_("zone serial must be configured in --auth-soa"), NULL, EC_BADCONF);
+      if (daemon->soa_sn == 0)
+       die(_("zone serial must be configured in --auth-soa"), NULL, EC_BADCONF);
 #else
-  daemon->soa_sn = now;
+      if (daemon->soa_sn == 0)
+       daemon->soa_sn = now;
 #endif
+    }
   
 #ifdef HAVE_DHCP6
   if (daemon->dhcp6)
@@ -273,11 +292,24 @@ int main (int argc, char **argv)
     }
   
   if (daemon->dhcp || daemon->relay4)
-    dhcp_init();
+    {
+      dhcp_init();
+#   ifdef HAVE_LINUX_NETWORK
+      if (!option_bool(OPT_NO_PING))
+       need_cap_net_raw = 1;
+      need_cap_net_admin = 1;
+#   endif
+    }
   
 #  ifdef HAVE_DHCP6
   if (daemon->doing_ra || daemon->doing_dhcp6 || daemon->relay6)
-    ra_init(now);
+    {
+      ra_init(now);
+#   ifdef HAVE_LINUX_NETWORK
+      need_cap_net_raw = 1;
+      need_cap_net_admin = 1;
+#   endif
+    }
   
   if (daemon->doing_dhcp6 || daemon->relay6)
     dhcp6_init();
@@ -287,11 +319,16 @@ int main (int argc, char **argv)
 
 #ifdef HAVE_IPSET
   if (daemon->ipsets)
-    ipset_init();
+    {
+      ipset_init();
+#  ifdef HAVE_LINUX_NETWORK
+      need_cap_net_admin = 1;
+#  endif
+    }
 #endif
 
 #if  defined(HAVE_LINUX_NETWORK)
-  netlink_init();
+  netlink_warn = netlink_init();
 #elif defined(HAVE_BSD_NETWORK)
   route_init();
 #endif
@@ -354,9 +391,7 @@ int main (int argc, char **argv)
     {
       cache_init();
 
-#ifdef HAVE_DNSSEC
       blockdata_init();
-#endif
     }
 
 #ifdef HAVE_INOTIFY
@@ -366,7 +401,16 @@ int main (int argc, char **argv)
   else
     daemon->inotifyfd = -1;
 #endif
-       
+
+  if (daemon->dump_file)
+#ifdef HAVE_DUMPFILE
+    dump_init();
+  else 
+    daemon->dumpfd = -1;
+#else
+  die(_("Packet dumps not available: set HAVE_DUMP in src/config.h"), NULL, EC_BADCONF);
+#endif
+  
   if (option_bool(OPT_DBUS))
 #ifdef HAVE_DBUS
     {
@@ -380,6 +424,16 @@ int main (int argc, char **argv)
   die(_("DBus not available: set HAVE_DBUS in src/config.h"), NULL, EC_BADCONF);
 #endif
 
+  if (option_bool(OPT_UBUS))
+#ifdef HAVE_UBUS
+    {
+      daemon->ubus = NULL;
+      ubus_init();
+    }
+#else
+  die(_("UBus not available: set HAVE_UBUS in src/config.h"), NULL, EC_BADCONF);
+#endif
+
   if (daemon->port != 0)
     pre_allocate_sfds();
 
@@ -421,28 +475,81 @@ int main (int argc, char **argv)
     }
 
 #if defined(HAVE_LINUX_NETWORK)
+  /* We keep CAP_NETADMIN (for ARP-injection) and
+     CAP_NET_RAW (for icmp) if we're doing dhcp,
+     if we have yet to bind ports because of DAD, 
+     or we're doing it dynamically, we need CAP_NET_BIND_SERVICE. */
+  if ((is_dad_listeners() || option_bool(OPT_CLEVERBIND)) &&
+      (option_bool(OPT_TFTP) || (daemon->port != 0 && daemon->port <= 1024)))
+    need_cap_net_bind_service = 1;
+
+  /* usptream servers which bind to an interface call SO_BINDTODEVICE
+     for each TCP connection, so need CAP_NET_RAW */
+  for (serv = daemon->servers; serv; serv = serv->next)
+    if (serv->interface[0] != 0)
+      need_cap_net_raw = 1;
+
+  /* If we're doing Dbus or UBus, the above can be set dynamically,
+     (as can ports) so always (potentially) needed. */
+#ifdef HAVE_DBUS
+  if (option_bool(OPT_DBUS))
+    {
+      need_cap_net_bind_service = 1;
+      need_cap_net_raw = 1;
+    }
+#endif
+
+#ifdef HAVE_UBUS
+  if (option_bool(OPT_UBUS))
+    {
+      need_cap_net_bind_service = 1;
+      need_cap_net_raw = 1;
+    }
+#endif
+  
   /* determine capability API version here, while we can still
      call safe_malloc */
-  if (ent_pw && ent_pw->pw_uid != 0)
+  int capsize = 1; /* for header version 1 */
+  char *fail = NULL;
+  
+  hdr = safe_malloc(sizeof(*hdr));
+  
+  /* find version supported by kernel */
+  memset(hdr, 0, sizeof(*hdr));
+  capget(hdr, NULL);
+  
+  if (hdr->version != LINUX_CAPABILITY_VERSION_1)
     {
-      int capsize = 1; /* for header version 1 */
-      hdr = safe_malloc(sizeof(*hdr));
-
-      /* find version supported by kernel */
-      memset(hdr, 0, sizeof(*hdr));
-      capget(hdr, NULL);
-      
-      if (hdr->version != LINUX_CAPABILITY_VERSION_1)
-       {
-         /* if unknown version, use largest supported version (3) */
-         if (hdr->version != LINUX_CAPABILITY_VERSION_2)
-           hdr->version = LINUX_CAPABILITY_VERSION_3;
-         capsize = 2;
-       }
-      
-      data = safe_malloc(sizeof(*data) * capsize);
-      memset(data, 0, sizeof(*data) * capsize);
+      /* if unknown version, use largest supported version (3) */
+      if (hdr->version != LINUX_CAPABILITY_VERSION_2)
+       hdr->version = LINUX_CAPABILITY_VERSION_3;
+      capsize = 2;
     }
+  
+  data = safe_malloc(sizeof(*data) * capsize);
+  capget(hdr, data); /* Get current values, for verification */
+
+  if (need_cap_net_admin && !(data->permitted & (1 << CAP_NET_ADMIN)))
+    fail = "NET_ADMIN";
+  else if (need_cap_net_raw && !(data->permitted & (1 << CAP_NET_RAW)))
+    fail = "NET_RAW";
+  else if (need_cap_net_bind_service && !(data->permitted & (1 << CAP_NET_BIND_SERVICE)))
+    fail = "NET_BIND_SERVICE";
+  
+  if (fail)
+    die(_("process is missing required capability %s"), fail, EC_MISC);
+
+  /* Now set bitmaps to set caps after daemonising */
+  memset(data, 0, sizeof(*data) * capsize);
+  
+  if (need_cap_net_admin)
+    data->effective |= (1 << CAP_NET_ADMIN);
+  if (need_cap_net_raw)
+    data->effective |= (1 << CAP_NET_RAW);
+  if (need_cap_net_bind_service)
+    data->effective |= (1 << CAP_NET_BIND_SERVICE);
+  
+  data->permitted = data->effective;  
 #endif
 
   /* Use a pipe to carry signals and other events back to the event loop 
@@ -464,7 +571,6 @@ int main (int argc, char **argv)
       if (chdir("/") != 0)
        die(_("cannot chdir to filesystem root: %s"), NULL, EC_MISC); 
 
-#ifndef NO_FORK      
       if (!option_bool(OPT_NO_FORK))
        {
          pid_t pid;
@@ -483,7 +589,7 @@ int main (int argc, char **argv)
              char *msg;
 
              /* close our copy of write-end */
-             while (retry_send(close(err_pipe[1])));
+             close(err_pipe[1]);
              
              /* check for errors after the fork */
              if (read_event(err_pipe[0], &ev, &msg))
@@ -492,7 +598,7 @@ int main (int argc, char **argv)
              _exit(EC_GOOD);
            } 
          
-         while (retry_send(close(err_pipe[0])));
+         close(err_pipe[0]);
 
          /* NO calls to die() from here on. */
          
@@ -504,7 +610,6 @@ int main (int argc, char **argv)
          if (pid != 0)
            _exit(0);
        }
-#endif
             
       /* write pidfile _after_ forking ! */
       if (daemon->runfile)
@@ -555,8 +660,7 @@ int main (int argc, char **argv)
                err = 1;
              else
                {
-                 while (retry_send(close(fd)));
-                 if (errno != 0)
+                 if (close(fd) == -1)
                    err = 1;
                }
            }
@@ -609,18 +713,9 @@ int main (int argc, char **argv)
       if (ent_pw && ent_pw->pw_uid != 0)
        {     
 #if defined(HAVE_LINUX_NETWORK)          
-         /* On linux, we keep CAP_NETADMIN (for ARP-injection) and
-            CAP_NET_RAW (for icmp) if we're doing dhcp. If we have yet to bind 
-            ports because of DAD, or we're doing it dynamically,
-            we need CAP_NET_BIND_SERVICE too. */
-         if (is_dad_listeners() || option_bool(OPT_CLEVERBIND))
-           data->effective = data->permitted = data->inheritable =
-             (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) | 
-             (1 << CAP_SETUID) | (1 << CAP_NET_BIND_SERVICE);
-         else
-           data->effective = data->permitted = data->inheritable =
-             (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) | (1 << CAP_SETUID);
-         
+         /* Need to be able to drop root. */
+         data->effective |= (1 << CAP_SETUID);
+         data->permitted |= (1 << CAP_SETUID);
          /* Tell kernel to not clear capabilities when dropping root */
          if (capset(hdr, data) == -1 || prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1)
            bad_capabilities = errno;
@@ -661,15 +756,10 @@ int main (int argc, char **argv)
            }     
 
 #ifdef HAVE_LINUX_NETWORK
-         if (is_dad_listeners() || option_bool(OPT_CLEVERBIND))
-          data->effective = data->permitted =
-            (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) | (1 << CAP_NET_BIND_SERVICE);
-        else
-          data->effective = data->permitted = 
-            (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
-         data->inheritable = 0;
+         data->effective &= ~(1 << CAP_SETUID);
+         data->permitted &= ~(1 << CAP_SETUID);
          
-         /* lose the setuid and setgid capabilities */
+         /* lose the setuid capability */
          if (capset(hdr, data) == -1)
            {
              send_event(err_pipe[1], EVENT_CAP_ERR, errno, NULL);
@@ -731,7 +821,11 @@ int main (int argc, char **argv)
   else 
     {
       if (daemon->cachesize != 0)
-       my_syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize);
+       {
+         my_syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize);
+         if (daemon->cachesize > 10000)
+           my_syslog(LOG_WARNING, _("cache size greater than 10000 may cause performance issues, and is unlikely to be useful."));
+       }
       else
        my_syslog(LOG_INFO, _("started, version %s cache disabled"), VERSION);
 
@@ -754,11 +848,22 @@ int main (int argc, char **argv)
     }
 #endif
 
+#ifdef HAVE_UBUS
+  if (option_bool(OPT_UBUS))
+    {
+      if (daemon->ubus)
+        my_syslog(LOG_INFO, _("UBus support enabled: connected to system bus"));
+      else
+        my_syslog(LOG_INFO, _("UBus support enabled: bus connection pending"));
+    }
+#endif
+
 #ifdef HAVE_DNSSEC
   if (option_bool(OPT_DNSSEC_VALID))
     {
       int rc;
-
+      struct ds_config *ds;
+      
       /* Delay creating the timestamp file until here, after we've changed user, so that
         it has the correct owner to allow updating the mtime later. 
         This means we have to report fatal errors via the pipe. */
@@ -768,7 +873,10 @@ int main (int argc, char **argv)
          _exit(0);
        }
       
-      my_syslog(LOG_INFO, _("DNSSEC validation enabled"));
+      if (option_bool(OPT_DNSSEC_IGN_NS))
+       my_syslog(LOG_INFO, _("DNSSEC validation enabled but all unsigned answers are trusted"));
+      else
+       my_syslog(LOG_INFO, _("DNSSEC validation enabled"));
       
       daemon->dnssec_no_time_check = option_bool(OPT_DNSSEC_TIME);
       if (option_bool(OPT_DNSSEC_TIME) && !daemon->back_to_the_future)
@@ -776,6 +884,10 @@ int main (int argc, char **argv)
       
       if (rc == 1)
        my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until system time valid"));
+
+      for (ds = daemon->ds; ds; ds = ds->next)
+       my_syslog(LOG_INFO, _("configured with trust anchor for %s keytag %u"),
+                 ds->name[0] == 0 ? "<root>" : ds->name, ds->keytag);
     }
 #endif
 
@@ -835,6 +947,9 @@ int main (int argc, char **argv)
 #  ifdef HAVE_LINUX_NETWORK
   if (did_bind)
     my_syslog(MS_DHCP | LOG_INFO, _("DHCP, sockets bound exclusively to interface %s"), bound_device);
+
+  if (netlink_warn)
+    my_syslog(LOG_WARNING, netlink_warn);
 #  endif
 
   /* after dhcp_construct_contexts */
@@ -847,10 +962,11 @@ int main (int argc, char **argv)
     {
       struct tftp_prefix *p;
 
-      my_syslog(MS_TFTP | LOG_INFO, "TFTP %s%s %s", 
+      my_syslog(MS_TFTP | LOG_INFO, "TFTP %s%s %s %s", 
                daemon->tftp_prefix ? _("root is ") : _("enabled"),
-               daemon->tftp_prefix ? daemon->tftp_prefix: "",
-               option_bool(OPT_TFTP_SECURE) ? _("secure mode") : "");
+               daemon->tftp_prefix ? daemon->tftp_prefix : "",
+               option_bool(OPT_TFTP_SECURE) ? _("secure mode") : "",
+               option_bool(OPT_SINGLE_PORT) ? _("single port mode") : "");
 
       if (tftp_prefix_missing)
        my_syslog(MS_TFTP | LOG_WARNING, _("warning: %s inaccessible"), daemon->tftp_prefix);
@@ -868,7 +984,7 @@ int main (int argc, char **argv)
       
       if (max_fd < 0)
        max_fd = 5;
-      else if (max_fd < 100)
+      else if (max_fd < 100 && !option_bool(OPT_SINGLE_PORT))
        max_fd = max_fd/2;
       else
        max_fd = max_fd - 20;
@@ -891,12 +1007,16 @@ int main (int argc, char **argv)
 
   /* finished start-up - release original process */
   if (err_pipe[1] != -1)
-    while (retry_send(close(err_pipe[1])));
+    close(err_pipe[1]);
   
   if (daemon->port != 0)
     check_servers();
   
   pid = getpid();
+
+  daemon->pipe_to_parent = -1;
+  for (i = 0; i < MAX_PROCS; i++)
+    daemon->tcp_pipes[i] = -1;
   
 #ifdef HAVE_INOTIFY
   /* Using inotify, have to select a resolv file at startup */
@@ -926,8 +1046,13 @@ int main (int argc, char **argv)
 
 #ifdef HAVE_DBUS
       set_dbus_listeners();
-#endif 
-  
+#endif
+
+#ifdef HAVE_UBUS
+      if (option_bool(OPT_UBUS))
+        set_ubus_listeners();
+#endif
+         
 #ifdef HAVE_DHCP
       if (daemon->dhcp || daemon->relay4)
        {
@@ -989,7 +1114,7 @@ int main (int argc, char **argv)
 #endif
 
    
-      /* must do this just before select(), when we know no
+      /* must do this just before do_poll(), when we know no
         more calls to my_syslog() can occur */
       set_log_writer();
       
@@ -1057,7 +1182,20 @@ int main (int argc, char **argv)
        }
       check_dbus_listeners();
 #endif
-      
+
+#ifdef HAVE_UBUS
+      if (option_bool(OPT_UBUS))
+        {
+          /* if we didn't create a UBus connection, retry now. */
+          if (!daemon->ubus)
+            {
+              ubus_init();
+            }
+
+          check_ubus_listeners();
+        }
+#endif
+
       check_dns_listeners(now);
 
 #ifdef HAVE_TFTP
@@ -1403,7 +1541,7 @@ static void async_event(int pipe, time_t now)
            do {
              helper_write();
            } while (!helper_buf_empty() || do_script_run(now));
-           while (retry_send(close(daemon->helperfd)));
+           close(daemon->helperfd);
          }
 #endif
        
@@ -1421,6 +1559,11 @@ static void async_event(int pipe, time_t now)
 
        if (daemon->runfile)
          unlink(daemon->runfile);
+
+#ifdef HAVE_DUMPFILE
+       if (daemon->dumpfd != -1)
+         close(daemon->dumpfd);
+#endif
        
        my_syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
        flush_log();
@@ -1534,16 +1677,17 @@ static int set_dns_listeners(time_t now)
 #ifdef HAVE_TFTP
   int  tftp = 0;
   struct tftp_transfer *transfer;
-  for (transfer = daemon->tftp_trans; transfer; transfer = transfer->next)
-    {
-      tftp++;
-      poll_listen(transfer->sockfd, POLLIN);
-    }
+  if (!option_bool(OPT_SINGLE_PORT))
+    for (transfer = daemon->tftp_trans; transfer; transfer = transfer->next)
+      {
+       tftp++;
+       poll_listen(transfer->sockfd, POLLIN);
+      }
 #endif
   
   /* will we be able to get memory? */
   if (daemon->port != 0)
-    get_new_frec(now, &wait, 0);
+    get_new_frec(now, &wait, NULL);
   
   for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
     poll_listen(serverfdp->fd, POLLIN);
@@ -1563,19 +1707,25 @@ static int set_dns_listeners(time_t now)
         we don't need to explicitly arrange to wake up here */
       if  (listener->tcpfd != -1)
        for (i = 0; i < MAX_PROCS; i++)
-         if (daemon->tcp_pids[i] == 0)
+         if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
            {
              poll_listen(listener->tcpfd, POLLIN);
              break;
            }
 
 #ifdef HAVE_TFTP
+      /* tftp == 0 in single-port mode. */
       if (tftp <= daemon->tftp_max && listener->tftpfd != -1)
        poll_listen(listener->tftpfd, POLLIN);
 #endif
 
     }
   
+  if (!option_bool(OPT_DEBUG))
+    for (i = 0; i < MAX_PROCS; i++)
+      if (daemon->tcp_pipes[i] != -1)
+       poll_listen(daemon->tcp_pipes[i], POLLIN);
+  
   return wait;
 }
 
@@ -1584,7 +1734,8 @@ static void check_dns_listeners(time_t now)
   struct serverfd *serverfdp;
   struct listener *listener;
   int i;
-
+  int pipefd[2];
+  
   for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
     if (poll_check(serverfdp->fd, POLLIN))
       reply_query(serverfdp->fd, serverfdp->source_addr.sa.sa_family, now);
@@ -1594,7 +1745,24 @@ static void check_dns_listeners(time_t now)
       if (daemon->randomsocks[i].refcount != 0 && 
          poll_check(daemon->randomsocks[i].fd, POLLIN))
        reply_query(daemon->randomsocks[i].fd, daemon->randomsocks[i].family, now);
-  
+
+  /* Races. The child process can die before we read all of the data from the
+     pipe, or vice versa. Therefore send tcp_pids to zero when we wait() the 
+     process, and tcp_pipes to -1 and close the FD when we read the last
+     of the data - indicated by cache_recv_insert returning zero.
+     The order of these events is indeterminate, and both are needed
+     to free the process slot. Once the child process has gone, poll()
+     returns POLLHUP, not POLLIN, so have to check for both here. */
+  if (!option_bool(OPT_DEBUG))
+    for (i = 0; i < MAX_PROCS; i++)
+      if (daemon->tcp_pipes[i] != -1 &&
+         poll_check(daemon->tcp_pipes[i], POLLIN | POLLHUP) &&
+         !cache_recv_insert(now, daemon->tcp_pipes[i]))
+       {
+         close(daemon->tcp_pipes[i]);
+         daemon->tcp_pipes[i] = -1;    
+       }
+       
   for (listener = daemon->listeners; listener; listener = listener->next)
     {
       if (listener->fd != -1 && poll_check(listener->fd, POLLIN))
@@ -1620,7 +1788,7 @@ static void check_dns_listeners(time_t now)
          
          if (getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) == -1)
            {
-             while (retry_send(close(confd)));
+             close(confd);
              continue;
            }
          
@@ -1648,15 +1816,16 @@ static void check_dns_listeners(time_t now)
              if ((if_index = tcp_interface(confd, tcp_addr.sa.sa_family)) != 0 &&
                  indextoname(listener->tcpfd, if_index, intr_name))
                {
-                 struct all_addr addr;
-                 addr.addr.addr4 = tcp_addr.in.sin_addr;
-#ifdef HAVE_IPV6
+                 union all_addr addr;
+                 
                  if (tcp_addr.sa.sa_family == AF_INET6)
-                   addr.addr.addr6 = tcp_addr.in6.sin6_addr;
-#endif
+                   addr.addr6 = tcp_addr.in6.sin6_addr;
+                 else
+                   addr.addr4 = tcp_addr.in.sin_addr;
                  
                  for (iface = daemon->interfaces; iface; iface = iface->next)
-                   if (iface->index == if_index)
+                   if (iface->index == if_index &&
+                       iface->addr.sa.sa_family == tcp_addr.sa.sa_family)
                      break;
                  
                  if (!iface && !loopback_exception(listener->tcpfd, tcp_addr.sa.sa_family, &addr, intr_name))
@@ -1685,27 +1854,48 @@ static void check_dns_listeners(time_t now)
          if (!client_ok)
            {
              shutdown(confd, SHUT_RDWR);
-             while (retry_send(close(confd)));
+             close(confd);
            }
-#ifndef NO_FORK
-         else if (!option_bool(OPT_DEBUG) && (p = fork()) != 0)
+         else if (!option_bool(OPT_DEBUG) && pipe(pipefd) == 0 && (p = fork()) != 0)
            {
-             if (p != -1)
+             close(pipefd[1]); /* parent needs read pipe end. */
+             if (p == -1)
+               close(pipefd[0]);
+             else
                {
                  int i;
+#ifdef HAVE_LINUX_NETWORK
+                 /* The child process inherits the netlink socket, 
+                    which it never uses, but when the parent (us) 
+                    uses it in the future, the answer may go to the 
+                    child, resulting in the parent blocking
+                    forever awaiting the result. To avoid this
+                    the child closes the netlink socket, but there's
+                    a nasty race, since the parent may use netlink
+                    before the child has done the close.
+                    
+                    To avoid this, the parent blocks here until a 
+                    single byte comes back up the pipe, which
+                    is sent by the child after it has closed the
+                    netlink socket. */
+                 
+                 unsigned char a;
+                 read_write(pipefd[0], &a, 1, 1);
+#endif
+
                  for (i = 0; i < MAX_PROCS; i++)
-                   if (daemon->tcp_pids[i] == 0)
+                   if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
                      {
                        daemon->tcp_pids[i] = p;
+                       daemon->tcp_pipes[i] = pipefd[0];
                        break;
                      }
                }
-             while (retry_send(close(confd)));
+             close(confd);
 
              /* The child can use up to TCP_MAX_QUERIES ids, so skip that many. */
              daemon->log_id += TCP_MAX_QUERIES;
            }
-#endif
          else
            {
              unsigned char *buff;
@@ -1713,7 +1903,7 @@ static void check_dns_listeners(time_t now)
              int flags;
              struct in_addr netmask;
              int auth_dns;
-
+          
              if (iface)
                {
                  netmask = iface->netmask;
@@ -1725,12 +1915,21 @@ static void check_dns_listeners(time_t now)
                  auth_dns = 0;
                }
 
-#ifndef NO_FORK
              /* Arrange for SIGALRM after CHILD_LIFETIME seconds to
                 terminate the process. */
              if (!option_bool(OPT_DEBUG))
-               alarm(CHILD_LIFETIME);
-#endif
+               {
+#ifdef HAVE_LINUX_NETWORK
+                 /* See comment above re: netlink socket. */
+                 unsigned char a = 0;
+
+                 close(daemon->netlinkfd);
+                 read_write(pipefd[1], &a, 1, 0);
+#endif           
+                 alarm(CHILD_LIFETIME);
+                 close(pipefd[0]); /* close read end in child. */
+                 daemon->pipe_to_parent = pipefd[1];
+               }
 
              /* start with no upstream connections. */
              for (s = daemon->servers; s; s = s->next)
@@ -1745,7 +1944,7 @@ static void check_dns_listeners(time_t now)
              buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);
               
              shutdown(confd, SHUT_RDWR);
-             while (retry_send(close(confd)));
+             close(confd);
              
              if (buff)
                free(buff);
@@ -1754,15 +1953,15 @@ static void check_dns_listeners(time_t now)
                if (s->tcpfd != -1)
                  {
                    shutdown(s->tcpfd, SHUT_RDWR);
-                   while (retry_send(close(s->tcpfd)));
+                   close(s->tcpfd);
                  }
-#ifndef NO_FORK                   
+             
              if (!option_bool(OPT_DEBUG))
                {
+                 close(daemon->pipe_to_parent);
                  flush_log();
                  _exit(0);
                }
-#endif
            }
        }
     }
@@ -1832,7 +2031,7 @@ int icmp_ping(struct in_addr addr)
   gotreply = delay_dhcp(dnsmasq_time(), PING_WAIT, fd, addr.s_addr, id);
 
 #if defined(HAVE_LINUX_NETWORK) || defined(HAVE_SOLARIS_NETWORK)
-  while (retry_send(close(fd)));
+  close(fd);
 #else
   opt = 1;
   setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
@@ -1919,6 +2118,4 @@ int delay_dhcp(time_t start, int sec, int fd, uint32_t addr, unsigned short id)
 
   return 0;
 }
-#endif
-
+#endif /* HAVE_DHCP */
index 6773b69..4220798 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
  
    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
@@ -14,7 +14,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#define COPYRIGHT "Copyright (c) 2000-2018 Simon Kelley"
+#define COPYRIGHT "Copyright (c) 2000-2020 Simon Kelley"
 
 /* We do defines that influence behavior of stdio.h, so complain
    if included too early. */
 #  define __EXTENSIONS__
 #endif
 
+#if (defined(__GNUC__) && __GNUC__ >= 3) || defined(__clang__)
+#define ATTRIBUTE_NORETURN __attribute__ ((noreturn))
+#else
+#define ATTRIBUTE_NORETURN
+#endif
+
 /* get these before config.h  for IPv6 stuff... */
 #include <sys/types.h> 
 #include <sys/socket.h>
@@ -57,6 +63,7 @@
 
 #include "config.h"
 #include "ip6addr.h"
+#include "metrics.h"
 
 typedef unsigned char u8;
 typedef unsigned short u16;
@@ -88,7 +95,11 @@ typedef unsigned long long u64;
 #if defined(HAVE_SOLARIS_NETWORK)
 #  include <sys/sockio.h>
 #endif
-#include <sys/poll.h>
+#if defined(HAVE_POLL_H)
+#  include <poll.h>
+#else
+#  include <sys/poll.h>
+#endif
 #include <sys/wait.h>
 #include <sys/time.h>
 #include <sys/un.h>
@@ -119,7 +130,9 @@ typedef unsigned long long u64;
 #include <net/if_arp.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
+#include <netinet/ip6.h>
 #include <netinet/ip_icmp.h>
+#include <netinet/tcp.h>
 #include <sys/uio.h>
 #include <syslog.h>
 #include <dirent.h>
@@ -128,6 +141,8 @@ typedef unsigned long long u64;
 #endif
 
 #if defined(HAVE_LINUX_NETWORK)
+#include <linux/version.h>
+#include <linux/sockios.h>
 #include <linux/capability.h>
 /* There doesn't seem to be a universally-available 
    userspace header for these. */
@@ -149,6 +164,8 @@ extern int capget(cap_user_header_t header, cap_user_data_t data);
 /* daemon is function in the C library.... */
 #define daemon dnsmasq_daemon
 
+#define ADDRSTRLEN INET6_ADDRSTRLEN
+
 /* Async event queue */
 struct event_desc {
   int event, data, msg_sz;
@@ -190,9 +207,6 @@ struct event_desc {
 #define EC_MISC        5
 #define EC_INIT_OFFSET 10
 
-/* Trust the compiler dead-code eliminator.... */
-#define option_bool(x) (((x) < 32) ? daemon->options & (1u << (x)) : daemon->options2 & (1u << ((x) - 32)))
-
 #define OPT_BOGUSPRIV      0
 #define OPT_FILTER         1
 #define OPT_LOG            2
@@ -241,7 +255,7 @@ struct event_desc {
 #define OPT_DNSSEC_VALID   45
 #define OPT_DNSSEC_TIME    46
 #define OPT_DNSSEC_DEBUG   47
-#define OPT_DNSSEC_NO_SIGN 48 
+#define OPT_DNSSEC_IGN_NS  48 
 #define OPT_LOCAL_SERVICE  49
 #define OPT_LOOP_DETECT    50
 #define OPT_EXTRALOG       51
@@ -250,7 +264,18 @@ struct event_desc {
 #define OPT_MAC_B64        54
 #define OPT_MAC_HEX        55
 #define OPT_TFTP_APREF_MAC 56
-#define OPT_LAST           57
+#define OPT_RAPID_COMMIT   57
+#define OPT_UBUS           58
+#define OPT_IGNORE_CLID    59
+#define OPT_SINGLE_PORT    60
+#define OPT_LEASE_RENEW    61
+#define OPT_LAST           62
+
+#define OPTION_BITS (sizeof(unsigned int)*8)
+#define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) )
+#define option_var(x) (daemon->options[(x) / OPTION_BITS])
+#define option_val(x) ((1u) << ((x) % OPTION_BITS))
+#define option_bool(x) (option_var(x) & option_val(x))
 
 /* extra flags for my_syslog, we use a couple of facilities since they are known 
    not to occupy the same bits as priorities, no matter how syslog.h is set up. */
@@ -258,23 +283,44 @@ struct event_desc {
 #define MS_DHCP   LOG_DAEMON
 #define MS_SCRIPT LOG_MAIL
 
-struct all_addr {
-  union {
-    struct in_addr addr4;
-#ifdef HAVE_IPV6
-    struct in6_addr addr6;
-#endif
-    /* for log_query */
-    struct {
-      unsigned short keytag, algo, digest;
-    } log; 
-    /* for cache_insert of DNSKEY, DS */
-    struct {
-      unsigned short class, type;
-    } dnssec;      
-  } addr;
+/* Note that this is used widely as a container for IPv4/IPv6 addresses,
+   so for that reason, was well as to avoid wasting memory in almost every
+   cache entry, the other variants should not be larger than
+   sizeof(struct in6_addr) - 16 bytes.
+*/
+union all_addr {
+  struct in_addr addr4;
+  struct in6_addr addr6;
+  struct {
+    union {
+      struct crec *cache;
+      char *name;
+    } target;
+    unsigned int uid;
+    int is_name_ptr;  /* disciminates target union */
+  } cname;
+  struct {
+    struct blockdata *keydata;
+    unsigned short keylen, flags, keytag;
+    unsigned char algo;
+  } key; 
+  struct {
+    struct blockdata *keydata;
+    unsigned short keylen, keytag;
+    unsigned char algo;
+    unsigned char digest; 
+  } ds;
+  struct {
+    struct blockdata *target;
+    unsigned short targetlen, srvport, priority, weight;
+  } srv;
+  /* for log_query */
+  struct {
+    unsigned short keytag, algo, digest, rcode;
+  } log;
 };
 
+
 struct bogus_addr {
   struct in_addr addr;
   struct bogus_addr *next;
@@ -334,13 +380,17 @@ struct ds_config {
   struct ds_config *next;
 };
 
-#define ADDRLIST_LITERAL 1
-#define ADDRLIST_IPV6    2
-#define ADDRLIST_REVONLY 4
+#define ADDRLIST_LITERAL  1
+#define ADDRLIST_IPV6     2
+#define ADDRLIST_REVONLY  4
+#define ADDRLIST_PREFIX   8
+#define ADDRLIST_WILDCARD 16
+#define ADDRLIST_DECLINED 32
 
 struct addrlist {
-  struct all_addr addr;
-  int flags, prefixlen; 
+  union all_addr addr;
+  int flags, prefixlen;
+  time_t decline_time;
   struct addrlist *next;
 };
 
@@ -359,17 +409,17 @@ struct auth_zone {
   struct auth_zone *next;
 };
 
+#define HR_6 1
+#define HR_4 2
 
 struct host_record {
-  int ttl;
+  int ttl, flags;
   struct name_list {
     char *name;
     struct name_list *next;
   } *names;
   struct in_addr addr;
-#ifdef HAVE_IPV6
   struct in6_addr addr6;
-#endif
   struct host_record *next;
 };
 
@@ -393,32 +443,11 @@ struct blockdata {
 
 struct crec { 
   struct crec *next, *prev, *hash_next;
-  /* union is 16 bytes when doing IPv6, 8 bytes on 32 bit machines without IPv6 */
-  union {
-    struct all_addr addr;
-    struct {
-      union {
-       struct crec *cache;
-       struct interface_name *int_name;
-      } target;
-      unsigned int uid; /* 0 if union is interface-name */
-    } cname;
-    struct {
-      struct blockdata *keydata;
-      unsigned short keylen, flags, keytag;
-      unsigned char algo;
-    } key; 
-    struct {
-      struct blockdata *keydata;
-      unsigned short keylen, keytag;
-      unsigned char algo;
-      unsigned char digest; 
-    } ds; 
-  } addr;
+  union all_addr addr;
   time_t ttd; /* time to die */
   /* used as class if DNSKEY/DS, index to source for F_HOSTS */
   unsigned int uid; 
-  unsigned short flags;
+  unsigned int flags;
   union {
     char sname[SMALLDNAME];
     union bigname *bname;
@@ -426,6 +455,9 @@ struct crec {
   } name;
 };
 
+#define SIZEOF_BARE_CREC (sizeof(struct crec) - SMALLDNAME)
+#define SIZEOF_POINTER_CREC (sizeof(struct crec) + sizeof(char *) - SMALLDNAME)
+
 #define F_IMMORTAL  (1u<<0)
 #define F_NAMEP     (1u<<1)
 #define F_REVERSE   (1u<<2)
@@ -442,9 +474,6 @@ struct crec {
 #define F_CONFIG    (1u<<13)
 #define F_DS        (1u<<14)
 #define F_DNSSECOK  (1u<<15)
-
-/* below here are only valid as args to log_query: cache
-   entries are limited to 16 bits */
 #define F_UPSTREAM  (1u<<16)
 #define F_RRNAME    (1u<<17)
 #define F_SERVER    (1u<<18)
@@ -457,10 +486,12 @@ struct crec {
 #define F_NO_RR     (1u<<25)
 #define F_IPSET     (1u<<26)
 #define F_NOEXTRA   (1u<<27)
-#define F_SERVFAIL  (1u<<28)
+#define F_SERVFAIL  (1u<<28) /* currently unused. */
+#define F_RCODE     (1u<<29)
+#define F_SRV       (1u<<30)
 
+#define UID_NONE      0
 /* Values of uid in crecs with F_CONFIG bit set. */
-#define SRC_INTERFACE 0
 #define SRC_CONFIG    1
 #define SRC_HOSTS     2
 #define SRC_AH        3
@@ -472,9 +503,7 @@ struct crec {
 union mysockaddr {
   struct sockaddr sa;
   struct sockaddr_in in;
-#if defined(HAVE_IPV6)
   struct sockaddr_in6 in6;
-#endif
 };
 
 /* bits in flag param to IPv6 callbacks from iface_enumerate() */
@@ -505,7 +534,7 @@ struct serverfd {
   int fd;
   union mysockaddr source_addr;
   char interface[IF_NAMESIZE+1];
-  unsigned int ifindex, used;
+  unsigned int ifindex, used, preallocated;
   struct serverfd *next;
 };
 
@@ -543,7 +572,8 @@ struct irec {
 };
 
 struct listener {
-  int fd, tcpfd, tftpfd, family;
+  int fd, tcpfd, tftpfd, used;
+  union mysockaddr addr;
   struct irec *iface; /* only sometimes valid for non-wildcard */
   struct listener *next;
 };
@@ -592,6 +622,16 @@ struct hostsfile {
   unsigned int index; /* matches to cache entries for logging */
 };
 
+/* packet-dump flags */
+#define DUMP_QUERY     0x0001
+#define DUMP_REPLY     0x0002
+#define DUMP_UP_QUERY  0x0004
+#define DUMP_UP_REPLY  0x0008
+#define DUMP_SEC_QUERY 0x0010
+#define DUMP_SEC_REPLY 0x0020
+#define DUMP_BOGUS     0x0040
+#define DUMP_SEC_BOGUS 0x0080
+
 
 /* DNSSEC status values. */
 #define STAT_SECURE             1
@@ -623,12 +663,10 @@ struct hostsfile {
 
 struct frec {
   union mysockaddr source;
-  struct all_addr dest;
+  union all_addr dest;
   struct server *sentto; /* NULL means free */
   struct randfd *rfd4;
-#ifdef HAVE_IPV6
   struct randfd *rfd6;
-#endif
   unsigned int iface;
   unsigned short orig_id, new_id;
   int log_id, fd, forwardall, flags;
@@ -670,6 +708,7 @@ struct frec {
 #define LEASE_NA            32  /* IPv6 no-temporary lease */
 #define LEASE_TA            64  /* IPv6 temporary lease */
 #define LEASE_HAVE_HWADDR  128  /* Have set hwaddress */
+#define LEASE_EXP_CHANGED  256  /* Lease expiry time changed */
 
 struct dhcp_lease {
   int clid_len;          /* length of client identifier */
@@ -691,7 +730,7 @@ struct dhcp_lease {
   int new_prefixlen;     /* and its prefix length */
 #ifdef HAVE_DHCP6
   struct in6_addr addr6;
-  int iaid;
+  unsigned int iaid;
   struct slaac_address {
     struct in6_addr addr;
     time_t ping_time;
@@ -738,8 +777,9 @@ struct dhcp_config {
   unsigned char *clid;   /* clientid */
   char *hostname, *domain;
   struct dhcp_netid_list *netid;
+  struct dhcp_netid *filter;
 #ifdef HAVE_DHCP6
-  struct in6_addr addr6;
+  struct addrlist *addr6;
 #endif
   struct in_addr addr;
   time_t decline_time;
@@ -761,7 +801,7 @@ struct dhcp_config {
 #define CONFIG_DECLINED       1024    /* address declined by client */
 #define CONFIG_BANK           2048    /* from dhcp hosts file */
 #define CONFIG_ADDR6          4096
-#define CONFIG_WILDCARD       8192
+#define CONFIG_ADDR6_HOSTS   16384    /* address added by from /etc/hosts */
 
 struct dhcp_opt {
   int opt, len, flags;
@@ -797,6 +837,13 @@ struct dhcp_boot {
   struct dhcp_boot *next;
 };
 
+struct dhcp_match_name {
+  char *name;
+  int wildcard;
+  struct dhcp_netid *netid;
+  struct dhcp_match_name *next;
+};
+
 struct pxe_service {
   unsigned short CSA, type; 
   char *menu, *basename, *sname;
@@ -836,21 +883,11 @@ struct dhcp_bridge {
 struct cond_domain {
   char *domain, *prefix;
   struct in_addr start, end;
-#ifdef HAVE_IPV6
   struct in6_addr start6, end6;
-#endif
   int is6, indexed;
   struct cond_domain *next;
 }; 
 
-#ifdef OPTION6_PREFIX_CLASS 
-struct prefix_class {
-  int class;
-  struct dhcp_netid tag;
-  struct prefix_class *next;
-};
-#endif
-
 struct ra_interface {
   char *name;
   char *mtu_name;
@@ -876,6 +913,16 @@ struct dhcp_context {
   struct dhcp_context *next, *current;
 };
 
+struct shared_network {
+  int if_index;
+  struct in_addr match_addr, shared_addr;
+#ifdef HAVE_DHCP6
+  /* shared_addr == 0 for IP6 entries. */
+  struct in6_addr match_addr6, shared_addr6;
+#endif
+  struct shared_network *next;
+};
+
 #define CONTEXT_STATIC         (1u<<0)
 #define CONTEXT_NETMASK        (1u<<1)
 #define CONTEXT_BRDCAST        (1u<<2)
@@ -895,6 +942,7 @@ struct dhcp_context {
 #define CONTEXT_OLD            (1u<<16)
 #define CONTEXT_V6             (1u<<17)
 #define CONTEXT_RA_OFF_LINK    (1u<<18)
+#define CONTEXT_SETLEASE       (1u<<19)
 
 struct ping_result {
   struct in_addr addr;
@@ -918,6 +966,8 @@ struct tftp_transfer {
   unsigned int block, blocksize, expansion;
   off_t offset;
   union mysockaddr peer;
+  union all_addr source;
+  int if_index;
   char opt_blocksize, opt_transize, netascii, carrylf;
   struct tftp_file *file;
   struct tftp_transfer *next;
@@ -936,7 +986,7 @@ struct tftp_prefix {
 };
 
 struct dhcp_relay {
-  struct all_addr local, server;
+  union all_addr local, server;
   char *interface; /* Allowable interface for replies from server, and dest for IPv6 multicast */
   int iface_index; /* working - interface in which requests arrived, for return */
   struct dhcp_relay *current, *next;
@@ -947,7 +997,7 @@ extern struct daemon {
      config file arguments. All set (including defaults)
      in option.c */
 
-  unsigned int options, options2;
+  unsigned int options[OPTION_SIZE];
   struct resolvc default_resolv, *resolv_files;
   time_t last_resolv;
   char *servers_file;
@@ -989,6 +1039,7 @@ extern struct daemon {
   struct ra_interface *ra_interfaces;
   struct dhcp_config *dhcp_conf;
   struct dhcp_opt *dhcp_opts, *dhcp_match, *dhcp_opts6, *dhcp_match6;
+  struct dhcp_match_name *dhcp_name_match;
   struct dhcp_vendor *dhcp_vendors;
   struct dhcp_mac *dhcp_macs;
   struct dhcp_boot *boot_config;
@@ -1014,14 +1065,13 @@ extern struct daemon {
   unsigned int duid_enterprise, duid_config_len;
   unsigned char *duid_config;
   char *dbus_name;
+  char *ubus_name;
+  char *dump_file;
+  int dump_mask;
   unsigned long soa_sn, soa_refresh, soa_retry, soa_expiry;
-#ifdef OPTION6_PREFIX_CLASS 
-  struct prefix_class *prefix_classes;
-#endif
+  u32 metrics[__METRIC_MAX];
 #ifdef HAVE_DNSSEC
   struct ds_config *ds;
-  int dnssec_no_time_check;
-  int back_to_the_future;
   char *timestamp_file;
 #endif
 
@@ -1032,10 +1082,11 @@ extern struct daemon {
 #ifdef HAVE_DNSSEC
   char *keyname; /* MAXDNAME size buffer */
   char *workspacename; /* ditto */
-  char *rr_status; /* flags for individual RRs */
+  unsigned long *rr_status; /* ceiling in TTL from DNSSEC or zero for insecure */
   int rr_status_sz;
+  int dnssec_no_time_check;
+  int back_to_the_future;
 #endif
-  unsigned int local_answer, queries_forwarded, auth_answer;
   struct frec *frec_list;
   struct serverfd *sfds;
   struct irec *interfaces;
@@ -1047,6 +1098,8 @@ extern struct daemon {
   size_t packet_len;       /*      "        "        */
   struct randfd *rfd_save; /*      "        "        */
   pid_t tcp_pids[MAX_PROCS];
+  int tcp_pipes[MAX_PROCS];
+  int pipe_to_parent;
   struct randfd randomsocks[RANDOM_SOCKS];
   int v6pktinfo; 
   struct addrlist *interface_addrs; /* list of all addresses/prefix lengths associated with all local interfaces */
@@ -1059,7 +1112,7 @@ extern struct daemon {
   int inotifyfd;
 #endif
 #if defined(HAVE_LINUX_NETWORK)
-  int netlinkfd;
+  int netlinkfd, kernel_version;
 #elif defined(HAVE_BSD_NETWORK)
   int dhcp_raw_fd, dhcp_icmp_fd, routefd;
 #endif
@@ -1068,6 +1121,7 @@ extern struct daemon {
   struct ping_result *ping_results;
   FILE *lease_stream;
   struct dhcp_bridge *bridges;
+  struct shared_network *shared_networks;
 #ifdef HAVE_DHCP6
   int duid_len;
   unsigned char *duid;
@@ -1080,6 +1134,11 @@ extern struct daemon {
 #ifdef HAVE_DBUS
   struct watch *watches;
 #endif
+  /* UBus stuff */
+#ifdef HAVE_UBUS
+  /* void * here to avoid depending on ubus headers outside ubus.c */
+  void *ubus;
+#endif
 
   /* TFTP stuff */
   struct tftp_transfer *tftp_trans, *tftp_done_trans;
@@ -1088,24 +1147,31 @@ extern struct daemon {
   char *addrbuff;
   char *addrbuff2; /* only allocated when OPT_EXTRALOG */
 
+#ifdef HAVE_DUMPFILE
+  /* file for packet dumps. */
+  int dumpfd;
+#endif
 } *daemon;
 
 /* cache.c */
 void cache_init(void);
-void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg); 
+void next_uid(struct crec *crecp);
+void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg); 
 char *record_source(unsigned int index);
 char *querystr(char *desc, unsigned short type);
+int cache_find_non_terminal(char *name, time_t now);
 struct crec *cache_find_by_addr(struct crec *crecp,
-                               struct all_addr *addr, time_t now, 
+                               union all_addr *addr, time_t now, 
                                unsigned int prot);
 struct crec *cache_find_by_name(struct crec *crecp, 
                                char *name, time_t now, unsigned int prot);
 void cache_end_insert(void);
 void cache_start_insert(void);
-struct crec *cache_insert(char *name, struct all_addr *addr,
-                         time_t now, unsigned long ttl, unsigned short flags);
+int cache_recv_insert(time_t now, int fd);
+struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class, 
+                         time_t now, unsigned long ttl, unsigned int flags);
 void cache_reload(void);
-void cache_add_dhcp_entry(char *host_name, int prot, struct all_addr *host_address, time_t ttd);
+void cache_add_dhcp_entry(char *host_name, int prot, union all_addr *host_address, time_t ttd);
 struct in_addr a_record_from_hosts(char *name, time_t now);
 void cache_unhash_dhcp(void);
 void dump_cache(time_t now);
@@ -1119,21 +1185,19 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size,
                   struct crec **rhash, int hashsz);
 
 /* blockdata.c */
-#ifdef HAVE_DNSSEC
 void blockdata_init(void);
 void blockdata_report(void);
 struct blockdata *blockdata_alloc(char *data, size_t len);
 void *blockdata_retrieve(struct blockdata *block, size_t len, void *data);
+struct blockdata *blockdata_read(int fd, size_t len);
+void blockdata_write(struct blockdata *block, size_t len, int fd);
 void blockdata_free(struct blockdata *blocks);
-#endif
 
 /* domain.c */
 char *get_domain(struct in_addr addr);
-#ifdef HAVE_IPV6
 char *get_domain6(struct in6_addr *addr);
-#endif
-int is_name_synthetic(int flags, char *name, struct all_addr *addr);
-int is_rev_synth(int flag, struct all_addr *addr, char *name);
+int is_name_synthetic(int flags, char *name, union all_addr *addr);
+int is_rev_synth(int flag, union all_addr *addr, char *name);
 
 /* rfc1035.c */
 int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, 
@@ -1144,7 +1208,7 @@ unsigned char *skip_section(unsigned char *ansp, int count, struct dns_header *h
 unsigned int extract_request(struct dns_header *header, size_t qlen, 
                               char *name, unsigned short *typep);
 size_t setup_reply(struct dns_header *header, size_t  qlen,
-                  struct all_addr *addrp, unsigned int flags,
+                  union all_addr *addrp, unsigned int flags,
                   unsigned long ttl);
 int extract_addresses(struct dns_header *header, size_t qlen, char *name,
                      time_t now, char **ipsets, int is_sign, int check_rebind,
@@ -1162,10 +1226,7 @@ size_t resize_packet(struct dns_header *header, size_t plen,
 int add_resource_record(struct dns_header *header, char *limit, int *truncp,
                        int nameoffset, unsigned char **pp, unsigned long ttl, 
                        int *offset, unsigned short type, unsigned short class, char *format, ...);
-unsigned char *skip_questions(struct dns_header *header, size_t plen);
-int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, 
-                char *name, int isExtract, int extrabytes);
-int in_arpa_name_2_addr(char *namein, struct all_addr *addrp);
+int in_arpa_name_2_addr(char *namein, union all_addr *addrp);
 int private_net(struct in_addr addr, int ban_localhost);
 
 /* auth.c */
@@ -1177,11 +1238,11 @@ int in_zone(struct auth_zone *zone, char *name, char **cut);
 #endif
 
 /* dnssec.c */
-size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char *name, int class, int type, union mysockaddr *addr, int edns_pktsz);
+size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char *name, int class, int type, int edns_pktsz);
 int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class);
 int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class);
 int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int *class,
-                         int check_unsigned, int *neganswer, int *nons);
+                         int check_unsigned, int *neganswer, int *nons, int *nsec_ttl);
 int dnskey_keytag(int alg, int flags, unsigned char *key, int keylen);
 size_t filter_rrsigs(struct dns_header *header, size_t plen);
 unsigned char* hash_questions(struct dns_header *header, size_t plen, char *name);
@@ -1205,19 +1266,19 @@ int legal_hostname(char *name);
 char *canonicalise(char *in, int *nomem);
 unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit);
 void *safe_malloc(size_t size);
+void safe_strncpy(char *dest, const char *src, size_t size);
 void safe_pipe(int *fd, int read_noblock);
 void *whine_malloc(size_t size);
 int sa_len(union mysockaddr *addr);
 int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2);
 int hostname_isequal(const char *a, const char *b);
+int hostname_issubdomain(char *a, char *b);
 time_t dnsmasq_time(void);
 int netmask_length(struct in_addr mask);
 int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask);
-#ifdef HAVE_IPV6
 int is_same_net6(struct in6_addr *a, struct in6_addr *b, int prefixlen);
 u64 addr6part(struct in6_addr *addr);
 void setaddr6part(struct in6_addr *addr, u64 host);
-#endif
 int retry_send(ssize_t rc);
 void prettyprint_time(char *buf, unsigned int t);
 int prettyprint_addr(union mysockaddr *addr, char *buf);
@@ -1228,12 +1289,15 @@ int memcmp_masked(unsigned char *a, unsigned char *b, int len,
 int expand_buf(struct iovec *iov, size_t size);
 char *print_mac(char *buff, unsigned char *mac, int len);
 int read_write(int fd, unsigned char *packet, int size, int rw);
-
+void close_fds(long max_fd, int spare1, int spare2, int spare3);
 int wildcard_match(const char* wildcard, const char* match);
 int wildcard_matchn(const char* wildcard, const char* match, int num);
+#ifdef HAVE_LINUX_NETWORK
+int kernel_version(void);
+#endif
 
 /* log.c */
-void die(char *message, char *arg1, int exit_code);
+void die(char *message, char *arg1, int exit_code) ATTRIBUTE_NORETURN;
 int log_start(struct passwd *ent_pw, int errfd);
 int log_reopen(char *log_file);
 
@@ -1262,9 +1326,9 @@ void receive_query(struct listener *listen, time_t now);
 unsigned char *tcp_request(int confd, time_t now,
                           union mysockaddr *local_addr, struct in_addr netmask, int auth_dns);
 void server_gone(struct server *server);
-struct frec *get_new_frec(time_t now, int *wait, int force);
+struct frec *get_new_frec(time_t now, int *wait, struct frec *force);
 int send_from(int fd, int nowild, char *packet, size_t len, 
-              union mysockaddr *to, struct all_addr *source,
+              union mysockaddr *to, union all_addr *source,
               unsigned int iface);
 void resend_query(void);
 struct randfd *allocate_rfd(int family);
@@ -1291,14 +1355,12 @@ void warn_bound_listeners(void);
 void warn_wild_labels(void);
 void warn_int_names(void);
 int is_dad_listeners(void);
-int iface_check(int family, struct all_addr *addr, char *name, int *auth);
-int loopback_exception(int fd, int family, struct all_addr *addr, char *name);
-int label_exception(int index, int family, struct all_addr *addr);
+int iface_check(int family, union all_addr *addr, char *name, int *auth);
+int loopback_exception(int fd, int family, union all_addr *addr, char *name);
+int label_exception(int index, int family, union all_addr *addr);
 int fix_fd(int fd);
 int tcp_interface(int fd, int af);
-#ifdef HAVE_IPV6
 int set_ipv6pktinfo(int fd);
-#endif
 #ifdef HAVE_DHCP6
 void join_multicast(int dienow);
 #endif
@@ -1336,14 +1398,15 @@ struct dhcp_lease *lease4_allocate(struct in_addr addr);
 #ifdef HAVE_DHCP6
 struct dhcp_lease *lease6_allocate(struct in6_addr *addrp, int lease_type);
 struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len, 
-                              int lease_type, int iaid, struct in6_addr *addr);
+                              int lease_type, unsigned int iaid, struct in6_addr *addr);
 void lease6_reset(void);
-struct dhcp_lease *lease6_find_by_client(struct dhcp_lease *first, int lease_type, unsigned char *clid, int clid_len, int iaid);
+struct dhcp_lease *lease6_find_by_client(struct dhcp_lease *first, int lease_type,
+                                        unsigned char *clid, int clid_len, unsigned int iaid);
 struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 addr);
 u64 lease_find_max_addr6(struct dhcp_context *context);
 void lease_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface);
 void lease_update_slaac(time_t now);
-void lease_set_iaid(struct dhcp_lease *lease, int iaid);
+void lease_set_iaid(struct dhcp_lease *lease, unsigned int iaid);
 void lease_make_duid(time_t now);
 #endif
 void lease_set_hwaddr(struct dhcp_lease *lease, const unsigned char *hwaddr,
@@ -1389,7 +1452,7 @@ void clear_cache_and_reload(time_t now);
 
 /* netlink.c */
 #ifdef HAVE_LINUX_NETWORK
-void netlink_init(void);
+char *netlink_init(void);
 void netlink_multicast(void);
 #endif
 
@@ -1415,10 +1478,18 @@ void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname);
 #  endif
 #endif
 
+/* ubus.c */
+#ifdef HAVE_UBUS
+void ubus_init(void);
+void set_ubus_listeners(void);
+void check_ubus_listeners(void);
+void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface);
+#endif
+
 /* ipset.c */
 #ifdef HAVE_IPSET
 void ipset_init(void);
-int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags, int remove);
+int add_to_ipset(const char *setname, const union all_addr *ipaddr, int flags, int remove);
 #endif
 
 /* helper.c */
@@ -1431,7 +1502,7 @@ void queue_script(int action, struct dhcp_lease *lease,
 void queue_tftp(off_t file_len, char *filename, union mysockaddr *peer);
 #endif
 void queue_arp(int action, unsigned char *mac, int maclen,
-              int family, struct all_addr *addr);
+              int family, union all_addr *addr);
 int helper_buf_empty(void);
 #endif
 
@@ -1444,7 +1515,7 @@ int do_tftp_script_run(void);
 
 /* conntrack.c */
 #ifdef HAVE_CONNTRACK
-int get_incoming_mark(union mysockaddr *peer_addr, struct all_addr *local_addr,
+int get_incoming_mark(union mysockaddr *peer_addr, union all_addr *local_addr,
                      int istcp, unsigned int *markp);
 #endif
 
@@ -1453,8 +1524,7 @@ int get_incoming_mark(union mysockaddr *peer_addr, struct all_addr *local_addr,
 void dhcp6_init(void);
 void dhcp6_packet(time_t now);
 struct dhcp_context *address6_allocate(struct dhcp_context *context,  unsigned char *clid, int clid_len, int temp_addr,
-                                      int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans);
-int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr);
+                                      unsigned int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans);
 struct dhcp_context *address6_available(struct dhcp_context *context, 
                                        struct in6_addr *taddr,
                                        struct dhcp_netid *netids,
@@ -1464,7 +1534,7 @@ struct dhcp_context *address6_valid(struct dhcp_context *context,
                                    struct dhcp_netid *netids,
                                    int plain_range);
 struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct in6_addr *net, 
-                                           int prefix, u64 addr);
+                                           int prefix, struct in6_addr *addr);
 void make_duid(time_t now);
 void dhcp_construct_contexts(time_t now);
 void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac, 
@@ -1497,13 +1567,12 @@ void dhcp_update_configs(struct dhcp_config *configs);
 void display_opts(void);
 int lookup_dhcp_opt(int prot, char *name);
 int lookup_dhcp_len(int prot, int val);
-char *option_string(int prot, unsigned int opt, unsigned char *val, 
-                   int opt_len, char *buf, int buf_len);
 struct dhcp_config *find_config(struct dhcp_config *configs,
                                struct dhcp_context *context,
                                unsigned char *clid, int clid_len,
                                unsigned char *hwaddr, int hw_len, 
-                               int hw_type, char *hostname);
+                               int hw_type, char *hostname,
+                               struct dhcp_netid *filter);
 int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type);
 #ifdef HAVE_LINUX_NETWORK
 char *whichdevice(void);
@@ -1582,3 +1651,9 @@ int check_source(struct dns_header *header, size_t plen, unsigned char *pseudohe
 /* arp.c */
 int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now);
 int do_arp_script_run(void);
+
+/* dump.c */
+#ifdef HAVE_DUMPFILE
+void dump_init(void);
+void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src, union mysockaddr *dst);
+#endif
index 8143185..db5c2d1 100644 (file)
@@ -1,5 +1,5 @@
 /* dnssec.c is Copyright (c) 2012 Giovanni Bajo <rasky@develer.com>
-           and Copyright (c) 2012-2018 Simon Kelley
+           and Copyright (c) 2012-2020 Simon Kelley
 
    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
@@ -186,10 +186,8 @@ int setup_timestamp(void)
 }
 
 /* Check whether today/now is between date_start and date_end */
-static int check_date_range(u32 date_start, u32 date_end)
+static int is_check_date(unsigned long curtime)
 {
-  unsigned long curtime = time(0);
   /* Checking timestamps may be temporarily disabled */
     
   /* If the current time if _before_ the timestamp
@@ -211,12 +209,15 @@ static int check_date_range(u32 date_start, u32 date_end)
          queue_event(EVENT_RELOAD); /* purge cache */
        } 
 
-      if (daemon->back_to_the_future == 0)
-       return 1;
+      return daemon->back_to_the_future;
     }
-  else if (daemon->dnssec_no_time_check)
-    return 1;
-  
+  else
+    return !daemon->dnssec_no_time_check;
+}
+
+/* Check whether today/now is between date_start and date_end */
+static int check_date_range(unsigned long curtime, u32 date_start, u32 date_end)
+{
   /* We must explicitly check against wanted values, because of SERIAL_UNDEF */
   return serial_compare_32(curtime, date_start) == SERIAL_GT
     && serial_compare_32(curtime, date_end) == SERIAL_LT;
@@ -374,7 +375,7 @@ static int explore_rrset(struct dns_header *header, size_t plen, int class, int
   int gotkey = 0;
 
   if (!(p = skip_questions(header, plen)))
-    return STAT_BOGUS;
+    return 0;
 
    /* look for RRSIGs for this RRset and get pointers to each RR in the set. */
   for (rrsetidx = 0, sigidx = 0, j = ntohs(header->ancount) + ntohs(header->nscount); 
@@ -386,14 +387,14 @@ static int explore_rrset(struct dns_header *header, size_t plen, int class, int
       pstart = p;
       
       if (!(res = extract_name(header, plen, &p, name, 0, 10)))
-       return STAT_BOGUS; /* bad packet */
+       return 0; /* bad packet */
       
       GETSHORT(stype, p);
       GETSHORT(sclass, p);
-      p += 4; /* TTL */
-      
+           
       pdata = p;
 
+      p += 4; /* TTL */
       GETSHORT(rdlen, p);
       
       if (!CHECK_LEN(header, p, plen, rdlen))
@@ -456,7 +457,7 @@ static int explore_rrset(struct dns_header *header, size_t plen, int class, int
                  sigs[sigidx++] = pdata;
                } 
              
-             p = pdata + 2; /* restore for ADD_RDLEN */
+             p = pdata + 6; /* restore for ADD_RDLEN */
            }
        }
       
@@ -485,16 +486,22 @@ static int explore_rrset(struct dns_header *header, size_t plen, int class, int
    Name is unchanged on exit. keyname is used as workspace and trashed.
 
    Call explore_rrset first to find and count RRs and sigs.
+
+   ttl_out is the floor on TTL, based on TTL and orig_ttl and expiration of sig used to validate.
 */
 static int validate_rrset(time_t now, struct dns_header *header, size_t plen, int class, int type, int sigidx, int rrsetidx, 
-                         char *name, char *keyname, char **wildcard_out, struct blockdata *key, int keylen, int algo_in, int keytag_in)
+                         char *name, char *keyname, char **wildcard_out, struct blockdata *key, int keylen,
+                         int algo_in, int keytag_in, unsigned long *ttl_out)
 {
   unsigned char *p;
-  int rdlen, j, name_labels, algo, labels, orig_ttl, key_tag;
+  int rdlen, j, name_labels, algo, labels, key_tag;
   struct crec *crecp = NULL;
   u16 *rr_desc = rrfilter_desc(type);
-  u32 sig_expiration, sig_inception
-;
+  u32 sig_expiration, sig_inception;
+
+  unsigned long curtime = time(0);
+  int time_check = is_check_date(curtime);
+  
   if (wildcard_out)
     *wildcard_out = NULL;
   
@@ -513,9 +520,10 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
       const struct nettle_hash *hash;
       void *ctx;
       char *name_start;
-      u32 nsigttl;
+      u32 nsigttl, ttl, orig_ttl;
       
       p = sigs[j];
+      GETLONG(ttl, p);
       GETSHORT(rdlen, p); /* rdlen >= 18 checked previously */
       psav = p;
       
@@ -530,16 +538,28 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
       if (!extract_name(header, plen, &p, keyname, 1, 0))
        return STAT_BOGUS;
 
-      if (!check_date_range(sig_inception, sig_expiration) ||
+      if ((time_check && !check_date_range(curtime, sig_inception, sig_expiration)) ||
          labels > name_labels ||
          !(hash = hash_find(algo_digest_name(algo))) ||
          !hash_init(hash, &ctx, &digest))
        continue;
-      
+
       /* OK, we have the signature record, see if the relevant DNSKEY is in the cache. */
       if (!key && !(crecp = cache_find_by_name(NULL, keyname, now, F_DNSKEY)))
        return STAT_NEED_KEY;
-      
+
+       if (ttl_out)
+        {
+          /* 4035 5.3.3 rules on TTLs */
+          if (orig_ttl < ttl)
+            ttl = orig_ttl;
+          
+          if (time_check && difftime(sig_expiration, curtime) < ttl)
+            ttl = difftime(sig_expiration, curtime);
+
+          *ttl_out = ttl;
+        }
+       
       sig = p;
       sig_len = rdlen - (p - psav);
               
@@ -653,11 +673,13 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
 {
   unsigned char *psave, *p = (unsigned char *)(header+1);
   struct crec *crecp, *recp1;
-  int rc, j, qtype, qclass, ttl, rdlen, flags, algo, valid, keytag;
+  int rc, j, qtype, qclass, rdlen, flags, algo, valid, keytag;
+  unsigned long ttl, sig_ttl;
   struct blockdata *key;
-  struct all_addr a;
+  union all_addr a;
 
   if (ntohs(header->qdcount) != 1 ||
+      RCODE(header) == SERVFAIL || RCODE(header) == REFUSED ||
       !extract_name(header, plen, &p, name, 1, 4))
     return STAT_BOGUS;
 
@@ -747,12 +769,12 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
              
              if (!(recp1->flags & F_NEG) &&
                  recp1->addr.ds.keylen == (int)hash->digest_size &&
-                 (ds_digest = blockdata_retrieve(recp1->addr.key.keydata, recp1->addr.ds.keylen, NULL)) &&
+                 (ds_digest = blockdata_retrieve(recp1->addr.ds.keydata, recp1->addr.ds.keylen, NULL)) &&
                  memcmp(ds_digest, digest, recp1->addr.ds.keylen) == 0 &&
                  explore_rrset(header, plen, class, T_DNSKEY, name, keyname, &sigcnt, &rrcnt) &&
                  sigcnt != 0 && rrcnt != 0 &&
                  validate_rrset(now, header, plen, class, T_DNSKEY, sigcnt, rrcnt, name, keyname, 
-                                NULL, key, rdlen - 4, algo, keytag) == STAT_SECURE)
+                                NULL, key, rdlen - 4, algo, keytag, &sig_ttl) == STAT_SECURE)
                {
                  valid = 1;
                  break;
@@ -779,6 +801,10 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
          GETSHORT(qclass, p);
          GETLONG(ttl, p);
          GETSHORT(rdlen, p);
+
+         /* TTL may be limited by sig. */
+         if (sig_ttl < ttl)
+           ttl = sig_ttl;
            
          if (!CHECK_LEN(header, p, plen, rdlen))
            return STAT_BOGUS; /* bad packet */
@@ -798,30 +824,27 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
                  algo = *p++;
                  keytag = dnskey_keytag(algo, flags, p, rdlen - 4);
                  
-                 /* Cache needs to known class for DNSSEC stuff */
-                 a.addr.dnssec.class = class;
-                 
                  if ((key = blockdata_alloc((char*)p, rdlen - 4)))
                    {
-                     if (!(recp1 = cache_insert(name, &a, now, ttl, F_FORWARD | F_DNSKEY | F_DNSSECOK)))
+                     a.key.keylen = rdlen - 4;
+                     a.key.keydata = key;
+                     a.key.algo = algo;
+                     a.key.keytag = keytag;
+                     a.key.flags = flags;
+                     
+                     if (!cache_insert(name, &a, class, now, ttl, F_FORWARD | F_DNSKEY | F_DNSSECOK))
                        {
                          blockdata_free(key);
                          return STAT_BOGUS;
                        }
                      else
                        {
-                         a.addr.log.keytag = keytag;
-                         a.addr.log.algo = algo;
+                         a.log.keytag = keytag;
+                         a.log.algo = algo;
                          if (algo_digest_name(algo))
                            log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu");
                          else
                            log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu (not supported)");
-                         
-                         recp1->addr.key.keylen = rdlen - 4;
-                         recp1->addr.key.keydata = key;
-                         recp1->addr.key.algo = algo;
-                         recp1->addr.key.keytag = keytag;
-                         recp1->addr.key.flags = flags;
                        }
                    }
                }
@@ -857,10 +880,10 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
 int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class)
 {
   unsigned char *p = (unsigned char *)(header+1);
-  int qtype, qclass, rc, i, neganswer, nons;
+  int qtype, qclass, rc, i, neganswer, nons, neg_ttl = 0;
   int aclass, atype, rdlen;
   unsigned long ttl;
-  struct all_addr a;
+  union all_addr a;
 
   if (ntohs(header->qdcount) != 1 ||
       !(p = skip_name(p, header, plen, 4)))
@@ -872,11 +895,14 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
   if (qtype != T_DS || qclass != class)
     rc = STAT_BOGUS;
   else
-    rc = dnssec_validate_reply(now, header, plen, name, keyname, NULL, 0, &neganswer, &nons);
+    rc = dnssec_validate_reply(now, header, plen, name, keyname, NULL, 0, &neganswer, &nons, &neg_ttl);
   
   if (rc == STAT_INSECURE)
-    rc = STAT_BOGUS;
+    {
+      my_syslog(LOG_WARNING, _("Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"), name);
+      rc = STAT_BOGUS;
+    }
+  
   p = (unsigned char *)(header+1);
   extract_name(header, plen, &p, name, 1, 4);
   p += 4; /* qtype, qclass */
@@ -915,8 +941,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
              int algo, digest, keytag;
              unsigned char *psave = p;
              struct blockdata *key;
-             struct crec *crecp;
-
+          
              if (rdlen < 4)
                return STAT_BOGUS; /* bad packet */
              
@@ -924,31 +949,28 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
              algo = *p++;
              digest = *p++;
              
-             /* Cache needs to known class for DNSSEC stuff */
-             a.addr.dnssec.class = class;
-             
              if ((key = blockdata_alloc((char*)p, rdlen - 4)))
                {
-                 if (!(crecp = cache_insert(name, &a, now, ttl, F_FORWARD | F_DS | F_DNSSECOK)))
+                 a.ds.digest = digest;
+                 a.ds.keydata = key;
+                 a.ds.algo = algo;
+                 a.ds.keytag = keytag;
+                 a.ds.keylen = rdlen - 4;
+
+                 if (!cache_insert(name, &a, class, now, ttl, F_FORWARD | F_DS | F_DNSSECOK))
                    {
                      blockdata_free(key);
                      return STAT_BOGUS;
                    }
                  else
                    {
-                     a.addr.log.keytag = keytag;
-                     a.addr.log.algo = algo;
-                     a.addr.log.digest = digest;
+                     a.log.keytag = keytag;
+                     a.log.algo = algo;
+                     a.log.digest = digest;
                      if (ds_digest_name(digest) && algo_digest_name(algo))
                        log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu");
                      else
                        log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu (not supported)");
-                     
-                     crecp->addr.ds.digest = digest;
-                     crecp->addr.ds.keydata = key;
-                     crecp->addr.ds.algo = algo;
-                     crecp->addr.ds.keytag = keytag;
-                     crecp->addr.ds.keylen = rdlen - 4; 
                    } 
                }
              
@@ -964,11 +986,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
   else
     {
       int flags = F_FORWARD | F_DS | F_NEG | F_DNSSECOK;
-      unsigned long minttl = ULONG_MAX;
-      
-      if (!(p = skip_section(p, ntohs(header->ancount), header, plen)))
-       return STAT_BOGUS;
-      
+            
       if (RCODE(header) == NXDOMAIN)
        flags |= F_NXDOMAIN;
       
@@ -977,55 +995,15 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
       if (nons)
        flags &= ~F_DNSSECOK;
       
-      for (i = ntohs(header->nscount); i != 0; i--)
-       {
-         if (!(p = skip_name(p, header, plen, 0)))
-           return STAT_BOGUS;
-         
-         GETSHORT(atype, p); 
-         GETSHORT(aclass, p);
-         GETLONG(ttl, p);
-         GETSHORT(rdlen, p);
-         
-         if (!CHECK_LEN(header, p, plen, rdlen))
-           return STAT_BOGUS; /* bad packet */
-         
-         if (aclass != class || atype != T_SOA)
-           {
-             p += rdlen;
-             continue;
-           }
-         
-         if (ttl < minttl)
-           minttl = ttl;
-         
-         /* MNAME */
-         if (!(p = skip_name(p, header, plen, 0)))
-           return STAT_BOGUS;
-         /* RNAME */
-         if (!(p = skip_name(p, header, plen, 20)))
-           return STAT_BOGUS;
-         p += 16; /* SERIAL REFRESH RETRY EXPIRE */
-         
-         GETLONG(ttl, p); /* minTTL */
-         if (ttl < minttl)
-           minttl = ttl;
+      cache_start_insert();
          
-         break;
-       }
+      /* Use TTL from NSEC for negative cache entries */
+      if (!cache_insert(name, NULL, class, now, neg_ttl, flags))
+       return STAT_BOGUS;
       
-      if (i != 0)
-       {
-         cache_start_insert();
-         
-         a.addr.dnssec.class = class;
-         if (!cache_insert(name, &a, now, ttl, flags))
-           return STAT_BOGUS;
-         
-         cache_end_insert();  
-         
-         log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "no DS");
-       }
+      cache_end_insert();  
+      
+      log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, nons ? "no DS/cut" : "no DS");
     }
       
   return STAT_OK;
@@ -1539,7 +1517,7 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
   return 1;
 }
 
-static int prove_non_existence(struct dns_header *header, size_t plen, char *keyname, char *name, int qtype, int qclass, char *wildname, int *nons)
+static int prove_non_existence(struct dns_header *header, size_t plen, char *keyname, char *name, int qtype, int qclass, char *wildname, int *nons, int *nsec_ttl)
 {
   static unsigned char **nsecset = NULL, **rrsig_labels = NULL;
   static int nsecset_sz = 0, rrsig_labels_sz = 0;
@@ -1547,6 +1525,7 @@ static int prove_non_existence(struct dns_header *header, size_t plen, char *key
   int type_found = 0;
   unsigned char *auth_start, *p = skip_questions(header, plen);
   int type, class, rdlen, i, nsecs_found;
+  unsigned long ttl;
   
   /* Move to NS section */
   if (!p || !(p = skip_section(p, ntohs(header->ancount), header, plen)))
@@ -1554,7 +1533,7 @@ static int prove_non_existence(struct dns_header *header, size_t plen, char *key
 
   auth_start = p;
   
-  for (nsecs_found = 0, i = ntohs(header->nscount); i != 0; i--)
+  for (nsecs_found = 0, i = 0; i < ntohs(header->nscount); i++)
     {
       unsigned char *pstart = p;
       
@@ -1563,11 +1542,19 @@ static int prove_non_existence(struct dns_header *header, size_t plen, char *key
          
       GETSHORT(type, p); 
       GETSHORT(class, p);
-      p += 4; /* TTL */
+      GETLONG(ttl, p);
       GETSHORT(rdlen, p);
 
       if (class == qclass && (type == T_NSEC || type == T_NSEC3))
        {
+         if (nsec_ttl)
+           {
+             /* Limit TTL with sig TTL */
+             if (daemon->rr_status[ntohs(header->ancount) + i] < ttl)
+               ttl = daemon->rr_status[ntohs(header->ancount) + i];
+             *nsec_ttl = ttl;
+           }
+         
          /* No mixed NSECing 'round here, thankyouverymuch */
          if (type_found != 0 && type_found != type)
            return 0;
@@ -1748,33 +1735,37 @@ static int zone_status(char *name, int class, char *keyname, time_t now)
    STAT_NEED_DS  need DS to complete validation (name is returned in keyname)
 
    daemon->rr_status points to a char array which corressponds to the RRs in the 
-   answer section (only). This is set to 1 for each RR which is validated, and 0 for any which aren't.
+   answer and auth sections. This is set to 1 for each RR which is validated, and 0 for any which aren't.
+
+   When validating replies to DS records, we're only interested in the NSEC{3} RRs in the auth section.
+   Other RRs in that section missing sigs will not cause am INSECURE reply. We determine this mode
+   is the nons argument is non-NULL.
 */
 int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, 
-                         int *class, int check_unsigned, int *neganswer, int *nons)
+                         int *class, int check_unsigned, int *neganswer, int *nons, int *nsec_ttl)
 {
   static unsigned char **targets = NULL;
   static int target_sz = 0;
 
   unsigned char *ans_start, *p1, *p2;
   int type1, class1, rdlen1 = 0, type2, class2, rdlen2, qclass, qtype, targetidx;
-  int i, j, rc;
+  int i, j, rc = STAT_INSECURE;
   int secure = STAT_SECURE;
 
   /* extend rr_status if necessary */
-  if (daemon->rr_status_sz < ntohs(header->ancount))
+  if (daemon->rr_status_sz < ntohs(header->ancount) + ntohs(header->nscount))
     {
-      char *new = whine_malloc(ntohs(header->ancount) + 64);
+      unsigned long *new = whine_malloc(sizeof(*daemon->rr_status) * (ntohs(header->ancount) + ntohs(header->nscount) + 64));
 
       if (!new)
        return STAT_BOGUS;
 
       free(daemon->rr_status);
       daemon->rr_status = new;
-      daemon->rr_status_sz = ntohs(header->ancount) + 64;
+      daemon->rr_status_sz = ntohs(header->ancount) + ntohs(header->nscount) + 64;
     }
   
-  memset(daemon->rr_status, 0, ntohs(header->ancount));
+  memset(daemon->rr_status, 0, sizeof(*daemon->rr_status) * daemon->rr_status_sz);
   
   if (neganswer)
     *neganswer = 0;
@@ -1832,10 +1823,10 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
   
   for (p1 = ans_start, i = 0; i < ntohs(header->ancount) + ntohs(header->nscount); i++)
     {
-       if (i != 0 && !ADD_RDLEN(header, p1, plen, rdlen1))
-        return STAT_BOGUS;
-
-       if (!extract_name(header, plen, &p1, name, 1, 10))
+      if (i != 0 && !ADD_RDLEN(header, p1, plen, rdlen1))
+       return STAT_BOGUS;
+      
+      if (!extract_name(header, plen, &p1, name, 1, 10))
        return STAT_BOGUS; /* bad packet */
       
       GETSHORT(type1, p1);
@@ -1865,12 +1856,9 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
            return STAT_BOGUS;
        }
       
+      /* Done already: copy the validation status */
       if (j != i)
-       {
-         /* Done already: copy the validation status */
-         if (i < ntohs(header->ancount))
-           daemon->rr_status[i] = daemon->rr_status[j];
-       }
+       daemon->rr_status[i] = daemon->rr_status[j];
       else
        {
          /* Not done, validate now */
@@ -1883,19 +1871,31 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
          /* No signatures for RRset. We can be configured to assume this is OK and return an INSECURE result. */
          if (sigcnt == 0)
            {
-             if (check_unsigned)
+             /* NSEC and NSEC3 records must be signed. We make this assumption elsewhere. */
+             if (type1 == T_NSEC || type1 == T_NSEC3)
+               rc = STAT_INSECURE;
+             else if (nons && i >= ntohs(header->ancount))
+               /* If we're validating a DS reply, rather than looking for the value of AD bit,
+                  we only care that NSEC and NSEC3 RRs in the auth section are signed. 
+                  Return SECURE even if others (SOA....) are not. */
+               rc = STAT_SECURE;
+             else
                {
-                 rc = zone_status(name, class1, keyname, now);
-                 if (rc == STAT_SECURE)
-                   rc = STAT_BOGUS;
-                 if (class)
-                   *class = class1; /* Class for NEED_DS or NEED_KEY */
+                 /* unsigned RRsets in auth section are not BOGUS, but do make reply insecure. */
+                 if (check_unsigned && i < ntohs(header->ancount))
+                   {
+                     rc = zone_status(name, class1, keyname, now);
+                     if (rc == STAT_SECURE)
+                       rc = STAT_BOGUS;
+                     if (class)
+                       *class = class1; /* Class for NEED_DS or NEED_KEY */
+                   }
+                 else 
+                   rc = STAT_INSECURE; 
+                 
+                 if (rc != STAT_INSECURE)
+                   return rc;
                }
-             else 
-               rc = STAT_INSECURE; 
-             
-             if (rc != STAT_INSECURE)
-               return rc;
            }
          else
            {
@@ -1906,7 +1906,6 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
              
              if (rc == STAT_BOGUS || rc == STAT_NEED_KEY || rc == STAT_NEED_DS)
                {
-                 /* Zone is insecure, don't need to validate RRset */
                  if (class)
                    *class = class1; /* Class for NEED_DS or NEED_KEY */
                  return rc;
@@ -1915,8 +1914,9 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
              /* Zone is insecure, don't need to validate RRset */
              if (rc == STAT_SECURE)
                {
+                 unsigned long sig_ttl;
                  rc = validate_rrset(now, header, plen, class1, type1, sigcnt,
-                                     rrcnt, name, keyname, &wildname, NULL, 0, 0, 0);
+                                     rrcnt, name, keyname, &wildname, NULL, 0, 0, 0, &sig_ttl);
                  
                  if (rc == STAT_BOGUS || rc == STAT_NEED_KEY || rc == STAT_NEED_DS)
                    {
@@ -1928,8 +1928,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
                  /* rc is now STAT_SECURE or STAT_SECURE_WILDCARD */
                  
                  /* Note that RR is validated */
-                  if (i < ntohs(header->ancount))
-                    daemon->rr_status[i] = 1;
+                 daemon->rr_status[i] = sig_ttl;
                   
                  /* Note if we've validated either the answer to the question
                     or the target of a CNAME. Any not noted will need NSEC or
@@ -1953,7 +1952,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
                     That's not a problem since if the RRsets later fail
                     we'll return BOGUS then. */
                  if (rc == STAT_SECURE_WILDCARD &&
-                     !prove_non_existence(header, plen, keyname, name, type1, class1, wildname, NULL))
+                     !prove_non_existence(header, plen, keyname, name, type1, class1, wildname, NULL, NULL))
                    return STAT_BOGUS;
 
                  rc = STAT_SECURE;
@@ -1966,35 +1965,36 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
     }
 
   /* OK, all the RRsets validate, now see if we have a missing answer or CNAME target. */
-  for (j = 0; j <targetidx; j++)
-    if ((p2 = targets[j]))
-      {
-       if (neganswer)
-         *neganswer = 1;
-
-       if (!extract_name(header, plen, &p2, name, 1, 10))
-         return STAT_BOGUS; /* bad packet */
-           
-       /* NXDOMAIN or NODATA reply, unanswered question is (name, qclass, qtype) */
-
-       /* For anything other than a DS record, this situation is OK if either
-          the answer is in an unsigned zone, or there's a NSEC records. */
-       if (!prove_non_existence(header, plen, keyname, name, qtype, qclass, NULL, nons))
-         {
-           /* Empty DS without NSECS */
-           if (qtype == T_DS)
-             return STAT_BOGUS;
-           
-           if ((rc = zone_status(name, qclass, keyname, now)) != STAT_SECURE)
-             {
-               if (class)
-                 *class = qclass; /* Class for NEED_DS or NEED_KEY */
-               return rc;
-             } 
-           
-           return STAT_BOGUS; /* signed zone, no NSECs */
-         }
-      }
+  if (secure == STAT_SECURE)
+    for (j = 0; j <targetidx; j++)
+      if ((p2 = targets[j]))
+       {
+         if (neganswer)
+           *neganswer = 1;
+         
+         if (!extract_name(header, plen, &p2, name, 1, 10))
+           return STAT_BOGUS; /* bad packet */
+         
+         /* NXDOMAIN or NODATA reply, unanswered question is (name, qclass, qtype) */
+         
+         /* For anything other than a DS record, this situation is OK if either
+            the answer is in an unsigned zone, or there's a NSEC records. */
+         if (!prove_non_existence(header, plen, keyname, name, qtype, qclass, NULL, nons, nsec_ttl))
+           {
+             /* Empty DS without NSECS */
+             if (qtype == T_DS)
+               return STAT_BOGUS;
+             
+             if ((rc = zone_status(name, qclass, keyname, now)) != STAT_SECURE)
+               {
+                 if (class)
+                   *class = qclass; /* Class for NEED_DS or NEED_KEY */
+                 return rc;
+               } 
+             
+             return STAT_BOGUS; /* signed zone, no NSECs */
+           }
+       }
   
   return secure;
 }
@@ -2023,19 +2023,11 @@ int dnskey_keytag(int alg, int flags, unsigned char *key, int keylen)
 }
 
 size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char *name, int class, 
-                            int type, union mysockaddr *addr, int edns_pktsz)
+                            int type, int edns_pktsz)
 {
   unsigned char *p;
-  char *types = querystr("dnssec-query", type);
   size_t ret;
 
-  if (addr->sa.sa_family == AF_INET) 
-    log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, name, (struct all_addr *)&addr->in.sin_addr, types);
-#ifdef HAVE_IPV6
-  else
-    log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, name, (struct all_addr *)&addr->in6.sin6_addr, types);
-#endif
-  
   header->qdcount = htons(1);
   header->ancount = htons(0);
   header->nscount = htons(0);
index 04d7cf8..3dc96ab 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
 
 
 static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c);
-#ifdef HAVE_IPV6
 static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c);
-#endif
 
 
-int is_name_synthetic(int flags, char *name, struct all_addr *addr)
+int is_name_synthetic(int flags, char *name, union all_addr *addr)
 {
   char *p;
   struct cond_domain *c = NULL;
-  int prot = AF_INET;
-
-#ifdef HAVE_IPV6
-  if (flags & F_IPV6)
-    prot = AF_INET6;
-#endif
+  int prot = (flags & F_IPV6) ? AF_INET6 : AF_INET;
 
   for (c = daemon->synth_domains; c; c = c->next)
     {
@@ -80,11 +73,10 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr)
                   if (!c->is6 &&
                      index <= ntohl(c->end.s_addr) - ntohl(c->start.s_addr))
                    {
-                     addr->addr.addr4.s_addr = htonl(ntohl(c->start.s_addr) + index);
+                     addr->addr4.s_addr = htonl(ntohl(c->start.s_addr) + index);
                      found = 1;
                    }
-               }
-#ifdef HAVE_IPV6 
+               } 
              else
                {
                  u64 index = atoll(tail);
@@ -93,12 +85,11 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr)
                      index <= addr6part(&c->end6) - addr6part(&c->start6))
                    {
                      u64 start = addr6part(&c->start6);
-                     addr->addr.addr6 = c->start6;
-                     setaddr6part(&addr->addr.addr6, start + index);
+                     addr->addr6 = c->start6;
+                     setaddr6part(&addr->addr6, start + index);
                      found = 1;
                    }
                }
-#endif
            }
        }
       else
@@ -111,10 +102,8 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr)
              if ((c >='0' && c <= '9') || c == '-')
                continue;
              
-#ifdef HAVE_IPV6
              if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f'))) 
                continue;
-#endif
              
              break;
            }
@@ -124,7 +113,6 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr)
          
          *p = 0;       
          
-#ifdef HAVE_IPV6
          if (prot == AF_INET6 && strstr(tail, "--ffff-") == tail)
            {
              /* special hack for v4-mapped. */
@@ -134,7 +122,6 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr)
                  *p = '.';
            }
          else
-#endif
            {
              /* swap . or : for - */
              for (p = tail; *p; p++)
@@ -142,10 +129,8 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr)
                  {
                    if (prot == AF_INET)
                      *p = '.';
-#ifdef HAVE_IPV6
                    else
                      *p = ':';
-#endif
                  }
            }
          
@@ -154,22 +139,20 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr)
              if (prot == AF_INET)
                {
                  if (!c->is6 &&
-                     ntohl(addr->addr.addr4.s_addr) >= ntohl(c->start.s_addr) &&
-                     ntohl(addr->addr.addr4.s_addr) <= ntohl(c->end.s_addr))
+                     ntohl(addr->addr4.s_addr) >= ntohl(c->start.s_addr) &&
+                     ntohl(addr->addr4.s_addr) <= ntohl(c->end.s_addr))
                    found = 1;
                }
-#ifdef HAVE_IPV6
              else
                {
-                 u64 addrpart = addr6part(&addr->addr.addr6);
+                 u64 addrpart = addr6part(&addr->addr6);
                  
                  if (c->is6 &&
-                     is_same_net6(&addr->addr.addr6, &c->start6, 64) &&
+                     is_same_net6(&addr->addr6, &c->start6, 64) &&
                      addrpart >= addr6part(&c->start6) &&
                      addrpart <= addr6part(&c->end6))
                    found = 1;
                }
-#endif
            }
 
        }
@@ -190,18 +173,18 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr)
 }
 
 
-int is_rev_synth(int flag, struct all_addr *addr, char *name)
+int is_rev_synth(int flag, union all_addr *addr, char *name)
 {
    struct cond_domain *c;
 
-   if (flag & F_IPV4 && (c = search_domain(addr->addr.addr4, daemon->synth_domains))) 
+   if (flag & F_IPV4 && (c = search_domain(addr->addr4, daemon->synth_domains))) 
      {
        char *p;
        
        *name = 0;
        if (c->indexed)
         {
-          unsigned int index = ntohl(addr->addr.addr4.s_addr) - ntohl(c->start.s_addr);
+          unsigned int index = ntohl(addr->addr4.s_addr) - ntohl(c->start.s_addr);
           snprintf(name, MAXDNAME, "%s%u", c->prefix ? c->prefix : "", index);
         }
        else
@@ -209,7 +192,7 @@ int is_rev_synth(int flag, struct all_addr *addr, char *name)
           if (c->prefix)
             strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
        
-                  inet_ntop(AF_INET, &addr->addr.addr4, name + strlen(name), ADDRSTRLEN);
+                  inet_ntop(AF_INET, &addr->addr4, name + strlen(name), ADDRSTRLEN);
           for (p = name; *p; p++)
             if (*p == '.')
               *p = '-';
@@ -221,15 +204,14 @@ int is_rev_synth(int flag, struct all_addr *addr, char *name)
        return 1;
      }
 
-#ifdef HAVE_IPV6
-   if (flag & F_IPV6 && (c = search_domain6(&addr->addr.addr6, daemon->synth_domains))) 
+   if ((flag & F_IPV6) && (c = search_domain6(&addr->addr6, daemon->synth_domains))) 
      {
        char *p;
        
        *name = 0;
        if (c->indexed)
         {
-          u64 index = addr6part(&addr->addr.addr6) - addr6part(&c->start6);
+          u64 index = addr6part(&addr->addr6) - addr6part(&c->start6);
           snprintf(name, MAXDNAME, "%s%llu", c->prefix ? c->prefix : "", index);
         }
        else
@@ -237,14 +219,14 @@ int is_rev_synth(int flag, struct all_addr *addr, char *name)
           if (c->prefix)
             strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
        
-          inet_ntop(AF_INET6, &addr->addr.addr6, name + strlen(name), ADDRSTRLEN);
+          inet_ntop(AF_INET6, &addr->addr6, name + strlen(name), ADDRSTRLEN);
 
           /* IPv6 presentation address can start with ":", but valid domain names
              cannot start with "-" so prepend a zero in that case. */
           if (!c->prefix && *name == ':')
             {
               *name = '0';
-              inet_ntop(AF_INET6, &addr->addr.addr6, name+1, ADDRSTRLEN);
+              inet_ntop(AF_INET6, &addr->addr6, name+1, ADDRSTRLEN);
             }
           
           /* V4-mapped have periods.... */
@@ -259,7 +241,6 @@ int is_rev_synth(int flag, struct all_addr *addr, char *name)
        
        return 1;
      }
-#endif
    
    return 0;
 }
@@ -286,7 +267,7 @@ char *get_domain(struct in_addr addr)
   return daemon->domain_suffix;
 } 
 
-#ifdef HAVE_IPV6
+
 static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c)
 {
   u64 addrpart = addr6part(addr);
@@ -310,4 +291,3 @@ char *get_domain6(struct in6_addr *addr)
 
   return daemon->domain_suffix;
 } 
-#endif
diff --git a/src/dump.c b/src/dump.c
new file mode 100644 (file)
index 0000000..9bd3a5f
--- /dev/null
@@ -0,0 +1,211 @@
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+
+   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; version 2 dated June, 1991, or
+   (at your option) version 3 dated 29 June, 2007.
+   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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "dnsmasq.h"
+
+#ifdef HAVE_DUMPFILE
+
+static u32 packet_count;
+
+/* https://wiki.wireshark.org/Development/LibpcapFileFormat */
+struct pcap_hdr_s {
+        u32 magic_number;   /* magic number */
+        u16 version_major;  /* major version number */
+        u16 version_minor;  /* minor version number */
+        u32 thiszone;       /* GMT to local correction */
+        u32 sigfigs;        /* accuracy of timestamps */
+        u32 snaplen;        /* max length of captured packets, in octets */
+        u32 network;        /* data link type */
+};
+
+struct pcaprec_hdr_s {
+        u32 ts_sec;         /* timestamp seconds */
+        u32 ts_usec;        /* timestamp microseconds */
+        u32 incl_len;       /* number of octets of packet saved in file */
+        u32 orig_len;       /* actual length of packet */
+};
+
+
+void dump_init(void)
+{
+  struct stat buf;
+  struct pcap_hdr_s header;
+  struct pcaprec_hdr_s pcap_header;
+
+  packet_count = 0;
+  
+  if (stat(daemon->dump_file, &buf) == -1)
+    {
+      /* doesn't exist, create and add header */
+      header.magic_number = 0xa1b2c3d4;
+      header.version_major = 2;
+      header.version_minor = 4;
+      header.thiszone = 0;
+      header.sigfigs = 0;
+      header.snaplen = daemon->edns_pktsz + 200; /* slop for IP/UDP headers */
+      header.network = 101; /* DLT_RAW http://www.tcpdump.org/linktypes.html */
+
+      if (errno != ENOENT ||
+         (daemon->dumpfd = creat(daemon->dump_file, S_IRUSR | S_IWUSR)) == -1 ||
+         !read_write(daemon->dumpfd, (void *)&header, sizeof(header), 0))
+       die(_("cannot create %s: %s"), daemon->dump_file, EC_FILE);
+    }
+  else if ((daemon->dumpfd = open(daemon->dump_file, O_APPEND | O_RDWR)) == -1 ||
+          !read_write(daemon->dumpfd, (void *)&header, sizeof(header), 1))
+    die(_("cannot access %s: %s"), daemon->dump_file, EC_FILE);
+  else if (header.magic_number != 0xa1b2c3d4)
+    die(_("bad header in %s"), daemon->dump_file, EC_FILE);
+  else
+    {
+      /* count existing records */
+      while (read_write(daemon->dumpfd, (void *)&pcap_header, sizeof(pcap_header), 1))
+       {
+         lseek(daemon->dumpfd, pcap_header.incl_len, SEEK_CUR);
+         packet_count++;
+       }
+    }
+}
+
+void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src, union mysockaddr *dst)
+{
+  struct ip ip;
+  struct ip6_hdr ip6;
+  int family;
+  struct udphdr {
+    u16 uh_sport;               /* source port */
+    u16 uh_dport;               /* destination port */
+    u16 uh_ulen;                /* udp length */
+    u16 uh_sum;                 /* udp checksum */
+  } udp;
+  struct pcaprec_hdr_s pcap_header;
+  struct timeval time;
+  u32 i, sum;
+  void *iphdr;
+  size_t ipsz;
+  int rc;
+  
+  if (daemon->dumpfd == -1 || !(mask & daemon->dump_mask))
+    return;
+  
+  /* So wireshark can Id the packet. */
+  udp.uh_sport = udp.uh_dport = htons(NAMESERVER_PORT);
+
+  if (src)
+    family = src->sa.sa_family;
+  else
+    family = dst->sa.sa_family;
+
+  if (family == AF_INET6)
+    {
+      iphdr = &ip6;
+      ipsz = sizeof(ip6);
+      memset(&ip6, 0, sizeof(ip6));
+      
+      ip6.ip6_vfc = 6 << 4;
+      ip6.ip6_plen = htons(sizeof(struct udphdr) + len);
+      ip6.ip6_nxt = IPPROTO_UDP;
+      ip6.ip6_hops = 64;
+
+      if (src)
+       {
+         memcpy(&ip6.ip6_src, &src->in6.sin6_addr, IN6ADDRSZ);
+         udp.uh_sport = src->in6.sin6_port;
+       }
+      
+      if (dst)
+       {
+         memcpy(&ip6.ip6_dst, &dst->in6.sin6_addr, IN6ADDRSZ);
+         udp.uh_dport = dst->in6.sin6_port;
+       }
+            
+      /* start UDP checksum */
+      for (sum = 0, i = 0; i < IN6ADDRSZ; i+=2)
+       {
+         sum += ip6.ip6_src.s6_addr[i] + (ip6.ip6_src.s6_addr[i+1] << 8) ;
+         sum += ip6.ip6_dst.s6_addr[i] + (ip6.ip6_dst.s6_addr[i+1] << 8) ;
+         
+       }
+    }
+  else
+    {
+      iphdr = &ip;
+      ipsz = sizeof(ip);
+      memset(&ip, 0, sizeof(ip));
+      
+      ip.ip_v = IPVERSION;
+      ip.ip_hl = sizeof(struct ip) / 4;
+      ip.ip_len = htons(sizeof(struct ip) + sizeof(struct udphdr) + len); 
+      ip.ip_ttl = IPDEFTTL;
+      ip.ip_p = IPPROTO_UDP;
+      
+      if (src)
+       {
+         ip.ip_src = src->in.sin_addr;
+         udp.uh_sport = src->in.sin_port;
+       }
+
+      if (dst)
+       {
+         ip.ip_dst = dst->in.sin_addr;
+         udp.uh_dport = dst->in.sin_port;
+       }
+      
+      ip.ip_sum = 0;
+      for (sum = 0, i = 0; i < sizeof(struct ip) / 2; i++)
+       sum += ((u16 *)&ip)[i];
+      while (sum >> 16)
+       sum = (sum & 0xffff) + (sum >> 16);  
+      ip.ip_sum = (sum == 0xffff) ? sum : ~sum;
+      
+      /* start UDP checksum */
+      sum = ip.ip_src.s_addr & 0xffff;
+      sum += (ip.ip_src.s_addr >> 16) & 0xffff;
+      sum += ip.ip_dst.s_addr & 0xffff;
+      sum += (ip.ip_dst.s_addr >> 16) & 0xffff;
+    }
+  
+  if (len & 1)
+    ((unsigned char *)packet)[len] = 0; /* for checksum, in case length is odd. */
+
+  udp.uh_sum = 0;
+  udp.uh_ulen = htons(sizeof(struct udphdr) + len);
+  sum += htons(IPPROTO_UDP);
+  sum += htons(sizeof(struct udphdr) + len);
+  for (i = 0; i < sizeof(struct udphdr)/2; i++)
+    sum += ((u16 *)&udp)[i];
+  for (i = 0; i < (len + 1) / 2; i++)
+    sum += ((u16 *)packet)[i];
+  while (sum >> 16)
+    sum = (sum & 0xffff) + (sum >> 16);
+  udp.uh_sum = (sum == 0xffff) ? sum : ~sum;
+
+  rc = gettimeofday(&time, NULL);
+  pcap_header.ts_sec = time.tv_sec;
+  pcap_header.ts_usec = time.tv_usec;
+  pcap_header.incl_len = pcap_header.orig_len = ipsz + sizeof(udp) + len;
+  
+  if (rc == -1 ||
+      !read_write(daemon->dumpfd, (void *)&pcap_header, sizeof(pcap_header), 0) ||
+      !read_write(daemon->dumpfd, iphdr, ipsz, 0) ||
+      !read_write(daemon->dumpfd, (void *)&udp, sizeof(udp), 0) ||
+      !read_write(daemon->dumpfd, (void *)packet, len, 0))
+    my_syslog(LOG_ERR, _("failed to write packet dump"));
+  else
+    my_syslog(LOG_INFO, _("dumping UDP packet %u mask 0x%04x"), ++packet_count, mask);
+
+}
+
+#endif
index af33877..d75d3cc 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -301,20 +301,14 @@ static size_t add_mac(struct dns_header *header, size_t plen, unsigned char *lim
 
 struct subnet_opt {
   u16 family;
-  u8 source_netmask, scope_netmask;
-#ifdef HAVE_IPV6 
+  u8 source_netmask, scope_netmask; 
   u8 addr[IN6ADDRSZ];
-#else
-  u8 addr[INADDRSZ];
-#endif
 };
 
 static void *get_addrp(union mysockaddr *addr, const short family) 
 {
-#ifdef HAVE_IPV6
   if (family == AF_INET6)
     return &addr->in6.sin6_addr;
-#endif
 
   return &addr->in.sin_addr;
 }
@@ -330,7 +324,6 @@ static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
   opt->source_netmask = 0;
   opt->scope_netmask = 0;
 
-#ifdef HAVE_IPV6
   if (source->sa.sa_family == AF_INET6 && daemon->add_subnet6)
     {
       opt->source_netmask = daemon->add_subnet6->mask;
@@ -342,7 +335,6 @@ static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
       else 
        addrp = &source->in6.sin6_addr;
     }
-#endif
 
   if (source->sa.sa_family == AF_INET && daemon->add_subnet4)
     {
@@ -356,11 +348,7 @@ static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
          addrp = &source->in.sin_addr;
     }
   
-#ifdef HAVE_IPV6
   opt->family = htons(sa_family == AF_INET6 ? 2 : 1);
-#else
-  opt->family = htons(1);
-#endif
   
   len = 0;
   
index cdd11d3..9c2b2c6 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -26,7 +26,7 @@ static void free_frec(struct frec *f);
 /* Send a UDP packet with its source address set as "source" 
    unless nowild is true, when we just send it with the kernel default */
 int send_from(int fd, int nowild, char *packet, size_t len, 
-             union mysockaddr *to, struct all_addr *source,
+             union mysockaddr *to, union all_addr *source,
              unsigned int iface)
 {
   struct msghdr msg;
@@ -38,9 +38,7 @@ int send_from(int fd, int nowild, char *packet, size_t len,
 #elif defined(IP_SENDSRCADDR)
     char control[CMSG_SPACE(sizeof(struct in_addr))];
 #endif
-#ifdef HAVE_IPV6
     char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
-#endif
   } control_u;
   
   iov[0].iov_base = packet;
@@ -66,47 +64,49 @@ int send_from(int fd, int nowild, char *packet, size_t len,
 #if defined(HAVE_LINUX_NETWORK)
          struct in_pktinfo p;
          p.ipi_ifindex = 0;
-         p.ipi_spec_dst = source->addr.addr4;
+         p.ipi_spec_dst = source->addr4;
+         msg.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
          memcpy(CMSG_DATA(cmptr), &p, sizeof(p));
-         msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+         cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
          cmptr->cmsg_level = IPPROTO_IP;
          cmptr->cmsg_type = IP_PKTINFO;
 #elif defined(IP_SENDSRCADDR)
-         memcpy(CMSG_DATA(cmptr), &(source->addr.addr4), sizeof(source->addr.addr4));
-         msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
+         msg.msg_controllen = CMSG_SPACE(sizeof(struct in_addr));
+         memcpy(CMSG_DATA(cmptr), &(source->addr4), sizeof(source->addr4));
+         cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
          cmptr->cmsg_level = IPPROTO_IP;
          cmptr->cmsg_type = IP_SENDSRCADDR;
 #endif
        }
       else
-#ifdef HAVE_IPV6
        {
          struct in6_pktinfo p;
          p.ipi6_ifindex = iface; /* Need iface for IPv6 to handle link-local addrs */
-         p.ipi6_addr = source->addr.addr6;
+         p.ipi6_addr = source->addr6;
+         msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
          memcpy(CMSG_DATA(cmptr), &p, sizeof(p));
-         msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
+         cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
          cmptr->cmsg_type = daemon->v6pktinfo;
          cmptr->cmsg_level = IPPROTO_IPV6;
        }
-#else
-      (void)iface; /* eliminate warning */
-#endif
     }
   
   while (retry_send(sendmsg(fd, &msg, 0)));
 
-  /* If interface is still in DAD, EINVAL results - ignore that. */
-  if (errno != 0 && errno != EINVAL)
+  if (errno != 0)
     {
-      my_syslog(LOG_ERR, _("failed to send packet: %s"), strerror(errno));
+#ifdef HAVE_LINUX_NETWORK
+      /* If interface is still in DAD, EINVAL results - ignore that. */
+      if (errno != EINVAL)
+       my_syslog(LOG_ERR, _("failed to send packet: %s"), strerror(errno));
+#endif
       return 0;
     }
   
   return 1;
 }
           
-static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigned int qtype,
+static unsigned int search_servers(time_t now, union all_addr **addrpp, unsigned int qtype,
                                   char *qdomain, int *type, char **domain, int *norebind)
                              
 {
@@ -118,6 +118,7 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigne
   unsigned int matchlen = 0;
   struct server *serv;
   unsigned int flags = 0;
+  static union all_addr zero;
   
   for (serv = daemon->servers; serv; serv=serv->next)
     if (qtype == F_DNSSECOK && !(serv->flags & SERV_DO_DNSSEC))
@@ -127,19 +128,26 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigne
       {
        unsigned int sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6; 
        *type = SERV_FOR_NODOTS;
-       if (serv->flags & SERV_NO_ADDR)
+       if ((serv->flags & SERV_NO_REBIND) && norebind)
+         *norebind = 1;
+       else if (serv->flags & SERV_NO_ADDR)
          flags = F_NXDOMAIN;
-       else if (serv->flags & SERV_LITERAL_ADDRESS) 
+       else if (serv->flags & SERV_LITERAL_ADDRESS)
          { 
-           if (sflag & qtype)
+           /* literal address = '#' -> return all-zero address for IPv4 and IPv6 */
+           if ((serv->flags & SERV_USE_RESOLV) && (qtype & (F_IPV6 | F_IPV4)))
+             {
+               memset(&zero, 0, sizeof(zero));
+               flags = qtype;
+               *addrpp = &zero;
+             }
+           else if (sflag & qtype)
              {
                flags = sflag;
                if (serv->addr.sa.sa_family == AF_INET) 
-                 *addrpp = (struct all_addr *)&serv->addr.in.sin_addr;
-#ifdef HAVE_IPV6
+                 *addrpp = (union all_addr *)&serv->addr.in.sin_addr;
                else
-                 *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr;
-#endif 
+                 *addrpp = (union all_addr *)&serv->addr.in6.sin6_addr;
              }
            else if (!flags || (flags & F_NXDOMAIN))
              flags = F_NOERR;
@@ -184,15 +192,20 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigne
                      flags = F_NXDOMAIN;
                    else if (serv->flags & SERV_LITERAL_ADDRESS)
                      {
-                       if (sflag & qtype)
+                        /* literal address = '#' -> return all-zero address for IPv4 and IPv6 */
+                       if ((serv->flags & SERV_USE_RESOLV) && (qtype & (F_IPV6 | F_IPV4)))
+                         {                         
+                           memset(&zero, 0, sizeof(zero));
+                           flags = qtype;
+                           *addrpp = &zero;
+                         }
+                       else if (sflag & qtype)
                          {
                            flags = sflag;
                            if (serv->addr.sa.sa_family == AF_INET) 
-                             *addrpp = (struct all_addr *)&serv->addr.in.sin_addr;
-#ifdef HAVE_IPV6
+                             *addrpp = (union all_addr *)&serv->addr.in.sin_addr;
                            else
-                             *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr;
-#endif
+                             *addrpp = (union all_addr *)&serv->addr.in6.sin6_addr;
                          }
                        else if (!flags || (flags & F_NXDOMAIN))
                          flags = F_NOERR;
@@ -214,12 +227,16 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigne
 
   if (flags)
     {
-      int logflags = 0;
-      
-      if (flags == F_NXDOMAIN || flags == F_NOERR)
-       logflags = F_NEG | qtype;
-  
-      log_query(logflags | flags | F_CONFIG | F_FORWARD, qdomain, *addrpp, NULL);
+       if (flags == F_NXDOMAIN || flags == F_NOERR)
+        log_query(flags | qtype | F_NEG | F_CONFIG | F_FORWARD, qdomain, NULL, NULL);
+       else
+        {
+          /* handle F_IPV4 and F_IPV6 set on ANY query to 0.0.0.0/:: domain. */
+          if (flags & F_IPV4)
+            log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV6, qdomain, *addrpp, NULL);
+          if (flags & F_IPV6)
+            log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV4, qdomain, *addrpp, NULL);
+        }
     }
   else if ((*type) & SERV_USE_RESOLV)
     {
@@ -230,13 +247,13 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigne
 }
 
 static int forward_query(int udpfd, union mysockaddr *udpaddr,
-                        struct all_addr *dst_addr, unsigned int dst_iface,
+                        union all_addr *dst_addr, unsigned int dst_iface,
                         struct dns_header *header, size_t plen, time_t now, 
                         struct frec *forward, int ad_reqd, int do_bit)
 {
   char *domain = NULL;
   int type = SERV_DO_DNSSEC, norebind = 0;
-  struct all_addr *addrp = NULL;
+  union all_addr *addrp = NULL;
   unsigned int flags = 0;
   struct server *start = NULL;
 #ifdef HAVE_DNSSEC
@@ -246,9 +263,9 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
   unsigned int crc = questions_crc(header, plen, daemon->namebuff);
   void *hash = &crc;
 #endif
- unsigned int gotname = extract_request(header, plen, daemon->namebuff, NULL);
-
- (void)do_bit;
 unsigned int gotname = extract_request(header, plen, daemon->namebuff, NULL);
+  unsigned char *oph = find_pseudoheader(header, plen, NULL, NULL, NULL, NULL);
 (void)do_bit;
 
   /* may be no servers available. */
   if (forward || (hash && (forward = lookup_frec_by_sender(ntohs(header->id), udpaddr, hash))))
@@ -280,27 +297,24 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
            PUTSHORT(SAFE_PKTSZ, pheader);
          
          if (forward->sentto->addr.sa.sa_family == AF_INET) 
-           log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, "retry", (struct all_addr *)&forward->sentto->addr.in.sin_addr, "dnssec");
-#ifdef HAVE_IPV6
+           log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, "retry", (union all_addr *)&forward->sentto->addr.in.sin_addr, "dnssec");
          else
-           log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, "retry", (struct all_addr *)&forward->sentto->addr.in6.sin6_addr, "dnssec");
-#endif
+           log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, "retry", (union all_addr *)&forward->sentto->addr.in6.sin6_addr, "dnssec");
+
   
          if (forward->sentto->sfd)
            fd = forward->sentto->sfd->fd;
          else
            {
-#ifdef HAVE_IPV6
              if (forward->sentto->addr.sa.sa_family == AF_INET6)
                fd = forward->rfd6->fd;
              else
-#endif
                fd = forward->rfd4->fd;
            }
          
-         while (retry_send( sendto(fd, (char *)header, plen, 0,
-                                   &forward->sentto->addr.sa,
-                                   sa_len(&forward->sentto->addr))));
+         while (retry_send(sendto(fd, (char *)header, plen, 0,
+                                  &forward->sentto->addr.sa,
+                                  sa_len(&forward->sentto->addr))));
          
          return 1;
        }
@@ -334,7 +348,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
       type &= ~SERV_DO_DNSSEC;      
 
       if (daemon->servers && !flags)
-       forward = get_new_frec(now, NULL, 0);
+       forward = get_new_frec(now, NULL, NULL);
       /* table full - flags == 0, return REFUSED */
       
       if (forward)
@@ -399,7 +413,6 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
       struct server *firstsentto = start;
       int subnet, forwarded = 0;
       size_t edns0_len;
-      unsigned char *oph = find_pseudoheader(header, plen, NULL, NULL, NULL, NULL);
       unsigned char *pheader;
       
       /* If a query is retried, use the log_id for the retry when logging the answer. */
@@ -455,7 +468,6 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
                fd = start->sfd->fd;
              else 
                {
-#ifdef HAVE_IPV6
                  if (start->addr.sa.sa_family == AF_INET6)
                    {
                      if (!forward->rfd6 &&
@@ -465,7 +477,6 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
                      fd = forward->rfd6->fd;
                    }
                  else
-#endif
                    {
                      if (!forward->rfd4 &&
                          !(forward->rfd4 = allocate_rfd(AF_INET)))
@@ -508,6 +519,10 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
            
              if (errno == 0)
                {
+#ifdef HAVE_DUMPFILE
+                 dump_packet(DUMP_UP_QUERY, (void *)header, plen, NULL, &start->addr);
+#endif
+                 
                  /* Keep info in case we want to re-send this packet */
                  daemon->srv_save = start;
                  daemon->packet_len = plen;
@@ -516,12 +531,10 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
                    strcpy(daemon->namebuff, "query");
                  if (start->addr.sa.sa_family == AF_INET)
                    log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff, 
-                             (struct all_addr *)&start->addr.in.sin_addr, NULL); 
-#ifdef HAVE_IPV6
+                             (union all_addr *)&start->addr.in.sin_addr, NULL); 
                  else
                    log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff, 
-                             (struct all_addr *)&start->addr.in6.sin6_addr, NULL);
-#endif 
+                             (union  all_addr *)&start->addr.in6.sin6_addr, NULL);
                  start->queries++;
                  forwarded = 1;
                  forward->sentto = start;
@@ -550,6 +563,8 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
   if (udpfd != -1)
     {
       plen = setup_reply(header, plen, addrp, flags, daemon->local_ttl);
+      if (oph)
+       plen = add_pseudoheader(header, plen, ((unsigned char *) header) + PACKETSZ, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
       send_from(udpfd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND), (char *)header, plen, udpaddr, dst_addr, dst_iface);
     }
 
@@ -563,6 +578,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
   unsigned char *pheader, *sizep;
   char **sets = 0;
   int munged = 0, is_sign;
+  unsigned int rcode = RCODE(header);
   size_t plen; 
   
   (void)ad_reqd;
@@ -593,6 +609,9 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
   
   if ((pheader = find_pseudoheader(header, n, &plen, &sizep, &is_sign, NULL)))
     {
+      /* Get extended RCODE. */
+      rcode |= sizep[2] << 4;
+
       if (check_subnet && !check_source(header, plen, pheader, query_source))
        {
          my_syslog(LOG_WARNING, _("discarding DNS reply: subnet option mismatch"));
@@ -641,20 +660,29 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
   if (!is_sign && !option_bool(OPT_DNSSEC_PROXY))
      header->hb4 &= ~HB4_AD;
   
-  if (OPCODE(header) != QUERY || (RCODE(header) != NOERROR && RCODE(header) != NXDOMAIN))
+  if (OPCODE(header) != QUERY)
     return resize_packet(header, n, pheader, plen);
+
+  if (rcode != NOERROR && rcode != NXDOMAIN)
+    {
+      union all_addr a;
+      a.log.rcode = rcode;
+      log_query(F_UPSTREAM | F_RCODE, "error", &a, NULL);
+      
+      return resize_packet(header, n, pheader, plen);
+    }
   
   /* Complain loudly if the upstream server is non-recursive. */
-  if (!(header->hb4 & HB4_RA) && RCODE(header) == NOERROR &&
+  if (!(header->hb4 & HB4_RA) && rcode == NOERROR &&
       server && !(server->flags & SERV_WARNED_RECURSIVE))
     {
-      prettyprint_addr(&server->addr, daemon->namebuff);
+      (void)prettyprint_addr(&server->addr, daemon->namebuff);
       my_syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff);
       if (!option_bool(OPT_LOG))
        server->flags |= SERV_WARNED_RECURSIVE;
     }  
 
-  if (daemon->bogus_addr && RCODE(header) != NXDOMAIN &&
+  if (daemon->bogus_addr && rcode != NXDOMAIN &&
       check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now))
     {
       munged = 1;
@@ -666,7 +694,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
     {
       int doctored = 0;
       
-      if (RCODE(header) == NXDOMAIN && 
+      if (rcode == NXDOMAIN && 
          extract_request(header, n, daemon->namebuff, NULL) &&
          check_for_local_domain(daemon->namebuff, now))
        {
@@ -749,14 +777,11 @@ void reply_query(int fd, int family, time_t now)
   daemon->srv_save = NULL;
   
   /* Determine the address of the server replying  so that we can mark that as good */
-  serveraddr.sa.sa_family = family;
-#ifdef HAVE_IPV6
-  if (serveraddr.sa.sa_family == AF_INET6)
+  if ((serveraddr.sa.sa_family = family) == AF_INET6)
     serveraddr.in6.sin6_flowinfo = 0;
-#endif
   
   header = (struct dns_header *)daemon->packet;
-  
+
   if (n < (int)sizeof(struct dns_header) || !(header->hb3 & HB3_QR))
     return;
   
@@ -783,6 +808,11 @@ void reply_query(int fd, int family, time_t now)
   if (!(forward = lookup_frec(ntohs(header->id), hash)))
     return;
   
+#ifdef HAVE_DUMPFILE
+  dump_packet((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_REPLY : DUMP_UP_REPLY,
+             (void *)header, n, &serveraddr, NULL);
+#endif
+
   /* log_query gets called indirectly all over the place, so 
      pass these in global variables - sorry. */
   daemon->log_display_id = forward->log_id;
@@ -794,7 +824,7 @@ void reply_query(int fd, int family, time_t now)
 
   /* Note: if we send extra options in the EDNS0 header, we can't recreate
      the query from the reply. */
-  if (RCODE(header) == REFUSED &&
+  if ((RCODE(header) == REFUSED || RCODE(header) == SERVFAIL) &&
       forward->forwardall == 0 &&
       !(forward->flags & FREC_HAS_EXTRADATA))
     /* for broken servers, attempt to send to another one. */
@@ -803,6 +833,70 @@ void reply_query(int fd, int family, time_t now)
       size_t plen;
       int is_sign;
 
+#ifdef HAVE_DNSSEC
+      /* For DNSSEC originated queries, just retry the query to the same server. */
+      if (forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY))
+       {
+         struct server *start;
+         
+         blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
+         plen = forward->stash_len;
+
+         forward->forwardall = 2; /* only retry once */
+         start = forward->sentto;
+
+         /* for non-domain specific servers, see if we can find another to try. */
+         if ((forward->sentto->flags & SERV_TYPE) == 0)
+           while (1)
+             {
+               if (!(start = start->next))
+                 start = daemon->servers;
+               if (start == forward->sentto)
+                 break;
+               
+               if ((start->flags & SERV_TYPE) == 0 &&
+                   (start->flags & SERV_DO_DNSSEC))
+                 break;
+             }
+           
+         
+         if (start->sfd)
+           fd = start->sfd->fd;
+         else
+           {
+             if (start->addr.sa.sa_family == AF_INET6)
+               {
+                 /* may have changed family */
+                 if (!forward->rfd6)
+                   forward->rfd6 = allocate_rfd(AF_INET6);
+                 fd = forward->rfd6->fd;
+               }
+             else
+               {
+                 /* may have changed family */
+                 if (!forward->rfd4)
+                   forward->rfd4 = allocate_rfd(AF_INET);
+                 fd = forward->rfd4->fd;
+               }
+           }
+
+#ifdef HAVE_DUMPFILE
+         dump_packet(DUMP_SEC_QUERY, (void *)header, (size_t)plen, NULL, &start->addr);
+#endif
+
+         while (retry_send(sendto(fd, (char *)header, plen, 0,
+                                  &start->addr.sa,
+                                  sa_len(&start->addr))));
+         
+         if (start->addr.sa.sa_family == AF_INET) 
+           log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, "retry", (union all_addr *)&start->addr.in.sin_addr, "dnssec");
+         else
+           log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, "retry", (union all_addr *)&start->addr.in6.sin6_addr, "dnssec");
+         
+         return;
+       }
+#endif
+      
       /* In strict order mode, there must be a server later in the chain
         left to send to, otherwise without the forwardall mechanism,
         code further on will cycle around the list forwever if they
@@ -861,12 +955,12 @@ void reply_query(int fd, int family, time_t now)
   /* We tried resending to this server with a smaller maximum size and got an answer.
      Make that permanent. To avoid reduxing the packet size for a single dropped packet,
      only do this when we get a truncated answer, or one larger than the safe size. */
-  if (server && server->edns_pktsz > SAFE_PKTSZ && (forward->flags & FREC_TEST_PKTSZ) && 
+  if (forward->sentto->edns_pktsz > SAFE_PKTSZ && (forward->flags & FREC_TEST_PKTSZ) && 
       ((header->hb3 & HB3_TC) || n >= SAFE_PKTSZ))
     {
-      server->edns_pktsz = SAFE_PKTSZ;
-      server->pktsz_reduced = now;
-      prettyprint_addr(&server->addr, daemon->addrbuff);
+      forward->sentto->edns_pktsz = SAFE_PKTSZ;
+      forward->sentto->pktsz_reduced = now;
+      (void)prettyprint_addr(&forward->sentto->addr, daemon->addrbuff);
       my_syslog(LOG_WARNING, _("reducing DNS packet size for nameserver %s to %d"), daemon->addrbuff, SAFE_PKTSZ);
     }
 
@@ -875,8 +969,7 @@ void reply_query(int fd, int family, time_t now)
      we get a good reply from another server. Kill it when we've
      had replies from all to avoid filling the forwarding table when
      everything is broken */
-  if (forward->forwardall == 0 || --forward->forwardall == 1 ||
-      (RCODE(header) != REFUSED && RCODE(header) != SERVFAIL))
+  if (forward->forwardall == 0 || --forward->forwardall == 1 || RCODE(header) != REFUSED)
     {
       int check_rebind = 0, no_cache_dnssec = 0, cache_secure = 0, bogusanswer = 0;
       
@@ -889,7 +982,7 @@ void reply_query(int fd, int family, time_t now)
        no_cache_dnssec = 1;
       
 #ifdef HAVE_DNSSEC
-      if (server && (server->flags & SERV_DO_DNSSEC) && 
+      if ((forward->sentto->flags & SERV_DO_DNSSEC) && 
          option_bool(OPT_DNSSEC_VALID) && !(forward->flags & FREC_CHECKING_DISABLED))
        {
          int status = 0;
@@ -919,8 +1012,13 @@ void reply_query(int fd, int family, time_t now)
                    status = dnssec_validate_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
                  else
                    status = dnssec_validate_reply(now, header, n, daemon->namebuff, daemon->keyname, &forward->class, 
-                                                  option_bool(OPT_DNSSEC_NO_SIGN) && (server->flags & SERV_DO_DNSSEC),
-                                                  NULL, NULL);
+                                                  !option_bool(OPT_DNSSEC_IGN_NS) && (forward->sentto->flags & SERV_DO_DNSSEC),
+                                                  NULL, NULL, NULL);
+#ifdef HAVE_DUMPFILE
+                 if (status == STAT_BOGUS)
+                   dump_packet((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_BOGUS : DUMP_BOGUS,
+                               header, (size_t)n, &serveraddr, NULL);
+#endif
                }
              
              /* Can't validate, as we're missing key data. Put this
@@ -941,11 +1039,13 @@ void reply_query(int fd, int family, time_t now)
                  /* Find the original query that started it all.... */
                  for (orig = forward; orig->dependent; orig = orig->dependent);
                  
-                 if (--orig->work_counter == 0 || !(new = get_new_frec(now, NULL, 1)))
+                 /* Make sure we don't expire and free the orig frec during the
+                    allocation of a new one. */
+                 if (--orig->work_counter == 0 || !(new = get_new_frec(now, NULL, orig)))
                    status = STAT_ABANDONED;
                  else
                    {
-                     int fd, type = SERV_DO_DNSSEC;
+                     int querytype, fd, type = SERV_DO_DNSSEC;
                      struct frec *next = new->next;
                      char *domain;
                      
@@ -958,12 +1058,13 @@ void reply_query(int fd, int family, time_t now)
                         servers for domains are involved. */                 
                      if (search_servers(now, NULL, F_DNSSECOK, daemon->keyname, &type, &domain, NULL) == 0)
                        {
-                         struct server *start = server, *new_server = NULL;
+                         struct server *start, *new_server = NULL;
+                         start = server = forward->sentto;
                          
                          while (1)
                            {
                              if (type == (start->flags & (SERV_TYPE | SERV_DO_DNSSEC)) &&
-                                 (type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
+                                 ((type & SERV_TYPE) != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
                                  !(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
                                {
                                  new_server = start;
@@ -986,10 +1087,9 @@ void reply_query(int fd, int family, time_t now)
                      
                      new->sentto = server;
                      new->rfd4 = NULL;
-#ifdef HAVE_IPV6
                      new->rfd6 = NULL;
-#endif
-                     new->flags &= ~(FREC_DNSKEY_QUERY | FREC_DS_QUERY);
+                     new->flags &= ~(FREC_DNSKEY_QUERY | FREC_DS_QUERY | FREC_HAS_EXTRADATA);
+                     new->forwardall = 0;
                      
                      new->dependent = forward; /* to find query awaiting new one. */
                      forward->blocking_query = new; /* for garbage cleaning */
@@ -997,15 +1097,24 @@ void reply_query(int fd, int family, time_t now)
                      if (status == STAT_NEED_KEY)
                        {
                          new->flags |= FREC_DNSKEY_QUERY; 
-                         nn = dnssec_generate_query(header, ((unsigned char *) header) + server->edns_pktsz,
-                                                    daemon->keyname, forward->class, T_DNSKEY, &server->addr, server->edns_pktsz);
+                         querytype = T_DNSKEY;
                        }
                      else 
                        {
                          new->flags |= FREC_DS_QUERY;
-                         nn = dnssec_generate_query(header,((unsigned char *) header) + server->edns_pktsz,
-                                                    daemon->keyname, forward->class, T_DS, &server->addr, server->edns_pktsz);
+                         querytype = T_DS;
                        }
+
+                     nn = dnssec_generate_query(header,((unsigned char *) header) + server->edns_pktsz,
+                                                daemon->keyname, forward->class, querytype, server->edns_pktsz);
+
+                     if (server->addr.sa.sa_family == AF_INET) 
+                       log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, daemon->keyname, (union all_addr *)&(server->addr.in.sin_addr),
+                                 querystr("dnssec-query", querytype));
+                     else
+                       log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, daemon->keyname, (union all_addr *)&(server->addr.in6.sin6_addr),
+                                 querystr("dnssec-query", querytype));
+  
                      if ((hash = hash_questions(header, nn, daemon->namebuff)))
                        memcpy(new->hash, hash, HASH_SIZE);
                      new->new_id = get_id();
@@ -1022,14 +1131,12 @@ void reply_query(int fd, int family, time_t now)
                      else
                        {
                          fd = -1;
-#ifdef HAVE_IPV6
                          if (server->addr.sa.sa_family == AF_INET6)
                            {
                              if (new->rfd6 || (new->rfd6 = allocate_rfd(AF_INET6)))
                                fd = new->rfd6->fd;
                            }
                          else
-#endif
                            {
                              if (new->rfd4 || (new->rfd4 = allocate_rfd(AF_INET)))
                                fd = new->rfd4->fd;
@@ -1047,6 +1154,11 @@ void reply_query(int fd, int family, time_t now)
                                setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
                            }
 #endif
+                         
+#ifdef HAVE_DUMPFILE
+                         dump_packet(DUMP_SEC_QUERY, (void *)header, (size_t)nn, NULL, &server->addr);
+#endif
+                         
                          while (retry_send(sendto(fd, (char *)header, nn, 0, 
                                                   &server->addr.sa, 
                                                   sa_len(&server->addr)))); 
@@ -1090,7 +1202,7 @@ void reply_query(int fd, int family, time_t now)
              if (status == STAT_BOGUS && extract_request(header, n, daemon->namebuff, NULL))
                domain = daemon->namebuff;
              
-             log_query(F_KEYTAG | F_SECSTAT, domain, NULL, result);
+             log_query(F_SECSTAT, domain, NULL, result);
            }
          
          if (status == STAT_SECURE)
@@ -1101,8 +1213,9 @@ void reply_query(int fd, int family, time_t now)
              bogusanswer = 1;
            }
        }
-#endif     
-      
+
+#endif
+
       /* restore CD bit to the value in the query */
       if (forward->flags & FREC_CHECKING_DISABLED)
        header->hb4 |= HB4_CD;
@@ -1128,6 +1241,11 @@ void reply_query(int fd, int family, time_t now)
              nn = resize_packet(header, nn, NULL, 0);
            }
 #endif
+
+#ifdef HAVE_DUMPFILE
+         dump_packet(DUMP_REPLY, daemon->packet, (size_t)nn, NULL, &forward->source);
+#endif
+         
          send_from(forward->fd, option_bool(OPT_NOWILD) || option_bool (OPT_CLEVERBIND), daemon->packet, nn, 
                    &forward->source, &forward->dest, forward->iface);
        }
@@ -1142,7 +1260,7 @@ void receive_query(struct listener *listen, time_t now)
   union mysockaddr source_addr;
   unsigned char *pheader;
   unsigned short type, udp_size = PACKETSZ; /* default if no EDNS0 */
-  struct all_addr dst_addr;
+  union all_addr dst_addr;
   struct in_addr netmask, dst_addr_4;
   size_t m;
   ssize_t n;
@@ -1155,9 +1273,7 @@ void receive_query(struct listener *listen, time_t now)
   struct cmsghdr *cmptr;
   union {
     struct cmsghdr align; /* this ensures alignment */
-#ifdef HAVE_IPV6
     char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
-#endif
 #if defined(HAVE_LINUX_NETWORK)
     char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
 #elif defined(IP_RECVDSTADDR) && defined(HAVE_SOLARIS_NETWORK)
@@ -1168,26 +1284,23 @@ void receive_query(struct listener *listen, time_t now)
                 CMSG_SPACE(sizeof(struct sockaddr_dl))];
 #endif
   } control_u;
-#ifdef HAVE_IPV6
+  int family = listen->addr.sa.sa_family;
    /* Can always get recvd interface for IPv6 */
-  int check_dst = !option_bool(OPT_NOWILD) || listen->family == AF_INET6;
-#else
-  int check_dst = !option_bool(OPT_NOWILD);
-#endif
+  int check_dst = !option_bool(OPT_NOWILD) || family == AF_INET6;
 
   /* packet buffer overwritten */
   daemon->srv_save = NULL;
   
-  dst_addr_4.s_addr = dst_addr.addr.addr4.s_addr = 0;
+  dst_addr_4.s_addr = dst_addr.addr4.s_addr = 0;
   netmask.s_addr = 0;
   
   if (option_bool(OPT_NOWILD) && listen->iface)
     {
       auth_dns = listen->iface->dns_auth;
      
-      if (listen->family == AF_INET)
+      if (family == AF_INET)
        {
-         dst_addr_4 = dst_addr.addr.addr4 = listen->iface->addr.in.sin_addr;
+         dst_addr_4 = dst_addr.addr4 = listen->iface->addr.in.sin_addr;
          netmask = listen->iface->netmask;
        }
     }
@@ -1215,16 +1328,15 @@ void receive_query(struct listener *listen, time_t now)
      information disclosure. */
   memset(daemon->packet + n, 0, daemon->edns_pktsz - n);
   
-  source_addr.sa.sa_family = listen->family;
+  source_addr.sa.sa_family = family;
   
-  if (listen->family == AF_INET)
+  if (family == AF_INET)
     {
        /* Source-port == 0 is an error, we can't send back to that. 
          http://www.ietf.org/mail-archive/web/dnsop/current/msg11441.html */
       if (source_addr.in.sin_port == 0)
        return;
     }
-#ifdef HAVE_IPV6
   else
     {
       /* Source-port == 0 is an error, we can't send back to that. */
@@ -1232,29 +1344,27 @@ void receive_query(struct listener *listen, time_t now)
        return;
       source_addr.in6.sin6_flowinfo = 0;
     }
-#endif
   
   /* We can be configured to only accept queries from at-most-one-hop-away addresses. */
   if (option_bool(OPT_LOCAL_SERVICE))
     {
       struct addrlist *addr;
-#ifdef HAVE_IPV6
-      if (listen->family == AF_INET6) 
+
+      if (family == AF_INET6) 
        {
          for (addr = daemon->interface_addrs; addr; addr = addr->next)
            if ((addr->flags & ADDRLIST_IPV6) &&
-               is_same_net6(&addr->addr.addr.addr6, &source_addr.in6.sin6_addr, addr->prefixlen))
+               is_same_net6(&addr->addr.addr6, &source_addr.in6.sin6_addr, addr->prefixlen))
              break;
        }
       else
-#endif
        {
          struct in_addr netmask;
          for (addr = daemon->interface_addrs; addr; addr = addr->next)
            {
              netmask.s_addr = htonl(~(in_addr_t)0 << (32 - addr->prefixlen));
              if (!(addr->flags & ADDRLIST_IPV6) &&
-                 is_same_net(addr->addr.addr.addr4, source_addr.in.sin_addr, netmask))
+                 is_same_net(addr->addr.addr4, source_addr.in.sin_addr, netmask))
                break;
            }
        }
@@ -1278,7 +1388,7 @@ void receive_query(struct listener *listen, time_t now)
        return;
 
 #if defined(HAVE_LINUX_NETWORK)
-      if (listen->family == AF_INET)
+      if (family == AF_INET)
        for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
          if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
            {
@@ -1287,11 +1397,11 @@ void receive_query(struct listener *listen, time_t now)
                struct in_pktinfo *p;
              } p;
              p.c = CMSG_DATA(cmptr);
-             dst_addr_4 = dst_addr.addr.addr4 = p.p->ipi_spec_dst;
+             dst_addr_4 = dst_addr.addr4 = p.p->ipi_spec_dst;
              if_index = p.p->ipi_ifindex;
            }
 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
-      if (listen->family == AF_INET)
+      if (family == AF_INET)
        {
          for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
            {
@@ -1305,7 +1415,7 @@ void receive_query(struct listener *listen, time_t now)
              } p;
               p.c = CMSG_DATA(cmptr);
               if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
-                dst_addr_4 = dst_addr.addr.addr4 = *(p.a);
+                dst_addr_4 = dst_addr.addr4 = *(p.a);
               else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
 #ifdef HAVE_SOLARIS_NETWORK
                 if_index = *(p.i);
@@ -1316,8 +1426,7 @@ void receive_query(struct listener *listen, time_t now)
        }
 #endif
       
-#ifdef HAVE_IPV6
-      if (listen->family == AF_INET6)
+      if (family == AF_INET6)
        {
          for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
            if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
@@ -1328,27 +1437,26 @@ void receive_query(struct listener *listen, time_t now)
                } p;
                p.c = CMSG_DATA(cmptr);
                  
-               dst_addr.addr.addr6 = p.p->ipi6_addr;
+               dst_addr.addr6 = p.p->ipi6_addr;
                if_index = p.p->ipi6_ifindex;
              }
        }
-#endif
       
       /* enforce available interface configuration */
       
       if (!indextoname(listen->fd, if_index, ifr.ifr_name))
        return;
       
-      if (!iface_check(listen->family, &dst_addr, ifr.ifr_name, &auth_dns))
+      if (!iface_check(family, &dst_addr, ifr.ifr_name, &auth_dns))
        {
           if (!option_bool(OPT_CLEVERBIND))
             enumerate_interfaces(0); 
-          if (!loopback_exception(listen->fd, listen->family, &dst_addr, ifr.ifr_name) &&
-              !label_exception(if_index, listen->family, &dst_addr))
+          if (!loopback_exception(listen->fd, family, &dst_addr, ifr.ifr_name) &&
+              !label_exception(if_index, family, &dst_addr))
             return;
        }
 
-      if (listen->family == AF_INET && option_bool(OPT_LOCALISE))
+      if (family == AF_INET && option_bool(OPT_LOCALISE))
        {
          struct irec *iface;
          
@@ -1381,7 +1489,11 @@ void receive_query(struct listener *listen, time_t now)
      pass these in global variables - sorry. */
   daemon->log_display_id = ++daemon->log_id;
   daemon->log_source_addr = &source_addr;
-  
+
+#ifdef HAVE_DUMPFILE
+  dump_packet(DUMP_QUERY, daemon->packet, (size_t)n, &source_addr, NULL);
+#endif
+         
   if (extract_request(header, (size_t)n, daemon->namebuff, &type))
     {
 #ifdef HAVE_AUTH
@@ -1389,14 +1501,12 @@ void receive_query(struct listener *listen, time_t now)
 #endif
       char *types = querystr(auth_dns ? "auth" : "query", type);
       
-      if (listen->family == AF_INET) 
+      if (family == AF_INET) 
        log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff, 
-                 (struct all_addr *)&source_addr.in.sin_addr, types);
-#ifdef HAVE_IPV6
+                 (union all_addr *)&source_addr.in.sin_addr, types);
       else
        log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, 
-                 (struct all_addr *)&source_addr.in6.sin6_addr, types);
-#endif
+                 (union all_addr *)&source_addr.in6.sin6_addr, types);
 
 #ifdef HAVE_AUTH
       /* find queries for zones we're authoritative for, and answer them directly */
@@ -1447,7 +1557,7 @@ void receive_query(struct listener *listen, time_t now)
        {
          send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
                    (char *)header, m, &source_addr, &dst_addr, if_index);
-         daemon->auth_answer++;
+         daemon->metrics[METRIC_DNS_AUTH_ANSWERED]++;
        }
     }
   else
@@ -1465,13 +1575,13 @@ void receive_query(struct listener *listen, time_t now)
        {
          send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
                    (char *)header, m, &source_addr, &dst_addr, if_index);
-         daemon->local_answer++;
+         daemon->metrics[METRIC_DNS_LOCAL_ANSWERED]++;
        }
       else if (forward_query(listen->fd, &source_addr, &dst_addr, if_index,
                             header, (size_t)n, now, NULL, ad_reqd, do_bit))
-       daemon->queries_forwarded++;
+       daemon->metrics[METRIC_DNS_QUERIES_FORWARDED]++;
       else
-       daemon->local_answer++;
+       daemon->metrics[METRIC_DNS_LOCAL_ANSWERED]++;
     }
 }
 
@@ -1504,8 +1614,8 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
        new_status = dnssec_validate_ds(now, header, n, name, keyname, class);
       else 
        new_status = dnssec_validate_reply(now, header, n, name, keyname, &class,
-                                          option_bool(OPT_DNSSEC_NO_SIGN) && (server->flags & SERV_DO_DNSSEC),
-                                          NULL, NULL);
+                                          !option_bool(OPT_DNSSEC_IGN_NS) && (server->flags & SERV_DO_DNSSEC),
+                                          NULL, NULL, NULL);
       
       if (new_status != STAT_NEED_DS && new_status != STAT_NEED_KEY)
        break;
@@ -1525,9 +1635,9 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
          new_status = STAT_ABANDONED;
          break;
        }
-        
+
       m = dnssec_generate_query(new_header, ((unsigned char *) new_header) + 65536, keyname, class, 
-                               new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS, &server->addr, server->edns_pktsz);
+                               new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS, server->edns_pktsz);
       
       *length = htons(m);
 
@@ -1542,6 +1652,8 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
        
       while (1)
        {
+         int data_sent = 0;
+         
          if (!firstsendto)
            firstsendto = server;
          else
@@ -1560,32 +1672,46 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
              (type == SERV_HAS_DOMAIN && !hostname_isequal(domain, server->domain)) ||
              (server->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
            continue;
-           
-         retry:
-           /* may need to make new connection. */
-           if (server->tcpfd == -1)
-             {
-               if ((server->tcpfd = socket(server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
-                 continue; /* No good, next server */
-               
+
+       retry:
+         /* may need to make new connection. */
+         if (server->tcpfd == -1)
+           {
+             if ((server->tcpfd = socket(server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
+               continue; /* No good, next server */
+             
 #ifdef HAVE_CONNTRACK
-               /* Copy connection mark of incoming query to outgoing connection. */
-               if (have_mark)
-                 setsockopt(server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
+             /* Copy connection mark of incoming query to outgoing connection. */
+             if (have_mark)
+               setsockopt(server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
 #endif 
-               
-               if (!local_bind(server->tcpfd,  &server->source_addr, server->interface, 0, 1) ||
-                   connect(server->tcpfd, &server->addr.sa, sa_len(&server->addr)) == -1)
-                 {
-                   close(server->tcpfd);
-                   server->tcpfd = -1;
-                   continue; /* No good, next server */
-                 }
-               
-               server->flags &= ~SERV_GOT_TCP;
-             }
+             
+             if (!local_bind(server->tcpfd,  &server->source_addr, server->interface, 0, 1))
+               {
+                 close(server->tcpfd);
+                 server->tcpfd = -1;
+                 continue; /* No good, next server */
+               }
+             
+#ifdef MSG_FASTOPEN
+             while(retry_send(sendto(server->tcpfd, packet, m + sizeof(u16),
+                                     MSG_FASTOPEN, &server->addr.sa, sa_len(&server->addr))));
+             
+             if (errno == 0)
+               data_sent = 1;
+#endif
+             
+             if (!data_sent && connect(server->tcpfd, &server->addr.sa, sa_len(&server->addr)) == -1)
+               {
+                 close(server->tcpfd);
+                 server->tcpfd = -1;
+                 continue; /* No good, next server */
+               }
+             
+             server->flags &= ~SERV_GOT_TCP;
+           }
          
-         if (!read_write(server->tcpfd, packet, m + sizeof(u16), 0) ||
+         if ((!data_sent && !read_write(server->tcpfd, packet, m + sizeof(u16), 0)) ||
              !read_write(server->tcpfd, &c1, 1, 1) ||
              !read_write(server->tcpfd, &c2, 1, 1) ||
              !read_write(server->tcpfd, payload, (c1 << 8) | c2, 1))
@@ -1600,6 +1726,14 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
              else
                continue;
            }
+
+
+         if (server->addr.sa.sa_family == AF_INET) 
+           log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, keyname, (union all_addr *)&(server->addr.in.sin_addr),
+                     querystr("dnssec-query", new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS));
+         else
+           log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, keyname, (union all_addr *)&(server->addr.in6.sin6_addr),
+                     querystr("dnssec-query", new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS));
          
          server->flags |= SERV_GOT_TCP;
          
@@ -1663,13 +1797,12 @@ unsigned char *tcp_request(int confd, time_t now,
   /* Get connection mark of incoming query to set on outgoing connections. */
   if (option_bool(OPT_CONNTRACK))
     {
-      struct all_addr local;
-#ifdef HAVE_IPV6                     
+      union all_addr local;
+                     
       if (local_addr->sa.sa_family == AF_INET6)
-       local.addr.addr6 = local_addr->in6.sin6_addr;
+       local.addr6 = local_addr->in6.sin6_addr;
       else
-#endif
-       local.addr.addr4 = local_addr->in.sin_addr;
+       local.addr4 = local_addr->in.sin_addr;
       
       have_mark = get_incoming_mark(&peer_addr, &local, 1, &mark);
     }
@@ -1679,23 +1812,22 @@ unsigned char *tcp_request(int confd, time_t now,
   if (option_bool(OPT_LOCAL_SERVICE))
     {
       struct addrlist *addr;
-#ifdef HAVE_IPV6
+
       if (peer_addr.sa.sa_family == AF_INET6) 
        {
          for (addr = daemon->interface_addrs; addr; addr = addr->next)
            if ((addr->flags & ADDRLIST_IPV6) &&
-               is_same_net6(&addr->addr.addr.addr6, &peer_addr.in6.sin6_addr, addr->prefixlen))
+               is_same_net6(&addr->addr.addr6, &peer_addr.in6.sin6_addr, addr->prefixlen))
              break;
        }
       else
-#endif
        {
          struct in_addr netmask;
          for (addr = daemon->interface_addrs; addr; addr = addr->next)
            {
              netmask.s_addr = htonl(~(in_addr_t)0 << (32 - addr->prefixlen));
              if (!(addr->flags & ADDRLIST_IPV6) && 
-                 is_same_net(addr->addr.addr.addr4, peer_addr.in.sin_addr, netmask))
+                 is_same_net(addr->addr.addr4, peer_addr.in.sin_addr, netmask))
                break;
            }
        }
@@ -1742,12 +1874,10 @@ unsigned char *tcp_request(int confd, time_t now,
          
          if (peer_addr.sa.sa_family == AF_INET) 
            log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff, 
-                     (struct all_addr *)&peer_addr.in.sin_addr, types);
-#ifdef HAVE_IPV6
+                     (union all_addr *)&peer_addr.in.sin_addr, types);
          else
            log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, 
-                     (struct all_addr *)&peer_addr.in6.sin6_addr, types);
-#endif
+                     (union all_addr *)&peer_addr.in6.sin6_addr, types);
          
 #ifdef HAVE_AUTH
          /* find queries for zones we're authoritative for, and answer them directly */
@@ -1803,7 +1933,7 @@ unsigned char *tcp_request(int confd, time_t now,
          if (m == 0)
            {
              unsigned int flags = 0;
-             struct all_addr *addrp = NULL;
+             union all_addr *addrp = NULL;
              int type = SERV_DO_DNSSEC;
              char *domain = NULL;
              unsigned char *oph = find_pseudoheader(header, size, NULL, NULL, NULL, NULL);
@@ -1854,6 +1984,8 @@ unsigned char *tcp_request(int confd, time_t now,
                     which can go to the same server, do so. */
                  while (1) 
                    {
+                     int data_sent = 0;
+
                      if (!firstsendto)
                        firstsendto = last_server;
                      else
@@ -1872,6 +2004,8 @@ unsigned char *tcp_request(int confd, time_t now,
                        continue;
 
                    retry:
+                     *length = htons(size);
+
                      if (last_server->tcpfd == -1)
                        {
                          if ((last_server->tcpfd = socket(last_server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
@@ -1881,10 +2015,24 @@ unsigned char *tcp_request(int confd, time_t now,
                          /* Copy connection mark of incoming query to outgoing connection. */
                          if (have_mark)
                            setsockopt(last_server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
-#endif 
+#endif                   
                      
-                         if ((!local_bind(last_server->tcpfd,  &last_server->source_addr, last_server->interface, 0, 1) ||
-                              connect(last_server->tcpfd, &last_server->addr.sa, sa_len(&last_server->addr)) == -1))
+                         if ((!local_bind(last_server->tcpfd,  &last_server->source_addr, last_server->interface, 0, 1)))
+                           {
+                             close(last_server->tcpfd);
+                             last_server->tcpfd = -1;
+                             continue;
+                           }
+                         
+#ifdef MSG_FASTOPEN
+                           while(retry_send(sendto(last_server->tcpfd, packet, size + sizeof(u16),
+                                                   MSG_FASTOPEN, &last_server->addr.sa, sa_len(&last_server->addr))));
+                           
+                           if (errno == 0)
+                             data_sent = 1;
+#endif
+                           
+                           if (!data_sent && connect(last_server->tcpfd, &last_server->addr.sa, sa_len(&last_server->addr)) == -1)
                            {
                              close(last_server->tcpfd);
                              last_server->tcpfd = -1;
@@ -1894,13 +2042,11 @@ unsigned char *tcp_request(int confd, time_t now,
                          last_server->flags &= ~SERV_GOT_TCP;
                        }
                      
-                     *length = htons(size);
-
                      /* get query name again for logging - may have been overwritten */
                      if (!(gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
                        strcpy(daemon->namebuff, "query");
                      
-                     if (!read_write(last_server->tcpfd, packet, size + sizeof(u16), 0) ||
+                     if ((!data_sent && !read_write(last_server->tcpfd, packet, size + sizeof(u16), 0)) ||
                          !read_write(last_server->tcpfd, &c1, 1, 1) ||
                          !read_write(last_server->tcpfd, &c2, 1, 1) ||
                          !read_write(last_server->tcpfd, payload, (c1 << 8) | c2, 1))
@@ -1922,12 +2068,10 @@ unsigned char *tcp_request(int confd, time_t now,
                      
                      if (last_server->addr.sa.sa_family == AF_INET)
                        log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff, 
-                                 (struct all_addr *)&last_server->addr.in.sin_addr, NULL); 
-#ifdef HAVE_IPV6
+                                 (union all_addr *)&last_server->addr.in.sin_addr, NULL); 
                      else
                        log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff, 
-                                 (struct all_addr *)&last_server->addr.in6.sin6_addr, NULL);
-#endif 
+                                 (union all_addr *)&last_server->addr.in6.sin6_addr, NULL);
 
 #ifdef HAVE_DNSSEC
                      if (option_bool(OPT_DNSSEC_VALID) && !checking_disabled && (last_server->flags & SERV_DO_DNSSEC))
@@ -1948,7 +2092,7 @@ unsigned char *tcp_request(int confd, time_t now,
                          if (status == STAT_BOGUS && extract_request(header, m, daemon->namebuff, NULL))
                            domain = daemon->namebuff;
 
-                         log_query(F_KEYTAG | F_SECSTAT, domain, NULL, result);
+                         log_query(F_SECSTAT, domain, NULL, result);
                          
                          if (status == STAT_BOGUS)
                            {
@@ -1998,7 +2142,11 @@ unsigned char *tcp_request(int confd, time_t now,
        
              /* In case of local answer or no connections made. */
              if (m == 0)
-               m = setup_reply(header, (unsigned int)size, addrp, flags, daemon->local_ttl);
+               {
+                 m = setup_reply(header, (unsigned int)size, addrp, flags, daemon->local_ttl);
+                 if (have_pseudoheader)
+                   m = add_pseudoheader(header, m, ((unsigned char *) header) + 65536, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
+               }
            }
        }
          
@@ -2022,9 +2170,7 @@ static struct frec *allocate_frec(time_t now)
       f->sentto = NULL;
       f->rfd4 = NULL;
       f->flags = 0;
-#ifdef HAVE_IPV6
       f->rfd6 = NULL;
-#endif
 #ifdef HAVE_DNSSEC
       f->dependent = NULL;
       f->blocking_query = NULL;
@@ -2084,11 +2230,8 @@ static void free_frec(struct frec *f)
   f->rfd4 = NULL;
   f->sentto = NULL;
   f->flags = 0;
-  
-#ifdef HAVE_IPV6
   free_rfd(f->rfd6);
   f->rfd6 = NULL;
-#endif
 
 #ifdef HAVE_DNSSEC
   if (f->stash)
@@ -2111,9 +2254,10 @@ static void free_frec(struct frec *f)
    else return *wait zero if one available, or *wait is delay to
    when the oldest in-use record will expire. Impose an absolute
    limit of 4*TIMEOUT before we wipe things (for random sockets).
-   If force is set, always return a result, even if we have
-   to allocate above the limit. */
-struct frec *get_new_frec(time_t now, int *wait, int force)
+   If force is non-NULL, always return a result, even if we have
+   to allocate above the limit, and never free the record pointed
+   to by the force argument. */
+struct frec *get_new_frec(time_t now, int *wait, struct frec *force)
 {
   struct frec *f, *oldest, *target;
   int count;
@@ -2130,7 +2274,7 @@ struct frec *get_new_frec(time_t now, int *wait, int force)
            /* Don't free DNSSEC sub-queries here, as we may end up with
               dangling references to them. They'll go when their "real" query 
               is freed. */
-           if (!f->dependent)
+           if (!f->dependent && f != force)
 #endif
              {
                if (difftime(now, f->time) >= 4*TIMEOUT)
index c134071..7072cf4 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -64,11 +64,10 @@ struct script_data
 #ifdef HAVE_TFTP
   off_t file_len;
 #endif
-#ifdef HAVE_IPV6
   struct in6_addr addr6;
-#endif
 #ifdef HAVE_DHCP6
-  int iaid, vendorclass_count;
+  int vendorclass_count;
+  unsigned int iaid;
 #endif
   unsigned char hwaddr[DHCP_CHADDR_MAX];
   char interface[IF_NAMESIZE];
@@ -82,7 +81,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
   pid_t pid;
   int i, pipefd[2];
   struct sigaction sigact;
-
+  unsigned char *alloc_buff = NULL;
+  
   /* create the pipe through which the main program sends us commands,
      then fork our process. */
   if (pipe(pipefd) == -1 || !fix_fd(pipefd[1]) || (pid = fork()) == -1)
@@ -131,12 +131,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
      Don't close err_fd, in case the lua-init fails.
      Note that we have to do this before lua init
      so we don't close any lua fds. */
-  for (max_fd--; max_fd >= 0; max_fd--)
-    if (max_fd != STDOUT_FILENO && max_fd != STDERR_FILENO && 
-       max_fd != STDIN_FILENO && max_fd != pipefd[0] && 
-       max_fd != event_fd && max_fd != err_fd)
-      close(max_fd);
-
+  close_fds(max_fd, pipefd[0], event_fd, err_fd);
+  
 #ifdef HAVE_LUASCRIPT
   if (daemon->luascript)
     {
@@ -188,11 +184,16 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
       struct script_data data;
       char *p, *action_str, *hostname = NULL, *domain = NULL;
       unsigned char *buf = (unsigned char *)daemon->namebuff;
-      unsigned char *end, *extradata, *alloc_buff = NULL;
+      unsigned char *end, *extradata;
       int is6, err = 0;
       int pipeout[2];
 
-      free(alloc_buff);
+      /* Free rarely-allocated memory from previous iteration. */
+      if (alloc_buff)
+       {
+         free(alloc_buff);
+         alloc_buff = NULL;
+       }
       
       /* we read zero bytes when pipe closed: this is our signal to exit */ 
       if (!read_write(pipefd[0], (unsigned char *)&data, sizeof(data), 1))
@@ -302,10 +303,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
     
       if (!is6)
        inet_ntop(AF_INET, &data.addr, daemon->addrbuff, ADDRSTRLEN);
-#ifdef HAVE_IPV6
       else
        inet_ntop(AF_INET6, &data.addr6, daemon->addrbuff, ADDRSTRLEN);
-#endif
 
 #ifdef HAVE_TFTP
       /* file length */
@@ -826,10 +825,8 @@ void queue_tftp(off_t file_len, char *filename, union mysockaddr *peer)
 
   if ((buf->flags = peer->sa.sa_family) == AF_INET)
     buf->addr = peer->in.sin_addr;
-#ifdef HAVE_IPV6
   else
     buf->addr6 = peer->in6.sin6_addr;
-#endif
 
   memcpy((unsigned char *)(buf+1), filename, filename_len);
   
@@ -837,7 +834,7 @@ void queue_tftp(off_t file_len, char *filename, union mysockaddr *peer)
 }
 #endif
 
-void queue_arp(int action, unsigned char *mac, int maclen, int family, struct all_addr *addr)
+void queue_arp(int action, unsigned char *mac, int maclen, int family, union all_addr *addr)
 {
   /* no script */
   if (daemon->helperfd == -1)
@@ -850,11 +847,9 @@ void queue_arp(int action, unsigned char *mac, int maclen, int family, struct al
   buf->hwaddr_len = maclen;
   buf->hwaddr_type =  ARPHRD_ETHER; 
   if ((buf->flags = family) == AF_INET)
-    buf->addr = addr->addr.addr4;
-#ifdef HAVE_IPV6
+    buf->addr = addr->addr4;
   else
-    buf->addr6 = addr->addr.addr6;
-#endif
+    buf->addr6 = addr->addr6;
   
   memcpy(buf->hwaddr, mac, maclen);
   
index 7107833..d5804cb 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
  
    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
index 6f6dff7..352b330 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
index 3a5ecc5..0c014cb 100644 (file)
@@ -22,9 +22,7 @@
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/socket.h>
-#include <sys/utsname.h>
 #include <arpa/inet.h>
-#include <linux/version.h>
 #include <linux/netlink.h>
 
 /* We want to be able to compile against old header files
@@ -87,20 +85,7 @@ static inline void add_attr(struct nlmsghdr *nlh, uint16_t type, size_t len, con
 
 void ipset_init(void)
 {
-  struct utsname utsname;
-  int version;
-  char *split;
-  
-  if (uname(&utsname) < 0)
-    die(_("failed to find kernel version: %s"), NULL, EC_MISC);
-  
-  split = strtok(utsname.release, ".");
-  version = (split ? atoi(split) : 0);
-  split = strtok(NULL, ".");
-  version = version * 256 + (split ? atoi(split) : 0);
-  split = strtok(NULL, ".");
-  version = version * 256 + (split ? atoi(split) : 0);
-  old_kernel = (version < KERNEL_VERSION(2,6,32));
+  old_kernel = (daemon->kernel_version < KERNEL_VERSION(2,6,32));
   
   if (old_kernel && (ipset_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) != -1)
     return;
@@ -114,19 +99,14 @@ void ipset_init(void)
   die (_("failed to create IPset control socket: %s"), NULL, EC_MISC);
 }
 
-static int new_add_to_ipset(const char *setname, const struct all_addr *ipaddr, int af, int remove)
+static int new_add_to_ipset(const char *setname, const union all_addr *ipaddr, int af, int remove)
 {
   struct nlmsghdr *nlh;
   struct my_nfgenmsg *nfg;
   struct my_nlattr *nested[2];
   uint8_t proto;
-  int addrsz = INADDRSZ;
+  int addrsz = (af == AF_INET6) ? IN6ADDRSZ : INADDRSZ;
 
-#ifdef HAVE_IPV6
-  if (af == AF_INET6)
-    addrsz = IN6ADDRSZ;
-#endif
-    
   if (strlen(setname) >= IPSET_MAXNAMELEN) 
     {
       errno = ENAMETOOLONG;
@@ -157,7 +137,7 @@ static int new_add_to_ipset(const char *setname, const struct all_addr *ipaddr,
   nested[1]->nla_type = NLA_F_NESTED | IPSET_ATTR_IP;
   add_attr(nlh, 
           (af == AF_INET ? IPSET_ATTR_IPADDR_IPV4 : IPSET_ATTR_IPADDR_IPV6) | NLA_F_NET_BYTEORDER,
-          addrsz, &ipaddr->addr);
+          addrsz, ipaddr);
   nested[1]->nla_len = (void *)buffer + NL_ALIGN(nlh->nlmsg_len) - (void *)nested[1];
   nested[0]->nla_len = (void *)buffer + NL_ALIGN(nlh->nlmsg_len) - (void *)nested[0];
        
@@ -168,7 +148,7 @@ static int new_add_to_ipset(const char *setname, const struct all_addr *ipaddr,
 }
 
 
-static int old_add_to_ipset(const char *setname, const struct all_addr *ipaddr, int remove)
+static int old_add_to_ipset(const char *setname, const union all_addr *ipaddr, int remove)
 {
   socklen_t size;
   struct ip_set_req_adt_get {
@@ -200,7 +180,7 @@ static int old_add_to_ipset(const char *setname, const struct all_addr *ipaddr,
     return -1;
   req_adt.op = remove ? 0x102 : 0x101;
   req_adt.index = req_adt_get.set.index;
-  req_adt.ip = ntohl(ipaddr->addr.addr4.s_addr);
+  req_adt.ip = ntohl(ipaddr->addr4.s_addr);
   if (setsockopt(ipset_sock, SOL_IP, 83, &req_adt, sizeof(req_adt)) < 0)
     return -1;
   
@@ -209,11 +189,10 @@ static int old_add_to_ipset(const char *setname, const struct all_addr *ipaddr,
 
 
 
-int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags, int remove)
+int add_to_ipset(const char *setname, const union all_addr *ipaddr, int flags, int remove)
 {
   int ret = 0, af = AF_INET;
 
-#ifdef HAVE_IPV6
   if (flags & F_IPV6)
     {
       af = AF_INET6;
@@ -224,7 +203,6 @@ int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags,
          ret = -1;
        }
     }
-#endif
   
   if (ret != -1) 
     ret = old_kernel ? old_add_to_ipset(setname, ipaddr, remove) : new_add_to_ipset(setname, ipaddr, af, remove);
index 5c33df7..23e6fe0 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -24,7 +24,7 @@ static int dns_dirty, file_dirty, leases_left;
 static int read_leases(time_t now, FILE *leasestream)
 {
   unsigned long ei;
-  struct all_addr addr;
+  union all_addr addr;
   struct dhcp_lease *lease;
   int clid_len, hw_len, hw_type;
   int items;
@@ -60,11 +60,16 @@ static int read_leases(time_t now, FILE *leasestream)
        
        if (fscanf(leasestream, " %64s %255s %764s",
                   daemon->namebuff, daemon->dhcp_buff, daemon->packet) != 3)
-         return 0;
-       
-       if (inet_pton(AF_INET, daemon->namebuff, &addr.addr.addr4))
          {
-           if ((lease = lease4_allocate(addr.addr.addr4)))
+           my_syslog(MS_DHCP | LOG_WARNING, _("ignoring invalid line in lease database: %s %s %s %s ..."),
+                     daemon->dhcp_buff3, daemon->dhcp_buff2,
+                     daemon->namebuff, daemon->dhcp_buff);
+           continue;
+         }
+               
+       if (inet_pton(AF_INET, daemon->namebuff, &addr.addr4))
+         {
+           if ((lease = lease4_allocate(addr.addr4)))
              domain = get_domain(lease->addr);
            
            hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, DHCP_CHADDR_MAX, NULL, &hw_type);
@@ -73,7 +78,7 @@ static int read_leases(time_t now, FILE *leasestream)
              hw_type = ARPHRD_ETHER; 
          }
 #ifdef HAVE_DHCP6
-       else if (inet_pton(AF_INET6, daemon->namebuff, &addr.addr.addr6))
+       else if (inet_pton(AF_INET6, daemon->namebuff, &addr.addr6))
          {
            char *s = daemon->dhcp_buff2;
            int lease_type = LEASE_NA;
@@ -84,15 +89,20 @@ static int read_leases(time_t now, FILE *leasestream)
                s++;
              }
            
-           if ((lease = lease6_allocate(&addr.addr.addr6, lease_type)))
+           if ((lease = lease6_allocate(&addr.addr6, lease_type)))
              {
                lease_set_iaid(lease, strtoul(s, NULL, 10));
-               domain = get_domain6((struct in6_addr *)lease->hwaddr);
+               domain = get_domain6(&lease->addr6);
              }
          }
 #endif
        else
-         return 0;
+         {
+           my_syslog(MS_DHCP | LOG_WARNING, _("ignoring invalid line in lease database, bad address: %s"),
+                     daemon->namebuff);
+           continue;
+         }
+       
 
        if (!lease)
          die (_("too many stored leases"), NULL, EC_MISC);
@@ -172,10 +182,8 @@ void lease_init(time_t now)
   if (leasestream)
     {
       if (!read_leases(now, leasestream))
-       my_syslog(MS_DHCP | LOG_ERR, _("failed to parse lease database, invalid line: %s %s %s %s ..."),
-                 daemon->dhcp_buff3, daemon->dhcp_buff2,
-                 daemon->namebuff, daemon->dhcp_buff);
-
+       my_syslog(MS_DHCP | LOG_ERR, _("failed to parse lease database cleanly"));
+      
       if (ferror(leasestream))
        die(_("failed to read lease file %s: %s"), daemon->lease_file, EC_FILE);
     }
@@ -222,7 +230,7 @@ void lease_update_from_configs(void)
     if (lease->flags & (LEASE_TA | LEASE_NA))
       continue;
     else if ((config = find_config(daemon->dhcp_conf, NULL, lease->clid, lease->clid_len, 
-                                  lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL)) && 
+                                  lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL, NULL)) && 
             (config->flags & CONFIG_NAME) &&
             (!(config->flags & CONFIG_ADDR) || config->addr.s_addr == lease->addr.s_addr))
       lease_set_hostname(lease, config->hostname, 1, get_domain(lease->addr), NULL);
@@ -514,28 +522,28 @@ void lease_update_dns(int force)
                if (slaac->backoff == 0)
                  {
                    if (lease->fqdn)
-                     cache_add_dhcp_entry(lease->fqdn, AF_INET6, (struct all_addr *)&slaac->addr, lease->expires);
+                     cache_add_dhcp_entry(lease->fqdn, AF_INET6, (union all_addr *)&slaac->addr, lease->expires);
                    if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)
-                     cache_add_dhcp_entry(lease->hostname, AF_INET6, (struct all_addr *)&slaac->addr, lease->expires);
+                     cache_add_dhcp_entry(lease->hostname, AF_INET6, (union all_addr *)&slaac->addr, lease->expires);
                  }
            }
          
          if (lease->fqdn)
            cache_add_dhcp_entry(lease->fqdn, prot, 
-                                prot == AF_INET ? (struct all_addr *)&lease->addr : (struct all_addr *)&lease->addr6,
+                                prot == AF_INET ? (union all_addr *)&lease->addr : (union all_addr *)&lease->addr6,
                                 lease->expires);
             
          if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)
            cache_add_dhcp_entry(lease->hostname, prot, 
-                                prot == AF_INET ? (struct all_addr *)&lease->addr : (struct all_addr *)&lease->addr6, 
+                                prot == AF_INET ? (union all_addr *)&lease->addr : (union all_addr *)&lease->addr6, 
                                 lease->expires);
        
 #else
          if (lease->fqdn)
-           cache_add_dhcp_entry(lease->fqdn, prot, (struct all_addr *)&lease->addr, lease->expires);
+           cache_add_dhcp_entry(lease->fqdn, prot, (union all_addr *)&lease->addr, lease->expires);
          
          if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)
-           cache_add_dhcp_entry(lease->hostname, prot, (struct all_addr *)&lease->addr, lease->expires);
+           cache_add_dhcp_entry(lease->hostname, prot, (union all_addr *)&lease->addr, lease->expires);
 #endif
        }
       
@@ -550,12 +558,14 @@ void lease_prune(struct dhcp_lease *target, time_t now)
   for (lease = leases, up = &leases; lease; lease = tmp)
     {
       tmp = lease->next;
-      if ((lease->expires != 0 && difftime(now, lease->expires) > 0) || lease == target)
+      if ((lease->expires != 0 && difftime(now, lease->expires) >= 0) || lease == target)
        {
          file_dirty = 1;
          if (lease->hostname)
            dns_dirty = 1;
-         
+
+         daemon->metrics[lease->addr.s_addr ? METRIC_LEASES_PRUNED_4 : METRIC_LEASES_PRUNED_6]++;
+
          *up = lease->next; /* unlink */
          
          /* Put on old_leases list 'till we
@@ -625,7 +635,8 @@ struct dhcp_lease *lease_find_by_addr(struct in_addr addr)
 #ifdef HAVE_DHCP6
 /* find address for {CLID, IAID, address} */
 struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len, 
-                              int lease_type, int iaid, struct in6_addr *addr)
+                              int lease_type, unsigned int iaid,
+                              struct in6_addr *addr)
 {
   struct dhcp_lease *lease;
   
@@ -657,7 +668,9 @@ void lease6_reset(void)
 }
 
 /* enumerate all leases belonging to {CLID, IAID} */
-struct dhcp_lease *lease6_find_by_client(struct dhcp_lease *first, int lease_type, unsigned char *clid, int clid_len, int iaid)
+struct dhcp_lease *lease6_find_by_client(struct dhcp_lease *first, int lease_type,
+                                        unsigned char *clid, int clid_len,
+                                        unsigned int iaid)
 {
   struct dhcp_lease *lease;
 
@@ -773,7 +786,10 @@ struct dhcp_lease *lease4_allocate(struct in_addr addr)
 {
   struct dhcp_lease *lease = lease_allocate();
   if (lease)
-    lease->addr = addr;
+    {
+      lease->addr = addr;
+      daemon->metrics[METRIC_LEASES_ALLOCATED_4]++;
+    }
   
   return lease;
 }
@@ -788,6 +804,8 @@ struct dhcp_lease *lease6_allocate(struct in6_addr *addrp, int lease_type)
       lease->addr6 = *addrp;
       lease->flags |= lease_type;
       lease->iaid = 0;
+
+      daemon->metrics[METRIC_LEASES_ALLOCATED_6]++;
     }
 
   return lease;
@@ -818,7 +836,7 @@ void lease_set_expires(struct dhcp_lease *lease, unsigned int len, time_t now)
       dns_dirty = 1;
       lease->expires = exp;
 #ifndef HAVE_BROKEN_RTC
-      lease->flags |= LEASE_AUX_CHANGED;
+      lease->flags |= LEASE_AUX_CHANGED | LEASE_EXP_CHANGED;
       file_dirty = 1;
 #endif
     }
@@ -834,7 +852,7 @@ void lease_set_expires(struct dhcp_lease *lease, unsigned int len, time_t now)
 } 
 
 #ifdef HAVE_DHCP6
-void lease_set_iaid(struct dhcp_lease *lease, int iaid)
+void lease_set_iaid(struct dhcp_lease *lease, unsigned int iaid)
 {
   if (lease->iaid != iaid)
     {
@@ -1118,7 +1136,8 @@ int do_script_run(time_t now)
   
   for (lease = leases; lease; lease = lease->next)
     if ((lease->flags & (LEASE_NEW | LEASE_CHANGED)) || 
-       ((lease->flags & LEASE_AUX_CHANGED) && option_bool(OPT_LEASE_RO)))
+       ((lease->flags & LEASE_AUX_CHANGED) && option_bool(OPT_LEASE_RO)) ||
+       ((lease->flags & LEASE_EXP_CHANGED) && option_bool(OPT_LEASE_RENEW)))
       {
 #ifdef HAVE_SCRIPT
        queue_script((lease->flags & LEASE_NEW) ? ACTION_ADD : ACTION_OLD, lease, 
@@ -1128,7 +1147,7 @@ int do_script_run(time_t now)
        emit_dbus_signal((lease->flags & LEASE_NEW) ? ACTION_ADD : ACTION_OLD, lease,
                         lease->fqdn ? lease->fqdn : lease->hostname);
 #endif
-       lease->flags &= ~(LEASE_NEW | LEASE_CHANGED | LEASE_AUX_CHANGED);
+       lease->flags &= ~(LEASE_NEW | LEASE_CHANGED | LEASE_AUX_CHANGED | LEASE_EXP_CHANGED);
        
        /* this is used for the "add" call, then junked, since they're not in the database */
        free(lease->extradata);
index dae8a75..dbd6bd4 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -232,7 +232,7 @@ static void log_write(void)
              logaddr.sun_len = sizeof(logaddr) - sizeof(logaddr.sun_path) + strlen(_PATH_LOG) + 1; 
 #endif
              logaddr.sun_family = AF_UNIX;
-             strncpy(logaddr.sun_path, _PATH_LOG, sizeof(logaddr.sun_path));
+             safe_strncpy(logaddr.sun_path, _PATH_LOG, sizeof(logaddr.sun_path));
              
              /* Got connection back? try again. */
              if (connect(log_fd, (struct sockaddr *)&logaddr, sizeof(logaddr)) != -1)
index 0b47a2f..78e1238 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
diff --git a/src/metrics.c b/src/metrics.c
new file mode 100644 (file)
index 0000000..79f20b0
--- /dev/null
@@ -0,0 +1,44 @@
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+
+   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; version 2 dated June, 1991, or
+   (at your option) version 3 dated 29 June, 2007.
+
+   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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "dnsmasq.h"
+
+const char * metric_names[] = {
+    "dns_cache_inserted",
+    "dns_cache_live_freed",
+    "dns_queries_forwarded",
+    "dns_auth_answered",
+    "dns_local_answered",
+    "bootp",
+    "pxe",
+    "dhcp_ack",
+    "dhcp_decline",
+    "dhcp_discover",
+    "dhcp_inform",
+    "dhcp_nak",
+    "dhcp_offer",
+    "dhcp_release",
+    "dhcp_request",
+    "noanswer",
+    "leases_allocated_4",
+    "leases_pruned_4",
+    "leases_allocated_6",
+    "leases_pruned_6",
+};
+
+const char* get_metric_name(int i) {
+    return metric_names[i];
+}
diff --git a/src/metrics.h b/src/metrics.h
new file mode 100644 (file)
index 0000000..ccc92a8
--- /dev/null
@@ -0,0 +1,43 @@
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+   
+   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; version 2 dated June, 1991, or
+   (at your option) version 3 dated 29 June, 2007.
+   
+   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 <http://www.gnu.org/licenses/>.
+*/
+
+/* If you modify this list, please keep the labels in metrics.c in sync. */
+enum {
+  METRIC_DNS_CACHE_INSERTED,
+  METRIC_DNS_CACHE_LIVE_FREED,
+  METRIC_DNS_QUERIES_FORWARDED,
+  METRIC_DNS_AUTH_ANSWERED,
+  METRIC_DNS_LOCAL_ANSWERED,
+  METRIC_BOOTP,
+  METRIC_PXE,
+  METRIC_DHCPACK,
+  METRIC_DHCPDECLINE,
+  METRIC_DHCPDISCOVER,
+  METRIC_DHCPINFORM,
+  METRIC_DHCPNAK,
+  METRIC_DHCPOFFER,
+  METRIC_DHCPRELEASE,
+  METRIC_DHCPREQUEST,
+  METRIC_NOANSWER,
+  METRIC_LEASES_ALLOCATED_4,
+  METRIC_LEASES_PRUNED_4,
+  METRIC_LEASES_ALLOCATED_6,
+  METRIC_LEASES_PRUNED_6,
+  
+  __METRIC_MAX,
+};
+
+const char* get_metric_name(int);
index 05153f5..8e8431f 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
 
+/* Blergh. Radv does this, so that's our excuse. */
+#ifndef SOL_NETLINK
+#define SOL_NETLINK 270
+#endif
+
+#ifndef NETLINK_NO_ENOBUFS
+#define NETLINK_NO_ENOBUFS 5
+#endif
+
 /* linux 2.6.19 buggers up the headers, patch it up here. */ 
 #ifndef IFA_RTA
 #  define IFA_RTA(r)  \
@@ -40,10 +49,11 @@ static u32 netlink_pid;
 
 static void nl_async(struct nlmsghdr *h);
 
-void netlink_init(void)
+char *netlink_init(void)
 {
   struct sockaddr_nl addr;
   socklen_t slen = sizeof(addr);
+  int opt = 1;
 
   addr.nl_family = AF_NETLINK;
   addr.nl_pad = 0;
@@ -51,11 +61,10 @@ void netlink_init(void)
   addr.nl_groups = RTMGRP_IPV4_ROUTE;
   if (option_bool(OPT_CLEVERBIND))
     addr.nl_groups |= RTMGRP_IPV4_IFADDR;  
-#ifdef HAVE_IPV6
   addr.nl_groups |= RTMGRP_IPV6_ROUTE;
   if (option_bool(OPT_CLEVERBIND))
     addr.nl_groups |= RTMGRP_IPV6_IFADDR;
-#endif
+
 #ifdef HAVE_DHCP6
   if (daemon->doing_ra || daemon->doing_dhcp6)
     addr.nl_groups |= RTMGRP_IPV6_IFADDR;
@@ -75,12 +84,19 @@ void netlink_init(void)
   if (daemon->netlinkfd == -1 || 
       getsockname(daemon->netlinkfd, (struct sockaddr *)&addr, &slen) == -1)
     die(_("cannot create netlink socket: %s"), NULL, EC_MISC);
-   
+  
+  
   /* save pid assigned by bind() and retrieved by getsockname() */ 
   netlink_pid = addr.nl_pid;
   
   iov.iov_len = 100;
   iov.iov_base = safe_malloc(iov.iov_len);
+  
+  if (daemon->kernel_version >= KERNEL_VERSION(2,6,30) &&
+      setsockopt(daemon->netlinkfd, SOL_NETLINK, NETLINK_NO_ENOBUFS, &opt, sizeof(opt)) == -1)
+    return _("warning: failed to set NETLINK_NO_ENOBUFS on netlink socket");
+  
+  return NULL;
 }
 
 static ssize_t netlink_recv(void)
@@ -149,10 +165,10 @@ int iface_enumerate(int family, void *parm, int (*callback)())
     struct rtgenmsg g; 
   } req;
 
+  memset(&req, 0, sizeof(req));
+  memset(&addr, 0, sizeof(addr));
+
   addr.nl_family = AF_NETLINK;
-  addr.nl_pad = 0;
-  addr.nl_groups = 0;
-  addr.nl_pid = 0; /* address to kernel */
  
  again: 
   if (family == AF_UNSPEC)
@@ -235,7 +251,6 @@ int iface_enumerate(int family, void *parm, int (*callback)())
                      if (!((*callback)(addr, ifa->ifa_index, label,  netmask, broadcast, parm)))
                        callback_ok = 0;
                  }
-#ifdef HAVE_IPV6
                else if (ifa->ifa_family == AF_INET6)
                  {
                    struct in6_addr *addrp = NULL;
@@ -270,7 +285,6 @@ int iface_enumerate(int family, void *parm, int (*callback)())
                                        (int) preferred, (int)valid, parm)))
                        callback_ok = 0;
                  }
-#endif
              }
          }
        else if (h->nlmsg_type == RTM_NEWNEIGH && family == AF_UNSPEC)
@@ -363,7 +377,9 @@ static void nl_async(struct nlmsghdr *h)
         failing. */ 
       struct rtmsg *rtm = NLMSG_DATA(h);
       
-      if (rtm->rtm_type == RTN_UNICAST && rtm->rtm_scope == RT_SCOPE_LINK)
+      if (rtm->rtm_type == RTN_UNICAST && rtm->rtm_scope == RT_SCOPE_LINK &&
+         (rtm->rtm_table == RT_TABLE_MAIN ||
+          rtm->rtm_table == RT_TABLE_LOCAL))
        queue_event(EVENT_NEWROUTE);
     }
   else if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR) 
index 0381513..c7d002b 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -29,7 +29,7 @@ int indextoname(int fd, int index, char *name)
   if (ioctl(fd, SIOCGIFNAME, &ifr) == -1)
     return 0;
 
-  strncpy(name, ifr.ifr_name, IF_NAMESIZE);
+  safe_strncpy(name, ifr.ifr_name, IF_NAMESIZE);
 
   return 1;
 }
@@ -82,12 +82,12 @@ int indextoname(int fd, int index, char *name)
   for (i = lifc.lifc_len / sizeof(struct lifreq); i; i--, lifrp++) 
     {
       struct lifreq lifr;
-      strncpy(lifr.lifr_name, lifrp->lifr_name, IF_NAMESIZE);
+      safe_strncpy(lifr.lifr_name, lifrp->lifr_name, IF_NAMESIZE);
       if (ioctl(fd, SIOCGLIFINDEX, &lifr) < 0) 
        return 0;
       
       if (lifr.lifr_index == index) {
-       strncpy(name, lifr.lifr_name, IF_NAMESIZE);
+       safe_strncpy(name, lifr.lifr_name, IF_NAMESIZE);
        return 1;
       }
     }
@@ -109,7 +109,7 @@ int indextoname(int fd, int index, char *name)
 
 #endif
 
-int iface_check(int family, struct all_addr *addr, char *name, int *auth)
+int iface_check(int family, union all_addr *addr, char *name, int *auth)
 {
   struct iname *tmp;
   int ret = 1, match_addr = 0;
@@ -135,14 +135,12 @@ int iface_check(int family, struct all_addr *addr, char *name, int *auth)
          if (tmp->addr.sa.sa_family == family)
            {
              if (family == AF_INET &&
-                 tmp->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
+                 tmp->addr.in.sin_addr.s_addr == addr->addr4.s_addr)
                ret = match_addr = tmp->used = 1;
-#ifdef HAVE_IPV6
              else if (family == AF_INET6 &&
                       IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, 
-                                         &addr->addr.addr6))
+                                         &addr->addr6))
                ret = match_addr = tmp->used = 1;
-#endif
            }          
     }
   
@@ -160,13 +158,11 @@ int iface_check(int family, struct all_addr *addr, char *name, int *auth)
          break;
       }
     else if (addr && tmp->addr.sa.sa_family == AF_INET && family == AF_INET &&
-            tmp->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
+            tmp->addr.in.sin_addr.s_addr == addr->addr4.s_addr)
       break;
-#ifdef HAVE_IPV6
     else if (addr && tmp->addr.sa.sa_family == AF_INET6 && family == AF_INET6 &&
-            IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, &addr->addr.addr6))
+            IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, &addr->addr6))
       break;
-#endif      
 
   if (tmp && auth) 
     {
@@ -183,12 +179,12 @@ int iface_check(int family, struct all_addr *addr, char *name, int *auth)
    an interface other than the loopback. Accept packet if it arrived via a loopback 
    interface, even when we're not accepting packets that way, as long as the destination
    address is one we're believing. Interface list must be up-to-date before calling. */
-int loopback_exception(int fd, int family, struct all_addr *addr, char *name)    
+int loopback_exception(int fd, int family, union all_addr *addr, char *name)    
 {
   struct ifreq ifr;
   struct irec *iface;
 
-  strncpy(ifr.ifr_name, name, IF_NAMESIZE);
+  safe_strncpy(ifr.ifr_name, name, IF_NAMESIZE);
   if (ioctl(fd, SIOCGIFFLAGS, &ifr) != -1 &&
       ifr.ifr_flags & IFF_LOOPBACK)
     {
@@ -197,14 +193,11 @@ int loopback_exception(int fd, int family, struct all_addr *addr, char *name)
          {
            if (family == AF_INET)
              {
-               if (iface->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
+               if (iface->addr.in.sin_addr.s_addr == addr->addr4.s_addr)
                  return 1;
              }
-#ifdef HAVE_IPV6
-           else if (IN6_ARE_ADDR_EQUAL(&iface->addr.in6.sin6_addr, &addr->addr.addr6))
+           else if (IN6_ARE_ADDR_EQUAL(&iface->addr.in6.sin6_addr, &addr->addr6))
              return 1;
-#endif
-           
          }
     }
   return 0;
@@ -214,7 +207,7 @@ int loopback_exception(int fd, int family, struct all_addr *addr, char *name)
    on the relevant address, but the name of the arrival interface, derived from the
    index won't match the config. Check that we found an interface address for the arrival 
    interface: daemon->interfaces must be up-to-date. */
-int label_exception(int index, int family, struct all_addr *addr)
+int label_exception(int index, int family, union all_addr *addr)
 {
   struct irec *iface;
 
@@ -224,7 +217,7 @@ int label_exception(int index, int family, struct all_addr *addr)
 
   for (iface = daemon->interfaces; iface; iface = iface->next)
     if (iface->index == index && iface->addr.sa.sa_family == AF_INET &&
-       iface->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
+       iface->addr.in.sin_addr.s_addr == addr->addr4.s_addr)
       return 1;
 
   return 0;
@@ -289,22 +282,18 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
          
          if (addr->sa.sa_family == AF_INET)
            {
-             al->addr.addr.addr4 = addr->in.sin_addr;
+             al->addr.addr4 = addr->in.sin_addr;
              al->flags = 0;
            }
-#ifdef HAVE_IPV6
          else
            {
-             al->addr.addr.addr6 = addr->in6.sin6_addr;
+             al->addr.addr6 = addr->in6.sin6_addr;
              al->flags = ADDRLIST_IPV6;
            } 
-#endif
        }
     }
   
-#ifdef HAVE_IPV6
   if (addr->sa.sa_family != AF_INET6 || !IN6_IS_ADDR_LINKLOCAL(&addr->in6.sin6_addr))
-#endif
     {
       struct interface_name *int_name;
       struct addrlist *al;
@@ -332,12 +321,11 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
                      al->next = zone->subnet;
                      zone->subnet = al;
                      al->prefixlen = prefixlen;
-                     al->addr.addr.addr4 = addr->in.sin_addr;
+                     al->addr.addr4 = addr->in.sin_addr;
                      al->flags = 0;
                    }
                }
              
-#ifdef HAVE_IPV6
              if (addr->sa.sa_family == AF_INET6 && (name->flags & AUTH6))
                {
                  if (param->spare)
@@ -353,12 +341,10 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
                      al->next = zone->subnet;
                      zone->subnet = al;
                      al->prefixlen = prefixlen;
-                     al->addr.addr.addr6 = addr->in6.sin6_addr;
+                     al->addr.addr6 = addr->in6.sin6_addr;
                      al->flags = ADDRLIST_IPV6;
                    }
                } 
-#endif
-             
            }
 #endif
        
@@ -383,20 +369,18 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
                
                if (addr->sa.sa_family == AF_INET)
                  {
-                   al->addr.addr.addr4 = addr->in.sin_addr;
+                   al->addr.addr4 = addr->in.sin_addr;
                    al->flags = 0;
                  }
-#ifdef HAVE_IPV6
                else
                 {
-                   al->addr.addr.addr6 = addr->in6.sin6_addr;
+                   al->addr.addr6 = addr->in6.sin6_addr;
                    al->flags = ADDRLIST_IPV6;
                    /* Privacy addresses and addresses still undergoing DAD and deprecated addresses
                       don't appear in forward queries, but will in reverse ones. */
                    if (!(iface_flags & IFACE_PERMANENT) || (iface_flags & (IFACE_DEPRECATED | IFACE_TENTATIVE)))
                      al->flags |= ADDRLIST_REVONLY;
                 } 
-#endif
              }
          }
     }
@@ -404,10 +388,11 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
   /* check whether the interface IP has been added already 
      we call this routine multiple times. */
   for (iface = daemon->interfaces; iface; iface = iface->next) 
-    if (sockaddr_isequal(&iface->addr, addr))
+    if (sockaddr_isequal(&iface->addr, addr) && iface->index == if_index)
       {
        iface->dad = !!(iface_flags & IFACE_TENTATIVE);
        iface->found = 1; /* for garbage collection */
+       iface->netmask = netmask;
        return 1;
       }
 
@@ -435,14 +420,12 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
     }
   
   if (addr->sa.sa_family == AF_INET &&
-      !iface_check(AF_INET, (struct all_addr *)&addr->in.sin_addr, label, &auth_dns))
+      !iface_check(AF_INET, (union all_addr *)&addr->in.sin_addr, label, &auth_dns))
     return 1;
 
-#ifdef HAVE_IPV6
   if (addr->sa.sa_family == AF_INET6 &&
-      !iface_check(AF_INET6, (struct all_addr *)&addr->in6.sin6_addr, label, &auth_dns))
+      !iface_check(AF_INET6, (union all_addr *)&addr->in6.sin6_addr, label, &auth_dns))
     return 1;
-#endif
     
 #ifdef HAVE_DHCP
   /* No DHCP where we're doing auth DNS. */
@@ -501,7 +484,6 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
   return 0;
 }
 
-#ifdef HAVE_IPV6
 static int iface_allowed_v6(struct in6_addr *local, int prefix, 
                            int scope, int if_index, int flags, 
                            int preferred, int valid, void *vparam)
@@ -529,7 +511,6 @@ static int iface_allowed_v6(struct in6_addr *local, int prefix,
   
   return iface_allowed((struct iface_param *)vparam, if_index, NULL, &addr, netmask, prefix, flags);
 }
-#endif
 
 static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
                            struct in_addr netmask, struct in_addr broadcast, void *vparam)
@@ -552,7 +533,82 @@ static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
 
   return iface_allowed((struct iface_param *)vparam, if_index, label, &addr, netmask, prefix, 0);
 }
-   
+
+/*
+ * Clean old interfaces no longer found.
+ */
+static void clean_interfaces()
+{
+  struct irec *iface;
+  struct irec **up = &daemon->interfaces;
+
+  for (iface = *up; iface; iface = *up)
+  {
+    if (!iface->found && !iface->done)
+      {
+        *up = iface->next;
+        free(iface->name);
+        free(iface);
+      }
+    else
+      {
+        up = &iface->next;
+      }
+  }
+}
+
+/** Release listener if no other interface needs it.
+ *
+ * @return 1 if released, 0 if still required
+ */
+static int release_listener(struct listener *l)
+{
+  if (l->used > 1)
+    {
+      struct irec *iface;
+      for (iface = daemon->interfaces; iface; iface = iface->next)
+       if (iface->done && sockaddr_isequal(&l->addr, &iface->addr))
+         {
+           if (iface->found)
+             {
+               /* update listener to point to active interface instead */
+               if (!l->iface->found)
+                 l->iface = iface;
+             }
+           else
+             {
+               l->used--;
+               iface->done = 0;
+             }
+         }
+
+      /* Someone is still using this listener, skip its deletion */
+      if (l->used > 0)
+       return 0;
+    }
+
+  if (l->iface->done)
+    {
+      int port;
+
+      port = prettyprint_addr(&l->iface->addr, daemon->addrbuff);
+      my_syslog(LOG_DEBUG, _("stopped listening on %s(#%d): %s port %d"),
+               l->iface->name, l->iface->index, daemon->addrbuff, port);
+      /* In case it ever returns */
+      l->iface->done = 0;
+    }
+
+  if (l->fd != -1)
+    close(l->fd);
+  if (l->tcpfd != -1)
+    close(l->tcpfd);
+  if (l->tftpfd != -1)
+    close(l->tftpfd);
+
+  free(l);
+  return 1;
+}
+
 int enumerate_interfaces(int reset)
 {
   static struct addrlist *spare = NULL;
@@ -633,9 +689,7 @@ int enumerate_interfaces(int reset)
 
   param.spare = spare;
   
-#ifdef HAVE_IPV6
   ret = iface_enumerate(AF_INET6, &param, iface_allowed_v6);
-#endif
 
   if (ret)
     ret = iface_enumerate(AF_INET, &param, iface_allowed_v4); 
@@ -652,6 +706,7 @@ int enumerate_interfaces(int reset)
         in OPT_CLEVERBIND mode, that at listener will just disappear after
         a call to enumerate_interfaces, this is checked OK on all calls. */
       struct listener *l, *tmp, **up;
+      int freed = 0;
       
       for (up = &daemon->listeners, l = daemon->listeners; l; l = tmp)
        {
@@ -659,25 +714,17 @@ int enumerate_interfaces(int reset)
          
          if (!l->iface || l->iface->found)
            up = &l->next;
-         else
+         else if (release_listener(l))
            {
-             *up = l->next;
-             
-             /* In case it ever returns */
-             l->iface->done = 0;
-             
-             if (l->fd != -1)
-               close(l->fd);
-             if (l->tcpfd != -1)
-               close(l->tcpfd);
-             if (l->tftpfd != -1)
-               close(l->tftpfd);
-             
-             free(l);
+             *up = tmp;
+             freed = 1;
            }
        }
+
+      if (freed)
+       clean_interfaces();
     }
-  
+
   errno = errsave;
   spare = param.spare;
     
@@ -740,16 +787,19 @@ static int make_sock(union mysockaddr *addr, int type, int dienow)
   if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 || !fix_fd(fd))
     goto err;
   
-#ifdef HAVE_IPV6
   if (family == AF_INET6 && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
     goto err;
-#endif
   
   if ((rc = bind(fd, (struct sockaddr *)addr, sa_len(addr))) == -1)
     goto err;
   
   if (type == SOCK_STREAM)
     {
+#ifdef TCP_FASTOPEN
+      int qlen = 5;                           
+      setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen));
+#endif
+      
       if (listen(fd, TCP_BACKLOG) == -1)
        goto err;
     }
@@ -767,15 +817,12 @@ static int make_sock(union mysockaddr *addr, int type, int dienow)
 #endif
        }
     }
-#ifdef HAVE_IPV6
   else if (!set_ipv6pktinfo(fd))
     goto err;
-#endif
   
   return fd;
 }
 
-#ifdef HAVE_IPV6  
 int set_ipv6pktinfo(int fd)
 {
   int opt = 1;
@@ -802,12 +849,13 @@ int set_ipv6pktinfo(int fd)
 
   return 0;
 }
-#endif
 
 
 /* Find the interface on which a TCP connection arrived, if possible, or zero otherwise. */
 int tcp_interface(int fd, int af)
 { 
+  (void)fd; /* suppress potential unused warning */
+  (void)af; /* suppress potential unused warning */
   int if_index = 0;
 
 #ifdef HAVE_LINUX_NETWORK
@@ -842,7 +890,6 @@ int tcp_interface(int fd, int af)
              }
        }
     }
-#ifdef HAVE_IPV6
   else
     {
       /* Only the RFC-2292 API has the ability to find the interface for TCP connections,
@@ -874,7 +921,6 @@ int tcp_interface(int fd, int af)
               }
        }
     }
-#endif /* IPV6 */
 #endif /* Linux */
  
   return if_index;
@@ -904,7 +950,6 @@ static struct listener *create_listeners(union mysockaddr *addr, int do_tftp, in
          tftpfd = make_sock(addr, SOCK_DGRAM, dienow);
          addr->in.sin_port = save;
        }
-#  ifdef HAVE_IPV6
       else
        {
          short save = addr->in6.sin6_port;
@@ -912,7 +957,6 @@ static struct listener *create_listeners(union mysockaddr *addr, int do_tftp, in
          tftpfd = make_sock(addr, SOCK_DGRAM, dienow);
          addr->in6.sin6_port = save;
        }  
-#  endif
     }
 #endif
 
@@ -920,10 +964,11 @@ static struct listener *create_listeners(union mysockaddr *addr, int do_tftp, in
     {
       l = safe_malloc(sizeof(struct listener));
       l->next = NULL;
-      l->family = addr->sa.sa_family;
       l->fd = fd;
       l->tcpfd = tcpfd;
-      l->tftpfd = tftpfd;      
+      l->tftpfd = tftpfd;
+      l->addr = *addr;
+      l->used = 1;
       l->iface = NULL;
     }
 
@@ -945,11 +990,10 @@ void create_wildcard_listeners(void)
 
   l = create_listeners(&addr, !!option_bool(OPT_TFTP), 1);
 
-#ifdef HAVE_IPV6
   memset(&addr, 0, sizeof(addr));
-#  ifdef HAVE_SOCKADDR_SA_LEN
+#ifdef HAVE_SOCKADDR_SA_LEN
   addr.in6.sin6_len = sizeof(addr.in6);
-#  endif
+#endif
   addr.in6.sin6_family = AF_INET6;
   addr.in6.sin6_addr = in6addr_any;
   addr.in6.sin6_port = htons(daemon->port);
@@ -959,25 +1003,52 @@ void create_wildcard_listeners(void)
     l->next = l6;
   else 
     l = l6;
-#endif
 
   daemon->listeners = l;
 }
 
+static struct listener *find_listener(union mysockaddr *addr)
+{
+  struct listener *l;
+  for (l = daemon->listeners; l; l = l->next)
+    if (sockaddr_isequal(&l->addr, addr))
+      return l;
+  return NULL;
+}
+
 void create_bound_listeners(int dienow)
 {
   struct listener *new;
   struct irec *iface;
   struct iname *if_tmp;
+  struct listener *existing;
 
   for (iface = daemon->interfaces; iface; iface = iface->next)
-    if (!iface->done && !iface->dad && iface->found &&
-       (new = create_listeners(&iface->addr, iface->tftp_ok, dienow)))
+    if (!iface->done && !iface->dad && iface->found)
       {
-       new->iface = iface;
-       new->next = daemon->listeners;
-       daemon->listeners = new;
-       iface->done = 1;
+       existing = find_listener(&iface->addr);
+       if (existing)
+         {
+           iface->done = 1;
+           existing->used++; /* increase usage counter */
+         }
+       else if ((new = create_listeners(&iface->addr, iface->tftp_ok, dienow)))
+         {
+           new->iface = iface;
+           new->next = daemon->listeners;
+           daemon->listeners = new;
+           iface->done = 1;
+
+           /* Don't log the initial set of listen addresses created
+               at startup, since this is happening before the logging
+               system is initialised and the sign-on printed. */
+            if (!dienow)
+              {
+               int port = prettyprint_addr(&iface->addr, daemon->addrbuff);
+               my_syslog(LOG_DEBUG, _("listening on %s(#%d): %s port %d"),
+                         iface->name, iface->index, daemon->addrbuff, port);
+             }
+         }
       }
 
   /* Check for --listen-address options that haven't been used because there's
@@ -997,6 +1068,12 @@ void create_bound_listeners(int dienow)
       {
        new->next = daemon->listeners;
        daemon->listeners = new;
+
+       if (!dienow)
+         {
+           int port = prettyprint_addr(&if_tmp->addr, daemon->addrbuff);
+           my_syslog(LOG_DEBUG, _("listening on %s port %d"), daemon->addrbuff, port);
+         }
       }
 }
 
@@ -1159,7 +1236,6 @@ int random_sock(int family)
                addr.in.sin_len = sizeof(struct sockaddr_in);
 #endif
              }
-#ifdef HAVE_IPV6
            else
              {
                addr.in6.sin6_addr = in6addr_any; 
@@ -1168,7 +1244,6 @@ int random_sock(int family)
                addr.in6.sin6_len = sizeof(struct sockaddr_in6);
 #endif
              }
-#endif
            
            if (bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == 0)
              return fd;
@@ -1193,10 +1268,8 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifind
     {
       if (addr_copy.sa.sa_family == AF_INET)
        addr_copy.in.sin_port = 0;
-#ifdef HAVE_IPV6
       else
        addr_copy.in6.sin6_port = 0;
-#endif
     }
   
   if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) == -1)
@@ -1211,7 +1284,7 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifind
           return setsockopt(fd, IPPROTO_IP, IP_UNICAST_IF, &ifindex_opt, sizeof(ifindex_opt)) == 0;
         }
 #endif
-#if defined(HAVE_IPV6) && defined (IPV6_UNICAST_IF)
+#if defined (IPV6_UNICAST_IF)
       if (addr_copy.sa.sa_family == AF_INET6)
         {
           uint32_t ifindex_opt = htonl(ifindex);
@@ -1220,6 +1293,7 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifind
 #endif
     }
 
+  (void)intname; /* suppress potential unused warning */
 #if defined(SO_BINDTODEVICE)
   if (intname[0] != 0 &&
       setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, IF_NAMESIZE) == -1)
@@ -1234,7 +1308,8 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
   struct serverfd *sfd;
   unsigned int ifindex = 0;
   int errsave;
-
+  int opt = 1;
+  
   /* when using random ports, servers which would otherwise use
      the INADDR_ANY/port0 socket have sfd set to NULL */
   if (!daemon->osport && intname[0] == 0)
@@ -1246,12 +1321,10 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
          addr->in.sin_port == htons(0)) 
        return NULL;
 
-#ifdef HAVE_IPV6
       if (addr->sa.sa_family == AF_INET6 &&
          memcmp(&addr->in6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
          addr->in6.sin6_port == htons(0)) 
        return NULL;
-#endif
     }
 
   if (intname && strlen(intname) != 0)
@@ -1274,20 +1347,22 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
       free(sfd);
       return NULL;
     }
-  
-  if (!local_bind(sfd->fd, addr, intname, ifindex, 0) || !fix_fd(sfd->fd))
+
+  if ((addr->sa.sa_family == AF_INET6 && setsockopt(sfd->fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) == -1) ||
+      !local_bind(sfd->fd, addr, intname, ifindex, 0) || !fix_fd(sfd->fd))
     { 
-      errsave = errno; /* save error from bind. */
+      errsave = errno; /* save error from bind/setsockopt. */
       close(sfd->fd);
       free(sfd);
       errno = errsave;
       return NULL;
     }
 
-  strcpy(sfd->interface, intname); 
+  safe_strncpy(sfd->interface, intname, sizeof(sfd->interface)); 
   sfd->source_addr = *addr;
   sfd->next = daemon->sfds;
   sfd->ifindex = ifindex;
+  sfd->preallocated = 0;
   daemon->sfds = sfd;
 
   return sfd; 
@@ -1298,6 +1373,7 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
 void pre_allocate_sfds(void)
 {
   struct server *srv;
+  struct serverfd *sfd;
   
   if (daemon->query_port != 0)
     {
@@ -1309,8 +1385,9 @@ void pre_allocate_sfds(void)
 #ifdef HAVE_SOCKADDR_SA_LEN
       addr.in.sin_len = sizeof(struct sockaddr_in);
 #endif
-      allocate_sfd(&addr, "");
-#ifdef HAVE_IPV6
+      if ((sfd = allocate_sfd(&addr, "")))
+       sfd->preallocated = 1;
+
       memset(&addr, 0, sizeof(addr));
       addr.in6.sin6_family = AF_INET6;
       addr.in6.sin6_addr = in6addr_any;
@@ -1318,8 +1395,8 @@ void pre_allocate_sfds(void)
 #ifdef HAVE_SOCKADDR_SA_LEN
       addr.in6.sin6_len = sizeof(struct sockaddr_in6);
 #endif
-      allocate_sfd(&addr, "");
-#endif
+      if ((sfd = allocate_sfd(&addr, "")))
+       sfd->preallocated = 1;
     }
   
   for (srv = daemon->servers; srv; srv = srv->next)
@@ -1328,7 +1405,7 @@ void pre_allocate_sfds(void)
        errno != 0 &&
        option_bool(OPT_NOWILD))
       {
-       prettyprint_addr(&srv->source_addr, daemon->namebuff);
+       (void)prettyprint_addr(&srv->source_addr, daemon->namebuff);
        if (srv->interface[0] != 0)
          {
            strcat(daemon->namebuff, " ");
@@ -1452,7 +1529,7 @@ void add_update_server(int flags,
        serv->flags |= SERV_HAS_DOMAIN;
       
       if (interface)
-       strcpy(serv->interface, interface);      
+       safe_strncpy(serv->interface, interface, sizeof(serv->interface));
       if (addr)
        serv->addr = *addr;
       if (source_addr)
@@ -1471,9 +1548,10 @@ void check_servers(void)
   /* interface may be new since startup */
   if (!option_bool(OPT_NOWILD))
     enumerate_interfaces(0);
-  
+
+  /* don't garbage collect pre-allocated sfds. */
   for (sfd = daemon->sfds; sfd; sfd = sfd->next)
-    sfd->used = 0;
+    sfd->used = sfd->preallocated;
 
   for (count = 0, serv = daemon->servers; serv; serv = serv->next)
     {
@@ -1569,7 +1647,7 @@ void check_servers(void)
                {
                  count--;
                  if (++locals <= LOCALS_LOGGED)
-                       my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
+                       my_syslog(LOG_INFO, _("using only locally-known addresses for %s %s"), s1, s2);
                }
              else if (serv->flags & SERV_USE_RESOLV)
                my_syslog(LOG_INFO, _("using standard nameservers for %s %s"), s1, s2);
@@ -1651,7 +1729,6 @@ int reload_servers(char *fname)
          source_addr.in.sin_addr.s_addr = INADDR_ANY;
          source_addr.in.sin_port = htons(daemon->query_port);
        }
-#ifdef HAVE_IPV6
       else 
        {       
          int scope_index = 0;
@@ -1679,10 +1756,6 @@ int reload_servers(char *fname)
          else
            continue;
        }
-#else /* IPV6 */
-      else
-       continue;
-#endif 
 
       add_update_server(SERV_FROM_RESOLV, &addr, &source_addr, NULL, NULL);
       gotone = 1;
index d358d99..dbe5f90 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -129,9 +129,6 @@ struct myoption {
 #define LOPT_AUTHPEER      318
 #define LOPT_IPSET         319
 #define LOPT_SYNTH         320
-#ifdef OPTION6_PREFIX_CLASS 
-#define LOPT_PREF_CLSS     321
-#endif
 #define LOPT_RELAY         323
 #define LOPT_RA_PARAM      324
 #define LOPT_ADD_SBNET     325
@@ -160,6 +157,16 @@ struct myoption {
 #define LOPT_DHCPTTL       348
 #define LOPT_TFTP_MTU      349
 #define LOPT_REPLY_DELAY   350
+#define LOPT_RAPID_COMMIT  351
+#define LOPT_DUMPFILE      352
+#define LOPT_DUMPMASK      353
+#define LOPT_UBUS          354
+#define LOPT_NAME_MATCH    355
+#define LOPT_CAA           356
+#define LOPT_SHARED_NET    357
+#define LOPT_IGNORE_CLID   358
+#define LOPT_SINGLE_PORT   359
+#define LOPT_SCRIPT_TIME   360
  
 #ifdef HAVE_GETOPT_LONG
 static const struct option opts[] =  
@@ -228,8 +235,10 @@ static const struct myoption opts[] =
     { "srv-host", 1, 0, 'W' },
     { "localise-queries", 0, 0, 'y' },
     { "txt-record", 1, 0, 'Y' },
+    { "caa-record", 1, 0 , LOPT_CAA },
     { "dns-rr", 1, 0, LOPT_RR },
     { "enable-dbus", 2, 0, '1' },
+    { "enable-ubus", 2, 0, LOPT_UBUS },
     { "bootp-dynamic", 2, 0, '3' },
     { "dhcp-mac", 1, 0, '4' },
     { "no-ping", 0, 0, '5' },
@@ -237,6 +246,7 @@ static const struct myoption opts[] =
     { "conf-dir", 1, 0, '7' },
     { "log-facility", 1, 0 ,'8' },
     { "leasefile-ro", 0, 0, '9' },
+    { "script-on-renewal", 0, 0, LOPT_SCRIPT_TIME},
     { "dns-forward-max", 1, 0, '0' },
     { "clear-on-reload", 0, 0, LOPT_RELOAD },
     { "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES },
@@ -248,9 +258,11 @@ static const struct myoption opts[] =
     { "tftp-max", 1, 0, LOPT_TFTP_MAX },
     { "tftp-mtu", 1, 0, LOPT_TFTP_MTU },
     { "tftp-lowercase", 0, 0, LOPT_TFTP_LC },
+    { "tftp-single-port", 0, 0, LOPT_SINGLE_PORT },
     { "ptr-record", 1, 0, LOPT_PTR },
     { "naptr-record", 1, 0, LOPT_NAPTR },
     { "bridge-interface", 1, 0 , LOPT_BRIDGE },
+    { "shared-network", 1, 0, LOPT_SHARED_NET },
     { "dhcp-option-force", 1, 0, LOPT_FORCE },
     { "tftp-no-blocksize", 0, 0, LOPT_NOBLOCK },
     { "log-dhcp", 0, 0, LOPT_LOG_OPTS },
@@ -268,7 +280,8 @@ static const struct myoption opts[] =
     { "stop-dns-rebind", 0, 0, LOPT_REBIND },
     { "rebind-domain-ok", 1, 0, LOPT_NO_REBIND },
     { "all-servers", 0, 0, LOPT_NOLAST }, 
-    { "dhcp-match", 1, 0, LOPT_MATCH }, 
+    { "dhcp-match", 1, 0, LOPT_MATCH },
+    { "dhcp-name-match", 1, 0, LOPT_NAME_MATCH },
     { "dhcp-broadcast", 2, 0, LOPT_BROADCAST },
     { "neg-ttl", 1, 0, LOPT_NEGTTL },
     { "max-ttl", 1, 0, LOPT_MAXTTL },
@@ -310,12 +323,9 @@ static const struct myoption opts[] =
     { "dnssec", 0, 0, LOPT_SEC_VALID },
     { "trust-anchor", 1, 0, LOPT_TRUST_ANCHOR },
     { "dnssec-debug", 0, 0, LOPT_DNSSEC_DEBUG },
-    { "dnssec-check-unsigned", 0, 0, LOPT_DNSSEC_CHECK },
+    { "dnssec-check-unsigned", 2, 0, LOPT_DNSSEC_CHECK },
     { "dnssec-no-timecheck", 0, 0, LOPT_DNSSEC_TIME },
     { "dnssec-timestamp", 1, 0, LOPT_DNSSEC_STAMP },
-#ifdef OPTION6_PREFIX_CLASS 
-    { "dhcp-prefix-class", 1, 0, LOPT_PREF_CLSS },
-#endif
     { "dhcp-relay", 1, 0, LOPT_RELAY },
     { "ra-param", 1, 0, LOPT_RA_PARAM },
     { "quiet-dhcp", 0, 0, LOPT_QUIET_DHCP },
@@ -325,6 +335,10 @@ static const struct myoption opts[] =
     { "script-arp", 0, 0, LOPT_SCRIPT_ARP },
     { "dhcp-ttl", 1, 0 , LOPT_DHCPTTL },
     { "dhcp-reply-delay", 1, 0, LOPT_REPLY_DELAY },
+    { "dhcp-rapid-commit", 0, 0, LOPT_RAPID_COMMIT },
+    { "dumpfile", 1, 0, LOPT_DUMPFILE },
+    { "dumpmask", 1, 0, LOPT_DUMPMASK },
+    { "dhcp-ignore-clid", 0, 0,  LOPT_IGNORE_CLID },
     { NULL, 0, 0, 0 }
   };
 
@@ -414,10 +428,12 @@ static struct {
   { 'z', OPT_NOWILD, NULL, gettext_noop("Bind only to interfaces in use."), NULL },
   { 'Z', OPT_ETHERS, NULL, gettext_noop("Read DHCP static host information from %s."), ETHERSFILE },
   { '1', ARG_ONE, "[=<busname>]", gettext_noop("Enable the DBus interface for setting upstream servers, etc."), NULL },
+  { LOPT_UBUS, ARG_ONE, "[=<busname>]", gettext_noop("Enable the UBus interface."), NULL },
   { '2', ARG_DUP, "<interface>", gettext_noop("Do not provide DHCP on this interface, only provide DNS."), NULL },
   { '3', ARG_DUP, "[=tag:<tag>]...", gettext_noop("Enable dynamic address allocation for bootp."), NULL },
   { '4', ARG_DUP, "set:<tag>,<mac address>", gettext_noop("Map MAC address (with wildcards) to option set."), NULL },
   { LOPT_BRIDGE, ARG_DUP, "<iface>,<alias>..", gettext_noop("Treat DHCP requests on aliases as arriving from interface."), NULL },
+  { LOPT_SHARED_NET, ARG_DUP, "<iface>|<addr>,<addr>", gettext_noop("Specify extra networks sharing a broadcast domain for DHCP"), NULL},
   { '5', OPT_NO_PING, NULL, gettext_noop("Disable ICMP echo address checking in the DHCP server."), NULL },
   { '6', ARG_ONE, "<path>", gettext_noop("Shell script to run on DHCP lease creation and destruction."), NULL },
   { LOPT_LUASCRIPT, ARG_DUP, "path", gettext_noop("Lua script to run on DHCP lease creation and destruction."), NULL },
@@ -440,6 +456,7 @@ static struct {
   { LOPT_NOBLOCK, OPT_TFTP_NOBLOCK, NULL, gettext_noop("Disable the TFTP blocksize extension."), NULL },
   { LOPT_TFTP_LC, OPT_TFTP_LC, NULL, gettext_noop("Convert TFTP filenames to lowercase"), NULL },
   { LOPT_TFTPPORTS, ARG_ONE, "<start>,<end>", gettext_noop("Ephemeral port range for use by TFTP transfers."), NULL },
+  { LOPT_SINGLE_PORT, OPT_SINGLE_PORT, NULL, gettext_noop("Use only one port for TFTP server."), NULL },
   { LOPT_LOG_OPTS, OPT_LOG_OPTS, NULL, gettext_noop("Extra logging for DHCP."), NULL },
   { LOPT_MAX_LOGS, ARG_ONE, "[=<integer>]", gettext_noop("Enable async. logging; optionally set queue length."), NULL },
   { LOPT_REBIND, OPT_NO_REBIND, NULL, gettext_noop("Stop DNS rebinding. Filter private IP ranges when resolving."), NULL },
@@ -447,6 +464,7 @@ static struct {
   { LOPT_NO_REBIND, ARG_DUP, "/<domain>/", gettext_noop("Inhibit DNS-rebind protection on this domain."), NULL },
   { LOPT_NOLAST, OPT_ALL_SERVERS, NULL, gettext_noop("Always perform DNS queries to all servers."), NULL },
   { LOPT_MATCH, ARG_DUP, "set:<tag>,<optspec>", gettext_noop("Set tag if client includes matching option in request."), NULL },
+  { LOPT_NAME_MATCH, ARG_DUP, "set:<tag>,<string>[*]", gettext_noop("Set tag if client provides given name."), NULL },
   { LOPT_ALTPORT, ARG_ONE, "[=<ports>]", gettext_noop("Use alternative ports for DHCP."), NULL },
   { LOPT_NAPTR, ARG_DUP, "<name>,<naptr>", gettext_noop("Specify NAPTR DNS record."), NULL },
   { LOPT_MINPORT, ARG_ONE, "<port>", gettext_noop("Specify lowest port available for DNS query transmission."), NULL },
@@ -464,11 +482,13 @@ static struct {
   { LOPT_CPE_ID, ARG_ONE, "<text>", gettext_noop("Add client identification to forwarded DNS queries."), NULL },
   { LOPT_DNSSEC, OPT_DNSSEC_PROXY, NULL, gettext_noop("Proxy DNSSEC validation results from upstream nameservers."), NULL },
   { LOPT_INCR_ADDR, OPT_CONSEC_ADDR, NULL, gettext_noop("Attempt to allocate sequential IP addresses to DHCP clients."), NULL },
+  { LOPT_IGNORE_CLID, OPT_IGNORE_CLID, NULL, gettext_noop("Ignore client identifier option sent by DHCP clients."), NULL },
   { LOPT_CONNTRACK, OPT_CONNTRACK, NULL, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL },
   { LOPT_FQDN, OPT_FQDN_UPDATE, NULL, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL },
   { LOPT_RA, OPT_RA, NULL, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL },
   { LOPT_DUID, ARG_ONE, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL },
   { LOPT_HOST_REC, ARG_DUP, "<name>,<address>[,<ttl>]", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL },
+  { LOPT_CAA, ARG_DUP, "<name>,<flags>,<tag>,<value>", gettext_noop("Specify certification authority authorization record"), NULL },  
   { LOPT_RR, ARG_DUP, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL },
   { LOPT_CLVERBIND, OPT_CLEVERBIND, NULL, gettext_noop("Bind to interfaces in use - check for new interfaces"), NULL },
   { LOPT_AUTHSERV, ARG_ONE, "<NS>,<interface>", gettext_noop("Export local names to global DNS"), NULL },
@@ -482,12 +502,9 @@ static struct {
   { LOPT_SEC_VALID, OPT_DNSSEC_VALID, NULL, gettext_noop("Activate DNSSEC validation"), NULL },
   { LOPT_TRUST_ANCHOR, ARG_DUP, "<domain>,[<class>],...", gettext_noop("Specify trust anchor key digest."), NULL },
   { LOPT_DNSSEC_DEBUG, OPT_DNSSEC_DEBUG, NULL, gettext_noop("Disable upstream checking for DNSSEC debugging."), NULL },
-  { LOPT_DNSSEC_CHECK, OPT_DNSSEC_NO_SIGN, NULL, gettext_noop("Ensure answers without DNSSEC are in unsigned zones."), NULL },
+  { LOPT_DNSSEC_CHECK, ARG_DUP, NULL, gettext_noop("Ensure answers without DNSSEC are in unsigned zones."), NULL },
   { LOPT_DNSSEC_TIME, OPT_DNSSEC_TIME, NULL, gettext_noop("Don't check DNSSEC signature timestamps until first cache-reload"), NULL },
   { LOPT_DNSSEC_STAMP, ARG_ONE, "<path>", gettext_noop("Timestamp file to verify system clock for DNSSEC"), NULL },
-#ifdef OPTION6_PREFIX_CLASS 
-  { LOPT_PREF_CLSS, ARG_DUP, "set:tag,<class>", gettext_noop("Specify DHCPv6 prefix class"), NULL },
-#endif
   { LOPT_RA_PARAM, ARG_DUP, "<iface>,[mtu:<value>|<interface>|off,][<prio>,]<intval>[,<lifetime>]", gettext_noop("Set MTU, priority, resend-interval and router-lifetime"), NULL },
   { LOPT_QUIET_DHCP, OPT_QUIET_DHCP, NULL, gettext_noop("Do not log routine DHCP."), NULL },
   { LOPT_QUIET_DHCP6, OPT_QUIET_DHCP6, NULL, gettext_noop("Do not log routine DHCPv6."), NULL },
@@ -497,6 +514,10 @@ static struct {
   { LOPT_IGNORE_ADDR, ARG_DUP, "<ipaddr>", gettext_noop("Ignore DNS responses containing ipaddr."), NULL }, 
   { LOPT_DHCPTTL, ARG_ONE, "<ttl>", gettext_noop("Set TTL in DNS responses with DHCP-derived addresses."), NULL }, 
   { LOPT_REPLY_DELAY, ARG_ONE, "<integer>", gettext_noop("Delay DHCP replies for at least number of seconds."), NULL },
+  { LOPT_RAPID_COMMIT, OPT_RAPID_COMMIT, NULL, gettext_noop("Enables DHCPv4 Rapid Commit option."), NULL },
+  { LOPT_DUMPFILE, ARG_ONE, "<path>", gettext_noop("Path to debug packet dump file"), NULL },
+  { LOPT_DUMPMASK, ARG_ONE, "<hex>", gettext_noop("Mask which packets to dump"), NULL },
+  { LOPT_SCRIPT_TIME, OPT_LEASE_RENEW, NULL, gettext_noop("Call dhcp-script when lease expiry changes."), NULL },
   { 0, 0, NULL, NULL, NULL }
 }; 
 
@@ -559,14 +580,15 @@ static void *opt_malloc(size_t size)
   return ret;
 }
 
-static char *opt_string_alloc(char *cp)
+static char *opt_string_alloc(const char *cp)
 {
   char *ret = NULL;
+  size_t len;
   
-  if (cp && strlen(cp) != 0)
+  if (cp && (len = strlen(cp)) != 0)
     {
-      ret = opt_malloc(strlen(cp)+1);
-      strcpy(ret, cp); 
+      ret = opt_malloc(len+1);
+      memcpy(ret, cp, len+1); 
       
       /* restore hidden metachars */
       unhide_metas(ret);
@@ -741,15 +763,15 @@ static void do_usage(void)
 }
 
 #define ret_err(x) do { strcpy(errstr, (x)); return 0; } while (0)
+#define ret_err_free(x,m) do { strcpy(errstr, (x)); free((m)); return 0; } while (0)
+#define goto_err(x) do { strcpy(errstr, (x)); goto on_error; } while (0)
 
 static char *parse_mysockaddr(char *arg, union mysockaddr *addr) 
 {
   if (inet_pton(AF_INET, arg, &addr->in.sin_addr) > 0)
     addr->sa.sa_family = AF_INET;
-#ifdef HAVE_IPV6
   else if (inet_pton(AF_INET6, arg, &addr->in6.sin6_addr) > 0)
     addr->sa.sa_family = AF_INET6;
-#endif
   else
     return _("bad address");
    
@@ -761,10 +783,8 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
   int source_port = 0, serv_port = NAMESERVER_PORT;
   char *portno, *source;
   char *interface_opt = NULL;
-#ifdef HAVE_IPV6
   int scope_index = 0;
   char *scope_id;
-#endif
   
   if (!arg || strlen(arg) == 0)
     {
@@ -782,9 +802,7 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
       !atoi_check16(portno, &serv_port))
     return _("bad port");
   
-#ifdef HAVE_IPV6
   scope_id = split_chr(arg, '%');
-#endif
   
   if (source) {
     interface_opt = split_chr(source, '@');
@@ -792,7 +810,7 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
     if (interface_opt)
       {
 #if defined(SO_BINDTODEVICE)
-       strncpy(interface, interface_opt, IF_NAMESIZE - 1);
+       safe_strncpy(interface, interface_opt, IF_NAMESIZE);
 #else
        return _("interface binding not supported");
 #endif
@@ -821,14 +839,13 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
                return _("interface can only be specified once");
              
              source_addr->in.sin_addr.s_addr = INADDR_ANY;
-             strncpy(interface, source, IF_NAMESIZE - 1);
+             safe_strncpy(interface, source, IF_NAMESIZE);
 #else
              return _("interface binding not supported");
 #endif
            }
        }
     }
-#ifdef HAVE_IPV6
   else if (inet_pton(AF_INET6, arg, &addr->in6.sin6_addr) > 0)
     {
       if (scope_id && (scope_index = if_nametoindex(scope_id)) == 0)
@@ -856,14 +873,13 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
                return _("interface can only be specified once");
              
              source_addr->in6.sin6_addr = in6addr_any;
-             strncpy(interface, source, IF_NAMESIZE - 1);
+             safe_strncpy(interface, source, IF_NAMESIZE);
 #else
              return _("interface binding not supported");
 #endif
            }
        }
     }
-#endif
   else
     return _("bad address");
 
@@ -894,6 +910,8 @@ static struct server *add_rev4(struct in_addr addr, int msize)
       p += sprintf(p, "%d.", (a >> 24) & 0xff);
       break;
     default:
+      free(serv->domain);
+      free(serv);
       return NULL;
     }
 
@@ -948,6 +966,116 @@ static char *set_prefix(char *arg)
    return arg;
 }
 
+static struct dhcp_netid *dhcp_netid_create(const char *net, struct dhcp_netid *next)
+{
+  struct dhcp_netid *tt;
+  tt = opt_malloc(sizeof (struct dhcp_netid));
+  tt->net = opt_string_alloc(net);
+  tt->next = next;
+  return tt;
+}
+
+static void dhcp_netid_free(struct dhcp_netid *nid)
+{
+  while (nid)
+    {
+      struct dhcp_netid *tmp = nid;
+      nid = nid->next;
+      free(tmp->net);
+      free(tmp);
+    }
+}
+
+/* Parse one or more tag:s before parameters.
+ * Moves arg to the end of tags. */
+static struct dhcp_netid * dhcp_tags(char **arg)
+{
+  struct dhcp_netid *id = NULL;
+
+  while (is_tag_prefix(*arg))
+    {
+      char *comma = split(*arg);
+      id = dhcp_netid_create((*arg)+4, id);
+      *arg = comma;
+    };
+  if (!*arg)
+    {
+      dhcp_netid_free(id);
+      id = NULL;
+    }
+  return id;
+}
+
+static void dhcp_netid_list_free(struct dhcp_netid_list *netid)
+{
+  while (netid)
+    {
+      struct dhcp_netid_list *tmplist = netid;
+      netid = netid->next;
+      dhcp_netid_free(tmplist->list);
+      free(tmplist);
+    }
+}
+
+static void dhcp_config_free(struct dhcp_config *config)
+{
+  if (config)
+    {
+      struct hwaddr_config *hwaddr = config->hwaddr;
+      
+      while (hwaddr)
+        {
+         struct hwaddr_config *tmp = hwaddr;
+          hwaddr = hwaddr->next;
+         free(tmp);
+        }
+      
+      dhcp_netid_list_free(config->netid);
+      dhcp_netid_free(config->filter);
+      
+      if (config->flags & CONFIG_CLID)
+        free(config->clid);
+
+#ifdef HAVE_DHCP6
+      if (config->flags & CONFIG_ADDR6)
+       {
+         struct addrlist *addr, *tmp;
+         
+         for (addr = config->addr6; addr; addr = tmp)
+           {
+             tmp = addr->next;
+             free(addr);
+           }
+       }
+#endif
+
+      free(config);
+    }
+}
+
+static void dhcp_context_free(struct dhcp_context *ctx)
+{
+  if (ctx)
+    {
+      dhcp_netid_free(ctx->filter);
+      free(ctx->netid.net);
+#ifdef HAVE_DHCP6
+      free(ctx->template_interface);
+#endif
+      free(ctx);
+    }
+}
+
+static void dhcp_opt_free(struct dhcp_opt *opt)
+{
+  if (opt->flags & DHOPT_VENDOR)
+    free(opt->u.vendor_class);
+  dhcp_netid_free(opt->netid);
+  free(opt->val);
+  free(opt);
+}
+
+
 /* This is too insanely large to keep in-line in the switch */
 static int parse_dhcp_opt(char *errstr, char *arg, int flags)
 {
@@ -955,7 +1083,6 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
   char lenchar = 0, *cp;
   int addrs, digs, is_addr, is_addr6, is_hex, is_dec, is_string, dots;
   char *comma = NULL;
-  struct dhcp_netid *np = NULL;
   u16 opt_len = 0;
   int is6 = 0;
   int option_ok = 0;
@@ -1042,14 +1169,9 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
        }
       else
        {
-         new->netid = opt_malloc(sizeof (struct dhcp_netid));
          /* allow optional "net:" or "tag:" for consistency */
-         if (is_tag_prefix(arg))
-           new->netid->net = opt_string_alloc(arg+4);
-         else
-           new->netid->net = opt_string_alloc(set_prefix(arg));
-         new->netid->next = np;
-         np = new->netid;
+         const char *name = (is_tag_prefix(arg)) ? arg+4 : set_prefix(arg);
+         new->netid = dhcp_netid_create(name, new->netid);
        }
       
       arg = comma; 
@@ -1059,7 +1181,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
   if (is6)
     {
       if (new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE))
-       ret_err(_("unsupported encapsulation for IPv6 option"));
+       goto_err(_("unsupported encapsulation for IPv6 option"));
       
       if (opt_len == 0 &&
          !(new->flags & DHOPT_RFC3925))
@@ -1073,13 +1195,13 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
   
   /* option may be missing with rfc3925 match */
   if (!option_ok)
-    ret_err(_("bad dhcp-option"));
+    goto_err(_("bad dhcp-option"));
   
   if (comma)
     {
       /* characterise the value */
       char c;
-      int found_dig = 0;
+      int found_dig = 0, found_colon = 0;
       is_addr = is_addr6 = is_hex = is_dec = is_string = 1;
       addrs = digs = 1;
       dots = 0;
@@ -1093,6 +1215,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
          {
            digs++;
            is_dec = is_addr = 0;
+           found_colon = 1;
          }
        else if (c == '/') 
          {
@@ -1102,7 +1225,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
          } 
        else if (c == '.')      
          {
-           is_addr6 = is_dec = is_hex = 0;
+           is_dec = is_hex = 0;
            dots++;
          }
        else if (c == '-')
@@ -1134,6 +1257,15 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
      
       if (!found_dig)
        is_dec = is_addr = 0;
+
+      if (!found_colon)
+       is_addr6 = 0;
+
+#ifdef HAVE_DHCP6
+      /* NTP server option takes hex, addresses or FQDN */
+      if (is6 && new->opt == OPTION6_NTP_SERVER && !is_hex)
+       opt_len |= is_addr6 ? OT_ADDR_LIST : OT_RFC1035_NAME;
+#endif
      
       /* We know that some options take addresses */
       if (opt_len & OT_ADDR_LIST)
@@ -1141,10 +1273,10 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
          is_string = is_dec = is_hex = 0;
          
          if (!is6 && (!is_addr || dots == 0))
-           ret_err(_("bad IP address"));
+           goto_err(_("bad IP address"));
 
           if (is6 && !is_addr6)
-            ret_err(_("bad IPv6 address"));
+            goto_err(_("bad IPv6 address"));
        }
       /* or names */
       else if (opt_len & (OT_NAME | OT_RFC1035_NAME | OT_CSTRING))
@@ -1237,7 +1369,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
              comma = split(cp);
              slash = split_chr(cp, '/');
              if (!inet_pton(AF_INET, cp, &in))
-               ret_err(_("bad IPv4 address"));
+               goto_err(_("bad IPv4 address"));
              if (!slash)
                {
                  memcpy(op, &in, INADDRSZ);
@@ -1282,8 +1414,8 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
                  op += IN6ADDRSZ;
                  continue;
                }
-         
-             ret_err(_("bad IPv6 address"));
+
+             goto_err(_("bad IPv6 address"));
            } 
          new->len = op - new->val;
        }
@@ -1310,7 +1442,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
                  if (strcmp (arg, ".") != 0)
                    {
                      if (!(dom = canonicalise_opt(arg)))
-                       ret_err(_("bad domain in dhcp-option"));
+                       goto_err(_("bad domain in dhcp-option"));
                        
                      domlen = strlen(dom) + 2;
                    }
@@ -1357,7 +1489,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
                }
       
              /* RFC 3361, enc byte is zero for names */
-             if (new->opt == OPTION_SIP_SERVER)
+             if (new->opt == OPTION_SIP_SERVER && m)
                m[0] = 0;
              new->len = (int) len + header_size;
              new->val = m;
@@ -1395,8 +1527,9 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
            }
          else if (comma && (opt_len & OT_RFC1035_NAME))
            {
-             unsigned char *p = NULL, *newp, *end;
+             unsigned char *p = NULL, *q, *newp, *end;
              int len = 0;
+             int header_size = (is6 && new->opt == OPTION6_NTP_SERVER) ? 4 : 0;
              arg = comma;
              comma = split(arg);
              
@@ -1404,9 +1537,9 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
                {
                  char *dom = canonicalise_opt(arg);
                  if (!dom)
-                   ret_err(_("bad domain in dhcp-option"));
+                   goto_err(_("bad domain in dhcp-option"));
                                  
-                 newp = opt_malloc(len + strlen(dom) + 2);
+                 newp = opt_malloc(len + header_size + strlen(dom) + 2);
                  
                  if (p)
                    {
@@ -1415,8 +1548,14 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
                    }
                  
                  p = newp;
-                 end = do_rfc1035_name(p + len, dom, NULL);
+                 q = p + len;
+                 end = do_rfc1035_name(q + header_size, dom, NULL);
                  *end++ = 0;
+                 if (is6 && new->opt == OPTION6_NTP_SERVER)
+                   {
+                     PUTSHORT(NTP_SUBOPTION_SRV_FQDN, q);
+                     PUTSHORT(end - q - 2, q);
+                   }
                  len = end - p;
                  free(dom);
 
@@ -1442,14 +1581,14 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
       ((new->len > 255) || 
       (new->len > 253 && (new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE))) ||
        (new->len > 250 && (new->flags & DHOPT_RFC3925))))
-    ret_err(_("dhcp-option too long"));
+    goto_err(_("dhcp-option too long"));
   
   if (flags == DHOPT_MATCH)
     {
       if ((new->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR)) ||
          !new->netid ||
          new->netid->next)
-       ret_err(_("illegal dhcp-match"));
+       goto_err(_("illegal dhcp-match"));
        
       if (is6)
        {
@@ -1474,24 +1613,31 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
     }
     
   return 1;
+on_error:
+  dhcp_opt_free(new);
+  return 0;
 }
 
 #endif
 
 void set_option_bool(unsigned int opt)
 {
-  if (opt < 32)
-    daemon->options |= 1u << opt;
-  else
-    daemon->options2 |= 1u << (opt - 32);
+  option_var(opt) |= option_val(opt);
 }
 
 void reset_option_bool(unsigned int opt)
 {
-  if (opt < 32)
-    daemon->options &= ~(1u << opt);
-  else
-    daemon->options2 &= ~(1u << (opt - 32));
+  option_var(opt) &= ~(option_val(opt));
+}
+
+static void server_list_free(struct server *list)
+{
+  while (list)
+    {
+      struct server *tmp = list;
+      list = list->next;
+      free(tmp);
+    }
 }
 
 static int one_opt(int option, char *arg, char *errstr, char *gen_err, int command_line, int servers_only)
@@ -1552,9 +1698,9 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
        struct dirent *ent;
        char *directory, *path;
        struct list {
-         char *suffix;
+         char *name;
          struct list *next;
-       } *ignore_suffix = NULL, *match_suffix = NULL, *li;
+       } *ignore_suffix = NULL, *match_suffix = NULL, *files = NULL, *li;
        
        comma = split(arg);
        if (!(directory = opt_string_alloc(arg)))
@@ -1576,7 +1722,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                        li->next = match_suffix;
                        match_suffix = li;
                        /* Have to copy: buffer is overwritten */
-                       li->suffix = opt_string_alloc(arg+1);
+                       li->name = opt_string_alloc(arg+1);
                      }
                  }
                else
@@ -1584,7 +1730,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                    li->next = ignore_suffix;
                    ignore_suffix = li;
                    /* Have to copy: buffer is overwritten */
-                   li->suffix = opt_string_alloc(arg);
+                   li->name = opt_string_alloc(arg);
                  }
              }
          }
@@ -1609,9 +1755,9 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                for (li = match_suffix; li; li = li->next)
                  {
                    /* check for required suffices */
-                   size_t ls = strlen(li->suffix);
+                   size_t ls = strlen(li->name);
                    if (len > ls &&
-                       strcmp(li->suffix, &ent->d_name[len - ls]) == 0)
+                       strcmp(li->name, &ent->d_name[len - ls]) == 0)
                      break;
                  }
                if (!li)
@@ -1621,9 +1767,9 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
            for (li = ignore_suffix; li; li = li->next)
              {
                /* check for proscribed suffices */
-               size_t ls = strlen(li->suffix);
+               size_t ls = strlen(li->name);
                if (len > ls &&
-                   strcmp(li->suffix, &ent->d_name[len - ls]) == 0)
+                   strcmp(li->name, &ent->d_name[len - ls]) == 0)
                  break;
              }
            if (li)
@@ -1640,25 +1786,44 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
            
            /* only reg files allowed. */
            if (S_ISREG(buf.st_mode))
-             one_file(path, 0);
-           
-           free(path);
+             {
+               /* sort files into order. */
+               struct list **up, *new = opt_malloc(sizeof(struct list));
+               new->name = path;
+               
+               for (up = &files, li = files; li; up = &li->next, li = li->next)
+                 if (strcmp(li->name, path) >=0)
+                   break;
+
+               new->next = li;
+               *up = new;
+             }
+
          }
-     
+
+       for (li = files; li; li = li->next)
+         one_file(li->name, 0);
+       
        closedir(dir_stream);
        free(directory);
        for(; ignore_suffix; ignore_suffix = li)
          {
            li = ignore_suffix->next;
-           free(ignore_suffix->suffix);
+           free(ignore_suffix->name);
            free(ignore_suffix);
          }
        for(; match_suffix; match_suffix = li)
          {
            li = match_suffix->next;
-           free(match_suffix->suffix);
+           free(match_suffix->name);
            free(match_suffix);
          }
+       for(; files; files = li)
+         {
+           li = files->next;
+           free(files->name);
+           free(files);
+         }
        break;
       }
 
@@ -1675,13 +1840,13 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
              /* has subnet+len */
              err = parse_mysockaddr(arg, &new->addr);
              if (err)
-               ret_err(err);
+               ret_err_free(err, new);
              if (!atoi_check(end, &new->mask))
-               ret_err(gen_err);
+               ret_err_free(gen_err, new);
              new->addr_used = 1;
            } 
          else if (!atoi_check(arg, &new->mask))
-           ret_err(gen_err);
+           ret_err_free(gen_err, new);
            
           daemon->add_subnet4 = new;
 
@@ -1693,15 +1858,15 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                  /* has subnet+len */
                   err = parse_mysockaddr(comma, &new->addr);
                   if (err)
-                    ret_err(err);
+                    ret_err_free(err, new);
                   if (!atoi_check(end, &new->mask))
-                    ret_err(gen_err);
+                    ret_err_free(gen_err, new);
                   new->addr_used = 1;
                 }
               else
                 {
                   if (!atoi_check(comma, &new->mask))
-                    ret_err(gen_err);
+                    ret_err_free(gen_err, new);
                 }
           
              daemon->add_subnet6 = new;
@@ -1716,7 +1881,15 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
       else
        daemon->dbus_name = DNSMASQ_SERVICE;
       break;
-      
+
+    case LOPT_UBUS: /* --enable-ubus */
+      set_option_bool(OPT_UBUS);
+      if (arg)
+       daemon->ubus_name = opt_string_alloc(arg);
+      else
+       daemon->ubus_name = DNSMASQ_UBUS_NAME;
+      break;
+
     case '8': /* --log-facility */
       /* may be a filename */
       if (strchr(arg, '/') || strcmp (arg, "-") == 0)
@@ -1737,7 +1910,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
 #endif
        }
       break;
-      
+
     case 'x': /* --pid-file */
       daemon->runfile = opt_string_alloc(arg);
       break;
@@ -1808,6 +1981,14 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
        ret_err(_("bad MX target"));
       break;
 
+    case LOPT_DUMPFILE:  /* --dumpfile */
+      daemon->dump_file = opt_string_alloc(arg);
+      break;
+
+    case LOPT_DUMPMASK:  /* --dumpmask */
+      daemon->dump_mask = strtol(arg, NULL, 0);
+      break;
+      
 #ifdef HAVE_DHCP      
     case 'l':  /* --dhcp-leasefile */
       daemon->lease_file = opt_string_alloc(arg);
@@ -1816,9 +1997,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
       /* Sorry about the gross pre-processor abuse */
     case '6':             /* --dhcp-script */
     case LOPT_LUASCRIPT:  /* --dhcp-luascript */
-#  if defined(NO_FORK)
-      ret_err(_("cannot run scripts under uClinux"));
-#  elif !defined(HAVE_SCRIPT)
+#  if !defined(HAVE_SCRIPT)
       ret_err(_("recompile with HAVE_SCRIPT defined to enable lease-change scripts"));
 #  else
       if (option == LOPT_LUASCRIPT)
@@ -1875,47 +2054,42 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
        break;
       }
       
-
-#ifdef HAVE_AUTH
     case LOPT_AUTHSERV: /* --auth-server */
-      if (!(comma = split(arg)))
-       ret_err(gen_err);
+      comma = split(arg);
       
       daemon->authserver = opt_string_alloc(arg);
-      arg = comma;
-      do {
-       struct iname *new = opt_malloc(sizeof(struct iname));
-       comma = split(arg);
-       new->name = NULL;
-       unhide_metas(arg);
-       if (inet_pton(AF_INET, arg, &new->addr.in.sin_addr) > 0)
-         new->addr.sa.sa_family = AF_INET;
-#ifdef HAVE_IPV6
-       else if (inet_pton(AF_INET6, arg, &new->addr.in6.sin6_addr) > 0)
-         new->addr.sa.sa_family = AF_INET6;
-#endif
-       else
-         {
-           char *fam = split_chr(arg, '/');
-           new->name = opt_string_alloc(arg);
-           new->addr.sa.sa_family = 0;
-           if (fam)
-             {
-               if (strcmp(fam, "4") == 0)
-                 new->addr.sa.sa_family = AF_INET;
-#ifdef HAVE_IPV6
-               else if (strcmp(fam, "6") == 0)
-                 new->addr.sa.sa_family = AF_INET6;
-#endif
-               else
-                 ret_err(gen_err);
-             } 
-         }
-       new->next = daemon->authinterface;
-       daemon->authinterface = new;
-       
-       arg = comma;
-      } while (arg);
+      
+      while ((arg = comma))
+       {
+         struct iname *new = opt_malloc(sizeof(struct iname));
+         comma = split(arg);
+         new->name = NULL;
+         unhide_metas(arg);
+         if (inet_pton(AF_INET, arg, &new->addr.in.sin_addr) > 0)
+           new->addr.sa.sa_family = AF_INET;
+         else if (inet_pton(AF_INET6, arg, &new->addr.in6.sin6_addr) > 0)
+           new->addr.sa.sa_family = AF_INET6;
+         else
+           {
+             char *fam = split_chr(arg, '/');
+             new->name = opt_string_alloc(arg);
+             new->addr.sa.sa_family = 0;
+             if (fam)
+               {
+                 if (strcmp(fam, "4") == 0)
+                   new->addr.sa.sa_family = AF_INET;
+                 else if (strcmp(fam, "6") == 0)
+                   new->addr.sa.sa_family = AF_INET6;
+                 else
+                 {
+                   free(new->name);
+                   ret_err_free(gen_err, new);
+                 }
+               } 
+           }
+         new->next = daemon->authinterface;
+         daemon->authinterface = new;
+       };
             
       break;
 
@@ -1954,7 +2128,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
            int is_exclude = 0;
            char *prefix;
            struct addrlist *subnet =  NULL;
-           struct all_addr addr;
+           union all_addr addr;
 
            comma = split(arg);
            prefix = split_chr(arg, '/');
@@ -1968,20 +2142,18 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                    arg = arg+8;
              }
 
-           if (inet_pton(AF_INET, arg, &addr.addr.addr4))
+           if (inet_pton(AF_INET, arg, &addr.addr4))
              {
                subnet = opt_malloc(sizeof(struct addrlist));
                subnet->prefixlen = (prefixlen == 0) ? 24 : prefixlen;
                subnet->flags = ADDRLIST_LITERAL;
              }
-#ifdef HAVE_IPV6
-           else if (inet_pton(AF_INET6, arg, &addr.addr.addr6))
+           else if (inet_pton(AF_INET6, arg, &addr.addr6))
              {
                subnet = opt_malloc(sizeof(struct addrlist));
                subnet->prefixlen = (prefixlen == 0) ? 64 : prefixlen;
                subnet->flags = ADDRLIST_LITERAL | ADDRLIST_IPV6;
              }
-#endif
            else 
              {
                struct auth_name_list *name =  opt_malloc(sizeof(struct auth_name_list));
@@ -1993,10 +2165,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                  {
                    if (prefixlen == 4)
                      name->flags &= ~AUTH6;
-#ifdef HAVE_IPV6
                    else if (prefixlen == 6)
                      name->flags &= ~AUTH4;
-#endif
                    else
                      ret_err(gen_err);
                  }
@@ -2051,7 +2221,6 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
        }
 
       break;
-#endif
 
     case 's':         /* --domain */
     case LOPT_SYNTH:  /* --synth-domain */
@@ -2080,7 +2249,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
 
                      arg = split(netpart);
                      if (!atoi_check(netpart, &msize))
-                       ret_err(gen_err);
+                       ret_err_free(gen_err, new);
                      else if (inet_pton(AF_INET, comma, &new->start))
                        {
                          int mask = (1 << (32 - msize)) - 1;
@@ -2093,18 +2262,18 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                                {
                                  if (!(new->prefix = canonicalise_opt(arg)) ||
                                      strlen(new->prefix) > MAXLABEL - INET_ADDRSTRLEN)
-                                   ret_err(_("bad prefix"));
+                                   ret_err_free(_("bad prefix"), new);
                                }
                              else if (strcmp(arg, "local") != 0 ||
                                       (msize != 8 && msize != 16 && msize != 24))
-                               ret_err(gen_err);
+                               ret_err_free(gen_err, new);
                              else
                                {
                                   /* generate the equivalent of
                                      local=/xxx.yyy.zzz.in-addr.arpa/ */
                                  struct server *serv = add_rev4(new->start, msize);
                                  if (!serv)
-                                   ret_err(_("bad prefix"));
+                                   ret_err_free(_("bad prefix"), new);
 
                                  serv->flags |= SERV_NO_ADDR;
 
@@ -2118,7 +2287,6 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                                }
                            }
                        }
-#ifdef HAVE_IPV6
                      else if (inet_pton(AF_INET6, comma, &new->start6))
                        {
                          u64 mask = (1LLU << (128 - msize)) - 1LLU;
@@ -2134,17 +2302,17 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                          setaddr6part(&new->end6, addrpart | mask);
                          
                          if (msize < 64)
-                           ret_err(gen_err);
+                           ret_err_free(gen_err, new);
                          else if (arg)
                            {
                              if (option != 's')
                                {
                                  if (!(new->prefix = canonicalise_opt(arg)) ||
                                      strlen(new->prefix) > MAXLABEL - INET6_ADDRSTRLEN)
-                                   ret_err(_("bad prefix"));
+                                   ret_err_free(_("bad prefix"), new);
                                }       
                              else if (strcmp(arg, "local") != 0 || ((msize & 4) != 0))
-                               ret_err(gen_err);
+                               ret_err_free(gen_err, new);
                              else 
                                {
                                  /* generate the equivalent of
@@ -2162,9 +2330,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                                }
                            }
                        }
-#endif
                      else
-                       ret_err(gen_err);
+                       ret_err_free(gen_err, new);
                    }
                  else
                    {
@@ -2178,26 +2345,24 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                          if (!arg)
                            new->end.s_addr = new->start.s_addr;
                          else if (!inet_pton(AF_INET, arg, &new->end))
-                           ret_err(gen_err);
+                           ret_err_free(gen_err, new);
                        }
-#ifdef HAVE_IPV6
                      else if (inet_pton(AF_INET6, comma, &new->start6))
                        {
                          new->is6 = 1;
                          if (!arg)
                            memcpy(&new->end6, &new->start6, IN6ADDRSZ);
                          else if (!inet_pton(AF_INET6, arg, &new->end6))
-                           ret_err(gen_err);
+                           ret_err_free(gen_err, new);
                        }
-#endif
                      else 
-                       ret_err(gen_err);
+                       ret_err_free(gen_err, new);
 
                      if (option != 's' && prefstr)
                        {
                          if (!(new->prefix = canonicalise_opt(prefstr)) ||
                              strlen(new->prefix) > MAXLABEL - INET_ADDRSTRLEN)
-                           ret_err(_("bad prefix"));
+                           ret_err_free(_("bad prefix"), new);
                        }
                    }
 
@@ -2212,7 +2377,9 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                      char *star;
                      new->next = daemon->synth_domains;
                      daemon->synth_domains = new;
-                     if ((star = strrchr(new->prefix, '*')) && *(star+1) == 0)
+                     if (new->prefix &&
+                         (star = strrchr(new->prefix, '*'))
+                         && *(star+1) == 0)
                        {
                          *star = 0;
                          new->indexed = 1;
@@ -2346,7 +2513,6 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
            new->addr.in.sin_len = sizeof(new->addr.in);
 #endif
          }
-#ifdef HAVE_IPV6
        else if (arg && inet_pton(AF_INET6, arg, &new->addr.in6.sin6_addr) > 0)
          {
            new->addr.sa.sa_family = AF_INET6;
@@ -2357,9 +2523,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
            new->addr.in6.sin6_len = sizeof(new->addr.in6);
 #endif
          }
-#endif
        else
-         ret_err(gen_err);
+         ret_err_free(gen_err, new);
 
        new->used = 0;
        if (option == 'a')
@@ -2400,7 +2565,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                if (strcmp(arg, "#") == 0)
                  domain = "";
                else if (strlen (arg) != 0 && !(domain = canonicalise_opt(arg)))
-                 option = '?';
+                 ret_err(gen_err);
                serv = opt_malloc(sizeof(struct server));
                memset(serv, 0, sizeof(struct server));
                serv->next = newlist;
@@ -2430,7 +2595,10 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
          {
            newlist->flags |= SERV_LITERAL_ADDRESS;
            if (!(newlist->flags & SERV_TYPE))
-             ret_err(gen_err);
+             {
+               server_list_free(newlist);
+               ret_err(gen_err);
+             }
          }
        else if (option == LOPT_NO_REBIND)
          newlist->flags |= SERV_NO_REBIND;
@@ -2442,22 +2610,21 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
          }
 
        else if (strcmp(arg, "#") == 0)
-         {
-           newlist->flags |= SERV_USE_RESOLV; /* treat in ordinary way */
-           if (newlist->flags & SERV_LITERAL_ADDRESS)
-             ret_err(gen_err);
-         }
+         newlist->flags |= SERV_USE_RESOLV; /* treat in ordinary way */
        else
          {
            char *err = parse_server(arg, &newlist->addr, &newlist->source_addr, newlist->interface, &newlist->flags);
            if (err)
-             ret_err(err);
+             {
+               server_list_free(newlist);
+               ret_err(err);
+             }
          }
        
        serv = newlist;
        while (serv->next)
          {
-           serv->next->flags = serv->flags;
+           serv->next->flags |= serv->flags & ~(SERV_HAS_DOMAIN | SERV_FOR_NODOTS);
            serv->next->addr = serv->addr;
            serv->next->source_addr = serv->source_addr;
            strcpy(serv->next->interface, serv->interface);
@@ -2474,24 +2641,25 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
        int size;
        struct server *serv;
        struct in_addr addr4;
-#ifdef HAVE_IPV6
        struct in6_addr addr6;
-#endif
  
        unhide_metas(arg);
-       if (!arg || !(comma=split(arg)) || !(string = split_chr(arg, '/')) || !atoi_check(string, &size))
+       if (!arg)
          ret_err(gen_err);
+       
+       comma=split(arg);
 
+       if (!(string = split_chr(arg, '/')) || !atoi_check(string, &size))
+         ret_err(gen_err);
+       
        if (inet_pton(AF_INET, arg, &addr4))
          {
            serv = add_rev4(addr4, size);
            if (!serv)
              ret_err(_("bad prefix"));
          }
-#ifdef HAVE_IPV6
        else if (inet_pton(AF_INET6, arg, &addr6))
          serv = add_rev6(&addr6, size);
-#endif
        else
          ret_err(gen_err);
  
@@ -2532,7 +2700,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                 if (strcmp(arg, "#") == 0 || !*arg)
                   domain = "";
                 else if (strlen(arg) != 0 && !(domain = canonicalise_opt(arg)))
-                  option = '?';
+                  ret_err(gen_err);
                 ipsets->next = opt_malloc(sizeof(struct ipsets));
                 ipsets = ipsets->next;
                 memset(ipsets, 0, sizeof(struct ipsets));
@@ -2547,13 +2715,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
             memset(ipsets, 0, sizeof(struct ipsets));
             ipsets->domain = "";
           }
+        
         if (!arg || !*arg)
-          {
-            option = '?';
-            break;
-          }
-        size = 2;
-        for (end = arg; *end; ++end) 
+          ret_err(gen_err);
+        
+        for (size = 2, end = arg; *end; ++end) 
           if (*end == ',')
               ++size;
      
@@ -2586,8 +2752,14 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
            
            if (size < 0)
              size = 0;
-           else if (size > 10000)
-             size = 10000;
+
+           /* Note that for very large cache sizes, the malloc()
+              will overflow. For the size of the cache record
+              at the time this was noted, the value of "very large"
+               was 46684428. Limit to an order of magnitude less than
+              that to be safe from changes to the cache record. */
+           if (size > 5000000)
+             size = 5000000;
            
            daemon->cachesize = size;
          }
@@ -2774,6 +2946,44 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
       }
 
 #ifdef HAVE_DHCP
+    case LOPT_SHARED_NET: /* --shared-network */
+      {
+       struct shared_network *new = opt_malloc(sizeof(struct shared_network));
+
+#ifdef HAVE_DHCP6
+       new->shared_addr.s_addr = 0;
+#endif
+       new->if_index = 0;
+       
+       if (!(comma = split(arg)))
+         {
+         snerr:
+           free(new);
+           ret_err(_("bad shared-network"));
+         }
+       
+       if (inet_pton(AF_INET, comma, &new->shared_addr))
+         {
+           if (!inet_pton(AF_INET, arg, &new->match_addr) &&
+               !(new->if_index = if_nametoindex(arg)))
+             goto snerr;
+         }
+#ifdef HAVE_DHCP6
+       else if (inet_pton(AF_INET6, comma, &new->shared_addr6))
+         {
+           if (!inet_pton(AF_INET6, arg, &new->match_addr6) &&
+               !(new->if_index = if_nametoindex(arg)))
+             goto snerr;
+         }
+#endif
+       else
+         goto snerr;
+
+       new->next = daemon->shared_networks;
+       daemon->shared_networks = new;
+       break;
+      }
+         
     case 'F':  /* --dhcp-range */
       {
        int k, leasepos = 2;
@@ -2781,13 +2991,6 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
        struct dhcp_context *new = opt_malloc(sizeof(struct dhcp_context));
        
        memset (new, 0, sizeof(*new));
-       new->lease_time = DEFLEASE;
-       
-       if (!arg)
-         {
-           option = '?';
-           break;
-         }
        
        while(1)
          {
@@ -2801,21 +3004,19 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
              {
                if (is_tag_prefix(arg))
                  {
-                   struct dhcp_netid *tt = opt_malloc(sizeof (struct dhcp_netid));
-                   tt->net = opt_string_alloc(arg+4);
-                   tt->next = new->filter;
                    /* ignore empty tag */
-                   if (tt->net)
-                     new->filter = tt;
+                   if (arg[4])
+                     new->filter = dhcp_netid_create(arg+4, new->filter);
                  }
                else
                  {
                    if (new->netid.net)
-                     ret_err(_("only one tag allowed"));
-                   else if (strstr(arg, "set:") == arg)
-                     new->netid.net = opt_string_alloc(arg+4);
+                     {
+                       dhcp_context_free(new);
+                       ret_err(_("only one tag allowed"));
+                     }
                    else
-                     new->netid.net = opt_string_alloc(arg);
+                     new->netid.net = opt_string_alloc(set_prefix(arg));
                  }
                arg = comma;
              }
@@ -2831,11 +3032,15 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
            break;
        
        if (k < 2)
-         ret_err(_("bad dhcp-range"));
+         {
+           dhcp_context_free(new);
+           ret_err(_("bad dhcp-range"));
+         }
        
        if (inet_pton(AF_INET, a[0], &new->start))
          {
            new->next = daemon->dhcp;
+           new->lease_time = DEFLEASE;
            daemon->dhcp = new;
            new->end = new->start;
            if (strcmp(a[1], "static") == 0)
@@ -2843,7 +3048,10 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
            else if (strcmp(a[1], "proxy") == 0)
              new->flags |= CONTEXT_PROXY;
            else if (!inet_pton(AF_INET, a[1], &new->end))
-             ret_err(_("bad dhcp-range"));
+             {
+               dhcp_context_free(new);
+               ret_err(_("bad dhcp-range"));
+             }
            
            if (ntohl(new->start.s_addr) > ntohl(new->end.s_addr))
              {
@@ -2858,7 +3066,10 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                new->flags |= CONTEXT_NETMASK;
                leasepos = 3;
                if (!is_same_net(new->start, new->end, new->netmask))
-                 ret_err(_("inconsistent DHCP range"));
+                 {
+                   dhcp_context_free(new);
+                   ret_err(_("inconsistent DHCP range"));
+                 }
                
            
                if (k >= 4 && strchr(a[3], '.') &&  
@@ -2872,9 +3083,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
 #ifdef HAVE_DHCP6
        else if (inet_pton(AF_INET6, a[0], &new->start6))
          {
+           const char *err = NULL;
+
            new->flags |= CONTEXT_V6; 
            new->prefix = 64; /* default */
            new->end6 = new->start6;
+           new->lease_time = DEFLEASE6;
            new->next = daemon->dhcp6;
            daemon->dhcp6 = new;
 
@@ -2917,19 +3131,24 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                  }
              }
            
-           if (new->prefix != 64)
+           if (new->prefix > 64)
              {
                if (new->flags & CONTEXT_RA)
-                 ret_err(_("prefix length must be exactly 64 for RA subnets"));
+                 err=(_("prefix length must be exactly 64 for RA subnets"));
                else if (new->flags & CONTEXT_TEMPLATE)
-                 ret_err(_("prefix length must be exactly 64 for subnet constructors"));
+                 err=(_("prefix length must be exactly 64 for subnet constructors"));
              }
-
-           if (new->prefix < 64)
-             ret_err(_("prefix length must be at least 64"));
+           else if (new->prefix < 64)
+             err=(_("prefix length must be at least 64"));
            
-           if (!is_same_net6(&new->start6, &new->end6, new->prefix))
-             ret_err(_("inconsistent DHCPv6 range"));
+           if (!err && !is_same_net6(&new->start6, &new->end6, new->prefix))
+             err=(_("inconsistent DHCPv6 range"));
+
+           if (err)
+             {
+               dhcp_context_free(new);
+               ret_err(err);
+             }
 
            /* dhcp-range=:: enables DHCP stateless on any interface */
            if (IN6_IS_ADDR_UNSPECIFIED(&new->start6) && !(new->flags & CONTEXT_TEMPLATE))
@@ -2940,7 +3159,10 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                struct in6_addr zero;
                memset(&zero, 0, sizeof(zero));
                if (!is_same_net6(&zero, &new->start6, new->prefix))
-                 ret_err(_("prefix must be zero with \"constructor:\" argument"));
+                 {
+                   dhcp_context_free(new);
+                   ret_err(_("prefix must be zero with \"constructor:\" argument"));
+                 }
              }
            
            if (addr6part(&new->start6) > addr6part(&new->end6))
@@ -2952,15 +3174,24 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
          }
 #endif
        else
-         ret_err(_("bad dhcp-range"));
+         {
+           dhcp_context_free(new);
+           ret_err(_("bad dhcp-range"));
+         }
        
        if (leasepos < k)
          {
            if (leasepos != k-1)
-             ret_err(_("bad dhcp-range"));
+             {
+               dhcp_context_free(new);
+               ret_err(_("bad dhcp-range"));
+             }
            
            if (strcmp(a[leasepos], "infinite") == 0)
-             new->lease_time = 0xffffffff;
+             {
+               new->lease_time = 0xffffffff;
+               new->flags |= CONTEXT_SETLEASE;
+             }
            else if (strcmp(a[leasepos], "deprecated") == 0)
              new->flags |= CONTEXT_DEPRECATE;
            else
@@ -2996,9 +3227,10 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                        break;
 
                    if (*cp || (leasepos+1 < k))
-                     ret_err(_("bad dhcp-range"));
+                     ret_err_free(_("bad dhcp-range"), new);
                    
                    new->lease_time = atoi(a[leasepos]) * fac;
+                   new->flags |= CONTEXT_SETLEASE;
                    /* Leases of a minute or less confuse
                       some clients, notably Apple's */
                    if (new->lease_time < 120)
@@ -3006,14 +3238,13 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                  }
              }
          }
+
        break;
       }
 
     case LOPT_BANK:
     case 'G':  /* --dhcp-host */
       {
-       int j, k = 0;
-       char *a[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
        struct dhcp_config *new;
        struct in_addr in;
        
@@ -3023,185 +3254,223 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
        new->flags = (option == LOPT_BANK) ? CONFIG_BANK : 0;
        new->hwaddr = NULL;
        new->netid = NULL;
-
-       if ((a[0] = arg))
-         for (k = 1; k < 7; k++)
-           if (!(a[k] = split(a[k-1])))
-             break;
-       
-       for (j = 0; j < k; j++)
-         if (strchr(a[j], ':')) /* ethernet address, netid or binary CLID */
-           {
-             char *arg = a[j];
-             
-             if ((arg[0] == 'i' || arg[0] == 'I') &&
-                 (arg[1] == 'd' || arg[1] == 'D') &&
-                 arg[2] == ':')
-               {
-                 if (arg[3] == '*')
-                   new->flags |= CONFIG_NOCLID;
-                 else
-                   {
-                     int len;
-                     arg += 3; /* dump id: */
-                     if (strchr(arg, ':'))
-                       len = parse_hex(arg, (unsigned char *)arg, -1, NULL, NULL);
-                     else
-                       {
-                         unhide_metas(arg);
-                         len = (int) strlen(arg);
-                       }
-
-                     if (len == -1)
-                       ret_err(_("bad hex constant"));
-                     else if ((new->clid = opt_malloc(len)))
-                       {
-                         new->flags |= CONFIG_CLID;
-                         new->clid_len = len;
-                         memcpy(new->clid, arg, len);
-                       }
-                   }
-               }
-             /* dhcp-host has strange backwards-compat needs. */
-             else if (strstr(arg, "net:") == arg || strstr(arg, "set:") == arg)
-               {
-                 struct dhcp_netid *newtag = opt_malloc(sizeof(struct dhcp_netid));
-                 struct dhcp_netid_list *newlist = opt_malloc(sizeof(struct dhcp_netid_list));
-                 newtag->net = opt_malloc(strlen(arg + 4) + 1);
-                 newlist->next = new->netid;
-                 new->netid = newlist;
-                 newlist->list = newtag;
-                 strcpy(newtag->net, arg+4);
-                 unhide_metas(newtag->net);
-               }
-             else if (strstr(arg, "tag:") == arg)
-               ret_err(_("cannot match tags in --dhcp-host"));
+       new->filter = NULL;
+       new->clid = NULL;
 #ifdef HAVE_DHCP6
-             else if (arg[0] == '[' && arg[strlen(arg)-1] == ']')
-               {
-                 arg[strlen(arg)-1] = 0;
-                 arg++;
-                 
-                 if (!inet_pton(AF_INET6, arg, &new->addr6))
-                   ret_err(_("bad IPv6 address"));
+       new->addr6 = NULL;
+#endif
 
-                 for (i= 0; i < 8; i++)
-                   if (new->addr6.s6_addr[i] != 0)
-                     break;
+       while (arg)
+         {
+           comma = split(arg);
+           if (strchr(arg, ':')) /* ethernet address, netid or binary CLID */
+             {
+               if ((arg[0] == 'i' || arg[0] == 'I') &&
+                   (arg[1] == 'd' || arg[1] == 'D') &&
+                   arg[2] == ':')
+                 {
+                   if (arg[3] == '*')
+                     new->flags |= CONFIG_NOCLID;
+                   else
+                     {
+                       int len;
+                       arg += 3; /* dump id: */
+                       if (strchr(arg, ':'))
+                         len = parse_hex(arg, (unsigned char *)arg, -1, NULL, NULL);
+                       else
+                         {
+                           unhide_metas(arg);
+                           len = (int) strlen(arg);
+                         }
+                       
+                       if (len == -1)
+                         {
+                           dhcp_config_free(new);
+                           ret_err(_("bad hex constant"));
+                         }
+                       else if ((new->clid = opt_malloc(len)))
+                         {
+                           new->flags |= CONFIG_CLID;
+                           new->clid_len = len;
+                           memcpy(new->clid, arg, len);
+                         }
+                     }
+                 }
+               /* dhcp-host has strange backwards-compat needs. */
+               else if (strstr(arg, "net:") == arg || strstr(arg, "set:") == arg)
+                 {
+                   struct dhcp_netid_list *newlist = opt_malloc(sizeof(struct dhcp_netid_list));
+                   newlist->next = new->netid;
+                   new->netid = newlist;
+                   newlist->list = dhcp_netid_create(arg+4, NULL);
+                 }
+               else if (strstr(arg, "tag:") == arg)
+                 new->filter = dhcp_netid_create(arg+4, new->filter);
+                 
+#ifdef HAVE_DHCP6
+               else if (arg[0] == '[' && arg[strlen(arg)-1] == ']')
+                 {
+                   char *pref;
+                   struct in6_addr in6;
+                   struct addrlist *new_addr;
+                   
+                   arg[strlen(arg)-1] = 0;
+                   arg++;
+                   pref = split_chr(arg, '/');
+                   
+                   if (!inet_pton(AF_INET6, arg, &in6))
+                     {
+                       dhcp_config_free(new);
+                       ret_err(_("bad IPv6 address"));
+                     }
 
-                 /* set WILDCARD if network part all zeros */
-                 if (i == 8)
-                   new->flags |= CONFIG_WILDCARD;
+                   new_addr = opt_malloc(sizeof(struct addrlist));
+                   new_addr->next = new->addr6;
+                   new_addr->flags = 0;
+                   new_addr->addr.addr6 = in6;
+                   new->addr6 = new_addr;
+                   
+                   if (pref)
+                     {
+                       u64 addrpart = addr6part(&in6);
+                       
+                       if (!atoi_check(pref, &new_addr->prefixlen) ||
+                           new_addr->prefixlen > 128 ||
+                           ((((u64)1<<(128-new_addr->prefixlen))-1) & addrpart) != 0)
+                         {
+                           dhcp_config_free(new);
+                           ret_err(_("bad IPv6 prefix"));
+                         }
+                       
+                       new_addr->flags |= ADDRLIST_PREFIX;
+                     }
                  
-                 new->flags |= CONFIG_ADDR6;
-               }
+                   for (i= 0; i < 8; i++)
+                     if (in6.s6_addr[i] != 0)
+                       break;
+                   
+                   /* set WILDCARD if network part all zeros */
+                   if (i == 8)
+                     new_addr->flags |= ADDRLIST_WILDCARD;
+                   
+                   new->flags |= CONFIG_ADDR6;
+                 }
 #endif
-             else
-               {
-                 struct hwaddr_config *newhw = opt_malloc(sizeof(struct hwaddr_config));
-                 if ((newhw->hwaddr_len = parse_hex(a[j], newhw->hwaddr, DHCP_CHADDR_MAX, 
-                                                    &newhw->wildcard_mask, &newhw->hwaddr_type)) == -1)
-                   ret_err(_("bad hex constant"));
-                 else
-                   {
-                     
-                     newhw->next = new->hwaddr;
-                     new->hwaddr = newhw;
-                   }               
-               }
-           }
-         else if (strchr(a[j], '.') && (inet_pton(AF_INET, a[j], &in) > 0))
-           {
-             struct dhcp_config *configs;
-             
-             new->addr = in;
-             new->flags |= CONFIG_ADDR;
-
-             /* If the same IP appears in more than one host config, then DISCOVER
-                for one of the hosts will get the address, but REQUEST will be NAKed,
-                since the address is reserved by the other one -> protocol loop. */
-             for (configs = daemon->dhcp_conf; configs; configs = configs->next) 
-               if ((configs->flags & CONFIG_ADDR) && configs->addr.s_addr == in.s_addr)
+               else
                  {
-                   sprintf(errstr, _("duplicate dhcp-host IP address %s"),  inet_ntoa(in));
-                   return 0;
-                 }           
-           }
-         else
-           {
-             char *cp, *lastp = NULL, last = 0;
-             int fac = 1, isdig = 0;
-             
-             if (strlen(a[j]) > 1)
-               {
-                 lastp = a[j] + strlen(a[j]) - 1;
-                 last = *lastp;
-                 switch (last)
+                   struct hwaddr_config *newhw = opt_malloc(sizeof(struct hwaddr_config));
+                   if ((newhw->hwaddr_len = parse_hex(arg, newhw->hwaddr, DHCP_CHADDR_MAX, 
+                                                      &newhw->wildcard_mask, &newhw->hwaddr_type)) == -1)
+                     {
+                       free(newhw);
+                       dhcp_config_free(new);
+                       ret_err(_("bad hex constant"));
+                     }
+                   else
+                     {
+                       newhw->next = new->hwaddr;
+                       new->hwaddr = newhw;
+                     }             
+                 }
+             }
+           else if (strchr(arg, '.') && (inet_pton(AF_INET, arg, &in) > 0))
+             {
+               struct dhcp_config *configs;
+               
+               new->addr = in;
+               new->flags |= CONFIG_ADDR;
+               
+               /* If the same IP appears in more than one host config, then DISCOVER
+                  for one of the hosts will get the address, but REQUEST will be NAKed,
+                  since the address is reserved by the other one -> protocol loop. */
+               for (configs = daemon->dhcp_conf; configs; configs = configs->next) 
+                 if ((configs->flags & CONFIG_ADDR) && configs->addr.s_addr == in.s_addr)
                    {
-                   case 'w':
-                   case 'W':
-                     fac *= 7;
-                     /* fall through */
-                   case 'd':
-                   case 'D':
-                     fac *= 24;
-                     /* fall through */
-                   case 'h':
-                   case 'H':
-                     fac *= 60;
-                     /* fall through */
-                   case 'm':
-                   case 'M':
-                     fac *= 60;
-                     /* fall through */
-                   case 's':
-                   case 'S':
-                     *lastp = 0;
-                   }
-               }
-             
-             for (cp = a[j]; *cp; cp++)
-               if (isdigit((unsigned char)*cp))
-                 isdig = 1;
-               else if (*cp != ' ')
-                 break;
+                     sprintf(errstr, _("duplicate dhcp-host IP address %s"),  inet_ntoa(in));
+                     return 0;
+                   }         
+             }
+           else
+             {
+               char *cp, *lastp = NULL, last = 0;
+               int fac = 1, isdig = 0;
+               
+               if (strlen(arg) > 1)
+                 {
+                   lastp = arg + strlen(arg) - 1;
+                   last = *lastp;
+                   switch (last)
+                     {
+                     case 'w':
+                     case 'W':
+                       fac *= 7;
+                       /* fall through */
+                     case 'd':
+                     case 'D':
+                       fac *= 24;
+                       /* fall through */
+                     case 'h':
+                     case 'H':
+                       fac *= 60;
+                       /* fall through */
+                     case 'm':
+                     case 'M':
+                       fac *= 60;
+                       /* fall through */
+                     case 's':
+                     case 'S':
+                       *lastp = 0;
+                     }
+                 }
+               
+               for (cp = arg; *cp; cp++)
+                 if (isdigit((unsigned char)*cp))
+                   isdig = 1;
+                 else if (*cp != ' ')
+                   break;
+
+               if (*cp)
+                 {
+                   if (lastp)
+                     *lastp = last;
+                   if (strcmp(arg, "infinite") == 0)
+                     {
+                       new->lease_time = 0xffffffff;
+                       new->flags |= CONFIG_TIME;
+                     }
+                   else if (strcmp(arg, "ignore") == 0)
+                     new->flags |= CONFIG_DISABLE;
+                   else
+                     {
+                       if (!(new->hostname = canonicalise_opt(arg)) ||
+                           !legal_hostname(new->hostname))
+                         {
+                           dhcp_config_free(new);
+                           ret_err(_("bad DHCP host name"));
+                         }
+                       
+                       new->flags |= CONFIG_NAME;
+                       new->domain = strip_hostname(new->hostname);                    
+                     }
+                 }
+               else if (isdig)
+                 {
+                   new->lease_time = atoi(arg) * fac; 
+                   /* Leases of a minute or less confuse
+                      some clients, notably Apple's */
+                   if (new->lease_time < 120)
+                     new->lease_time = 120;
+                   new->flags |= CONFIG_TIME;
+                 }
+             }
+
+           arg = comma;
+         }
 
-             if (*cp)
-               {
-                 if (lastp)
-                   *lastp = last;
-                 if (strcmp(a[j], "infinite") == 0)
-                   {
-                     new->lease_time = 0xffffffff;
-                     new->flags |= CONFIG_TIME;
-                   }
-                 else if (strcmp(a[j], "ignore") == 0)
-                   new->flags |= CONFIG_DISABLE;
-                 else
-                   {
-                     if (!(new->hostname = canonicalise_opt(a[j])) ||
-                         !legal_hostname(new->hostname))
-                       ret_err(_("bad DHCP host name"));
-                    
-                     new->flags |= CONFIG_NAME;
-                     new->domain = strip_hostname(new->hostname);                      
-                   }
-               }
-             else if (isdig)
-               {
-                 new->lease_time = atoi(a[j]) * fac; 
-                 /* Leases of a minute or less confuse
-                    some clients, notably Apple's */
-                 if (new->lease_time < 120)
-                   new->lease_time = 120;
-                 new->flags |= CONFIG_TIME;
-               }
-           }
-       
        daemon->dhcp_conf = new;
        break;
       }
-
+      
     case LOPT_TAG_IF:  /* --tag-if */
       {
        struct tag_if *new = opt_malloc(sizeof(struct tag_if));
@@ -3234,10 +3503,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
              }
            else
              {
-               struct dhcp_netid *newtag = opt_malloc(sizeof(struct dhcp_netid));
-               newtag->net = opt_malloc(len - 3);
-               strcpy(newtag->net, arg+4);
-               unhide_metas(newtag->net);
+               struct dhcp_netid *newtag = dhcp_netid_create(arg+4, NULL);
 
                if (strstr(arg, "set:") == arg)
                  {
@@ -3254,7 +3520,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                else 
                  {
                    new->set = NULL;
-                   free(newtag);
+                   dhcp_netid_free(newtag);
                    break;
                  }
              }
@@ -3263,7 +3529,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
          }
 
        if (!new->set)
-         ret_err(_("bad tag-if"));
+         {
+           dhcp_netid_free(new->tag);
+           dhcp_netid_list_free(new->set);
+           ret_err_free(_("bad tag-if"), new);
+         }
          
        break;
       }
@@ -3277,22 +3547,41 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
                            option == LOPT_FORCE ? DHOPT_FORCE : 
                            (option == LOPT_MATCH ? DHOPT_MATCH :
                             (option == LOPT_OPTS ? DHOPT_BANK : 0)));
-     
-    case 'M': /* --dhcp-boot */
+
+    case LOPT_NAME_MATCH: /* --dhcp-name-match */
       {
-       struct dhcp_netid *id = NULL;
-       while (is_tag_prefix(arg))
+       struct dhcp_match_name *new = opt_malloc(sizeof(struct dhcp_match_name));
+       struct dhcp_netid *id = opt_malloc(sizeof(struct dhcp_netid));
+       ssize_t len;
+       
+       if (!(comma = split(arg)) || (len = strlen(comma)) == 0)
+         ret_err(gen_err);
+
+       new->wildcard = 0;
+       new->netid = id;
+       id->net = opt_string_alloc(set_prefix(arg));
+
+       if (comma[len-1] == '*')
          {
-           struct dhcp_netid *newid = opt_malloc(sizeof(struct dhcp_netid));
-           newid->next = id;
-           id = newid;
-           comma = split(arg);
-           newid->net = opt_string_alloc(arg+4);
-           arg = comma;
-         };
+           comma[len-1] = 0;
+           new->wildcard = 1;
+         }
+       new->name = opt_string_alloc(comma);
+
+       new->next = daemon->dhcp_name_match;
+       daemon->dhcp_name_match = new;
+
+       break;
+      }
+      
+    case 'M': /* --dhcp-boot */
+      {
+       struct dhcp_netid *id = dhcp_tags(&arg);
        
        if (!arg)
-         ret_err(gen_err);
+         {
+           ret_err(gen_err);
+         }
        else 
          {
            char *dhcp_file, *dhcp_sname = NULL, *tftp_sname = NULL;
@@ -3338,19 +3627,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
 
     case LOPT_REPLY_DELAY: /* --dhcp-reply-delay */
       {
-       struct dhcp_netid *id = NULL;
-       while (is_tag_prefix(arg))
-         {
-           struct dhcp_netid *newid = opt_malloc(sizeof(struct dhcp_netid));
-           newid->next = id;
-           id = newid;
-           comma = split(arg);
-           newid->net = opt_string_alloc(arg+4);
-           arg = comma;
-         };
+       struct dhcp_netid *id = dhcp_tags(&arg);
        
        if (!arg)
-         ret_err(gen_err);
+         {
+           ret_err(gen_err);
+         }
        else
          {
            struct delay_config *new;
@@ -3375,19 +3657,13 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
         
         new->netid = NULL;
         new->opt = 10; /* PXE_MENU_PROMPT */
-
-        while (is_tag_prefix(arg))
-         {
-            struct dhcp_netid *nn = opt_malloc(sizeof (struct dhcp_netid));
-            comma = split(arg);
-            nn->next = new->netid;
-            new->netid = nn;
-            nn->net = opt_string_alloc(arg+4);
-            arg = comma;
-          }
+        new->netid = dhcp_tags(&arg);
         
         if (!arg)
-          ret_err(gen_err);
+          {
+            dhcp_opt_free(new);
+            ret_err(gen_err);
+          }
         else
           {
             comma = split(arg);
@@ -3423,17 +3699,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
         new->netid = NULL;
         new->sname = NULL;
         new->server.s_addr = 0;
+        new->netid = dhcp_tags(&arg);
 
-        while (is_tag_prefix(arg))
-          {
-            struct dhcp_netid *nn = opt_malloc(sizeof (struct dhcp_netid));
-            comma = split(arg);
-            nn->next = new->netid;
-            new->netid = nn;
-            nn->net = opt_string_alloc(arg+4);
-            arg = comma;
-          }
-       
         if (arg && (comma = split(arg)))
           {
             for (i = 0; CSA[i]; i++)
@@ -3510,7 +3777,10 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
            unhide_metas(comma);
            new->hwaddr_len = parse_hex(comma, new->hwaddr, DHCP_CHADDR_MAX, &new->mask, &new->hwaddr_type);
            if (new->hwaddr_len == -1)
-             ret_err(gen_err);
+             {
+               free(new->netid.net);
+               ret_err_free(gen_err, new);
+             }
            else
              {
                new->next = daemon->dhcp_macs;
@@ -3520,24 +3790,6 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
       }
       break;
 
-#ifdef OPTION6_PREFIX_CLASS 
-    case LOPT_PREF_CLSS: /* --dhcp-prefix-class */
-      {
-       struct prefix_class *new = opt_malloc(sizeof(struct prefix_class));
-       
-       if (!(comma = split(arg)) ||
-           !atoi_check16(comma, &new->class))
-         ret_err(gen_err);
-       
-       new->tag.net = opt_string_alloc(set_prefix(arg));
-       new->next = daemon->prefix_classes;
-       daemon->prefix_classes = new;
-       
-       break;
-      }
-#endif
-                             
-
     case 'U':           /* --dhcp-vendorclass */
     case 'j':           /* --dhcp-userclass */
     case LOPT_CIRCUIT:  /* --dhcp-circuitid */
@@ -3549,7 +3801,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
         struct dhcp_vendor *new = opt_malloc(sizeof(struct dhcp_vendor));
         
         if (!(comma = split(arg)))
-          ret_err(gen_err);
+          ret_err_free(gen_err, new);
        
         new->netid.net = opt_string_alloc(set_prefix(arg));
         /* check for hex string - must digits may include : must not have nothing else, 
@@ -3559,7 +3811,10 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
         if ((comma = split(arg)))
           {
             if (option  != 'U' || strstr(arg, "enterprise:") != arg)
-              ret_err(gen_err);
+              {
+                free(new->netid.net);
+                ret_err_free(gen_err, new);
+              }
             else
               new->enterprise = atoi(arg+11);
           }
@@ -3661,14 +3916,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
          }
        
        while (arg) {
-         struct dhcp_netid *member = opt_malloc(sizeof(struct dhcp_netid));
          comma = split(arg);
-         member->next = list;
-         list = member;
-         if (is_tag_prefix(arg))
-           member->net = opt_string_alloc(arg+4);
-         else
-           member->net = opt_string_alloc(arg);
+         list = dhcp_netid_create(is_tag_prefix(arg) ? arg+4 :arg, list);
          arg = comma;
        }
        
@@ -3682,7 +3931,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
        struct addr_list *new = opt_malloc(sizeof(struct addr_list));
        comma = split(arg);
        if (!(inet_pton(AF_INET, arg, &new->addr) > 0))
-         ret_err(_("bad dhcp-proxy address"));
+         ret_err_free(_("bad dhcp-proxy address"), new);
        new->next = daemon->override_relays;
        daemon->override_relays = new;
        arg = comma;
@@ -3708,7 +3957,10 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
          }
 #endif
        else
-         ret_err(_("Bad dhcp-relay"));
+         {
+           free(new->interface);
+           ret_err_free(_("Bad dhcp-relay"), new);
+         }
        
        break;
       }
@@ -3748,8 +4000,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
           arg = split(comma);
           if (!atoi_check(comma, &new->interval) || 
              (arg && !atoi_check(arg, &new->lifetime)))
+             {
 err:
-           ret_err(_("bad RA-params"));
+              free(new->name);
+              ret_err_free(_("bad RA-params"), new);
+             }
          
          new->next = daemon->ra_interfaces;
          daemon->ra_interfaces = new;
@@ -3790,17 +4045,15 @@ err:
 
        if ((k < 2) || 
            (!(inet_pton(AF_INET, a[0], &new->in) > 0)) ||
-           (!(inet_pton(AF_INET, a[1], &new->out) > 0)))
-         option = '?';
-       
-       if (k == 3 && !inet_pton(AF_INET, a[2], &new->mask))
-         option = '?';
+           (!(inet_pton(AF_INET, a[1], &new->out) > 0)) ||
+           (k == 3 && !inet_pton(AF_INET, a[2], &new->mask)))
+         ret_err(_("missing address in alias"));
        
        if (dash && 
            (!(inet_pton(AF_INET, dash, &new->end) > 0) ||
             !is_same_net(new->in, new->end, new->mask) ||
             ntohl(new->in.s_addr) > ntohl(new->end.s_addr)))
-         ret_err(_("invalid alias range"));
+         ret_err_free(_("invalid alias range"), new);
        
        break;
       }
@@ -3830,12 +4083,10 @@ err:
          {
            if (strcmp(arg, "4") == 0)
              new->family = AF_INET;
-#ifdef HAVE_IPV6
            else if (strcmp(arg, "6") == 0)
              new->family = AF_INET6;
-#endif
            else
-             ret_err(gen_err);
+             ret_err_free(gen_err, new);
          } 
        new->intr = opt_string_alloc(comma);
        break;
@@ -3867,11 +4118,19 @@ err:
            alias = canonicalise_opt(arg);
 
            if (!alias || !target)
-             ret_err(_("bad CNAME"));
+             {
+               free(target);
+               free(alias);
+               ret_err(_("bad CNAME"));
+             }
            
            for (new = daemon->cnames; new; new = new->next)
              if (hostname_isequal(new->alias, alias))
-               ret_err(_("duplicate CNAME"));
+               {
+                 free(target);
+                 free(alias);
+                 ret_err(_("duplicate CNAME"));
+               }
            new = opt_malloc(sizeof(struct cname));
            new->next = daemon->cnames;
            daemon->cnames = new;
@@ -3894,7 +4153,11 @@ err:
        
        if (!(dom = canonicalise_opt(arg)) ||
            (comma && !(target = canonicalise_opt(comma))))
-         ret_err(_("bad PTR record"));
+         {
+           free(dom);
+           free(target);
+           ret_err(_("bad PTR record"));
+         }
        else
          {
            new = opt_malloc(sizeof(struct ptr_record));
@@ -3912,7 +4175,7 @@ err:
        int k = 0;
        struct naptr *new;
        int order, pref;
-       char *name, *replace = NULL;
+       char *name=NULL, *replace = NULL;
 
        if ((a[0] = arg))
          for (k = 1; k < 7; k++)
@@ -3925,7 +4188,11 @@ err:
            !atoi_check16(a[1], &order) || 
            !atoi_check16(a[2], &pref) ||
            (k == 7 && !(replace = canonicalise_opt(a[6]))))
-         ret_err(_("bad NAPTR record"));
+          {
+           free(name);
+           free(replace);
+           ret_err(_("bad NAPTR record"));
+          }
        else
          {
            new = opt_malloc(sizeof(struct naptr));
@@ -3947,26 +4214,30 @@ err:
                struct txt_record *new;
        size_t len = 0;
        char *data;
-       int val;
+       int class;
 
        comma = split(arg);
        data = split(comma);
                
        new = opt_malloc(sizeof(struct txt_record));
-       new->next = daemon->rr;
-       daemon->rr = new;
+       new->name = NULL;
        
-       if (!atoi_check(comma, &val) || 
+       if (!atoi_check(comma, &class) || 
            !(new->name = canonicalise_opt(arg)) ||
            (data && (len = parse_hex(data, (unsigned char *)data, -1, NULL, NULL)) == -1U))
-         ret_err(_("bad RR record"));
-               
-       new->class = val;
+          {
+            free(new->name);
+           ret_err_free(_("bad RR record"), new);
+          }
+
        new->len = 0;
+       new->class = class;
+       new->next = daemon->rr;
+       daemon->rr = new;
        
        if (data)
          {
-           new->txt=opt_malloc(len);
+           new->txt = opt_malloc(len);
            new->len = len;
            memcpy(new->txt, data, len);
          }
@@ -3974,6 +4245,37 @@ err:
        break;
       }
 
+    case LOPT_CAA: /* --caa-record */
+      {
+               struct txt_record *new;
+       char *tag, *value;
+       int flags;
+       
+       comma = split(arg);
+       tag = split(comma);
+       value = split(tag);
+       
+       new = opt_malloc(sizeof(struct txt_record));
+       new->next = daemon->rr;
+       daemon->rr = new;
+
+       if (!atoi_check(comma, &flags) || !tag || !value || !(new->name = canonicalise_opt(arg)))
+         ret_err(_("bad CAA record"));
+       
+       unhide_metas(tag);
+       unhide_metas(value);
+
+       new->len = strlen(tag) + strlen(value) + 2;
+       new->txt = opt_malloc(new->len);
+       new->txt[0] = flags;
+       new->txt[1] = strlen(tag);
+       memcpy(&new->txt[2], tag, strlen(tag));
+       memcpy(&new->txt[2 + strlen(tag)], value, strlen(value));
+       new->class = T_CAA;
+       
+       break;
+      }
+       
     case 'Y':  /* --txt-record */
       {
        struct txt_record *new;
@@ -3983,14 +4285,14 @@ err:
        comma = split(arg);
                
        new = opt_malloc(sizeof(struct txt_record));
-       new->next = daemon->txt;
-       daemon->txt = new;
        new->class = C_IN;
        new->stat = 0;
 
        if (!(new->name = canonicalise_opt(arg)))
-         ret_err(_("bad TXT record"));
+         ret_err_free(_("bad TXT record"), new);
        
+       new->next = daemon->txt;
+       daemon->txt = new;
        len = comma ? strlen(comma) : 0;
        len += (len/255) + 1; /* room for extra counts */
        new->txt = p = opt_malloc(len);
@@ -4037,24 +4339,32 @@ err:
            arg = comma;
            comma = split(arg);
            if (!(target = canonicalise_opt(arg)))
-             ret_err(_("bad SRV target"));
+             ret_err_free(_("bad SRV target"), name);
                
            if (comma)
              {
                arg = comma;
                comma = split(arg);
                if (!atoi_check16(arg, &port))
-                 ret_err(_("invalid port number"));
+                  {
+                    free(name);
+                   ret_err_free(_("invalid port number"), target);
+                  }
                
                if (comma)
                  {
                    arg = comma;
                    comma = split(arg);
                    if (!atoi_check16(arg, &priority))
-                     ret_err(_("invalid priority"));
-                       
+                      {
+                        free(name);
+                       ret_err_free(_("invalid priority"), target);
+                     }
                    if (comma && !atoi_check16(comma, &weight))
-                     ret_err(_("invalid weight"));
+                      {
+                        free(name);
+                       ret_err_free(_("invalid weight"), target);
+                      }
                  }
              }
          }
@@ -4073,16 +4383,19 @@ err:
       
     case LOPT_HOST_REC: /* --host-record */
       {
-       struct host_record *new = opt_malloc(sizeof(struct host_record));
-       memset(new, 0, sizeof(struct host_record));
-       new->ttl = -1;
+       struct host_record *new;
 
        if (!arg || !(comma = split(arg)))
          ret_err(_("Bad host-record"));
        
+       new = opt_malloc(sizeof(struct host_record));
+       memset(new, 0, sizeof(struct host_record));
+       new->ttl = -1;
+       new->flags = 0;
+
        while (arg)
          {
-           struct all_addr addr;
+           union all_addr addr;
            char *dig;
 
            for (dig = arg; *dig != 0; dig++)
@@ -4090,20 +4403,33 @@ err:
                break;
            if (*dig == 0)
              new->ttl = atoi(arg);
-           else if (inet_pton(AF_INET, arg, &addr))
-             new->addr = addr.addr.addr4;
-#ifdef HAVE_IPV6
-           else if (inet_pton(AF_INET6, arg, &addr))
-             new->addr6 = addr.addr.addr6;
-#endif
+           else if (inet_pton(AF_INET, arg, &addr.addr4))
+             {
+               new->addr = addr.addr4;
+               new->flags |= HR_4;
+             }
+           else if (inet_pton(AF_INET6, arg, &addr.addr6))
+             {
+               new->addr6 = addr.addr6;
+               new->flags |= HR_6;
+             }
            else
              {
                int nomem;
                char *canon = canonicalise(arg, &nomem);
-               struct name_list *nl = opt_malloc(sizeof(struct name_list));
+               struct name_list *nl;
                if (!canon)
-                 ret_err(_("Bad name in host-record"));
+                  {
+                   struct name_list *tmp = new->names, *next;
+                   for (tmp = new->names; tmp; tmp = next)
+                     {
+                       next = tmp->next;
+                       free(tmp);
+                     }
+                   ret_err_free(_("Bad name in host-record"), new);
+                  }
 
+               nl = opt_malloc(sizeof(struct name_list));
                nl->name = canon;
                /* keep order, so that PTR record goes to first name */
                nl->next = NULL;
@@ -4132,17 +4458,28 @@ err:
       }
 
 #ifdef HAVE_DNSSEC
-    case LOPT_DNSSEC_STAMP:
+    case LOPT_DNSSEC_STAMP: /* --dnssec-timestamp */
       daemon->timestamp_file = opt_string_alloc(arg); 
       break;
 
-    case LOPT_TRUST_ANCHOR:
+    case LOPT_DNSSEC_CHECK: /* --dnssec-check-unsigned */
+      if (arg)
+       {
+         if (strcmp(arg, "no") == 0)
+           set_option_bool(OPT_DNSSEC_IGN_NS);
+         else
+           ret_err(_("bad value for dnssec-check-unsigned"));
+       }
+      break;
+      
+    case LOPT_TRUST_ANCHOR: /* --trust-anchor */
       {
        struct ds_config *new = opt_malloc(sizeof(struct ds_config));
        char *cp, *cp1, *keyhex, *digest, *algo = NULL;
        int len;
        
        new->class = C_IN;
+       new->name = NULL;
 
        if ((comma = split(arg)) && (algo = split(comma)))
          {
@@ -4167,7 +4504,7 @@ err:
            !atoi_check8(algo, &new->algo) ||
            !atoi_check8(digest, &new->digest_type) ||
            !(new->name = canonicalise_opt(arg)))
-         ret_err(_("bad trust anchor"));
+         ret_err_free(_("bad trust anchor"), new);
            
        /* Upper bound on length */
        len = (2*strlen(keyhex))+1;
@@ -4181,7 +4518,10 @@ err:
          else
            cp++;
        if ((new->digestlen = parse_hex(keyhex, (unsigned char *)new->digest, len, NULL, NULL)) == -1)
-         ret_err(_("bad HEX in trust anchor"));
+         {
+           free(new->name);
+           ret_err_free(_("bad HEX in trust anchor"), new);
+         }
        
        new->next = daemon->ds;
        daemon->ds = new;
@@ -4321,7 +4661,7 @@ static void read_file(char *file, FILE *f, int hard_opt)
       if (errmess)
        strcpy(daemon->namebuff, errmess);
          
-      if (errmess || !one_opt(option, arg, buff, _("error"), 0, hard_opt == LOPT_REV_SERV))
+      if (errmess || !one_opt(option, arg, daemon->namebuff, _("error"), 0, hard_opt == LOPT_REV_SERV))
        {
          sprintf(daemon->namebuff + strlen(daemon->namebuff), _(" at line %d of %s"), lineno, file);
          if (hard_opt != 0)
@@ -4650,8 +4990,8 @@ void read_opts(int argc, char **argv, char *compile_opts)
   size_t argbuf_size = MAXDNAME;
   char *argbuf = opt_malloc(argbuf_size);
   char *buff = opt_malloc(MAXDNAME);
-  int option, conffile_opt = '7', testmode = 0;
-  char *arg, *conffile = CONFFILE;
+  int option, testmode = 0;
+  char *arg, *conffile = NULL;
       
   opterr = 0;
 
@@ -4725,8 +5065,7 @@ void read_opts(int argc, char **argv, char *compile_opts)
              argbuf_size = strlen(optarg) + 1;
              argbuf = opt_malloc(argbuf_size);
            }
-         strncpy(argbuf, optarg, argbuf_size);
-         argbuf[argbuf_size-1] = 0;
+         safe_strncpy(argbuf, optarg, argbuf_size);
          arg = argbuf;
        }
       else
@@ -4761,8 +5100,14 @@ void read_opts(int argc, char **argv, char *compile_opts)
         }
       else if (option == 'C')
        {
-         conffile_opt = 0; /* file must exist */
-         conffile = opt_string_alloc(arg);
+          if (!conffile)
+           conffile = opt_string_alloc(arg);
+         else
+           {
+             char *extra = opt_string_alloc(arg);
+             one_file(extra, 0);
+             free(extra);
+           }
        }
       else
        {
@@ -4779,10 +5124,11 @@ void read_opts(int argc, char **argv, char *compile_opts)
 
   if (conffile)
     {
-      one_file(conffile, conffile_opt);
-      if (conffile_opt == 0)
-       free(conffile);
+      one_file(conffile, 0);
+      free(conffile);
     }
+  else
+    one_file(CONFFILE, '7');
 
   /* port might not be known when the address is parsed - fill in here */
   if (daemon->servers)
@@ -4793,10 +5139,8 @@ void read_opts(int argc, char **argv, char *compile_opts)
          {
            if (tmp->source_addr.sa.sa_family == AF_INET)
              tmp->source_addr.in.sin_port = htons(daemon->query_port);
-#ifdef HAVE_IPV6
            else if (tmp->source_addr.sa.sa_family == AF_INET6)
              tmp->source_addr.in6.sin6_port = htons(daemon->query_port);
-#endif 
          }
     } 
   
@@ -4816,7 +5160,7 @@ void read_opts(int argc, char **argv, char *compile_opts)
 #define NOLOOP 1
 #define TESTLOOP 2      
 
-      /* Fill in TTL for CNAMES noe we have local_ttl.
+      /* Fill in TTL for CNAMES now we have local_ttl.
         Also prepare to do loop detection. */
       for (cn = daemon->cnames; cn; cn = cn->next)
        {
@@ -4857,10 +5201,8 @@ void read_opts(int argc, char **argv, char *compile_opts)
       for(tmp = daemon->if_addrs; tmp; tmp = tmp->next)
        if (tmp->addr.sa.sa_family == AF_INET)
          tmp->addr.in.sin_port = htons(daemon->port);
-#ifdef HAVE_IPV6
        else if (tmp->addr.sa.sa_family == AF_INET6)
          tmp->addr.in6.sin6_port = htons(daemon->port);
-#endif /* IPv6 */
     }
        
   /* create default, if not specified */
index d20bd33..50513dc 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
index 0d8382f..24d01bb 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
index 2ca9ec7..edc1532 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
index 4f31457..41df852 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -288,7 +288,10 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad
       context->netid.next = &context->netid;
     }
 
-  if (!iface_enumerate(AF_INET6, &parm, add_prefixes))
+  /* If no link-local address then we can't advertise since source address of
+     advertisement must be link local address: RFC 4861 para 6.1.2. */
+  if (!iface_enumerate(AF_INET6, &parm, add_prefixes) ||
+      parm.link_pref_time == 0)
     return;
 
   /* Find smallest preferred time within address classes,
@@ -412,7 +415,7 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad
   if (mtu == 0)
     {
       char *mtu_name = ra_param ? ra_param->mtu_name : NULL;
-      sprintf(daemon->namebuff, "/proc/sys/net/ipv6/conf/%s/mtu", mtu_name ? : iface_name);
+      sprintf(daemon->namebuff, "/proc/sys/net/ipv6/conf/%s/mtu", mtu_name ? mtu_name : iface_name);
       if ((f = fopen(daemon->namebuff, "r")))
         {
           if (fgets(daemon->namebuff, MAXDNAME, f))
@@ -623,8 +626,11 @@ static int add_prefixes(struct in6_addr *local,  int prefix,
                    real_prefix = context->prefix;
                  }
 
-               /* find floor time, don't reduce below 3 * RA interval. */
-               if (time > context->lease_time)
+               /* find floor time, don't reduce below 3 * RA interval.
+                  If the lease time has been left as default, don't
+                  use that as a floor. */
+               if ((context->flags & CONTEXT_SETLEASE) &&
+                   time > context->lease_time)
                  {
                    time = context->lease_time;
                    if (time < ((unsigned int)(3 * param->adv_interval)))
@@ -888,11 +894,21 @@ static int iface_search(struct in6_addr *local,  int prefix,
 {
   struct search_param *param = vparam;
   struct dhcp_context *context;
-
+  struct iname *tmp;
+  
   (void)scope;
   (void)preferred;
   (void)valid;
+
+  /* ignore interfaces we're not doing DHCP on. */
+  if (!indextoname(daemon->icmp6fd, if_index, param->name) ||
+      !iface_check(AF_LOCAL, NULL, param->name, NULL))
+    return 1;
+
+  for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
+    if (tmp->name && wildcard_match(tmp->name, param->name))
+      return 1;
+
   for (context = daemon->dhcp6; context; context = context->next)
     if (!(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
        prefix <= context->prefix &&
@@ -904,17 +920,9 @@ static int iface_search(struct in6_addr *local,  int prefix,
        /* found an interface that's overdue for RA determine new 
           timeout value and arrange for RA to be sent unless interface is
           still doing DAD.*/
-       
        if (!(flags & IFACE_TENTATIVE))
          param->iface = if_index;
        
-       /* should never fail */
-       if (!indextoname(daemon->icmp6fd, if_index, param->name))
-         {
-           param->iface = 0;
-           return 0;
-         }
-       
        new_timeout(context, param->name, param->now);
        
        /* zero timers for other contexts on the same subnet, so they don't timeout 
index b078b59..fefe63d 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -143,7 +143,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
  
 /* Max size of input string (for IPv6) is 75 chars.) */
 #define MAXARPANAME 75
-int in_arpa_name_2_addr(char *namein, struct all_addr *addrp)
+int in_arpa_name_2_addr(char *namein, union all_addr *addrp)
 {
   int j;
   char name[MAXARPANAME+1], *cp1;
@@ -153,7 +153,7 @@ int in_arpa_name_2_addr(char *namein, struct all_addr *addrp)
   if (strlen(namein) > MAXARPANAME)
     return 0;
 
-  memset(addrp, 0, sizeof(struct all_addr));
+  memset(addrp, 0, sizeof(union all_addr));
 
   /* turn name into a series of asciiz strings */
   /* j counts no. of labels */
@@ -198,7 +198,6 @@ int in_arpa_name_2_addr(char *namein, struct all_addr *addrp)
 
       return F_IPV4;
     }
-#ifdef HAVE_IPV6
   else if (hostname_isequal(penchunk, "ip6") && 
           (hostname_isequal(lastchunk, "int") || hostname_isequal(lastchunk, "arpa")))
     {
@@ -235,7 +234,7 @@ int in_arpa_name_2_addr(char *namein, struct all_addr *addrp)
              if (*(cp1+1) || !isxdigit((unsigned char)*cp1))
                return 0;
              
-             for (j = sizeof(struct all_addr)-1; j>0; j--)
+             for (j = sizeof(struct in6_addr)-1; j>0; j--)
                addr[j] = (addr[j] >> 4) | (addr[j-1] << 4);
              addr[0] = (addr[0] >> 4) | (strtol(cp1, NULL, 16) << 4);
            }
@@ -243,7 +242,6 @@ int in_arpa_name_2_addr(char *namein, struct all_addr *addrp)
          return F_IPV6;
        }
     }
-#endif
   
   return 0;
 }
@@ -426,7 +424,6 @@ int private_net(struct in_addr addr, int ban_localhost)
     ((ip_addr & 0xFFFFFFFF) == 0xFFFFFFFF)  /* 255.255.255.255/32 (broadcast)*/ ;
 }
 
-#ifdef HAVE_IPV6
 static int private_net6(struct in6_addr *a)
 {
   return 
@@ -436,8 +433,6 @@ static int private_net6(struct in6_addr *a)
     ((unsigned char *)a)[0] == 0xfd ||   /* RFC 6303 4.4 */
     ((u32 *)a)[0] == htonl(0x20010db8); /* RFC 6303 4.6 */
 }
-#endif
-
 
 static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header *header, size_t qlen, char *name, int *doctored)
 {
@@ -590,7 +585,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
   unsigned char *p, *p1, *endrr, *namep;
   int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
   unsigned long ttl = 0;
-  struct all_addr addr;
+  union all_addr addr;
 #ifdef HAVE_IPSET
   char **ipsets_cur;
 #else
@@ -613,7 +608,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
 #ifdef HAVE_DNSSEC
          if (option_bool(OPT_DNSSEC_VALID))
            for (i = 0; i < ntohs(header->ancount); i++)
-             if (daemon->rr_status[i])
+             if (daemon->rr_status[i] != 0)
                return 0;
 #endif
        }
@@ -686,13 +681,16 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
                      if (!extract_name(header, qlen, &p1, name, 1, 0))
                        return 0;
 #ifdef HAVE_DNSSEC
-                     if (option_bool(OPT_DNSSEC_VALID) && daemon->rr_status[j])
+                     if (option_bool(OPT_DNSSEC_VALID) && daemon->rr_status[j] != 0)
                        {
                          /* validated RR anywhere in CNAME chain, don't cache. */
                          if (cname_short || aqtype == T_CNAME)
                            return 0;
 
                          secflag = F_DNSSECOK;
+                         /* limit TTL based on signature. */
+                         if (daemon->rr_status[j] < cttl)
+                           cttl = daemon->rr_status[j];
                        }
 #endif
 
@@ -706,7 +704,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
                          goto cname_loop;
                        }
                      
-                     cache_insert(name, &addr, now, cttl, name_encoding | secflag | F_REVERSE);
+                     cache_insert(name, &addr, C_IN, now, cttl, name_encoding | secflag | F_REVERSE);
                      found = 1; 
                    }
                  
@@ -724,28 +722,28 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
                  ttl = find_soa(header, qlen, NULL, doctored);
                }
              if (ttl)
-               cache_insert(NULL, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags | (secure ?  F_DNSSECOK : 0));    
+               cache_insert(NULL, &addr, C_IN, now, ttl, name_encoding | F_REVERSE | F_NEG | flags | (secure ?  F_DNSSECOK : 0));      
            }
        }
       else
        {
          /* everything other than PTR */
          struct crec *newc;
-         int addrlen;
+         int addrlen = 0;
 
          if (qtype == T_A)
            {
              addrlen = INADDRSZ;
              flags |= F_IPV4;
            }
-#ifdef HAVE_IPV6
          else if (qtype == T_AAAA)
            {
              addrlen = IN6ADDRSZ;
              flags |= F_IPV6;
            }
-#endif
-         else 
+         else if (qtype == T_SRV)
+           flags |= F_SRV;
+         else
            continue;
            
        cname_loop1:
@@ -773,21 +771,27 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
              if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype))
                {
 #ifdef HAVE_DNSSEC
-                 if (option_bool(OPT_DNSSEC_VALID) && daemon->rr_status[j])
+                 if (option_bool(OPT_DNSSEC_VALID) && daemon->rr_status[j] != 0)
+                   {
                      secflag = F_DNSSECOK;
+
+                     /* limit TTl based on sig. */
+                     if (daemon->rr_status[j] < attl)
+                       attl = daemon->rr_status[j];
+                   }
 #endif           
                  if (aqtype == T_CNAME)
                    {
                      if (!cname_count--)
                        return 0; /* looped CNAMES */
-                     newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD | secflag);
-                     if (newc)
+
+                     if ((newc = cache_insert(name, NULL, C_IN, now, attl, F_CNAME | F_FORWARD | secflag)))
                        {
                          newc->addr.cname.target.cache = NULL;
-                         /* anything other than zero, to avoid being mistaken for CNAME to interface-name */ 
-                         newc->addr.cname.uid = 1; 
+                         newc->addr.cname.is_name_ptr = 0; 
                          if (cpp)
                            {
+                             next_uid(newc);
                              cpp->addr.cname.target.cache = newc;
                              cpp->addr.cname.uid = newc->uid;
                            }
@@ -797,53 +801,90 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
                      if (attl < cttl)
                        cttl = attl;
                      
+                     namep = p1;
                      if (!extract_name(header, qlen, &p1, name, 1, 0))
                        return 0;
+                     
                      goto cname_loop1;
                    }
                  else if (!(flags & F_NXDOMAIN))
                    {
                      found = 1;
                      
-                     /* copy address into aligned storage */
-                     if (!CHECK_LEN(header, p1, qlen, addrlen))
-                       return 0; /* bad packet */
-                     memcpy(&addr, p1, addrlen);
-                     
-                     /* check for returned address in private space */
-                     if (check_rebind)
+                     if (flags & F_SRV)
                        {
-                         if ((flags & F_IPV4) &&
-                             private_net(addr.addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
-                           return 1;
-                         
-#ifdef HAVE_IPV6
-                         if ((flags & F_IPV6) &&
-                             IN6_IS_ADDR_V4MAPPED(&addr.addr.addr6))
+                          unsigned char *tmp = namep;
+
+                          if (!CHECK_LEN(header, p1, qlen, 6))
+                            return 0; /* bad packet */
+                          GETSHORT(addr.srv.priority, p1);
+                          GETSHORT(addr.srv.weight, p1);
+                          GETSHORT(addr.srv.srvport, p1);
+                          if (!extract_name(header, qlen, &p1, name, 1, 0))
+                            return 0;
+                          addr.srv.targetlen = strlen(name) + 1; /* include terminating zero */
+                          if (!(addr.srv.target = blockdata_alloc(name, addr.srv.targetlen)))
+                            return 0;
+                          
+                          /* we overwrote the original name, so get it back here. */
+                          if (!extract_name(header, qlen, &tmp, name, 1, 0))
+                            return 0;
+                       }
+                     else
+                       {
+                         /* copy address into aligned storage */
+                         if (!CHECK_LEN(header, p1, qlen, addrlen))
+                           return 0; /* bad packet */
+                         memcpy(&addr, p1, addrlen);
+                     
+                         /* check for returned address in private space */
+                         if (check_rebind)
                            {
-                             struct in_addr v4;
-                             v4.s_addr = ((const uint32_t *) (&addr.addr.addr6))[3];
-                             if (private_net(v4, !option_bool(OPT_LOCAL_REBIND)))
+                             if ((flags & F_IPV4) &&
+                                 private_net(addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
                                return 1;
+
+                             /* Block IPv4-mapped IPv6 addresses in private IPv4 address space */
+                             if (flags & F_IPV6)
+                               {
+                                 if (IN6_IS_ADDR_V4MAPPED(&addr.addr6))
+                                   {
+                                     struct in_addr v4;
+                                     v4.s_addr = ((const uint32_t *) (&addr.addr6))[3];
+                                     if (private_net(v4, !option_bool(OPT_LOCAL_REBIND)))
+                                       return 1;
+                                   }
+
+                                 /* Check for link-local (LL) and site-local (ULA) IPv6 addresses */
+                                 if (IN6_IS_ADDR_LINKLOCAL(&addr.addr6) ||
+                                     IN6_IS_ADDR_SITELOCAL(&addr.addr6))
+                                   return 1;
+
+                                 /* Check for the IPv6 loopback address (::1) when
+                                    option rebind-localhost-ok is NOT set */
+                                 if (!option_bool(OPT_LOCAL_REBIND) &&
+                                     IN6_IS_ADDR_LOOPBACK(&addr.addr6))
+                                   return 1;
+                               }
                            }
-#endif
-                       }
-                     
+
 #ifdef HAVE_IPSET
-                     if (ipsets && (flags & (F_IPV4 | F_IPV6)))
-                       {
-                         ipsets_cur = ipsets;
-                         while (*ipsets_cur)
+                         if (ipsets && (flags & (F_IPV4 | F_IPV6)))
                            {
-                             log_query((flags & (F_IPV4 | F_IPV6)) | F_IPSET, name, &addr, *ipsets_cur);
-                             add_to_ipset(*ipsets_cur++, &addr, flags, 0);
+                             ipsets_cur = ipsets;
+                             while (*ipsets_cur)
+                               {
+                                 log_query((flags & (F_IPV4 | F_IPV6)) | F_IPSET, name, &addr, *ipsets_cur);
+                                 add_to_ipset(*ipsets_cur++, &addr, flags, 0);
+                               }
                            }
-                       }
 #endif
+                       }
                      
-                     newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD | secflag);
+                     newc = cache_insert(name, &addr, C_IN, now, attl, flags | F_FORWARD | secflag);
                      if (newc && cpp)
                        {
+                         next_uid(newc);
                          cpp->addr.cname.target.cache = newc;
                          cpp->addr.cname.uid = newc->uid;
                        }
@@ -867,9 +908,10 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
                 pointing at this, inherit its TTL */
              if (ttl || cpp)
                {
-                 newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0));        
+                 newc = cache_insert(name, NULL, C_IN, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0));  
                  if (newc && cpp)
                    {
+                     next_uid(newc);
                      cpp->addr.cname.target.cache = newc;
                      cpp->addr.cname.uid = newc->uid;
                    }
@@ -922,23 +964,29 @@ unsigned int extract_request(struct dns_header *header, size_t qlen, char *name,
       if (qtype == T_ANY)
        return  F_IPV4 | F_IPV6;
     }
+
+  /* F_DNSSECOK as agument to search_servers() inhibits forwarding
+     to servers for domains without a trust anchor. This make the
+     behaviour for DS and DNSKEY queries we forward the same
+     as for DS and DNSKEY queries we originate. */
+  if (qtype == T_DS || qtype == T_DNSKEY)
+    return F_DNSSECOK;
   
   return F_QUERY;
 }
 
-
 size_t setup_reply(struct dns_header *header, size_t qlen,
-               struct all_addr *addrp, unsigned int flags, unsigned long ttl)
+                  union all_addr *addrp, unsigned int flags, unsigned long ttl)
 {
   unsigned char *p;
-
+  
   if (!(p = skip_questions(header, qlen)))
     return 0;
   
   /* clear authoritative and truncated flags, set QR flag */
-  header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
-  /* set RA flag */
-  header->hb4 |= HB4_RA;
+  header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC )) | HB3_QR;
+  /* clear AD flag, set RA flag */
+  header->hb4 = (header->hb4 & ~HB4_AD) | HB4_RA;
 
   header->nscount = htons(0);
   header->arcount = htons(0);
@@ -948,66 +996,73 @@ size_t setup_reply(struct dns_header *header, size_t qlen,
   else if (flags == F_NXDOMAIN)
     SET_RCODE(header, NXDOMAIN);
   else if (flags == F_SERVFAIL)
-    SET_RCODE(header, SERVFAIL);
-  else if (flags == F_IPV4)
-    { /* we know the address */
-      SET_RCODE(header, NOERROR);
-      header->ancount = htons(1);
-      header->hb3 |= HB3_AA;
-      add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_A, C_IN, "4", addrp);
+    {
+      union all_addr a;
+      a.log.rcode = SERVFAIL;
+      log_query(F_CONFIG | F_RCODE, "error", &a, NULL);
+      SET_RCODE(header, SERVFAIL);
     }
-#ifdef HAVE_IPV6
-  else if (flags == F_IPV6)
+  else if (flags & ( F_IPV4 | F_IPV6))
     {
-      SET_RCODE(header, NOERROR);
-      header->ancount = htons(1);
-      header->hb3 |= HB3_AA;
-      add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_AAAA, C_IN, "6", addrp);
+      if (flags & F_IPV4)
+       { /* we know the address */
+         SET_RCODE(header, NOERROR);
+         header->ancount = htons(1);
+         header->hb3 |= HB3_AA;
+         add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_A, C_IN, "4", addrp);
+       }
+      
+      if (flags & F_IPV6)
+       {
+         SET_RCODE(header, NOERROR);
+         header->ancount = htons(ntohs(header->ancount) + 1);
+         header->hb3 |= HB3_AA;
+         add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_AAAA, C_IN, "6", addrp);
+       }
     }
-#endif
   else /* nowhere to forward to */
-    SET_RCODE(header, REFUSED);
+    {
+      union all_addr a;
+      a.log.rcode = REFUSED;
+      log_query(F_CONFIG | F_RCODE, "error", &a, NULL);
+      SET_RCODE(header, REFUSED);
+    }
+  
   return p - (unsigned char *)header;
 }
 
 /* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
 int check_for_local_domain(char *name, time_t now)
 {
-  struct crec *crecp;
   struct mx_srv_record *mx;
   struct txt_record *txt;
   struct interface_name *intr;
   struct ptr_record *ptr;
   struct naptr *naptr;
 
-  /* Note: the call to cache_find_by_name is intended to find any record which matches
-     ie A, AAAA, CNAME. */
-
-  if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_CNAME | F_NO_RR)) &&
-      (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
-    return 1;
-  
   for (naptr = daemon->naptr; naptr; naptr = naptr->next)
-     if (hostname_isequal(name, naptr->name))
+     if (hostname_issubdomain(name, naptr->name))
       return 1;
 
    for (mx = daemon->mxnames; mx; mx = mx->next)
-    if (hostname_isequal(name, mx->name))
+    if (hostname_issubdomain(name, mx->name))
       return 1;
 
   for (txt = daemon->txt; txt; txt = txt->next)
-    if (hostname_isequal(name, txt->name))
+    if (hostname_issubdomain(name, txt->name))
       return 1;
 
   for (intr = daemon->int_names; intr; intr = intr->next)
-    if (hostname_isequal(name, intr->name))
+    if (hostname_issubdomain(name, intr->name))
       return 1;
 
   for (ptr = daemon->ptr; ptr; ptr = ptr->next)
-    if (hostname_isequal(name, ptr->name))
+    if (hostname_issubdomain(name, ptr->name))
       return 1;
+
+  if (cache_find_non_terminal(name, now))
+    return 1;
+
   return 0;
 }
 
@@ -1047,7 +1102,7 @@ int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
                /* Found a bogus address. Insert that info here, since there no SOA record
                   to get the ttl from in the normal processing */
                cache_start_insert();
-               cache_insert(name, NULL, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN);
+               cache_insert(name, NULL, C_IN, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN);
                cache_end_insert();
                
                return 1;
@@ -1153,14 +1208,12 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
   for (; *format; format++)
     switch (*format)
       {
-#ifdef HAVE_IPV6
       case '6':
         CHECK_LIMIT(IN6ADDRSZ);
        sval = va_arg(ap, char *); 
        memcpy(p, sval, IN6ADDRSZ);
        p += IN6ADDRSZ;
        break;
-#endif
        
       case '4':
         CHECK_LIMIT(INADDRSZ);
@@ -1262,7 +1315,11 @@ static unsigned long crec_ttl(struct crec *crecp, time_t now)
   else
     return daemon->max_ttl;
 }
-  
+
+static int cache_validated(const struct crec *crecp)
+{
+  return (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK));
+}
 
 /* return zero if we can't answer from cache, or packet size if we can */
 size_t answer_request(struct dns_header *header, char *limit, size_t qlen,  
@@ -1272,26 +1329,24 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
   char *name = daemon->namebuff;
   unsigned char *p, *ansp;
   unsigned int qtype, qclass;
-  struct all_addr addr;
+  union all_addr addr;
   int nameoffset;
   unsigned short flag;
   int q, ans, anscount = 0, addncount = 0;
   int dryrun = 0;
   struct crec *crecp;
-  int nxdomain = 0, auth = 1, trunc = 0, sec_data = 1;
+  int nxdomain = 0, notimp = 0, auth = 1, trunc = 0, sec_data = 1;
   struct mx_srv_record *rec;
   size_t len;
+  int rd_bit = (header->hb3 & HB3_RD);
 
+  /* never answer queries with RD unset, to avoid cache snooping. */
   if (ntohs(header->ancount) != 0 ||
       ntohs(header->nscount) != 0 ||
-      ntohs(header->qdcount) == 0 || 
+      ntohs(header->qdcount) == 0 ||
       OPCODE(header) != QUERY )
     return 0;
 
-  /* always servfail queries with RD unset, to avoid cache snooping. */
-  if (!(header->hb3 & HB3_RD))
-    return setup_reply(header, qlen, NULL, F_SERVFAIL, 0);
-  
   /* Don't return AD set if checking disabled. */
   if (header->hb4 & HB4_CD)
     sec_data = 0;
@@ -1315,6 +1370,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
 
   for (q = ntohs(header->qdcount); q != 0; q--)
     {
+      int count = 255; /* catch loops */
+      
       /* save pointer to name for copying into answers */
       nameoffset = p - (unsigned char *)header;
 
@@ -1326,7 +1383,35 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
       GETSHORT(qclass, p);
 
       ans = 0; /* have we answered this question */
-      
+
+      while (--count != 0 && (crecp = cache_find_by_name(NULL, name, now, F_CNAME)))
+       {
+         char *cname_target = cache_get_cname_target(crecp);
+
+         /* If the client asked for DNSSEC  don't use cached data. */
+         if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
+             (rd_bit && (!do_bit || cache_validated(crecp))))
+           {
+             if (crecp->flags & F_CONFIG || qtype == T_CNAME)
+               ans = 1;
+
+             if (!(crecp->flags & F_DNSSECOK))
+               sec_data = 0;
+
+             if (!dryrun)
+               {
+                 log_query(crecp->flags, name, NULL, record_source(crecp->uid));
+                 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
+                                         crec_ttl(crecp, now), &nameoffset,
+                                         T_CNAME, C_IN, "d", cname_target))
+                   anscount++;
+               }
+
+           }
+
+         strcpy(name, cname_target);
+       }
+         
       if (qtype == T_TXT || qtype == T_ANY)
        {
          struct txt_record *t;
@@ -1334,12 +1419,11 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
            {
              if (t->class == qclass && hostname_isequal(name, t->name))
                {
-                 ans = 1;
+                 ans = 1, sec_data = 0;
                  if (!dryrun)
                    {
                      unsigned long ttl = daemon->local_ttl;
                      int ok = 1;
-                     log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>");
 #ifndef NO_ID
                      /* Dynamically generate stat record */
                      if (t->stat != 0)
@@ -1349,12 +1433,33 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                            ok = 0;
                        }
 #endif
-                     if (ok && add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
-                                                   ttl, NULL,
-                                                   T_TXT, t->class, "t", t->len, t->txt))
-                       anscount++;
+                     if (ok)
+                       {
+                         log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>");
+                         if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
+                                                 ttl, NULL,
+                                                 T_TXT, t->class, "t", t->len, t->txt))
+                           anscount++;
+                       }
+                   }
+               }
+           }
+       }
 
+      if (qclass == C_CHAOS)
+       {
+         /* don't forward *.bind and *.server chaos queries - always reply with NOTIMP */
+         if (hostname_issubdomain("bind", name) || hostname_issubdomain("server", name))
+           {
+             if (!ans)
+               {
+                 notimp = 1, auth = 0;
+                 if (!dryrun)
+                   {
+                      addr.log.rcode = NOTIMP;
+                      log_query(F_CONFIG | F_RCODE, name, &addr, NULL);
                    }
+                 ans = 1, sec_data = 0;
                }
            }
        }
@@ -1370,11 +1475,11 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                sec_data = 0;
                if (!dryrun)
                  {
-                   log_query(F_CONFIG | F_RRNAME, name, NULL, "<RR>");
+                   log_query(F_CONFIG | F_RRNAME, name, NULL, querystr(NULL, t->class));
                    if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
                                            daemon->local_ttl, NULL,
                                            t->class, C_IN, "t", t->len, t->txt))
-                     anscount ++;
+                     anscount++;
                  }
              }
                
@@ -1395,7 +1500,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                    struct addrlist *addrlist;
                    
                    for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
-                     if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr)
+                     if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr4.s_addr == addrlist->addr.addr4.s_addr)
                        break;
                    
                    if (addrlist)
@@ -1404,14 +1509,13 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                      while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
                        intr = intr->next;
                  }
-#ifdef HAVE_IPV6
              else if (is_arpa == F_IPV6)
                for (intr = daemon->int_names; intr; intr = intr->next)
                  {
                    struct addrlist *addrlist;
                    
                    for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
-                     if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6))
+                     if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr6, &addrlist->addr.addr6))
                        break;
                    
                    if (addrlist)
@@ -1420,7 +1524,6 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                      while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
                        intr = intr->next;
                  }
-#endif
              
              if (intr)
                {
@@ -1456,9 +1559,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                  /* Don't use cache when DNSSEC data required, unless we know that
                     the zone is unsigned, which implies that we're doing
                     validation. */
-                 if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) || 
-                     !do_bit || 
-                     (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK)))
+                 if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
+                     (rd_bit && (!do_bit || cache_validated(crecp)) ))
                    {
                      do 
                        { 
@@ -1512,10 +1614,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                    }
                }
              else if (option_bool(OPT_BOGUSPRIV) && (
-#ifdef HAVE_IPV6
-                      (is_arpa == F_IPV6 && private_net6(&addr.addr.addr6)) ||
-#endif
-                      (is_arpa == F_IPV4 && private_net(addr.addr.addr4, 1))))
+                      (is_arpa == F_IPV6 && private_net6(&addr.addr6)) ||
+                      (is_arpa == F_IPV4 && private_net(addr.addr4, 1))))
                {
                  struct server *serv;
                  unsigned int namelen = strlen(name);
@@ -1552,24 +1652,16 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                    }
                }
            }
-         
+
          for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0)
            {
-             unsigned short type = T_A;
+             unsigned short type = (flag == F_IPV6) ? T_AAAA : T_A;
              struct interface_name *intr;
 
-             if (flag == F_IPV6)
-#ifdef HAVE_IPV6
-               type = T_AAAA;
-#else
-               break;
-#endif
-             
              if (qtype != type && qtype != T_ANY)
                continue;
              
              /* interface name stuff */
-           intname_restart:
              for (intr = daemon->int_names; intr; intr = intr->next)
                if (hostname_isequal(name, intr->name))
                  break;
@@ -1587,31 +1679,26 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                    for (intr = daemon->int_names; intr; intr = intr->next)
                      if (hostname_isequal(name, intr->name))
                        for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
-#ifdef HAVE_IPV6
-                         if (!(addrlist->flags & ADDRLIST_IPV6))
-#endif
-                           if (is_same_net(*((struct in_addr *)&addrlist->addr), local_addr, local_netmask))
-                             {
-                               localise = 1;
-                               break;
-                             }
+                         if (!(addrlist->flags & ADDRLIST_IPV6) && 
+                             is_same_net(addrlist->addr.addr4, local_addr, local_netmask))
+                           {
+                             localise = 1;
+                             break;
+                           }
                  
                  for (intr = daemon->int_names; intr; intr = intr->next)
                    if (hostname_isequal(name, intr->name))
                      {
                        for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
-#ifdef HAVE_IPV6
                          if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == type)
-#endif
                            {
                              if (localise && 
-                                 !is_same_net(*((struct in_addr *)&addrlist->addr), local_addr, local_netmask))
+                                 !is_same_net(addrlist->addr.addr4, local_addr, local_netmask))
                                continue;
 
-#ifdef HAVE_IPV6
                              if (addrlist->flags & ADDRLIST_REVONLY)
                                continue;
-#endif 
+
                              ans = 1;  
                              sec_data = 0;
                              if (!dryrun)
@@ -1632,8 +1719,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                  continue;
                }
 
-           cname_restart:
-             if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME | (dryrun ? F_NO_RR : 0))))
+             if ((crecp = cache_find_by_name(NULL, name, now, flag | (dryrun ? F_NO_RR : 0))))
                {
                  int localise = 0;
                  
@@ -1644,17 +1730,18 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                      struct crec *save = crecp;
                      do {
                        if ((crecp->flags & F_HOSTS) &&
-                           is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
+                           is_same_net(crecp->addr.addr4, local_addr, local_netmask))
                          {
                            localise = 1;
                            break;
                          } 
-                       } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
+                       } while ((crecp = cache_find_by_name(crecp, name, now, flag)));
                      crecp = save;
                    }
 
                  /* If the client asked for DNSSEC  don't use cached data. */
-                 if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) || !do_bit || !(crecp->flags & F_DNSSECOK))
+                 if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
+                     (rd_bit && (!do_bit || cache_validated(crecp)) ))
                    do
                      { 
                        /* don't answer wildcard queries with data not from /etc/hosts
@@ -1665,27 +1752,6 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                        if (!(crecp->flags & F_DNSSECOK))
                          sec_data = 0;
                        
-                       if (crecp->flags & F_CNAME)
-                         {
-                           char *cname_target = cache_get_cname_target(crecp);
-                           
-                           if (!dryrun)
-                             {
-                               log_query(crecp->flags, name, NULL, record_source(crecp->uid));
-                               if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
-                                                       crec_ttl(crecp, now), &nameoffset,
-                                                       T_CNAME, C_IN, "d", cname_target))
-                                 anscount++;
-                             }
-                           
-                           strcpy(name, cname_target);
-                           /* check if target interface_name */
-                           if (crecp->addr.cname.uid == SRC_INTERFACE)
-                             goto intname_restart;
-                           else
-                             goto cname_restart;
-                         }
-                       
                        if (crecp->flags & F_NEG)
                          {
                            ans = 1;
@@ -1701,7 +1767,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                               filter here. */
                            if (localise && 
                                (crecp->flags & F_HOSTS) &&
-                               !is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
+                               !is_same_net(crecp->addr.addr4, local_addr, local_netmask))
                              continue;
                            
                            if (!(crecp->flags & (F_HOSTS | F_DHCP)))
@@ -1710,7 +1776,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                            ans = 1;
                            if (!dryrun)
                              {
-                               log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
+                               log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr,
                                          record_source(crecp->uid));
                                
                                if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
@@ -1719,11 +1785,11 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                                  anscount++;
                              }
                          }
-                     } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
+                     } while ((crecp = cache_find_by_name(crecp, name, now, flag)));
                }
              else if (is_name_synthetic(flag, name, &addr))
                {
-                 ans = 1;
+                 ans = 1, sec_data = 0;
                  if (!dryrun)
                    {
                      log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL);
@@ -1734,52 +1800,33 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                }
            }
 
-         if (qtype == T_CNAME || qtype == T_ANY)
-           {
-             if ((crecp = cache_find_by_name(NULL, name, now, F_CNAME | (dryrun ? F_NO_RR : 0))) &&
-                 (qtype == T_CNAME || (crecp->flags & F_CONFIG)) &&
-                 ((crecp->flags & F_CONFIG) || !do_bit || !(crecp->flags & F_DNSSECOK)))
-               {
-                 if (!(crecp->flags & F_DNSSECOK))
-                   sec_data = 0;
-                 
-                 ans = 1;
-                 if (!dryrun)
-                   {
-                     log_query(crecp->flags, name, NULL, record_source(crecp->uid));
-                     if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
-                                             crec_ttl(crecp, now), &nameoffset,
-                                             T_CNAME, C_IN, "d", cache_get_cname_target(crecp)))
-                       anscount++;
-                   }
-               }
-           }
-
          if (qtype == T_MX || qtype == T_ANY)
            {
              int found = 0;
              for (rec = daemon->mxnames; rec; rec = rec->next)
                if (!rec->issrv && hostname_isequal(name, rec->name))
                  {
-                 ans = found = 1;
-                 if (!dryrun)
-                   {
-                     int offset;
-                     log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
-                     if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
-                                             &offset, T_MX, C_IN, "sd", rec->weight, rec->target))
-                       {
-                         anscount++;
-                         if (rec->target)
-                           rec->offset = offset;
-                       }
-                   }
+                   ans = found = 1;
+                   sec_data = 0;
+                   if (!dryrun)
+                     {
+                       int offset;
+                       log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
+                       if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
+                                               &offset, T_MX, C_IN, "sd", rec->weight, rec->target))
+                         {
+                           anscount++;
+                           if (rec->target)
+                             rec->offset = offset;
+                         }
+                     }
                  }
              
-             if (!found && (option_bool(OPT_SELFMX) || option_bool(OPT_LOCALMX)) && 
+             if (!found && (option_bool(OPT_SELFMX) || option_bool(OPT_LOCALMX)) &&
                  cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP | F_NO_RR))
                { 
                  ans = 1;
+                 sec_data = 0;
                  if (!dryrun)
                    {
                      log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
@@ -1800,6 +1847,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                if (rec->issrv && hostname_isequal(name, rec->name))
                  {
                    found = ans = 1;
+                   sec_data = 0;
                    if (!dryrun)
                      {
                        int offset;
@@ -1832,10 +1880,45 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                  *up = move;
                  move->next = NULL;
                }
-             
+
+             if (!found)
+               {
+                 if ((crecp = cache_find_by_name(NULL, name, now, F_SRV | (dryrun ? F_NO_RR : 0))) &&
+                     rd_bit && (!do_bit || (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK))))
+                   {
+                     if (!(crecp->flags & F_DNSSECOK))
+                       sec_data = 0;
+                     
+                     auth = 0;
+                     found = ans = 1;
+                     
+                     do {
+                       if (crecp->flags & F_NEG)
+                         {
+                           if (crecp->flags & F_NXDOMAIN)
+                             nxdomain = 1;
+                           if (!dryrun)
+                             log_query(crecp->flags, name, NULL, NULL);
+                         }
+                       else if (!dryrun)
+                         {
+                           char *target = blockdata_retrieve(crecp->addr.srv.target, crecp->addr.srv.targetlen, NULL);
+                           log_query(crecp->flags, name, NULL, 0);
+                           
+                           if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
+                                                   crec_ttl(crecp, now), NULL, T_SRV, C_IN, "sssd",
+                                                   crecp->addr.srv.priority, crecp->addr.srv.weight, crecp->addr.srv.srvport,
+                                                   target))
+                             anscount++;
+                         }
+                     } while ((crecp = cache_find_by_name(crecp, name, now, F_SRV)));
+                   }
+               }
+
              if (!found && option_bool(OPT_FILTER) && (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
                {
                  ans = 1;
+                 sec_data = 0;
                  if (!dryrun)
                    log_query(F_CONFIG | F_NEG, name, NULL, NULL);
                }
@@ -1848,6 +1931,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                if (hostname_isequal(name, na->name))
                  {
                    ans = 1;
+                   sec_data = 0;
                    if (!dryrun)
                      {
                        log_query(F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>");
@@ -1860,11 +1944,12 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
            }
          
          if (qtype == T_MAILB)
-           ans = 1, nxdomain = 1;
+           ans = 1, nxdomain = 1, sec_data = 0;
 
          if (qtype == T_SOA && option_bool(OPT_FILTER))
            {
-             ans = 1; 
+             ans = 1;
+             sec_data = 0;
              if (!dryrun)
                log_query(F_CONFIG | F_NEG, name, &addr, NULL);
            }
@@ -1893,11 +1978,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
        crecp = NULL;
        while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6)))
          {
-#ifdef HAVE_IPV6
            int type =  crecp->flags & F_IPV4 ? T_A : T_AAAA;
-#else
-           int type = T_A;
-#endif
+
            if (crecp->flags & F_NEG)
              continue;
 
@@ -1924,6 +2006,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
   
   if (nxdomain)
     SET_RCODE(header, NXDOMAIN);
+  else if (notimp)
+    SET_RCODE(header, NOTIMP);
   else
     SET_RCODE(header, NOERROR); /* no error */
   header->ancount = htons(anscount);
index c08a8ab..fc54aab 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -75,7 +75,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
   struct dhcp_vendor *vendor;
   struct dhcp_mac *mac;
   struct dhcp_netid_list *id_list;
-  int clid_len = 0, ignore = 0, do_classes = 0, selecting = 0, pxearch = -1;
+  int clid_len = 0, ignore = 0, do_classes = 0, rapid_commit = 0, selecting = 0, pxearch = -1;
   struct dhcp_packet *mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
   unsigned char *end = (unsigned char *)(mess + 1); 
   unsigned char *real_end = (unsigned char *)(mess + 1); 
@@ -234,7 +234,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
        subnet_addr = option_addr(opt);
       
       /* If there is no client identifier option, use the hardware address */
-      if ((opt = option_find(mess, sz, OPTION_CLIENT_ID, 1)))
+      if (!option_bool(OPT_IGNORE_CLID) && (opt = option_find(mess, sz, OPTION_CLIENT_ID, 1)))
        {
          clid_len = option_len(opt);
          clid = option_ptr(opt, 0);
@@ -274,8 +274,9 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
   if (mess->giaddr.s_addr || subnet_addr.s_addr || mess->ciaddr.s_addr)
     {
       struct dhcp_context *context_tmp, *context_new = NULL;
+      struct shared_network *share = NULL;
       struct in_addr addr;
-      int force = 0;
+      int force = 0, via_relay = 0;
       
       if (subnet_addr.s_addr)
        {
@@ -286,6 +287,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
        {
          addr = mess->giaddr;
          force = 1;
+         via_relay = 1;
        }
       else
        {
@@ -302,42 +304,65 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
        } 
                
       if (!context_new)
-       for (context_tmp = daemon->dhcp; context_tmp; context_tmp = context_tmp->next)
-         {
-           struct in_addr netmask = context_tmp->netmask;
+       {
+         for (context_tmp = daemon->dhcp; context_tmp; context_tmp = context_tmp->next)
+           {
+             struct in_addr netmask = context_tmp->netmask;
+             
+             /* guess the netmask for relayed networks */
+             if (!(context_tmp->flags & CONTEXT_NETMASK) && context_tmp->netmask.s_addr == 0)
+               {
+                 if (IN_CLASSA(ntohl(context_tmp->start.s_addr)) && IN_CLASSA(ntohl(context_tmp->end.s_addr)))
+                   netmask.s_addr = htonl(0xff000000);
+                 else if (IN_CLASSB(ntohl(context_tmp->start.s_addr)) && IN_CLASSB(ntohl(context_tmp->end.s_addr)))
+                   netmask.s_addr = htonl(0xffff0000);
+                 else if (IN_CLASSC(ntohl(context_tmp->start.s_addr)) && IN_CLASSC(ntohl(context_tmp->end.s_addr)))
+                   netmask.s_addr = htonl(0xffffff00); 
+               }
 
-           /* guess the netmask for relayed networks */
-           if (!(context_tmp->flags & CONTEXT_NETMASK) && context_tmp->netmask.s_addr == 0)
-             {
-               if (IN_CLASSA(ntohl(context_tmp->start.s_addr)) && IN_CLASSA(ntohl(context_tmp->end.s_addr)))
-                 netmask.s_addr = htonl(0xff000000);
-               else if (IN_CLASSB(ntohl(context_tmp->start.s_addr)) && IN_CLASSB(ntohl(context_tmp->end.s_addr)))
-                 netmask.s_addr = htonl(0xffff0000);
-               else if (IN_CLASSC(ntohl(context_tmp->start.s_addr)) && IN_CLASSC(ntohl(context_tmp->end.s_addr)))
-                 netmask.s_addr = htonl(0xffffff00); 
-             }
-           
-           /* This section fills in context mainly when a client which is on a remote (relayed)
-              network renews a lease without using the relay, after dnsmasq has restarted. */
-           if (netmask.s_addr != 0  && 
-               is_same_net(addr, context_tmp->start, netmask) &&
-               is_same_net(addr, context_tmp->end, netmask))
-             {
-               context_tmp->netmask = netmask;
-               if (context_tmp->local.s_addr == 0)
-                 context_tmp->local = fallback;
-               if (context_tmp->router.s_addr == 0)
-                 context_tmp->router = mess->giaddr;
-          
-               /* fill in missing broadcast addresses for relayed ranges */
-               if (!(context_tmp->flags & CONTEXT_BRDCAST) && context_tmp->broadcast.s_addr == 0 )
-                 context_tmp->broadcast.s_addr = context_tmp->start.s_addr | ~context_tmp->netmask.s_addr;
-               
-               context_tmp->current = context_new;
-               context_new = context_tmp;
-             }
-         }
-      
+             /* check to see is a context is OK because of a shared address on
+                the relayed subnet. */
+             if (via_relay)
+               for (share = daemon->shared_networks; share; share = share->next)
+                 {
+#ifdef HAVE_DHCP6
+                   if (share->shared_addr.s_addr == 0)
+                     continue;
+#endif
+                   if (share->if_index != 0 ||
+                       share->match_addr.s_addr != mess->giaddr.s_addr)
+                     continue;
+                   
+                   if (netmask.s_addr != 0  && 
+                       is_same_net(share->shared_addr, context_tmp->start, netmask) &&
+                       is_same_net(share->shared_addr, context_tmp->end, netmask))
+                     break;
+                 }
+             
+             /* This section fills in context mainly when a client which is on a remote (relayed)
+                network renews a lease without using the relay, after dnsmasq has restarted. */
+             if (share ||
+                 (netmask.s_addr != 0  && 
+                  is_same_net(addr, context_tmp->start, netmask) &&
+                  is_same_net(addr, context_tmp->end, netmask)))
+               {
+                 context_tmp->netmask = netmask;
+                 if (context_tmp->local.s_addr == 0)
+                   context_tmp->local = fallback;
+                 if (context_tmp->router.s_addr == 0 && !share)
+                   context_tmp->router = mess->giaddr;
+                 
+                 /* fill in missing broadcast addresses for relayed ranges */
+                 if (!(context_tmp->flags & CONTEXT_BRDCAST) && context_tmp->broadcast.s_addr == 0 )
+                   context_tmp->broadcast.s_addr = context_tmp->start.s_addr | ~context_tmp->netmask.s_addr;
+                 
+                 context_tmp->current = context_new;
+                 context_new = context_tmp;
+               }
+             
+           }
+       }
+         
       if (context_new || force)
        context = context_new; 
     }
@@ -388,7 +413,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
                for (o2 = offset + 5; o2 < offset + len + 5; o2 += elen + 1)
                  { 
                    elen = option_uint(opt, o2, 1);
-                   if ((o2 + elen + 1 <= option_len(opt)) &&
+                   if ((o2 + elen + 1 <= (unsigned)option_len(opt)) &&
                        (match = match_bytes(o, option_ptr(opt, o2 + 1), elen)))
                      break;
                  }
@@ -479,7 +504,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
   mess->op = BOOTREPLY;
   
   config = find_config(daemon->dhcp_conf, context, clid, clid_len, 
-                      mess->chaddr, mess->hlen, mess->htype, NULL);
+                      mess->chaddr, mess->hlen, mess->htype, NULL, run_tag_if(netid));
 
   /* set "known" tag for known hosts */
   if (config)
@@ -489,7 +514,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
       netid = &known_id;
     }
   else if (find_config(daemon->dhcp_conf, NULL, clid, clid_len, 
-                      mess->chaddr, mess->hlen, mess->htype, NULL))
+                      mess->chaddr, mess->hlen, mess->htype, NULL, run_tag_if(netid)))
     {
       known_id.net = "known-othernet";
       known_id.next = netid;
@@ -626,6 +651,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
            }
        }
       
+      daemon->metrics[METRIC_BOOTP]++;
       log_packet("BOOTP", logaddr, mess->chaddr, mess->hlen, iface_name, NULL, message, mess->xid);
       
       return message ? 0 : dhcp_packet_size(mess, agent_id, real_end);
@@ -699,8 +725,37 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
        client_hostname = daemon->dhcp_buff;
     }
 
-  if (client_hostname && option_bool(OPT_LOG_OPTS))
-    my_syslog(MS_DHCP | LOG_INFO, _("%u client provides name: %s"), ntohl(mess->xid), client_hostname);
+  if (client_hostname)
+    {
+      struct dhcp_match_name *m;
+      size_t nl = strlen(client_hostname);
+      
+      if (option_bool(OPT_LOG_OPTS))
+       my_syslog(MS_DHCP | LOG_INFO, _("%u client provides name: %s"), ntohl(mess->xid), client_hostname);
+      for (m = daemon->dhcp_name_match; m; m = m->next)
+       {
+         size_t ml = strlen(m->name);
+         char save = 0;
+         
+         if (nl < ml)
+           continue;
+         if (nl > ml)
+           {
+             save = client_hostname[ml];
+             client_hostname[ml] = 0;
+           }
+         
+         if (hostname_isequal(client_hostname, m->name) &&
+             (save == 0 || m->wildcard))
+           {
+             m->netid->next = netid;
+             netid = m->netid;
+           }
+         
+         if (save != 0)
+           client_hostname[ml] = save;
+       }
+    }
   
   if (have_config(config, CONFIG_NAME))
     {
@@ -718,6 +773,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
       if (strlen(client_hostname) != 0)
        {
          hostname = client_hostname;
+         
          if (!config)
            {
              /* Search again now we have a hostname. 
@@ -725,7 +781,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
                 to avoid impersonation by name. */
              struct dhcp_config *new = find_config(daemon->dhcp_conf, context, NULL, 0,
                                                    mess->chaddr, mess->hlen, 
-                                                   mess->htype, hostname);
+                                                   mess->htype, hostname, run_tag_if(netid));
              if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr)
                {
                  config = new;
@@ -917,7 +973,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
                        mess->siaddr = a_record_from_hosts(boot->tftp_sname, now);
                      
                      if (boot->file)
-                       strncpy((char *)mess->file, boot->file, sizeof(mess->file)-1);
+                       safe_strncpy((char *)mess->file, boot->file, sizeof(mess->file));
                    }
                  
                  option_put(mess, end, OPTION_MESSAGE_TYPE, 1, 
@@ -928,6 +984,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
                  if ((pxe && !workaround) || !redirect4011)
                    do_encap_opts(pxe_opts(pxearch, tagif_netid, tmp->local, now), OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
            
+                 daemon->metrics[METRIC_PXE]++;
                  log_packet("PXE", NULL, emac, emac_len, iface_name, ignore ? "proxy-ignored" : "proxy", NULL, mess->xid);
                  log_tags(tagif_netid, ntohl(mess->xid));
                  if (!ignore)
@@ -962,6 +1019,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
       if (!(opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ)))
        return 0;
       
+      daemon->metrics[METRIC_DHCPDECLINE]++;
       log_packet("DHCPDECLINE", option_ptr(opt, 0), emac, emac_len, iface_name, NULL, daemon->dhcp_buff, mess->xid);
       
       if (lease && lease->addr.s_addr == option_addr(opt).s_addr)
@@ -994,6 +1052,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
       else
        message = _("unknown lease");
 
+      daemon->metrics[METRIC_DHCPRELEASE]++;
       log_packet("DHCPRELEASE", &mess->ciaddr, emac, emac_len, iface_name, NULL, message, mess->xid);
        
       return 0;
@@ -1060,6 +1119,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
            message = _("no address available");      
        }
       
+      daemon->metrics[METRIC_DHCPDISCOVER]++;
       log_packet("DHCPDISCOVER", opt ? option_ptr(opt, 0) : NULL, emac, emac_len, iface_name, NULL, message, mess->xid); 
 
       if (message || !(context = narrow_context(context, mess->yiaddr, tagif_netid)))
@@ -1073,6 +1133,14 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
 
       log_tags(tagif_netid, ntohl(mess->xid));
       apply_delay(mess->xid, recvtime, tagif_netid);
+
+      if (option_bool(OPT_RAPID_COMMIT) && option_find(mess, sz, OPTION_RAPID_COMMIT, 0))
+       {
+         rapid_commit = 1;
+         goto rapid_commit;
+       }
+      
+      daemon->metrics[METRIC_DHCPOFFER]++;
       log_packet("DHCPOFFER" , &mess->yiaddr, emac, emac_len, iface_name, NULL, NULL, mess->xid);
       
       time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4));
@@ -1085,7 +1153,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
                 netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now, time, fuzz);
       
       return dhcp_packet_size(mess, agent_id, real_end);
-      
+       
+
     case DHCPREQUEST:
       if (ignore || have_config(config, CONFIG_DISABLE))
        return 0;
@@ -1183,9 +1252,11 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
          fuzz = rand16();
          mess->yiaddr = mess->ciaddr;
        }
-      
+
+      daemon->metrics[METRIC_DHCPREQUEST]++;
       log_packet("DHCPREQUEST", &mess->yiaddr, emac, emac_len, iface_name, NULL, NULL, mess->xid);
+      
+    rapid_commit:
       if (!message)
        {
          struct dhcp_config *addr_config;
@@ -1256,7 +1327,12 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
 
       if (message)
        {
-         log_packet("DHCPNAK", &mess->yiaddr, emac, emac_len, iface_name, NULL, message, mess->xid);
+         daemon->metrics[rapid_commit ? METRIC_NOANSWER : METRIC_DHCPNAK]++;
+         log_packet(rapid_commit ? "NOANSWER" : "DHCPNAK", &mess->yiaddr, emac, emac_len, iface_name, NULL, message, mess->xid);
+
+         /* rapid commit case: lease allocate failed but don't send DHCPNAK */
+         if (rapid_commit)
+           return 0;
          
          mess->yiaddr.s_addr = 0;
          clear_packet(mess, end);
@@ -1413,13 +1489,16 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
          else
            override = lease->override;
 
+         daemon->metrics[METRIC_DHCPACK]++;
          log_packet("DHCPACK", &mess->yiaddr, emac, emac_len, iface_name, hostname, NULL, mess->xid);  
-         
+
          clear_packet(mess, end);
          option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
          option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
          option_put(mess, end, OPTION_LEASE_TIME, 4, time);
-         do_options(context, mess, end, req_options, hostname, get_domain(mess->yiaddr), 
+         if (rapid_commit)
+            option_put(mess, end, OPTION_RAPID_COMMIT, 0, 0);
+          do_options(context, mess, end, req_options, hostname, get_domain(mess->yiaddr), 
                     netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now, time, fuzz);
        }
 
@@ -1429,6 +1508,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
       if (ignore || have_config(config, CONFIG_DISABLE))
        message = _("ignored");
       
+      daemon->metrics[METRIC_DHCPINFORM]++;
       log_packet("DHCPINFORM", &mess->ciaddr, emac, emac_len, iface_name, message, NULL, mess->xid);
      
       if (message || mess->ciaddr.s_addr == 0)
@@ -1455,6 +1535,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
 
       log_tags(tagif_netid, ntohl(mess->xid));
       
+      daemon->metrics[METRIC_DHCPACK]++;
       log_packet("DHCPACK", &mess->ciaddr, emac, emac_len, iface_name, hostname, NULL, mess->xid);
       
       if (lease)
@@ -1621,6 +1702,13 @@ static void log_packet(char *type, void *addr, unsigned char *ext_mac,
              daemon->namebuff,
              string ? string : "",
              err ? err : "");
+
+#ifdef HAVE_UBUS
+       if (!strcmp(type, "DHCPACK"))
+               ubus_event_bcast("dhcp.ack", daemon->namebuff, addr ? inet_ntoa(a) : NULL, string ? string : NULL, interface);
+       else if (!strcmp(type, "DHCPRELEASE"))
+               ubus_event_bcast("dhcp.release", daemon->namebuff, addr ? inet_ntoa(a) : NULL, string ? string : NULL, interface);
+#endif
 }
 
 static void log_options(unsigned char *start, u32 xid)
@@ -2296,7 +2384,7 @@ static void do_options(struct dhcp_context *context,
              in_list(req_options, OPTION_SNAME))
            option_put_string(mess, end, OPTION_SNAME, boot->sname, 1);
          else
-           strncpy((char *)mess->sname, boot->sname, sizeof(mess->sname)-1);
+           safe_strncpy((char *)mess->sname, boot->sname, sizeof(mess->sname));
        }
       
       if (boot->file)
@@ -2306,7 +2394,7 @@ static void do_options(struct dhcp_context *context,
              in_list(req_options, OPTION_FILENAME))
            option_put_string(mess, end, OPTION_FILENAME, boot->file, 1);
          else
-           strncpy((char *)mess->file, boot->file, sizeof(mess->file)-1);
+           safe_strncpy((char *)mess->file, boot->file, sizeof(mess->file));
        }
       
       if (boot->next_server.s_addr) 
@@ -2323,14 +2411,14 @@ static void do_options(struct dhcp_context *context,
       if ((!req_options || !in_list(req_options, OPTION_FILENAME)) &&
          (opt = option_find2(OPTION_FILENAME)) && !(opt->flags & DHOPT_FORCE))
        {
-         strncpy((char *)mess->file, (char *)opt->val, sizeof(mess->file)-1);
+         safe_strncpy((char *)mess->file, (char *)opt->val, sizeof(mess->file));
          done_file = 1;
        }
       
       if ((!req_options || !in_list(req_options, OPTION_SNAME)) &&
          (opt = option_find2(OPTION_SNAME)) && !(opt->flags & DHOPT_FORCE))
        {
-         strncpy((char *)mess->sname, (char *)opt->val, sizeof(mess->sname)-1);
+         safe_strncpy((char *)mess->sname, (char *)opt->val, sizeof(mess->sname));
          done_server = 1;
        }
       
index 21fcd9b..b3f0a0a 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
 
 struct state {
   unsigned char *clid;
-  int clid_len, iaid, ia_type, interface, hostname_auth, lease_allocate;
+  int clid_len, ia_type, interface, hostname_auth, lease_allocate;
   char *client_hostname, *hostname, *domain, *send_domain;
   struct dhcp_context *context;
   struct in6_addr *link_address, *fallback, *ll_addr, *ula_addr;
-  unsigned int xid, fqdn_flags;
+  unsigned int xid, fqdn_flags, iaid;
   char *iface_name;
   void *packet_options, *end;
   struct dhcp_netid *tags, *context_tags;
   unsigned char mac[DHCP_CHADDR_MAX];
   unsigned int mac_len, mac_type;
-#ifdef OPTION6_PREFIX_CLASS
-  struct prefix_class *send_prefix_class;
-#endif
 };
 
 static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz, 
@@ -49,12 +46,11 @@ static void get_context_tag(struct state *state, struct dhcp_context *context);
 static int check_ia(struct state *state, void *opt, void **endp, void **ia_option);
 static int build_ia(struct state *state, int *t1cntr);
 static void end_ia(int t1cntr, unsigned int min_time, int do_fuzz);
-#ifdef OPTION6_PREFIX_CLASS
-static struct prefix_class *prefix_class_from_context(struct dhcp_context *context);
-#endif
 static void mark_context_used(struct state *state, struct in6_addr *addr);
 static void mark_config_used(struct dhcp_context *context, struct in6_addr *addr);
 static int check_address(struct state *state, struct in6_addr *addr);
+static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state, time_t now);
+static struct addrlist *config_implies(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr);
 static void add_address(struct state *state, struct dhcp_context *context, unsigned int lease_time, void *ia_option, 
                        unsigned int *min_time, struct in6_addr *addr, time_t now);
 static void update_leases(struct state *state, struct dhcp_context *context, struct in6_addr *addr, unsigned int lease_time, time_t now);
@@ -134,21 +130,41 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
       else
        {
          struct dhcp_context *c;
+         struct shared_network *share = NULL;
          state->context = NULL;
-          
+
          if (!IN6_IS_ADDR_LOOPBACK(state->link_address) &&
              !IN6_IS_ADDR_LINKLOCAL(state->link_address) &&
              !IN6_IS_ADDR_MULTICAST(state->link_address))
            for (c = daemon->dhcp6; c; c = c->next)
-             if ((c->flags & CONTEXT_DHCP) &&
-                 !(c->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
-                 is_same_net6(state->link_address, &c->start6, c->prefix) &&
-                 is_same_net6(state->link_address, &c->end6, c->prefix))
-               {
-                 c->preferred = c->valid = 0xffffffff;
-                 c->current = state->context;
-                 state->context = c;
-               }
+             {
+               for (share = daemon->shared_networks; share; share = share->next)
+                 {
+                   if (share->shared_addr.s_addr != 0)
+                     continue;
+                   
+                   if (share->if_index != 0 ||
+                       !IN6_ARE_ADDR_EQUAL(state->link_address, &share->match_addr6))
+                     continue;
+                   
+                   if ((c->flags & CONTEXT_DHCP) &&
+                       !(c->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
+                       is_same_net6(&share->shared_addr6, &c->start6, c->prefix) &&
+                       is_same_net6(&share->shared_addr6, &c->end6, c->prefix))
+                     break;
+                 }
+               
+               if (share ||
+                   ((c->flags & CONTEXT_DHCP) &&
+                    !(c->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
+                    is_same_net6(state->link_address, &c->start6, c->prefix) &&
+                    is_same_net6(state->link_address, &c->end6, c->prefix)))
+                 {
+                   c->preferred = c->valid = 0xffffffff;
+                   c->current = state->context;
+                   state->context = c;
+                 }
+             }
          
          if (!state->context)
            {
@@ -219,21 +235,25 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
       if (opt6_ptr(opt, 0) + opt6_len(opt) > end) 
         return 0;
      
-      int o = new_opt6(opt6_type(opt));
-      if (opt6_type(opt) == OPTION6_RELAY_MSG)
+      /* Don't copy MAC address into reply. */
+      if (opt6_type(opt) != OPTION6_CLIENT_MAC)
        {
-         struct in6_addr align;
-         /* the packet data is unaligned, copy to aligned storage */
-         memcpy(&align, inbuff + 2, IN6ADDRSZ); 
-         state->link_address = &align;
-         /* zero is_unicast since that is now known to refer to the 
-            relayed packet, not the original sent by the client */
-         if (!dhcp6_maybe_relay(state, opt6_ptr(opt, 0), opt6_len(opt), client_addr, 0, now))
-           return 0;
+         int o = new_opt6(opt6_type(opt));
+         if (opt6_type(opt) == OPTION6_RELAY_MSG)
+           {
+             struct in6_addr align;
+             /* the packet data is unaligned, copy to aligned storage */
+             memcpy(&align, inbuff + 2, IN6ADDRSZ); 
+             state->link_address = &align;
+             /* zero is_unicast since that is now known to refer to the 
+                relayed packet, not the original sent by the client */
+             if (!dhcp6_maybe_relay(state, opt6_ptr(opt, 0), opt6_len(opt), client_addr, 0, now))
+               return 0;
+           }
+         else
+           put_opt6(opt6_ptr(opt, 0), opt6_len(opt));
+         end_opt6(o);
        }
-      else if (opt6_type(opt) != OPTION6_CLIENT_MAC)
-       put_opt6(opt6_ptr(opt, 0), opt6_len(opt));
-      end_opt6(o);         
     }
   
   return 1;
@@ -252,10 +272,6 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
   struct dhcp_context *context_tmp;
   struct dhcp_mac *mac_opt;
   unsigned int ignore = 0;
-#ifdef OPTION6_PREFIX_CLASS
-  struct prefix_class *p;
-  int dump_all_prefix_classes = 0;
-#endif
 
   state->packet_options = inbuff + 4;
   state->end = inbuff + sz;
@@ -269,9 +285,6 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
   state->hostname = NULL;
   state->client_hostname = NULL;
   state->fqdn_flags = 0x01; /* default to send if we receive no FQDN option */
-#ifdef OPTION6_PREFIX_CLASS
-  state->send_prefix_class = NULL;
-#endif
 
   /* set tag with name == interface */
   iface_id.net = state->iface_name;
@@ -477,39 +490,66 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
           
           if (legal_hostname(daemon->dhcp_buff))
             {
+              struct dhcp_match_name *m;
+              size_t nl = strlen(daemon->dhcp_buff);
+              
               state->client_hostname = daemon->dhcp_buff;
+              
               if (option_bool(OPT_LOG_OPTS))
-                my_syslog(MS_DHCP | LOG_INFO, _("%u client provides name: %s"), state->xid, state->client_hostname); 
+                my_syslog(MS_DHCP | LOG_INFO, _("%u client provides name: %s"), state->xid, state->client_hostname);
+              
+              for (m = daemon->dhcp_name_match; m; m = m->next)
+                {
+                  size_t ml = strlen(m->name);
+                  char save = 0;
+                  
+                  if (nl < ml)
+                    continue;
+                  if (nl > ml)
+                    {
+                      save = state->client_hostname[ml];
+                      state->client_hostname[ml] = 0;
+                    }
+                  
+                  if (hostname_isequal(state->client_hostname, m->name) &&
+                      (save == 0 || m->wildcard))
+                    {
+                      m->netid->next = state->tags;
+                      state->tags = m->netid;
+                    }
+                  
+                  if (save != 0)
+                    state->client_hostname[ml] = save;
+                }
             }
         }
     }   
   
-  if (state->clid)
+  if (state->clid &&
+      (config = find_config(daemon->dhcp_conf, state->context, state->clid, state->clid_len,
+                           state->mac, state->mac_len, state->mac_type, NULL, run_tag_if(state->tags))) &&
+      have_config(config, CONFIG_NAME))
     {
-      config = find_config(daemon->dhcp_conf, state->context, state->clid, state->clid_len, state->mac, state->mac_len, state->mac_type, NULL);
+      state->hostname = config->hostname;
+      state->domain = config->domain;
+      state->hostname_auth = 1;
+    }
+  else if (state->client_hostname)
+    {
+      state->domain = strip_hostname(state->client_hostname);
       
-      if (have_config(config, CONFIG_NAME))
-       {
-         state->hostname = config->hostname;
-         state->domain = config->domain;
-         state->hostname_auth = 1;
-       }
-      else if (state->client_hostname)
+      if (strlen(state->client_hostname) != 0)
        {
-         state->domain = strip_hostname(state->client_hostname);
+         state->hostname = state->client_hostname;
          
-         if (strlen(state->client_hostname) != 0)
+         if (!config)
            {
-             state->hostname = state->client_hostname;
-             if (!config)
-               {
-                 /* Search again now we have a hostname. 
-                    Only accept configs without CLID here, (it won't match)
-                    to avoid impersonation by name. */
-                 struct dhcp_config *new = find_config(daemon->dhcp_conf, state->context, NULL, 0, NULL, 0, 0, state->hostname);
-                 if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr)
-                   config = new;
-               }
+             /* Search again now we have a hostname. 
+                Only accept configs without CLID here, (it won't match)
+                to avoid impersonation by name. */
+             struct dhcp_config *new = find_config(daemon->dhcp_conf, state->context, NULL, 0, NULL, 0, 0, state->hostname, run_tag_if(state->tags));
+             if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr)
+               config = new;
            }
        }
     }
@@ -533,38 +573,14 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
        ignore = 1;
     }
   else if (state->clid &&
-          find_config(daemon->dhcp_conf, NULL, state->clid, state->clid_len, state->mac, state->mac_len, state->mac_type, NULL))
+          find_config(daemon->dhcp_conf, NULL, state->clid, state->clid_len,
+                      state->mac, state->mac_len, state->mac_type, NULL, run_tag_if(state->tags)))
     {
       known_id.net = "known-othernet";
       known_id.next = state->tags;
       state->tags = &known_id;
     }
   
-#ifdef OPTION6_PREFIX_CLASS
-  /* OPTION_PREFIX_CLASS in ORO, send addresses in all prefix classes */
-  if (daemon->prefix_classes && (msg_type == DHCP6SOLICIT || msg_type == DHCP6REQUEST))
-    {
-      void *oro;
-      
-      if ((oro = opt6_find(state->packet_options, state->end, OPTION6_ORO, 0)))
-       for (i = 0; i <  opt6_len(oro) - 1; i += 2)
-         if (opt6_uint(oro, i, 2) == OPTION6_PREFIX_CLASS)
-           {
-             dump_all_prefix_classes = 1;
-             break;
-           }
-      
-      if (msg_type != DHCP6SOLICIT || dump_all_prefix_classes)
-       /* Add the tags associated with prefix classes so we can use the DHCP ranges.
-          Not done for SOLICIT as we add them  one-at-time. */
-       for (p = daemon->prefix_classes; p ; p = p->next)
-         {
-           p->tag.next = state->tags;
-           state->tags = &p->tag;
-         }
-    }    
-#endif
-
   tagif = run_tag_if(state->tags);
   
   /* if all the netids in the ignore list are present, ignore this client */
@@ -639,9 +655,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
            int plain_range = 1;
            u32 lease_time;
            struct dhcp_lease *ltmp;
-           struct in6_addr *req_addr;
-           struct in6_addr addr;
-
+           struct in6_addr req_addr, addr;
+           
            if (!check_ia(state, opt, &ia_end, &ia_option))
              continue;
            
@@ -649,93 +664,36 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
            for (c = state->context; c; c = c->current)
              c->flags &= ~CONTEXT_USED;
 
-#ifdef OPTION6_PREFIX_CLASS
-           if (daemon->prefix_classes && state->ia_type == OPTION6_IA_NA)
-             {
-               void *prefix_opt;
-               int prefix_class;
-               
-               if (dump_all_prefix_classes)
-                 /* OPTION_PREFIX_CLASS in ORO, send addresses in all prefix classes */
-                 plain_range = 0;
-               else 
-                 { 
-                   if ((prefix_opt = opt6_find(opt6_ptr(opt, 12), ia_end, OPTION6_PREFIX_CLASS, 2)))
-                     {
-                       
-                       prefix_class = opt6_uint(prefix_opt, 0, 2);
-                       
-                       for (p = daemon->prefix_classes; p ; p = p->next)
-                         if (p->class == prefix_class)
-                           break;
-                       
-                       if (!p)
-                         my_syslog(MS_DHCP | LOG_WARNING, _("unknown prefix-class %d"), prefix_class);
-                       else
-                         {
-                           /* add tag to list, and exclude undecorated dhcp-ranges */
-                           p->tag.next = state->tags;
-                           solicit_tags = run_tag_if(&p->tag);
-                           plain_range = 0;
-                           state->send_prefix_class = p;
-                         }
-                     }
-                   else
-                     {
-                       /* client didn't ask for a prefix class, lets see if we can find one. */
-                       for (p = daemon->prefix_classes; p ; p = p->next)
-                         {
-                           p->tag.next = NULL;
-                           if (match_netid(&p->tag, solicit_tags, 1))
-                             break;
-                         }
-                       
-                       if (p)
-                         {
-                           plain_range = 0;
-                           state->send_prefix_class = p;
-                         }
-                     }
-
-                   if (p && option_bool(OPT_LOG_OPTS))
-                     my_syslog(MS_DHCP | LOG_INFO, "%u prefix class %d tag:%s", state->xid, p->class, p->tag.net); 
-                 }
-             }
-#endif
-
            o = build_ia(state, &t1cntr);
            if (address_assigned)
                address_assigned = 2;
 
            for (ia_counter = 0; ia_option; ia_counter++, ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
              {
-               req_addr = opt6_ptr(ia_option, 0);
+               /* worry about alignment here. */
+               memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
                                
-               if ((c = address6_valid(state->context, req_addr, solicit_tags, plain_range)))
+               if ((c = address6_valid(state->context, &req_addr, solicit_tags, plain_range)))
                  {
                    lease_time = c->lease_time;
                    /* If the client asks for an address on the same network as a configured address, 
                       offer the configured address instead, to make moving to newly-configured
                       addresses automatic. */
-                   if (!(c->flags & CONTEXT_CONF_USED) && config_valid(config, c, &addr) && check_address(state, &addr))
+                   if (!(c->flags & CONTEXT_CONF_USED) && config_valid(config, c, &addr, state, now))
                      {
-                       req_addr = &addr;
+                       req_addr = addr;
                        mark_config_used(c, &addr);
                        if (have_config(config, CONFIG_TIME))
                          lease_time = config->lease_time;
                      }
-                   else if (!(c = address6_available(state->context, req_addr, solicit_tags, plain_range)))
+                   else if (!(c = address6_available(state->context, &req_addr, solicit_tags, plain_range)))
                      continue; /* not an address we're allowed */
-                   else if (!check_address(state, req_addr))
+                   else if (!check_address(state, &req_addr))
                      continue; /* address leased elsewhere */
                    
                    /* add address to output packet */
-#ifdef OPTION6_PREFIX_CLASS
-                   if (dump_all_prefix_classes && state->ia_type == OPTION6_IA_NA)
-                     state->send_prefix_class = prefix_class_from_context(c);
-#endif             
-                   add_address(state, c, lease_time, ia_option, &min_time, req_addr, now);
-                   mark_context_used(state, req_addr);
+                   add_address(state, c, lease_time, ia_option, &min_time, &req_addr, now);
+                   mark_context_used(state, &req_addr);
                    get_context_tag(state, c);
                    address_assigned = 1;
                  }
@@ -745,19 +703,15 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
            for (c = state->context; c; c = c->current) 
              if (!(c->flags & CONTEXT_CONF_USED) &&
                  match_netid(c->filter, solicit_tags, plain_range) &&
-                 config_valid(config, c, &addr) && 
-                 check_address(state, &addr))
+                 config_valid(config, c, &addr, state, now))
                {
                  mark_config_used(state->context, &addr);
                  if (have_config(config, CONFIG_TIME))
                    lease_time = config->lease_time;
                  else
                    lease_time = c->lease_time;
+
                  /* add address to output packet */
-#ifdef OPTION6_PREFIX_CLASS
-                 if (dump_all_prefix_classes && state->ia_type == OPTION6_IA_NA)
-                   state->send_prefix_class = prefix_class_from_context(c);
-#endif
                  add_address(state, c, lease_time, NULL, &min_time, &addr, now);
                  mark_context_used(state, &addr);
                  get_context_tag(state, c);
@@ -768,15 +722,11 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
            ltmp = NULL;
            while ((ltmp = lease6_find_by_client(ltmp, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, state->clid, state->clid_len, state->iaid)))
              {
-               req_addr = &ltmp->addr6;
-               if ((c = address6_available(state->context, req_addr, solicit_tags, plain_range)))
+               req_addr = ltmp->addr6;
+               if ((c = address6_available(state->context, &req_addr, solicit_tags, plain_range)))
                  {
-#ifdef OPTION6_PREFIX_CLASS
-                   if (dump_all_prefix_classes && state->ia_type == OPTION6_IA_NA)
-                     state->send_prefix_class = prefix_class_from_context(c);
-#endif
-                   add_address(state, c, c->lease_time, NULL, &min_time, req_addr, now);
-                   mark_context_used(state, req_addr);
+                   add_address(state, c, c->lease_time, NULL, &min_time, &req_addr, now);
+                   mark_context_used(state, &req_addr);
                    get_context_tag(state, c);
                    address_assigned = 1;
                  }
@@ -786,10 +736,6 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
            while ((c = address6_allocate(state->context, state->clid, state->clid_len, state->ia_type == OPTION6_IA_TA,
                                          state->iaid, ia_counter, solicit_tags, plain_range, &addr)))
              {
-#ifdef OPTION6_PREFIX_CLASS
-               if (dump_all_prefix_classes && state->ia_type == OPTION6_IA_NA)
-                 state->send_prefix_class = prefix_class_from_context(c);
-#endif
                add_address(state, c, c->lease_time, NULL, &min_time, &addr, now);
                mark_context_used(state, &addr);
                get_context_tag(state, c);
@@ -892,16 +838,18 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
              
            for (; ia_option; ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
              {
-               struct in6_addr *req_addr = opt6_ptr(ia_option, 0);
+               struct in6_addr req_addr;
                struct dhcp_context *dynamic, *c;
                unsigned int lease_time;
-               struct in6_addr addr;
                int config_ok = 0;
+
+               /* align. */
+               memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
                
-               if ((c = address6_valid(state->context, req_addr, tagif, 1)))
-                 config_ok = config_valid(config, c, &addr) && IN6_ARE_ADDR_EQUAL(&addr, req_addr);
+               if ((c = address6_valid(state->context, &req_addr, tagif, 1)))
+                 config_ok = (config_implies(config, c, &req_addr) != NULL);
                
-               if ((dynamic = address6_available(state->context, req_addr, tagif, 1)) || c)
+               if ((dynamic = address6_available(state->context, &req_addr, tagif, 1)) || c)
                  {
                    if (!dynamic && !config_ok)
                      {
@@ -911,7 +859,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
                        put_opt6_string(_("address unavailable"));
                        end_opt6(o1);
                      }
-                   else if (!check_address(state, req_addr))
+                   else if (!check_address(state, &req_addr))
                      {
                        /* Address leased to another DUID/IAID */
                        o1 = new_opt6(OPTION6_STATUS_CODE);
@@ -929,11 +877,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
                        if (config_ok && have_config(config, CONFIG_TIME))
                          lease_time = config->lease_time;
 
-#ifdef OPTION6_PREFIX_CLASS
-                       if (dump_all_prefix_classes && state->ia_type == OPTION6_IA_NA)
-                         state->send_prefix_class = prefix_class_from_context(c);
-#endif
-                       add_address(state, dynamic, lease_time, ia_option, &min_time, req_addr, now);
+                       add_address(state, dynamic, lease_time, ia_option, &min_time, &req_addr, now);
                        get_context_tag(state, dynamic);
                        address_assigned = 1;
                      }
@@ -996,15 +940,17 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
            for (; ia_option; ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
              {
                struct dhcp_lease *lease = NULL;
-               struct in6_addr *req_addr = opt6_ptr(ia_option, 0);
+               struct in6_addr req_addr;
                unsigned int preferred_time =  opt6_uint(ia_option, 16, 4);
                unsigned int valid_time =  opt6_uint(ia_option, 20, 4);
                char *message = NULL;
                struct dhcp_context *this_context;
+
+               memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ); 
                
                if (!(lease = lease6_find(state->clid, state->clid_len,
                                          state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, 
-                                         state->iaid, req_addr)))
+                                         state->iaid, &req_addr)))
                  {
                    /* If the server cannot find a client entry for the IA the server
                       returns the IA containing no addresses with a Status Code option set
@@ -1012,7 +958,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
                    save_counter(iacntr);
                    t1cntr = 0;
                    
-                   log6_packet(state, "DHCPREPLY", req_addr, _("lease not found"));
+                   log6_packet(state, "DHCPREPLY", &req_addr, _("lease not found"));
                    
                    o1 = new_opt6(OPTION6_STATUS_CODE);
                    put_opt6_short(DHCP6NOBINDING);
@@ -1024,15 +970,14 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
                  }
                
                
-               if ((this_context = address6_available(state->context, req_addr, tagif, 1)) ||
-                   (this_context = address6_valid(state->context, req_addr, tagif, 1)))
+               if ((this_context = address6_available(state->context, &req_addr, tagif, 1)) ||
+                   (this_context = address6_valid(state->context, &req_addr, tagif, 1)))
                  {
-                   struct in6_addr addr;
                    unsigned int lease_time;
 
                    get_context_tag(state, this_context);
                    
-                   if (config_valid(config, this_context, &addr) && IN6_ARE_ADDR_EQUAL(&addr, req_addr) && have_config(config, CONFIG_TIME))
+                   if (config_implies(config, this_context, &req_addr) && have_config(config, CONFIG_TIME))
                      lease_time = config->lease_time;
                    else 
                      lease_time = this_context->lease_time;
@@ -1045,7 +990,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
                      lease_set_hwaddr(lease, state->mac, state->clid, state->mac_len, state->mac_type, state->clid_len, now, 0);
                    if (state->ia_type == OPTION6_IA_NA && state->hostname)
                      {
-                       char *addr_domain = get_domain6(req_addr);
+                       char *addr_domain = get_domain6(&req_addr);
                        if (!state->send_domain)
                          state->send_domain = addr_domain;
                        lease_set_hostname(lease, state->hostname, state->hostname_auth, addr_domain, state->domain); 
@@ -1063,12 +1008,12 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
                  } 
 
                if (message && (message != state->hostname))
-                 log6_packet(state, "DHCPREPLY", req_addr, message);   
+                 log6_packet(state, "DHCPREPLY", &req_addr, message);  
                else
-                 log6_quiet(state, "DHCPREPLY", req_addr, message);
+                 log6_quiet(state, "DHCPREPLY", &req_addr, message);
        
                o1 =  new_opt6(OPTION6_IAADDR);
-               put_opt6(req_addr, sizeof(*req_addr));
+               put_opt6(&req_addr, sizeof(req_addr));
                put_opt6_long(preferred_time);
                put_opt6_long(valid_time);
                end_opt6(o1);
@@ -1100,19 +1045,23 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
                 ia_option;
                 ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
              {
-               struct in6_addr *req_addr = opt6_ptr(ia_option, 0);
+               struct in6_addr req_addr;
+
+               /* alignment */
+               memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
                
-               if (!address6_valid(state->context, req_addr, tagif, 1))
+               if (!address6_valid(state->context, &req_addr, tagif, 1))
                  {
                    o1 = new_opt6(OPTION6_STATUS_CODE);
                    put_opt6_short(DHCP6NOTONLINK);
                    put_opt6_string(_("confirm failed"));
                    end_opt6(o1);
+                   log6_quiet(state, "DHCPREPLY", &req_addr, _("confirm failed"));
                    return 1;
                  }
 
                good_addr = 1;
-               log6_quiet(state, "DHCPREPLY", req_addr, state->hostname);
+               log6_quiet(state, "DHCPREPLY", &req_addr, state->hostname);
              }
          }      
        
@@ -1171,9 +1120,12 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
                 ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24)) 
              {
                struct dhcp_lease *lease;
-               
+               struct in6_addr addr;
+
+               /* align */
+               memcpy(&addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
                if ((lease = lease6_find(state->clid, state->clid_len, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA,
-                                        state->iaid, opt6_ptr(ia_option, 0))))
+                                        state->iaid, &addr)))
                  lease_prune(lease, now);
                else
                  {
@@ -1190,7 +1142,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
                      }
                    
                    o1 = new_opt6(OPTION6_IAADDR);
-                   put_opt6(opt6_ptr(ia_option, 0), IN6ADDRSZ);
+                   put_opt6(&addr, IN6ADDRSZ);
                    put_opt6_long(0);
                    put_opt6_long(0);
                    end_opt6(o1);
@@ -1233,16 +1185,20 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
                 ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24)) 
              {
                struct dhcp_lease *lease;
-               struct in6_addr *addrp = opt6_ptr(ia_option, 0);
+               struct in6_addr addr;
+               struct addrlist *addr_list;
+               
+               /* align */
+               memcpy(&addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
 
-               if (have_config(config, CONFIG_ADDR6) && IN6_ARE_ADDR_EQUAL(&config->addr6, addrp))
+               if ((addr_list = config_implies(config, state->context, &addr)))
                  {
                    prettyprint_time(daemon->dhcp_buff3, DECLINE_BACKOFF);
-                   inet_ntop(AF_INET6, addrp, daemon->addrbuff, ADDRSTRLEN);
+                   inet_ntop(AF_INET6, &addr, daemon->addrbuff, ADDRSTRLEN);
                    my_syslog(MS_DHCP | LOG_WARNING, _("disabling DHCP static address %s for %s"), 
                              daemon->addrbuff, daemon->dhcp_buff3);
-                   config->flags |= CONFIG_DECLINED;
-                   config->decline_time = now;
+                   addr_list->flags |= ADDRLIST_DECLINED;
+                   addr_list->decline_time = now;
                  }
                else
                  /* make sure this host gets a different address next time. */
@@ -1250,7 +1206,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
                    context_tmp->addr_epoch++;
                
                if ((lease = lease6_find(state->clid, state->clid_len, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA,
-                                        state->iaid, opt6_ptr(ia_option, 0))))
+                                        state->iaid, &addr)))
                  lease_prune(lease, now);
                else
                  {
@@ -1267,7 +1223,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
                      }
                    
                    o1 = new_opt6(OPTION6_IAADDR);
-                   put_opt6(opt6_ptr(ia_option, 0), IN6ADDRSZ);
+                   put_opt6(&addr, IN6ADDRSZ);
                    put_opt6_long(0);
                    put_opt6_long(0);
                    end_opt6(o1);
@@ -1355,23 +1311,39 @@ static struct dhcp_netid *add_options(struct state *state, int do_refresh)
                  
              for (a = (struct in6_addr *)opt_cfg->val, j = 0; j < opt_cfg->len; j+=IN6ADDRSZ, a++)
                {
+                 struct in6_addr *p = NULL;
+
                  if (IN6_IS_ADDR_UNSPECIFIED(a))
                    {
                      if (!add_local_addrs(state->context))
-                       put_opt6(state->fallback, IN6ADDRSZ);
+                       p = state->fallback;
                    }
                  else if (IN6_IS_ADDR_ULA_ZERO(a))
                    {
                      if (!IN6_IS_ADDR_UNSPECIFIED(state->ula_addr))
-                       put_opt6(state->ula_addr, IN6ADDRSZ);
+                       p = state->ula_addr;
                    }
                  else if (IN6_IS_ADDR_LINK_LOCAL_ZERO(a))
                    {
                      if (!IN6_IS_ADDR_UNSPECIFIED(state->ll_addr))
-                       put_opt6(state->ll_addr, IN6ADDRSZ);
+                       p = state->ll_addr;
                    }
                  else
-                   put_opt6(a, IN6ADDRSZ);
+                   p = a;
+
+                 if (!p)
+                   continue;
+                 else if (opt_cfg->opt == OPTION6_NTP_SERVER)
+                   {
+                     if (IN6_IS_ADDR_MULTICAST(p))
+                       o1 = new_opt6(NTP_SUBOPTION_MC_ADDR);
+                     else
+                       o1 = new_opt6(NTP_SUBOPTION_SRV_ADDR);
+                     put_opt6(p, IN6ADDRSZ);
+                     end_opt6(o1);
+                   }
+                 else
+                   put_opt6(p, IN6ADDRSZ);
                }
 
              end_opt6(o);
@@ -1565,21 +1537,6 @@ static void get_context_tag(struct state *state, struct dhcp_context *context)
     }
 } 
 
-#ifdef OPTION6_PREFIX_CLASS
-static struct prefix_class *prefix_class_from_context(struct dhcp_context *context)
-{
-  struct prefix_class *p;
-  struct dhcp_netid *t;
-  
-  for (p = daemon->prefix_classes; p ; p = p->next)
-    for (t = context->filter; t; t = t->next)
-      if (strcmp(p->tag.net, t->net) == 0)
-       return p;
-  
- return NULL;
-}
-#endif
-
 static int check_ia(struct state *state, void *opt, void **endp, void **ia_option)
 {
   state->ia_type = opt6_type(opt);
@@ -1664,16 +1621,6 @@ static void add_address(struct state *state, struct dhcp_context *context, unsig
   put_opt6(addr, sizeof(*addr));
   put_opt6_long(preferred_time);
   put_opt6_long(valid_time);               
-  
-#ifdef OPTION6_PREFIX_CLASS
-  if (state->send_prefix_class)
-    {
-      int o1 = new_opt6(OPTION6_PREFIX_CLASS);
-      put_opt6_short(state->send_prefix_class->class);
-      end_opt6(o1);
-    }
-#endif
-
   end_opt6(o);
   
   if (state->lease_allocate)
@@ -1709,16 +1656,9 @@ static void mark_context_used(struct state *state, struct in6_addr *addr)
   struct dhcp_context *context;
 
   /* Mark that we have an address for this prefix. */
-#ifdef OPTION6_PREFIX_CLASS
-  for (context = state->context; context; context = context->current)
-    if (is_same_net6(addr, &context->start6, context->prefix) &&
-       (!state->send_prefix_class || state->send_prefix_class == prefix_class_from_context(context)))
-      context->flags |= CONTEXT_USED;
-#else
   for (context = state->context; context; context = context->current)
     if (is_same_net6(addr, &context->start6, context->prefix))
       context->flags |= CONTEXT_USED;
-#endif
 }
 
 static void mark_config_used(struct dhcp_context *context, struct in6_addr *addr)
@@ -1745,6 +1685,78 @@ static int check_address(struct state *state, struct in6_addr *addr)
 }
 
 
+/* return true of *addr could have been generated from config. */
+static struct addrlist *config_implies(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr)
+{
+  int prefix;
+  struct in6_addr wild_addr;
+  struct addrlist *addr_list;
+  
+  if (!config || !(config->flags & CONFIG_ADDR6))
+    return NULL;
+  
+  for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
+    {
+      prefix = (addr_list->flags & ADDRLIST_PREFIX) ? addr_list->prefixlen : 128;
+      wild_addr = addr_list->addr.addr6;
+      
+      if ((addr_list->flags & ADDRLIST_WILDCARD) && context->prefix == 64)
+       {
+         wild_addr = context->start6;
+         setaddr6part(&wild_addr, addr6part(&addr_list->addr.addr6));
+       }
+      else if (!is_same_net6(&context->start6, addr, context->prefix))
+       continue;
+      
+      if (is_same_net6(&wild_addr, addr, prefix))
+       return addr_list;
+    }
+  
+  return NULL;
+}
+
+static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state, time_t now)
+{
+  u64 addrpart, i, addresses;
+  struct addrlist *addr_list;
+  
+  if (!config || !(config->flags & CONFIG_ADDR6))
+    return 0;
+
+  for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
+    if (!(addr_list->flags & ADDRLIST_DECLINED) ||
+       difftime(now, addr_list->decline_time) >= (float)DECLINE_BACKOFF)
+      {
+       addrpart = addr6part(&addr_list->addr.addr6);
+       addresses = 1;
+       
+       if (addr_list->flags & ADDRLIST_PREFIX)
+         addresses = (u64)1<<(128-addr_list->prefixlen);
+       
+       if ((addr_list->flags & ADDRLIST_WILDCARD))
+         {
+           if (context->prefix != 64)
+             continue;
+           
+           *addr = context->start6;
+         }
+       else if (is_same_net6(&context->start6, &addr_list->addr.addr6, context->prefix))
+         *addr = addr_list->addr.addr6;
+       else
+         continue;
+       
+       for (i = 0 ; i < addresses; i++)
+         {
+           setaddr6part(addr, addrpart+i);
+           
+           if (check_address(state, addr))
+             return 1;
+         }
+      }
+  
+  return 0;
+}
+
 /* Calculate valid and preferred times to send in leases/renewals. 
 
    Inputs are:
@@ -1935,19 +1947,16 @@ static void log6_opts(int nest, unsigned int xid, void *start_opts, void *end_op
        }
       else if (type == OPTION6_IAADDR)
        {
-         inet_ntop(AF_INET6, opt6_ptr(opt, 0), daemon->addrbuff, ADDRSTRLEN);
+         struct in6_addr addr;
+
+         /* align */
+         memcpy(&addr, opt6_ptr(opt, 0), IN6ADDRSZ);
+         inet_ntop(AF_INET6, &addr, daemon->addrbuff, ADDRSTRLEN);
          sprintf(daemon->namebuff, "%s PL=%u VL=%u", 
                  daemon->addrbuff, opt6_uint(opt, 16, 4), opt6_uint(opt, 20, 4));
          optname = "iaaddr";
          ia_options = opt6_ptr(opt, 24);
        }
-#ifdef OPTION6_PREFIX_CLASS
-      else if (type == OPTION6_PREFIX_CLASS)
-       {
-         optname = "prefix-class";
-         sprintf(daemon->namebuff, "class=%u", opt6_uint(opt, 0, 2));
-       }
-#endif
       else if (type == OPTION6_STATUS_CODE)
        {
          int len = sprintf(daemon->namebuff, "%u ", opt6_uint(opt, 0, 2));
@@ -2072,7 +2081,7 @@ void relay_upstream6(struct dhcp_relay *relay, ssize_t sz,
 {
   /* ->local is same value for all relays on ->current chain */
   
-  struct all_addr from;
+  union all_addr from;
   unsigned char *header;
   unsigned char *inbuff = daemon->dhcp_packet.iov_base;
   int msg_type = *inbuff;
@@ -2085,7 +2094,7 @@ void relay_upstream6(struct dhcp_relay *relay, ssize_t sz,
   get_client_mac(peer_address, scope_id, mac, &maclen, &mactype, now);
 
   /* source address == relay address */
-  from.addr.addr6 = relay->local.addr.addr6;
+  from.addr6 = relay->local.addr6;
     
   /* Get hop count from nested relayed message */ 
   if (msg_type == DHCP6RELAYFORW)
@@ -2105,7 +2114,7 @@ void relay_upstream6(struct dhcp_relay *relay, ssize_t sz,
 
       header[0] = DHCP6RELAYFORW;
       header[1] = hopcount;
-      memcpy(&header[2],  &relay->local.addr.addr6, IN6ADDRSZ);
+      memcpy(&header[2],  &relay->local.addr6, IN6ADDRSZ);
       memcpy(&header[18], peer_address, IN6ADDRSZ);
  
       /* RFC-6939 */
@@ -2126,12 +2135,12 @@ void relay_upstream6(struct dhcp_relay *relay, ssize_t sz,
          union mysockaddr to;
          
          to.sa.sa_family = AF_INET6;
-         to.in6.sin6_addr = relay->server.addr.addr6;
+         to.in6.sin6_addr = relay->server.addr6;
          to.in6.sin6_port = htons(DHCPV6_SERVER_PORT);
          to.in6.sin6_flowinfo = 0;
          to.in6.sin6_scope_id = 0;
 
-         if (IN6_ARE_ADDR_EQUAL(&relay->server.addr.addr6, &multicast))
+         if (IN6_ARE_ADDR_EQUAL(&relay->server.addr6, &multicast))
            {
              int multicast_iface;
              if (!relay->interface || strchr(relay->interface, '*') ||
@@ -2170,7 +2179,7 @@ unsigned short relay_reply6(struct sockaddr_in6 *peer, ssize_t sz, char *arrival
   memcpy(&link, &inbuff[2], IN6ADDRSZ); 
   
   for (relay = daemon->relay6; relay; relay = relay->next)
-    if (IN6_ARE_ADDR_EQUAL(&link, &relay->local.addr.addr6) &&
+    if (IN6_ARE_ADDR_EQUAL(&link, &relay->local.addr6) &&
        (!relay->interface || wildcard_match(relay->interface, arrival_interface)))
       break;
       
index f5b9c61..16e6b55 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
index 13317d8..4a3e01d 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -166,7 +166,8 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
            
            if (sendto(daemon->icmp6fd, daemon->outpacket.iov_base, save_counter(-1), 0,
                       (struct sockaddr *)&addr,  sizeof(addr)) == -1 &&
-               errno == EHOSTUNREACH)
+               errno == EHOSTUNREACH &&
+               slaac->backoff == 12)
              slaac->ping_time = 0; /* Give up */ 
            else
              {
index a3382ce..b34ea77 100644 (file)
@@ -62,7 +62,7 @@ void ipset_init(void)
     }
 }
 
-int add_to_ipset(const char *setname, const struct all_addr *ipaddr,
+int add_to_ipset(const char *setname, const union all_addr *ipaddr,
                 int flags, int remove)
 {
   struct pfr_addr addr;
@@ -108,19 +108,18 @@ int add_to_ipset(const char *setname, const struct all_addr *ipaddr,
     my_syslog(LOG_INFO, _("info: table created"));
  
   bzero(&addr, sizeof(addr));
-#ifdef HAVE_IPV6
+
   if (flags & F_IPV6) 
     {
       addr.pfra_af = AF_INET6;
       addr.pfra_net = 0x80;
-      memcpy(&(addr.pfra_ip6addr), &(ipaddr->addr), sizeof(struct in6_addr));
+      memcpy(&(addr.pfra_ip6addr), ipaddr, sizeof(struct in6_addr));
     } 
   else 
-#endif
     {
       addr.pfra_af = AF_INET;
       addr.pfra_net = 0x20;
-      addr.pfra_ip4addr.s_addr = ipaddr->addr.addr4.s_addr;
+      addr.pfra_ip4addr.s_addr = ipaddr->addr4.s_addr;
     }
 
   bzero(&io, sizeof(io));
index bccca69..aa240e5 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
@@ -18,6 +18,7 @@
 
 #ifdef HAVE_TFTP
 
+static void handle_tftp(time_t now, struct tftp_transfer *transfer, ssize_t len);
 static struct tftp_file *check_tftp_fileperm(ssize_t *len, char *prefix);
 static void free_transfer(struct tftp_transfer *transfer);
 static ssize_t tftp_err(int err, char *packet, char *message, char *file);
@@ -50,7 +51,7 @@ void tftp_request(struct listener *listen, time_t now)
   struct ifreq ifr;
   int is_err = 1, if_index = 0, mtu = 0;
   struct iname *tmp;
-  struct tftp_transfer *transfer;
+  struct tftp_transfer *transfer = NULL, **up;
   int port = daemon->start_tftp_port; /* may be zero to use ephemeral port */
 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
   int mtuflag = IP_PMTUDISC_DONT;
@@ -59,24 +60,21 @@ void tftp_request(struct listener *listen, time_t now)
   char *name = NULL;
   char *prefix = daemon->tftp_prefix;
   struct tftp_prefix *pref;
-  struct all_addr addra;
-#ifdef HAVE_IPV6
+  union all_addr addra;
+  int family = listen->addr.sa.sa_family;
   /* Can always get recvd interface for IPv6 */
-  int check_dest = !option_bool(OPT_NOWILD) || listen->family == AF_INET6;
-#else
-  int check_dest = !option_bool(OPT_NOWILD);
-#endif
+  int check_dest = !option_bool(OPT_NOWILD) || family == AF_INET6;
   union {
     struct cmsghdr align; /* this ensures alignment */
-#ifdef HAVE_IPV6
     char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
-#endif
 #if defined(HAVE_LINUX_NETWORK)
     char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
 #elif defined(HAVE_SOLARIS_NETWORK)
-    char control[CMSG_SPACE(sizeof(unsigned int))];
+    char control[CMSG_SPACE(sizeof(struct in_addr)) +
+                CMSG_SPACE(sizeof(unsigned int))];
 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
-    char control[CMSG_SPACE(sizeof(struct sockaddr_dl))];
+    char control[CMSG_SPACE(sizeof(struct in_addr)) +
+                CMSG_SPACE(sizeof(struct sockaddr_dl))];
 #endif
   } control_u; 
 
@@ -124,10 +122,10 @@ void tftp_request(struct listener *listen, time_t now)
       if (msg.msg_controllen < sizeof(struct cmsghdr))
         return;
       
-      addr.sa.sa_family = listen->family;
+      addr.sa.sa_family = family;
       
 #if defined(HAVE_LINUX_NETWORK)
-      if (listen->family == AF_INET)
+      if (family == AF_INET)
        for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
          if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
            {
@@ -141,7 +139,7 @@ void tftp_request(struct listener *listen, time_t now)
            }
       
 #elif defined(HAVE_SOLARIS_NETWORK)
-      if (listen->family == AF_INET)
+      if (family == AF_INET)
        for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
          {
            union {
@@ -157,7 +155,7 @@ void tftp_request(struct listener *listen, time_t now)
          }
       
 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
-      if (listen->family == AF_INET)
+      if (family == AF_INET)
        for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
          {
            union {
@@ -174,8 +172,7 @@ void tftp_request(struct listener *listen, time_t now)
          
 #endif
 
-#ifdef HAVE_IPV6
-      if (listen->family == AF_INET6)
+      if (family == AF_INET6)
         {
           for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
             if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
@@ -190,19 +187,16 @@ void tftp_request(struct listener *listen, time_t now)
                 if_index = p.p->ipi6_ifindex;
               }
         }
-#endif
       
       if (!indextoname(listen->tftpfd, if_index, namebuff))
        return;
 
       name = namebuff;
       
-      addra.addr.addr4 = addr.in.sin_addr;
+      addra.addr4 = addr.in.sin_addr;
 
-#ifdef HAVE_IPV6
-      if (listen->family == AF_INET6)
-       addra.addr.addr6 = addr.in6.sin6_addr;
-#endif
+      if (family == AF_INET6)
+       addra.addr6 = addr.in6.sin6_addr;
 
       if (daemon->tftp_interfaces)
        {
@@ -217,12 +211,12 @@ void tftp_request(struct listener *listen, time_t now)
       else
        {
          /* Do the same as DHCP */
-         if (!iface_check(listen->family, &addra, name, NULL))
+         if (!iface_check(family, &addra, name, NULL))
            {
              if (!option_bool(OPT_CLEVERBIND))
                enumerate_interfaces(0); 
-             if (!loopback_exception(listen->tftpfd, listen->family, &addra, name) &&
-                 !label_exception(if_index, listen->family, &addra) )
+             if (!loopback_exception(listen->tftpfd, family, &addra, name) &&
+                 !label_exception(if_index, family, &addra))
                return;
            }
          
@@ -234,7 +228,7 @@ void tftp_request(struct listener *listen, time_t now)
 #endif
        }
 
-      strncpy(ifr.ifr_name, name, IF_NAMESIZE);
+      safe_strncpy(ifr.ifr_name, name, IF_NAMESIZE);
       if (ioctl(listen->tftpfd, SIOCGIFMTU, &ifr) != -1)
        {
          mtu = ifr.ifr_mtu;  
@@ -247,6 +241,39 @@ void tftp_request(struct listener *listen, time_t now)
   if (mtu == 0)
     mtu = daemon->tftp_mtu;
 
+  /* data transfer via server listening socket */
+  if (option_bool(OPT_SINGLE_PORT))
+    {
+      int tftp_cnt;
+
+      for (tftp_cnt = 0, transfer = daemon->tftp_trans, up = &daemon->tftp_trans; transfer; up = &transfer->next, transfer = transfer->next)
+       {
+         tftp_cnt++;
+
+         if (sockaddr_isequal(&peer, &transfer->peer))
+           {
+             if (ntohs(*((unsigned short *)packet)) == OP_RRQ)
+               {
+                 /* Handle repeated RRQ or abandoned transfer from same host and port 
+                    by unlinking and reusing the struct transfer. */
+                 *up = transfer->next;
+                 break;
+               }
+             else
+               {
+                 handle_tftp(now, transfer, len);
+                 return;
+               }
+           }
+       }
+      
+      /* Enforce simultaneous transfer limit. In non-single-port mode
+        this is doene by not listening on the server socket when
+        too many transfers are in progress. */
+      if (!transfer && tftp_cnt >= daemon->tftp_max)
+       return;
+    }
+  
   if (name)
     {
       /* check for per-interface prefix */ 
@@ -255,14 +282,13 @@ void tftp_request(struct listener *listen, time_t now)
          prefix = pref->prefix;  
     }
 
-  if (listen->family == AF_INET)
+  if (family == AF_INET)
     {
       addr.in.sin_port = htons(port);
 #ifdef HAVE_SOCKADDR_SA_LEN
       addr.in.sin_len = sizeof(addr.in);
 #endif
     }
-#ifdef HAVE_IPV6
   else
     {
       addr.in6.sin6_port = htons(port);
@@ -272,18 +298,22 @@ void tftp_request(struct listener *listen, time_t now)
       addr.in6.sin6_len = sizeof(addr.in6);
 #endif
     }
-#endif
 
-  if (!(transfer = whine_malloc(sizeof(struct tftp_transfer))))
+  /* May reuse struct transfer from abandoned transfer in single port mode. */
+  if (!transfer && !(transfer = whine_malloc(sizeof(struct tftp_transfer))))
     return;
   
-  if ((transfer->sockfd = socket(listen->family, SOCK_DGRAM, 0)) == -1)
+  if (option_bool(OPT_SINGLE_PORT))
+    transfer->sockfd = listen->tftpfd;
+  else if ((transfer->sockfd = socket(family, SOCK_DGRAM, 0)) == -1)
     {
       free(transfer);
       return;
     }
   
   transfer->peer = peer;
+  transfer->source = addra;
+  transfer->if_index = if_index;
   transfer->timeout = now + 2;
   transfer->backoff = 1;
   transfer->block = 1;
@@ -293,10 +323,10 @@ void tftp_request(struct listener *listen, time_t now)
   transfer->opt_blocksize = transfer->opt_transize = 0;
   transfer->netascii = transfer->carrylf = 0;
  
-  prettyprint_addr(&peer, daemon->addrbuff);
+  (void)prettyprint_addr(&peer, daemon->addrbuff);
   
   /* if we have a nailed-down range, iterate until we find a free one. */
-  while (1)
+  while (!option_bool(OPT_SINGLE_PORT))
     {
       if (bind(transfer->sockfd, &addr.sa, sa_len(&addr)) == -1 ||
 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
@@ -308,12 +338,11 @@ void tftp_request(struct listener *listen, time_t now)
            {
              if (++port <= daemon->end_tftp_port)
                { 
-                 if (listen->family == AF_INET)
+                 if (family == AF_INET)
                    addr.in.sin_port = htons(port);
-#ifdef HAVE_IPV6
                  else
-                    addr.in6.sin6_port = htons(port);
-#endif
+                   addr.in6.sin6_port = htons(port);
+                 
                  continue;
                }
              my_syslog(MS_TFTP | LOG_ERR, _("unable to get free port for TFTP"));
@@ -326,7 +355,7 @@ void tftp_request(struct listener *listen, time_t now)
   
   p = packet + 2;
   end = packet + len;
-
+  
   if (ntohs(*((unsigned short *)packet)) != OP_RRQ ||
       !(filename = next(&p, end)) ||
       !(mode = next(&p, end)) ||
@@ -347,7 +376,7 @@ void tftp_request(struct listener *listen, time_t now)
              if ((opt = next(&p, end)) && !option_bool(OPT_TFTP_NOBLOCK))
                {
                  /* 32 bytes for IP, UDP and TFTP headers, 52 bytes for IPv6 */
-                 int overhead = (listen->family == AF_INET) ? 32 : 52;
+                 int overhead = (family == AF_INET) ? 32 : 52;
                  transfer->blocksize = atoi(opt);
                  if (transfer->blocksize < 1)
                    transfer->blocksize = 1;
@@ -450,9 +479,8 @@ void tftp_request(struct listener *listen, time_t now)
            is_err = 0;
        }
     }
-  
-  while (sendto(transfer->sockfd, packet, len, 0, 
-               (struct sockaddr *)&peer, sa_len(&peer)) == -1 && errno == EINTR);
+
+  send_from(transfer->sockfd, !option_bool(OPT_SINGLE_PORT), packet, len, &peer, &addra, if_index);
   
   if (is_err)
     free_transfer(transfer);
@@ -549,63 +577,28 @@ static struct tftp_file *check_tftp_fileperm(ssize_t *len, char *prefix)
 void check_tftp_listeners(time_t now)
 {
   struct tftp_transfer *transfer, *tmp, **up;
-  ssize_t len;
   
-  struct ack {
-    unsigned short op, block;
-  } *mess = (struct ack *)daemon->packet;
-  
-  /* Check for activity on any existing transfers */
-  for (transfer = daemon->tftp_trans, up = &daemon->tftp_trans; transfer; transfer = tmp)
-    {
-      tmp = transfer->next;
-      
-      prettyprint_addr(&transfer->peer, daemon->addrbuff);
-     
+  /* In single port mode, all packets come via port 69 and tftp_request() */
+  if (!option_bool(OPT_SINGLE_PORT))
+    for (transfer = daemon->tftp_trans; transfer; transfer = transfer->next)
       if (poll_check(transfer->sockfd, POLLIN))
        {
          /* we overwrote the buffer... */
          daemon->srv_save = NULL;
-         
-         if ((len = recv(transfer->sockfd, daemon->packet, daemon->packet_buff_sz, 0)) >= (ssize_t)sizeof(struct ack))
-           {
-             if (ntohs(mess->op) == OP_ACK && ntohs(mess->block) == (unsigned short)transfer->block) 
-               {
-                 /* Got ack, ensure we take the (re)transmit path */
-                 transfer->timeout = now;
-                 transfer->backoff = 0;
-                 if (transfer->block++ != 0)
-                   transfer->offset += transfer->blocksize - transfer->expansion;
-               }
-             else if (ntohs(mess->op) == OP_ERR)
-               {
-                 char *p = daemon->packet + sizeof(struct ack);
-                 char *end = daemon->packet + len;
-                 char *err = next(&p, end);
-                 
-                 /* Sanitise error message */
-                 if (!err)
-                   err = "";
-                 else
-                   sanitise(err);
-                 
-                 my_syslog(MS_TFTP | LOG_ERR, _("error %d %s received from %s"),
-                           (int)ntohs(mess->block), err, 
-                           daemon->addrbuff);  
-                 
-                 /* Got err, ensure we take abort */
-                 transfer->timeout = now;
-                 transfer->backoff = 100;
-               }
-           }
+         handle_tftp(now, transfer, recv(transfer->sockfd, daemon->packet, daemon->packet_buff_sz, 0));
        }
+
+  for (transfer = daemon->tftp_trans, up = &daemon->tftp_trans; transfer; transfer = tmp)
+    {
+      tmp = transfer->next;
       
       if (difftime(now, transfer->timeout) >= 0.0)
        {
          int endcon = 0;
+         ssize_t len;
 
          /* timeout, retransmit */
-         transfer->timeout += 1 + (1<<transfer->backoff);
+         transfer->timeout += 1 + (1<<(transfer->backoff/2));
                  
          /* we overwrote the buffer... */
          daemon->srv_save = NULL;
@@ -615,22 +608,24 @@ void check_tftp_listeners(time_t now)
              len = tftp_err_oops(daemon->packet, transfer->file->filename);
              endcon = 1;
            }
-         /* don't complain about timeout when we're awaiting the last
-            ACK, some clients never send it */
-         else if (++transfer->backoff > 7 && len != 0)
+         else if (++transfer->backoff > 7)
            {
-             endcon = 1;
+             /* don't complain about timeout when we're awaiting the last
+                ACK, some clients never send it */
+             if ((unsigned)len == transfer->blocksize + 4)
+               endcon = 1;
              len = 0;
            }
 
          if (len != 0)
-           while(sendto(transfer->sockfd, daemon->packet, len, 0, 
-                        (struct sockaddr *)&transfer->peer, sa_len(&transfer->peer)) == -1 && errno == EINTR);
-         
+           send_from(transfer->sockfd, !option_bool(OPT_SINGLE_PORT), daemon->packet, len,
+                     &transfer->peer, &transfer->source, transfer->if_index);
+                 
          if (endcon || len == 0)
            {
              strcpy(daemon->namebuff, transfer->file->filename);
              sanitise(daemon->namebuff);
+             (void)prettyprint_addr(&transfer->peer, daemon->addrbuff);
              my_syslog(MS_TFTP | LOG_INFO, endcon ? _("failed sending %s to %s") : _("sent %s to %s"), daemon->namebuff, daemon->addrbuff);
              /* unlink */
              *up = tmp;
@@ -649,15 +644,60 @@ void check_tftp_listeners(time_t now)
       up = &transfer->next;
     }    
 }
+         
+/* packet in daemon->packet as this is called. */
+static void handle_tftp(time_t now, struct tftp_transfer *transfer, ssize_t len)
+{
+  struct ack {
+    unsigned short op, block;
+  } *mess = (struct ack *)daemon->packet;
+  
+  if (len >= (ssize_t)sizeof(struct ack))
+    {
+      if (ntohs(mess->op) == OP_ACK && ntohs(mess->block) == (unsigned short)transfer->block) 
+       {
+         /* Got ack, ensure we take the (re)transmit path */
+         transfer->timeout = now;
+         transfer->backoff = 0;
+         if (transfer->block++ != 0)
+           transfer->offset += transfer->blocksize - transfer->expansion;
+       }
+      else if (ntohs(mess->op) == OP_ERR)
+       {
+         char *p = daemon->packet + sizeof(struct ack);
+         char *end = daemon->packet + len;
+         char *err = next(&p, end);
+         
+         (void)prettyprint_addr(&transfer->peer, daemon->addrbuff);
+         
+         /* Sanitise error message */
+         if (!err)
+           err = "";
+         else
+           sanitise(err);
+         
+         my_syslog(MS_TFTP | LOG_ERR, _("error %d %s received from %s"),
+                   (int)ntohs(mess->block), err, 
+                   daemon->addrbuff);  
+         
+         /* Got err, ensure we take abort */
+         transfer->timeout = now;
+         transfer->backoff = 100;
+       }
+    }
+}
 
 static void free_transfer(struct tftp_transfer *transfer)
 {
-  close(transfer->sockfd);
+  if (!option_bool(OPT_SINGLE_PORT))
+    close(transfer->sockfd);
+
   if (transfer->file && (--transfer->file->refcount) == 0)
     {
       close(transfer->file->fd);
       free(transfer->file);
     }
+  
   free(transfer);
 }
 
diff --git a/src/ubus.c b/src/ubus.c
new file mode 100644 (file)
index 0000000..5f81287
--- /dev/null
@@ -0,0 +1,205 @@
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
+
+   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; version 2 dated June, 1991, or
+   (at your option) version 3 dated 29 June, 2007.
+   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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "dnsmasq.h"
+
+#ifdef HAVE_UBUS
+
+#include <libubus.h>
+
+static struct blob_buf b;
+static int notify;
+static int error_logged = 0;
+
+static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
+                              struct ubus_request_data *req, const char *method,
+                              struct blob_attr *msg);
+
+static void ubus_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj);
+
+static const struct ubus_method ubus_object_methods[] = {
+  UBUS_METHOD_NOARG("metrics", ubus_handle_metrics),
+};
+
+static struct ubus_object_type ubus_object_type =
+  UBUS_OBJECT_TYPE("dnsmasq", ubus_object_methods);
+
+static struct ubus_object ubus_object = {
+  .name = NULL,
+  .type = &ubus_object_type,
+  .methods = ubus_object_methods,
+  .n_methods = ARRAY_SIZE(ubus_object_methods),
+  .subscribe_cb = ubus_subscribe_cb,
+};
+
+static void ubus_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj)
+{
+  (void)ctx;
+
+  my_syslog(LOG_DEBUG, _("UBus subscription callback: %s subscriber(s)"), obj->has_subscribers ? "1" : "0");
+  notify = obj->has_subscribers;
+}
+
+static void ubus_destroy(struct ubus_context *ubus)
+{
+  // Forces re-initialization when we're reusing the same definitions later on.
+  ubus_object.id = 0;
+  ubus_object_type.id = 0;
+
+  ubus_free(ubus);
+  daemon->ubus = NULL;
+}
+
+static void ubus_disconnect_cb(struct ubus_context *ubus)
+{
+  int ret;
+
+  ret = ubus_reconnect(ubus, NULL);
+  if (ret)
+    {
+      my_syslog(LOG_ERR, _("Cannot reconnect to UBus: %s"), ubus_strerror(ret));
+
+      ubus_destroy(ubus);
+    }
+}
+
+void ubus_init()
+{
+  struct ubus_context *ubus = NULL;
+  int ret = 0;
+
+  ubus = ubus_connect(NULL);
+  if (!ubus)
+    {
+      if (!error_logged)
+        {
+          my_syslog(LOG_ERR, _("Cannot initialize UBus: connection failed"));
+          error_logged = 1;
+        }
+
+      ubus_destroy(ubus);
+      return;
+    }
+
+  ubus_object.name = daemon->ubus_name;
+  ret = ubus_add_object(ubus, &ubus_object);
+  if (ret)
+    {
+      if (!error_logged)
+        {
+          my_syslog(LOG_ERR, _("Cannot add object to UBus: %s"), ubus_strerror(ret));
+          error_logged = 1;
+        }
+      ubus_destroy(ubus);
+      return;
+    }
+
+  ubus->connection_lost = ubus_disconnect_cb;
+  daemon->ubus = ubus;
+  error_logged = 0;
+
+  my_syslog(LOG_INFO, _("Connected to system UBus"));
+}
+
+void set_ubus_listeners()
+{
+  struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
+  if (!ubus)
+    {
+      if (!error_logged)
+        {
+          my_syslog(LOG_ERR, _("Cannot set UBus listeners: no connection"));
+          error_logged = 1;
+        }
+      return;
+    }
+
+  error_logged = 0;
+
+  poll_listen(ubus->sock.fd, POLLIN);
+  poll_listen(ubus->sock.fd, POLLERR);
+  poll_listen(ubus->sock.fd, POLLHUP);
+}
+
+void check_ubus_listeners()
+{
+  struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
+  if (!ubus)
+    {
+      if (!error_logged)
+        {
+          my_syslog(LOG_ERR, _("Cannot poll UBus listeners: no connection"));
+          error_logged = 1;
+        }
+      return;
+    }
+  
+  error_logged = 0;
+
+  if (poll_check(ubus->sock.fd, POLLIN))
+    ubus_handle_event(ubus);
+  
+  if (poll_check(ubus->sock.fd, POLLHUP | POLLERR))
+    {
+      my_syslog(LOG_INFO, _("Disconnecting from UBus"));
+
+      ubus_destroy(ubus);
+    }
+}
+
+static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
+                              struct ubus_request_data *req, const char *method,
+                              struct blob_attr *msg)
+{
+  int i;
+
+  (void)obj;
+  (void)method;
+  (void)msg;
+
+  blob_buf_init(&b, BLOBMSG_TYPE_TABLE);
+
+  for (i=0; i < __METRIC_MAX; i++)
+    blobmsg_add_u32(&b, get_metric_name(i), daemon->metrics[i]);
+  
+  return ubus_send_reply(ctx, req, b.head);
+}
+
+void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface)
+{
+  struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
+  int ret;
+
+  if (!ubus || !notify)
+    return;
+
+  blob_buf_init(&b, BLOBMSG_TYPE_TABLE);
+  if (mac)
+    blobmsg_add_string(&b, "mac", mac);
+  if (ip)
+    blobmsg_add_string(&b, "ip", ip);
+  if (name)
+    blobmsg_add_string(&b, "name", name);
+  if (interface)
+    blobmsg_add_string(&b, "interface", interface);
+  
+  ret = ubus_notify(ubus, &ubus_object, type, b.head, -1);
+  if (!ret)
+    my_syslog(LOG_ERR, _("Failed to send UBus event: %s"), ubus_strerror(ret));
+}
+
+
+#endif /* HAVE_UBUS */
index 532bc16..5f13027 100644 (file)
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
 
    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
 #include <idna.h>
 #endif
 
+#ifdef HAVE_LINUX_NETWORK
+#include <sys/utsname.h>
+#endif
+
 /* SURF random number generator */
 
 static u32 seed[32];
@@ -281,7 +285,18 @@ void *safe_malloc(size_t size)
     die(_("could not get memory"), NULL, EC_NOMEM);
       
   return ret;
-}    
+}
+
+/* Ensure limited size string is always terminated.
+ * Can be replaced by (void)strlcpy() on some platforms */
+void safe_strncpy(char *dest, const char *src, size_t size)
+{
+  if (size != 0)
+    {
+      dest[size-1] = '\0';
+      strncpy(dest, src, size-1);
+    }
+}
 
 void safe_pipe(int *fd, int read_noblock)
 {
@@ -309,13 +324,12 @@ int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2)
          s1->in.sin_port == s2->in.sin_port &&
          s1->in.sin_addr.s_addr == s2->in.sin_addr.s_addr)
        return 1;
-#ifdef HAVE_IPV6      
+      
       if (s1->sa.sa_family == AF_INET6 &&
          s1->in6.sin6_port == s2->in6.sin6_port &&
          s1->in6.sin6_scope_id == s2->in6.sin6_scope_id &&
          IN6_ARE_ADDR_EQUAL(&s1->in6.sin6_addr, &s2->in6.sin6_addr))
        return 1;
-#endif
     }
   return 0;
 }
@@ -325,11 +339,9 @@ int sa_len(union mysockaddr *addr)
 #ifdef HAVE_SOCKADDR_SA_LEN
   return addr->sa.sa_len;
 #else
-#ifdef HAVE_IPV6
   if (addr->sa.sa_family == AF_INET6)
     return sizeof(addr->in6);
   else
-#endif
     return sizeof(addr->in); 
 #endif
 }
@@ -355,6 +367,44 @@ int hostname_isequal(const char *a, const char *b)
   return 1;
 }
 
+/* is b equal to or a subdomain of a return 2 for equal, 1 for subdomain */
+int hostname_issubdomain(char *a, char *b)
+{
+  char *ap, *bp;
+  unsigned int c1, c2;
+  
+  /* move to the end */
+  for (ap = a; *ap; ap++); 
+  for (bp = b; *bp; bp++);
+
+  /* a shorter than b or a empty. */
+  if ((bp - b) < (ap - a) || ap == a)
+    return 0;
+
+  do
+    {
+      c1 = (unsigned char) *(--ap);
+      c2 = (unsigned char) *(--bp);
+  
+       if (c1 >= 'A' && c1 <= 'Z')
+        c1 += 'a' - 'A';
+       if (c2 >= 'A' && c2 <= 'Z')
+        c2 += 'a' - 'A';
+
+       if (c1 != c2)
+        return 0;
+    } while (ap != a);
+
+  if (bp == b)
+    return 2;
+
+  if (*(--bp) == '.')
+    return 1;
+
+  return 0;
+}
+  
 time_t dnsmasq_time(void)
 {
 #ifdef HAVE_BROKEN_RTC
@@ -388,7 +438,6 @@ int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask)
   return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr);
 } 
 
-#ifdef HAVE_IPV6
 int is_same_net6(struct in6_addr *a, struct in6_addr *b, int prefixlen)
 {
   int pfbytes = prefixlen >> 3;
@@ -427,15 +476,12 @@ void setaddr6part(struct in6_addr *addr, u64 host)
     }
 }
 
-#endif
 
 /* returns port number from address */
 int prettyprint_addr(union mysockaddr *addr, char *buf)
 {
   int port = 0;
   
-#ifdef HAVE_IPV6
   if (addr->sa.sa_family == AF_INET)
     {
       inet_ntop(AF_INET, &addr->in.sin_addr, buf, ADDRSTRLEN);
@@ -454,10 +500,6 @@ int prettyprint_addr(union mysockaddr *addr, char *buf)
        }
       port = ntohs(addr->in6.sin6_port);
     }
-#else
-  strcpy(buf, inet_ntoa(addr->in.sin_addr));
-  port = ntohs(addr->in.sin_port); 
-#endif
   
   return port;
 }
@@ -486,20 +528,20 @@ void prettyprint_time(char *buf, unsigned int t)
 int parse_hex(char *in, unsigned char *out, int maxlen, 
              unsigned int *wildcard_mask, int *mac_type)
 {
-  int mask = 0, i = 0;
+  int done = 0, mask = 0, i = 0;
   char *r;
     
   if (mac_type)
     *mac_type = 0;
   
-  while (maxlen == -1 || i < maxlen)
+  while (!done && (maxlen == -1 || i < maxlen))
     {
       for (r = in; *r != 0 && *r != ':' && *r != '-' && *r != ' '; r++)
        if (*r != '*' && !isxdigit((unsigned char)*r))
          return -1;
       
       if (*r == 0)
-       maxlen = i;
+       done = 1;
       
       if (r != in )
        {
@@ -667,6 +709,47 @@ int read_write(int fd, unsigned char *packet, int size, int rw)
   return 1;
 }
 
+/* close all fds except STDIN, STDOUT and STDERR, spare1, spare2 and spare3 */
+void close_fds(long max_fd, int spare1, int spare2, int spare3) 
+{
+  /* On Linux, use the /proc/ filesystem to find which files
+     are actually open, rather than iterate over the whole space,
+     for efficiency reasons. If this fails we drop back to the dumb code. */
+#ifdef HAVE_LINUX_NETWORK 
+  DIR *d;
+  
+  if ((d = opendir("/proc/self/fd")))
+    {
+      struct dirent *de;
+
+      while ((de = readdir(d)))
+       {
+         long fd;
+         char *e = NULL;
+         
+         errno = 0;
+         fd = strtol(de->d_name, &e, 10);
+                 
+         if (errno != 0 || !e || *e || fd == dirfd(d) ||
+             fd == STDOUT_FILENO || fd == STDERR_FILENO || fd == STDIN_FILENO ||
+             fd == spare1 || fd == spare2 || fd == spare3)
+           continue;
+         
+         close(fd);
+       }
+      
+      closedir(d);
+      return;
+  }
+#endif
+
+  /* fallback, dumb code. */
+  for (max_fd--; max_fd >= 0; max_fd--)
+    if (max_fd != STDOUT_FILENO && max_fd != STDERR_FILENO && max_fd != STDIN_FILENO &&
+       max_fd != spare1 && max_fd != spare2 && max_fd != spare3)
+      close(max_fd);
+}
+
 /* Basically match a string value against a wildcard pattern.  */
 int wildcard_match(const char* wildcard, const char* match)
 {
@@ -703,3 +786,22 @@ int wildcard_matchn(const char* wildcard, const char* match, int num)
 
   return (!num) || (*wildcard == *match);
 }
+
+#ifdef HAVE_LINUX_NETWORK
+int kernel_version(void)
+{
+  struct utsname utsname;
+  int version;
+  char *split;
+  
+  if (uname(&utsname) < 0)
+    die(_("failed to find kernel version: %s"), NULL, EC_MISC);
+  
+  split = strtok(utsname.release, ".");
+  version = (split ? atoi(split) : 0);
+  split = strtok(NULL, ".");
+  version = version * 256 + (split ? atoi(split) : 0);
+  split = strtok(NULL, ".");
+  return version * 256 + (split ? atoi(split) : 0);
+}
+#endif
index 6f807cf..2a1e2a0 100644 (file)
@@ -1,9 +1,8 @@
-# The root DNSSEC trust anchor, valid as at 10/02/2017
+# The root DNSSEC trust anchor, valid as at 11/01/2019
 
 # Note that this is a DS record (ie a hash of the root Zone Signing Key) 
 # If was downloaded from https://data.iana.org/root-anchors/root-anchors.xml
 
-trust-anchor=.,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5
 trust-anchor=.,20326,8,2,E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D