Compare commits

...
52 Commits
Author SHA1 Message Date
Simon Kelley fc4c4fda05 Fix MAC address enumeration on *BSD. 2013-07-26 15:38:59 +01:00
Simon Kelley ef1a94abaa Advertise lost prefixes with pref_time == 0 for 2 hours. 2013-07-26 13:59:03 +01:00
Simon Kelley d9fb0be8c7 Make --clear-on-reload apply to DBus API too. 2013-07-25 21:47:17 +01:00
Roy Marples 3f3adae6bc DHCP FQDN option tweaks. 2013-07-25 16:22:46 +01:00
Simon Kelley 1ecbaaa382 Tweak parameter lifetimes in Router advertisements. 2013-07-25 14:19:27 +01:00
Kyle Mestery d859ca2f9b Allow hostnames to start with a number. 2013-07-24 13:17:54 +01:00
Simon Kelley b4b9308079 Increase timeout/number of retries in TFTP. 2013-06-19 10:31:23 +01:00
Simon Kelley e2ba0df2d4 Don't BIND DHCP socket if more interfaces may come along later. 2013-05-31 17:04:25 +01:00
Simon Kelley 921360ce62 Add constructor-noauth: keyword 2013-05-31 14:07:22 +01:00
Simon Kelley 429805dbbc Allow constructed ranges from interface address at end of range.
Also make man page on this clearer, as it's been confusing many.
2013-05-31 13:47:26 +01:00
Marcelo Salhab Brogliato 0da5e8979b Log forwarding table overflows. 2013-05-31 11:49:06 +01:00
Simon Kelley baa80ae512 Remove limit in prefix length in --auth-zone. 2013-05-29 16:32:07 +01:00
Simon Kelley 3e8ed78bf1 Fix option parsing for --dhcp-host. 2013-05-29 14:31:33 +01:00
Simon Kelley 48493329d6 Update Debian resolvconf script for dnscrypt-proxy integration. 2013-05-28 14:49:54 +01:00
Simon Kelley 76dd75de77 Fix hang from new interface-name code, when using TCP. 2013-05-23 10:04:25 +01:00
Simon Kelley 63fd27e35f Debian changelog update. 2013-05-20 11:50:33 +01:00
Simon Kelley 115ac3e4d7 Generalise --interface-name to cope with IPv6 addresses. 2013-05-20 11:28:32 +01:00
Simon Kelley cfcad42ff1 Fix failure to start with ENOTSOCK 2013-05-17 11:32:03 +01:00
Simon Kelley 3f2873d42c Handle IPv4 interface-address labels in Linux. 2013-05-14 11:28:47 +01:00
Simon Kelley ab915f837c Only use ourselves as default DNS server for RA if we're doing DNS.
This makes RA the same as DHCP4/6
2013-04-30 10:43:09 +01:00
Simon Kelley ddd9a6b499 replace inet_addr with inet_pton() in src/option.c 2013-04-29 17:00:21 +01:00
Simon Kelley 7abb69b5dc Tighten checks in legal_hostname(). 2013-04-29 10:52:16 +01:00
Simon Kelley d5052fb24f Fix FTBFS in ipset.c with old kernel headers. 2013-04-25 12:44:20 +01:00
Simon Kelley b5a7ff42bb Check length of synth-domain prefix. 2013-04-25 11:03:47 +01:00
Simon Kelley 48fd1c4dd6 Allow option prefix in --synth-domain. 2013-04-25 09:49:38 +01:00
Simon Kelley 2bb73af7d1 Add --synth-domain 2013-04-24 20:35:43 +01:00
Simon Kelley 86e92f9983 --dhcp-match et al now work with BOOTP as well as DHCP. 2013-04-23 11:31:39 +01:00
Simon Kelley 1c10b9de11 Note that dhcp_lease_time and dhcp_release only work for IPv4. 2013-04-23 10:58:35 +01:00
Tomas Hozza a66d36ea11 Manpage typos. 2013-04-22 15:08:07 +01:00
Simon Kelley aa63a21ce0 Fix regression in dhcp_lease_time utility. 2013-04-22 15:01:52 +01:00
Giacomo Tazzari 797a7afba4 Fix crash on SERVFAIL when --conntrack in use. 2013-04-22 13:16:37 +01:00
Simon Kelley 4b5ea12e90 Send TCP DNS messages in one write() call. Stops TCP stream fragmenting.
This is an optimisation, not a bugfix. Thanks to Jim Bos for spotting it.
2013-04-22 10:22:55 +01:00
Simon Kelley 2b6390fdc9 Bump Debian version number. 2013-04-19 10:23:50 +01:00
Simon Kelley bd08ae67f9 Allow option number zero in encapsulated DHCP options. 2013-04-19 10:22:06 +01:00
Dave Reisner 4582c0efe7 Fix wrong size in memset() call.
Thanks to Dave Reisner.
2013-04-18 21:02:41 +01:00
Simon Kelley 834f36fe6d Update French translation. 2013-04-17 13:52:49 +01:00
Simon Kelley 6f130def07 Manpage typos.
Thanks to Gildas Le Nadan.
2013-04-15 14:58:56 +01:00
Simon Kelley 3931a7bd85 FAQ typos.
Thanks to Moritz Warning.
2013-04-15 14:31:52 +01:00
Simon Kelley d9ee9c0872 Better error check on options parsing. 2013-04-12 11:17:55 +01:00
Simon Kelley 0b0a73c1c9 Fix crash on exceeding DHCP lease limit. 2013-04-11 14:07:02 +01:00
Simon Kelley 81925ab73a Manpage typos 2013-04-10 11:43:58 +01:00
Simon Kelley 9de1aa9b7f Fix parsing of IAID>MAXINT in leases file.
Thanks to Christof Meerwald for the bug report.
2013-04-10 11:17:12 +01:00
Simon Kelley 6f9aaa93e9 ->hwaddr_len must be zero always in DHCPv6 leases. 2013-04-10 10:25:26 +01:00
Simon Kelley 7e5664bdbc Fix trivial access of un-initialised memory.
Thanks to sven falpin for finding this.
2013-04-09 22:28:04 +01:00
Simon Kelley 83f28bef6c Manpage typos. 2013-04-03 14:46:46 +01:00
Simon Kelley 96c727fda6 Cope with duplicate dhcp-options with tags (last one wins). 2013-04-02 21:35:41 +01:00
Simon Kelley 49dc570a72 Manpage typo. 2013-04-02 20:27:07 +01:00
Simon Kelley cd1e04a234 Polish translation. 2013-04-02 20:11:48 +01:00
Simon Kelley 27cb314e54 Fix endless loop when dhcp-range goes away. 2013-04-02 20:06:39 +01:00
Simon Kelley 56a1142f03 SO_REUSEPORT may be defined, but not supported. 2013-04-02 17:02:58 +01:00
Simon Kelley 5b37aa8c19 Trivial change: 0->NULL for pointer constant. 2013-04-02 16:32:25 +01:00
Simon Kelley 8ac9787350 Fix lease time calculation when using DHCPv6 relay. 2013-03-30 21:34:19 +00:00
38 changed files with 1915 additions and 805 deletions

No files matched your search

+98
View File
@@ -1,3 +1,88 @@
version 2.67
Fix crash if upstream server returns SERVFAIL when
--conntrack in use. Thanks to Giacomo Tazzari for finding
this and supplying the patch.
Repair regression in 2.64. That release stopped sending
lease-time information in the reply to DHCPINFORM
requests, on the correct grounds that it was a standards
violation. However, this broke the dnsmasq-specific
dhcp_lease_time utility. Now, DHCPINFORM returns
lease-time only if it's specifically requested
(maintaining standards) and the dhcp_lease_time utility
has been taught to ask for it (restoring functionality).
Fix --dhcp-match, --dhcp-vendorclass and --dhcp-userclass
to work with BOOTP and well as DHCP. Thanks to Peter
Korsgaard for spotting the problem.
Add --synth-domain. Thanks to Vishvananda Ishaya for
suggesting this.
Fix failure to compile ipset.c if old kernel headers are
in use. Thanks to Eugene Rudoy for pointing this out.
Handle IPv4 interface-address labels in Linux. These are
often used to emulate the old IP-alias addresses. Before,
using --interface=eth0 would service all the addresses of
eth0, including ones configured as aliases, which appear
in ifconfig as eth0:0. Now, only addresses with the label
eth0 are active. This is not backwards compatible: if you
want to continue to bind the aliases too, you need to add
eg. --interface=eth0:0 to the config.
Fix "failed to set SO_BINDTODEVICE on DHCP socket: Socket
operation on non-socket" error on startup with
configurations which have exactly one --interface option
and do RA but _not_ DHCPv6. Thanks to Trever Adams for the
bug report.
Generalise --interface-name to cope with IPv6 addresses
and multiple addresses per interface per address family.
Fix option parsing for --dhcp-host, which was generating a
spurious error when all seven possible items were
included. Thanks to Zhiqiang Wang for the bug report.
Remove restriction on prefix-length in --auth-zone. Thanks
to Toke Hoiland-Jorgensen for suggesting this.
Log when the maximum number of concurrent DNS queries is
reached. Thanks to Marcelo Salhab Brogliato for the patch.
If wildcards are used in --interface, don't assume that
there will only ever be one available interface for DHCP
just because there is one at start-up. More may appear, so
we can't use SO_BINDTODEVICE. Thanks to Natrio for the bug
report.
Increase timeout/number of retries in TFTP to accomodate
AudioCodes Voice Gateways doing streaming writes to flash.
Thanks to Damian Kaczkowski for spotting the problem.
Allow hostnames to start with a number, as allowed in
RFC-1123. Thanks to Kyle Mestery for the patch.
Fixes to DHCP FQDN option handling: don't terminate FQDN
if domain not known and allow a FQDN option with blank
name to request that a FQDN option is returned in the
reply. Thanks to Roy Marples for the patch.
Make --clear-on-reload apply to setting upstream servers
via DBus too.
When the address which triggered the construction of an
advertised IPv6 prefix disappears, continue to advertise
the prefix for up to 2 hours, with the preferred lifetime
set to zero. This satisfies RFC 6204 4.3 L-13 and makes
things work better if a prefix disappears without being
deprecated first. Thanks to Uwe Schindler for persuasively
arguing for this.
Fix MAC address enumeration on *BSD. Thanks to Brad Smith
for the bug report.
version 2.66
Add the ability to act as an authoritative DNS
server. Dnsmasq can now answer queries from the wider 'net
@@ -52,6 +137,19 @@ version 2.66
Allow a trailing '*' wildcard in all interface-name
configurations. Thanks to Christian Parpart for the patch.
Handle the situation where libc headers define
SO_REUSEPORT, but the kernel in use doesn't, to cope with
the introduction of this option to Linux. Thanks to Rich
Felker for the bug report.
Update Polish translation. Thanks to Jan Psota.
Fix crash if the configured DHCP lease limit is
reached. Regression occurred in 2.61. Thanks to Tsachi for
the bug report.
Update the French translation. Thanks to Gildas le Nadan.
version 2.65
Fix regression which broke forwarding of queries sent via
+2 -2
View File
@@ -22,7 +22,7 @@ A: The high ports that dnsmasq opens are for replies from the upstream
now uses a new, randomly selected, port for each query. The old
default behaviour (use one port allocated by the OS) is available by
setting --query-port=0, and setting the query port to a positive
value is still works. You should think hard and know what you are
value still works. You should think hard and know what you are
doing before using either of these options.
Q: Why doesn't dnsmasq support DNS queries over TCP? Don't the RFC's specify
@@ -112,7 +112,7 @@ A: Resolver code sometime does strange things when given names without
hostname will fix things. (ie "ping myhost" fails, but "ping
myhost." works. The solution is to make sure that all your hosts
have a domain set ("domain" in resolv.conf, or set a domain in
your DHCP server, see below fr Windows XP and Mac OS X).
your DHCP server, see below for Windows XP and Mac OS X).
Any domain will do, but "localnet" is traditional. Now when you
resolve "myhost" the resolver will attempt to look up
"myhost.localnet" so you need to have dnsmasq reply to that name.
+1 -1
View File
@@ -65,7 +65,7 @@ version = -DVERSION='\"`$(top)/bld/get-version $(top)`\"'
objs = cache.o rfc1035.o util.o option.o forward.o network.o \
dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.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
dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o domain.o
hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
dns-protocol.h radv-protocol.h
+1 -1
View File
@@ -8,7 +8,7 @@ LOCAL_SRC_FILES := bpf.c cache.c dbus.c dhcp.c dnsmasq.c \
netlink.c network.c option.c rfc1035.c \
rfc2131.c tftp.c util.c conntrack.c \
dhcp6.c rfc3315.c dhcp-common.c outpacket.c \
radv.c slaac.c auth.c ipset.c
radv.c slaac.c auth.c ipset.c domain.c
LOCAL_MODULE := dnsmasq
+4 -2
View File
@@ -12,9 +12,11 @@ If an error occurs or no lease exists for the given address,
nothing is sent to stdout a message is sent to stderr and a
non-zero error code is returned.
Requires dnsmasq 2.40 or later and may not work with other DHCP servers.
Requires dnsmasq 2.67 or later and may not work with other DHCP servers.
The address argument is a dotted-quad IP addresses and mandatory.
The address argument is a dotted-quad IP addresses and mandatory.
.SH LIMITATIONS
Only works with IPv4 addresses and DHCP leases.
.SH SEE ALSO
.BR dnsmasq (8)
.SH AUTHOR
+8 -1
View File
@@ -20,7 +20,7 @@
nothing is sent to stdout a message is sent to stderr and a
non-zero error code is returned.
Requires dnsmasq 2.40 or later.
This version requires dnsmasq 2.67 or later.
*/
#include <sys/types.h>
@@ -46,6 +46,7 @@
#define OPTION_LEASE_TIME 51
#define OPTION_OVERLOAD 52
#define OPTION_MESSAGE_TYPE 53
#define OPTION_REQUESTED_OPTIONS 55
#define OPTION_END 255
#define DHCPINFORM 8
#define DHCP_SERVER_PORT 67
@@ -167,6 +168,12 @@ int main(int argc, char **argv)
*(p++) = 1;
*(p++) = DHCPINFORM;
/* Explicity request the lease time, it won't be sent otherwise:
this is a dnsmasq extension, not standard. */
*(p++) = OPTION_REQUESTED_OPTIONS;
*(p++) = 1;
*(p++) = OPTION_LEASE_TIME;
*(p++) = OPTION_END;
dest.sin_family = AF_INET;
+2
View File
@@ -27,6 +27,8 @@ for ethernet. This encoding is the one used in dnsmasq lease files.
The client-id is optional. If it is "*" then it treated as being missing.
.SH NOTES
MUST be run as root - will fail otherwise.
.SH LIMITATIONS
Only usable on IPv4 DHCP leases.
.SH SEE ALSO
.BR dnsmasq (8)
.SH AUTHOR
+18
View File
@@ -1,3 +1,21 @@
dnsmasq (2.67-1) unstable; urgency=low
* New upstream.
-- Simon Kelley <simon@thekelleys.org.uk> Tue, 28 May 2013 14:50:22 +0000
dnsmasq (2.66-3) unstable; urgency=low
* Update resolvconf script for dnscrypt-proxy integration. (closes: #709179)
-- Simon Kelley <simon@thekelleys.org.uk> Tue, 28 May 2013 14:39:51 +0000
dnsmasq (2.66-2) unstable; urgency=low
* Fix error on startup with some configs. (closes: #709010)
-- Simon Kelley <simon@thekelleys.org.uk> Mon, 20 May 2013 11:46:11 +0000
dnsmasq (2.66-1) unstable; urgency=low
* New upstream.
+27 -12
View File
@@ -1,16 +1,14 @@
#!/bin/bash
#!/bin/sh
#
# Script to update the resolver list for dnsmasq
#
# N.B. Resolvconf may run us even if dnsmasq is not running.
# If dnsmasq is installed then we go ahead and update
# the resolver list in case dnsmasq is started later.
# N.B. Resolvconf may run us even if dnsmasq is not (yet) running.
# If dnsmasq is installed then we go ahead and update the resolver list
# in case dnsmasq is started later.
#
# Assumption: On entry, PWD contains the resolv.conf-type files
# Assumption: On entry, PWD contains the resolv.conf-type files.
#
# Requires bash because it uses a non-POSIX printf extension.
#
# Licensed under the GNU GPL. See /usr/share/common-licenses/GPL.
# This file is part of the dnsmasq package.
#
set -e
@@ -18,6 +16,8 @@ set -e
RUN_DIR="/var/run/dnsmasq"
RSLVRLIST_FILE="${RUN_DIR}/resolv.conf"
TMP_FILE="${RSLVRLIST_FILE}_new.$$"
MY_RECORD_NAME="lo.dnsmasq"
DNSCRYPT_RECORD_NAME="lo.dnscrypt"
[ -x /usr/sbin/dnsmasq ] || exit 0
[ -x /lib/resolvconf/list-records ] || exit 1
@@ -27,7 +27,7 @@ PATH=/bin:/sbin
report_err() { echo "$0: Error: $*" >&2 ; }
# Stores arguments (minus duplicates) in RSLT, separated by spaces
# Doesn't work properly if an argument itself contain whitespace
# Doesn't work properly if an argument itself contains whitespace
uniquify()
{
RSLT=""
@@ -45,7 +45,22 @@ if [ ! -d "$RUN_DIR" ] && ! mkdir --parents --mode=0755 "$RUN_DIR" ; then
exit 1
fi
RSLVCNFFILES="$(/lib/resolvconf/list-records | sed -e '/^lo.dnsmasq$/d')"
RSLVCNFFILES=""
for F in $(/lib/resolvconf/list-records) ; do
case "$F" in
"$MY_RECORD_NAME")
# Omit
;;
"$DNSCRYPT_RECORD_NAME")
# Dnscrypt, I only have eyes for you
RSLVCNFFILES="$DNSCRYPT_RECORD_NAME"
break
;;
*)
RSLVCNFFILES="${RSLVCNFFILES:+$RSLVCNFFILES }$F"
;;
esac
done
NMSRVRS=""
if [ "$RSLVCNFFILES" ] ; then
@@ -56,8 +71,8 @@ fi
# Dnsmasq uses the mtime of $RSLVRLIST_FILE, with a resolution of one second,
# to detect changes in the file. This means that if a resolvconf update occurs
# within one second of the previous one then dnsmasq may fail to notice the
# more recent change. To work around this problem we sleep here to ensure
# that the new mtime is different.
# more recent change. To work around this problem we sleep one second here
# if necessary in order to ensure that the new mtime is different.
if [ -f "$RSLVRLIST_FILE" ] && [ "$(ls -go --time-style='+%s' "$RSLVRLIST_FILE" | { read p h s t n ; echo "$t" ; })" = "$(date +%s)" ] ; then
sleep 1
fi
+66 -26
View File
@@ -22,7 +22,10 @@ send any desired set of DHCP options, including vendor-encapsulated
options. It includes a secure, read-only,
TFTP server to allow net/PXE boot of DHCP hosts and also supports BOOTP. The PXE support is full featured, and includes a proxy mode which supplies PXE information to clients whilst DHCP address allocation is done by another server.
.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 RA 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.
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
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 uneeded functions to be omitted from the compiled binary.
.SH OPTIONS
@@ -189,7 +192,7 @@ options does not matter and that
options always override the others.
.TP
.B --auth-server=<domain>,<interface>|<ip-address>
Enable DNS authoritative mode for queries arriving at an interface or address. Note that the the interface or 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
or
@@ -335,7 +338,8 @@ by '/', like the --server syntax, eg.
Don't poll /etc/resolv.conf for changes.
.TP
.B --clear-on-reload
Whenever /etc/resolv.conf is re-read, clear the DNS cache.
Whenever /etc/resolv.conf is re-read or the upstream servers are set
via DBus, clear the DNS cache.
This is useful when new nameservers may have different
data than that held in cache.
.TP
@@ -516,6 +520,22 @@ 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.
.TP
.B --synth-domain=<domain>,<address range>[,<prefix>]
Create artificial A/AAAA and PTR records for an address range. The
records use the address, with periods (or colons for IPv6) replaced
with dashes.
An example should make this clearer.
.B --synth-domain=thekelleys.org.uk,192.168.0.0/24,internal-
will result in a query for internal-192-168-0-56.thekelleys.org.uk returning
192.168.0.56 and a reverse query vice versa. The same applies to IPv6,
but IPv6 addresses may start with '::'
but DNS labels may not start with '-' so in this case if no prefix is
configured a zero is added in front of the label. ::1 becomes 0--1.
The address range can be of the form
<ip address>,<ip address> or <ip address>/<netmask>
.TP
.B --add-mac
Add the MAC address of the requestor to DNS queries which are
forwarded upstream. This may be used to DNS filtering by the upstream
@@ -553,13 +573,18 @@ If you use the first DNSSEC mode, validating resolvers in clients,
this option is not required. Dnsmasq always returns all the data
needed for a client to do validation itself.
.TP
.B --auth-zone=<domain>[,<subnet>[,<subnet>.....]]
.B --auth-zone=<domain>[,<subnet>[/<prefix length>][,<subnet>[/<prefix length>].....]]
Define a DNS zone for which dnsmasq acts as authoritative server. Locally defined DNS records which are in the domain
will be served, except that A and AAAA records must be in one of the
specified subnets, or in a subnet corresponding to a contructed DHCP
range. The subnet(s) are also used to define in-addr.arpa and
ipv6.arpa domains which are served for reverse-DNS queries. For IPv4
subnets, the prefix length is limited to the values 8, 16 or 24.
will be served. A and AAAA records must be in one of the
specified subnets, or in a subnet corresponding to a constructed DHCP
range. (This can be overridden with
.B constructor-noauth:
) The subnet(s) are also used to define in-addr.arpa and
ipv6.arpa domains which are served for reverse-DNS queries. If not
specified, the prefix length defaults to 24 for IPv4 and 64 for IPv6.
For IPv4 subnets, the prefix length should be have the value 8, 16 or 24
unless you are familiar with RFC 2317 and have arranged the
in-addr.arpa delegation accordingly.
.TP
.B --auth-soa=<serial>[,<hostmaster>[,<refresh>[,<retry>[,<expiry>]]]]
Specify fields in the SOA record associated with authoritative
@@ -569,12 +594,12 @@ zones. Note that this is optional, all the values are set to sane defaults.
Specify any secondary servers for a zone for which dnsmasq is
authoritative. These servers must be configured to get zone data from
dnsmasq by zone transfer, and answer queries for the same
authoritative zones and dnsmasq.
authoritative zones as dnsmasq.
.TP
.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 wil be
authoritative. If this option is not given, then AXFR requests will be
accepted from any secondary.
.TP
.B --conntrack
@@ -587,9 +612,9 @@ compiled in and the kernel must have conntrack support
included and configured. This option cannot be combined with
--query-port.
.TP
.B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag],]<start-addr>[,<end-addr>][,<mode>][,<netmask>[,<broadcast>]][,<lease time>]
.B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-addr>[,<end-addr>][,<mode>][,<netmask>[,<broadcast>]][,<lease time>]
.TP
.B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag],]<start-IPv6addr>[,<end-IPv6addr>|constuctor:<interface>][,<mode>][,<prefix-len>][,<lease time>]
.B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-IPv6addr>[,<end-IPv6addr>|constructor:<interface>][,<mode>][,<prefix-len>][,<lease time>]
Enable the DHCP server. Addresses will be given out from the range
<start-addr> to <end-addr> and from statically defined addresses given
@@ -625,9 +650,24 @@ IPv6 (only) supports another type of range. In this, the start address and optio
.B constructor:<interface>.
This forms a template which describes how to create ranges, based on the addresses assigned to the interface. For instance
.B --dhcp-range=::1,::4,constructor:eth0
.B --dhcp-range=::1,::400,constructor:eth0
will look for addreses of the form <network>::1 on eth0 and then create a range from <network>::1 to <network>::400. If the interface is assigned more than one network, then the corresponding ranges will be automatically created, and then deprecated and finally removed again as the address is deprecated and then deleted. The interface name may have a final "*" wildcard.
will look for addresses of the form <network>::1 or <network>:400 on
eth0 and then create a range from <network>::1 to <network>::400. If
the interface is assigned more than one network, then the
corresponding ranges will be automatically created, and then
deprecated and finally removed again as the address is deprecated and
then deleted. The interface name may have a final "*" wildcard. Note
that just any address on eth0 will not do: the non-prefix part must be
equal either the start or end address given in the dhcp-range. This is
to prevent prefixes becoming perpetual if the interface
gains a SLAAC address for the prefix when it is advertised by dnsmasq.
There is a variant of the constructor: syntax using the keyword
.B constructor-noauth.
See
.B --auth-zone
for an explanation of this.
The optional
.B set:<tag>
@@ -731,7 +771,7 @@ may contain an IPv4 address or an IPv6 address, or both. IPv6 addresses must be
.B --dhcp-host=laptop,[1234::56]
IPv6 addresses may contain only the host-identifier part:
.B --dhcp-host=laptop,[::56]
in which case thay act as wildcards in constructed dhcp ranges, with
in which case they act as wildcards in constructed dhcp ranges, with
the appropriate network part inserted.
Note that in IPv6 DHCP, the hardware address is not normally
available, so a client must be identified by client-id (called client
@@ -760,7 +800,7 @@ This is
useful when there is another DHCP server on the network which should
be used by some machines.
The set:<tag> contruct sets the tag
The set:<tag> construct sets the tag
whenever this dhcp-host 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
@@ -975,7 +1015,7 @@ agent ID and one provided by a relay agent, the tag is set.
(IPv4 only) A normal DHCP relay agent is only used to forward the initial parts of
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 addding extra information to the DHCP packets, such as
relay agent is adding extra information to the DHCP packets, such as
that used by
.B dhcp-circuitid
and
@@ -992,7 +1032,7 @@ relays at those addresses are affected.
Without a value, set the tag if the client sends a DHCP
option of the given number or name. When a value is given, set the tag only if
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 widcards)
"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
@@ -1005,7 +1045,7 @@ 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.
The special form with vi-encap:<enterpise number> matches against
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
@@ -1033,7 +1073,7 @@ dhcp-host configuration in dnsmasq and the contents of /etc/hosts and
.TP
.B --dhcp-generate-names=tag:<tag>[,tag:<tag>]
(IPv4 only) Generate a name for DHCP clients which do not otherwise have one,
using the MAC address expressed in hex, seperated by dashes. Note that
using the MAC address expressed in hex, separated by dashes. Note that
if a host provides a name, it will be used by preference to this,
unless
.B --dhcp-ignore-names
@@ -1110,7 +1150,7 @@ 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
is ommitted the system will wait for user input if there are multiple
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
@@ -1409,7 +1449,7 @@ In the default mode, dnsmasq inserts the unqualified names of
DHCP clients into the DNS. For this reason, the names must be unique,
even if two clients which have the same name are in different
domains. If a second DHCP client appears which has the same name as an
existing client, the name is transfered to the new client. If
existing client, the name is transferred to the new client. If
.B --dhcp-fqdn
is set, this behaviour changes: the unqualified name is no longer
put in the DNS, only the qualified name. Two DHCP clients with the
@@ -1663,7 +1703,7 @@ used to allocate the address, one from any matching
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 includes one or more tag:<tag> contructs
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
@@ -1721,7 +1761,7 @@ 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
increasing complexity. Prerequisites for all of these scenarios
are a globally accesible IP address, an A or AAAA record pointing to that address,
are a globally accessible IP address, an A or AAAA record pointing to that address,
and an external DNS server capable of doing delegation of the zone in
question. For the first part of this explanation, we will call the A (or AAAA) record
for the globally accessible address server.example.com, and the zone
@@ -1781,7 +1821,7 @@ entry or
If the external address is dynamic, the address
associated with our.zone.com must be derived from the address of the
relvant interface. This is done using
relevant interface. This is done using
.B interface-name
Something like:
+294 -19
View File
@@ -6,24 +6,40 @@ Dnsmasq \- Un serveur DHCP et cache DNS poids-plume.
.I [OPTION]...
.SH "DESCRIPTION"
.BR dnsmasq
est un serveur DHCP et DNS à faible empreinte mémoire. Il offre à la fois les
services DNS et DHCP pour un réseau local (LAN).
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
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
globaux soient tout de même résolus, et assure également la résolution de nom
pour les hôtes présents dans le service DHCP.
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
réseaux multiples. Il envoie par défaut un jeu raisonnable de paramètres DHCP, et
peut être configuré pour envoyer n'importe quel option DHCP.
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 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.
.PP
Dnsmasq supporte IPv6 et contient un démon minimaliste capable de faire des
annonces routeurs ("router-advertisements").
Le serveur DHCPv6 de dnsmasq possède non seulement les mêmes fonctionalité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
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
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
Notes : Il est possible d'utiliser des options sans leur donner de paramètre.
Dans ce cas, la fonction correspondante sera désactivée. Par exemple
@@ -76,9 +92,16 @@ l'absence d'enregistrement SOA.
.TP
.B --max-ttl=<durée>
Définie la valeur de TTL maximum qui sera fournie aux clients. La valeur maximum
de TTL spécifiée sera fournie aux clients en remplacement de la vraie valeur de TTL
si cette dernière est supérieure. La valeur réelle de TTL est cependant conservée dans
le cache afin d'éviter de saturer les serveurs DNS en amont.
de TTL spécifiée sera fournie aux clients en remplacement de la vraie valeur de
TTL si cette dernière est supérieure. La valeur réelle de TTL est cependant
conservée dans le cache afin d'éviter de saturer les serveurs DNS en amont.
.TP
.B --max-cache-ttl=<durée>
Définie la valeur de TTL maximum pour les entrées dans le cache
.TP
.B --auth-ttl=<durée>
Définie la valeur de TTL retournée pour les réponses du serveur faisant
autorité.
.TP
.B \-k, --keep-in-foreground
Ne pas aller en tâche de fond au lancement, mais en dehors de cela, fonctionner
@@ -90,7 +113,10 @@ Mode debug (déverminage) : ne pas aller en tâche de fond, ne pas écrire de
fichier pid, ne pas changer d'identifiant utilisateur, générer un état complet
du cache lors de la réception d'un signal SIGUSR1, envoyer les logs sur la
sortie standard d'erreur ("stderr") de même que dans le syslog, ne pas créer de
processus fils pour traiter les requêtes TCP.
processus fils pour traiter les requêtes TCP. A noter que cette option est à
user pour du déverminage seulement : pour empêcher dnsmasq se fonctionner en
mode démon en production, utiliser
.B -k.
.TP
.B \-q, --log-queries
Enregistrer les résultats des requêtes DNS traitées par Dnsmasq dans un fichier
@@ -185,7 +211,11 @@ ni
.B \--except-interface.
Utiliser l'option
.B --listen-address
à la place.
à la place. Un simple joker, consistant d'un '*' final, peut-être utilisé dans
les options
.B \--interface
et
.B \--except-interface
.TP
.B \-I, --except-interface=<interface name>
Ne pas écouter sur l'interface spécifiée. Notez que l'ordre dans lesquelles les
@@ -198,6 +228,21 @@ et
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>
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
.B --interface
ni dans
.B --listen-address
En effet,
.B --auth-server
va passer outre ceux-ci et fournir un service DNS différent sur l'interface
spécifiée. La valeur de <domaine> est l'enregistrement de type "colle"
("glue record"). Il doit correspondre dans le service DNS global avec un
enregistrement de type A et/ou AAAA pointant sur l'adresse sur laquelle dnsmasq
écoute pour le mode DNS faisant autorité.
.TP
.B \-2, --no-dhcp-interface=<nom d'interface>
Ne pas fournir de service DHCP sur l'interface spécifiée, mais fournir tout de
@@ -312,11 +357,14 @@ Ne pas lire le contenu du fichier /etc/resolv.conf. N'obtenir l'adresse des
serveurs de nom amont que depuis la ligne de commande ou le fichier de
configuration de Dnsmasq.
.TP
.B \-1, --enable-dbus
.B \-1, --enable-dbus[=<nom de service>]
Autoriser la mise à jour de la configuration de Dnsmasq par le biais d'appel de
méthodes DBus. Il est possible par ce biais de mettre à jour l'adresse de
serveurs DNS amont (et les domaines correspondants) et de vider le cache. Cette
option nécessite que Dnsmasq soit compilé avec le support DBus.
option nécessite que Dnsmasq soit compilé avec le support DBus. Si un nom de
service est fourni, dnsmasq fourni un service à ce nom, plutôt qu'avec la
valeur par défaut :
.B uk.org.thekelleys.dnsmasq
.TP
.B \-o, --strict-order
Par défaut, Dnsmasq envoie les requêtes à n'importe lequel des serveurs amonts
@@ -455,6 +503,12 @@ n'ayant de réponse ni dans /etc/hosts, ni dans les baux DHCP, et n'étant pas
transmise à un serveur spécifique par le biais d'une directive
.B --server.
.TP
.B --ipset=/<domaine>/[domaine/]<ipset>[,<ipset>]
Obtient les adresses IP des domaines spécifiés et les place dans les groupes
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>]
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
@@ -611,6 +665,34 @@ Si vous utilisez le premier mode DNSSEC, la validation par le resolveur 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
.B --auth-zone=<domaine>[,<sous-réseau>[,<sous-réseau>.....]]
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, à ceci près que les enregistrements A et AAAA doivent
se situer dans l'un des sous-réseaux précisés si ceux-ci sont définis, ou dans
un réseau correspondant à une plage DHCP. Le ou les sous-réseaux sont également
utilisé pour définir les domaines in-addr.arpa et ipv6.arpa servant à
l'interrogation DNS inverse. Dans le cas d'IPv4, la longueur du masque de
réseau doit être de 8, 16 ou 24.
.TP
.B --auth-soa=<numéro de série>[,<mainteneur de zone (hostmaster)>[,<rafraichissement>[,<nombre de réessais>[,<expiration>]]]]
Spécifie les champs de l'enregistrement de type SOA (Start Of Authority)
associé à une zone pour laquelle le serveur fait autorité. A noter que cela est
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
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é.
.TP
.B --auth-peer=<adresse IP>[,<adresse IP>[,<adresse IP>...]]
Spécifie la ou les adresses de serveurs secondaires autorisés à initier des
requêtes de transfert de zone (AXFR) pour les zones pour lesquelles
dnsmasq fait autorité. Si cette option n'est pas fournie, les requêtes AXFR
seront acceptées pour tous les serveurs secondaires.
.TP
.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
@@ -623,7 +705,8 @@ 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>][,<mode>][,<longueur de préfixe>][,<durée de bail>]
.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>]
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
statiquement dans l'option
@@ -663,6 +746,22 @@ d'IPv4, la longueur de préfixe n'est pas automatiquement déduite de la
configuration de l'interface. La taille minimale pour la longueur de préfixe
est 64.
Pour IPv6 (et IPv6 uniquement), il est possible de définir les plages d'une
autre façon. Dans ce cas, l'adresse de départ et l'adresse de fin optionnelle
contiennent uniquement la partie réseau (par exemple ::1) et sont suivies par
.B constructor:<interface>.
Cela forme un modèle décrivant comment construire la plage, à partir des
adresses assignées à l'interface. Par exemple
.B --dhcp-range=::1,::400,constructor:eth0
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
supprimée. Le nom de l'interface peut être spécifié avec un caractère joker '*'
final.
L'identifiant de label optionnel
.B set:<label>
fournie une étiquette alphanumérique qui identifie ce réseau, afin de permettre
@@ -677,7 +776,13 @@ Le mot clef optionnel <mode> peut être égal à
spécifié, mais de ne pas activer l'allocation dynamique d'adresses IP : Seuls
les hôtes possédant des adresses IP statiques fournies via
.B dhcp-host
ou présentes dans le fichier /etc/ethers seront alors servis par le DHCP.
ou présentes dans le fichier /etc/ethers seront alors servis par le DHCP. Il est
possible d'activer un mode "fourre-tout" en définissant un réseau statique
comportant uniquement des zéros, c'est à dire :
.B --dhcp=range=::,static
Cela permet de retourner des réponses à tous les paquets de type
Information-request (requête d'information) en mode DHCPv6 sans état sur le
sous-réseau configuré.
Pour IPv4, le <mode> peut est égal à
.B proxy
@@ -762,6 +867,10 @@ Un seul
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 :
.B --dhcp-host=laptop,[1234::56]
Les adresses IPv6 peuvent ne contenir que la partie identifiant de client :
.B --dhcp-host=laptop,[::56]
Dans ce cas, lorsque des plages dhcp sont définies automatiquement par le biais
de constructeurs, la partie réseau correspondante est rajoutée à l'adresse.
A noter que pour le DHCP IPv6, l'adresse matérielle n'est en principe pas
disponible, aussi un client doit-être identifié par un identifiant de client
(appellé "DUID client") ou un nom d'hôte.
@@ -1204,14 +1313,16 @@ créant des milliers de baux et utilisant beaucoup de mémoire dans le processus
Dnsmasq.
.TP
.B \-K, --dhcp-authoritative
(IPv4 seulement) Cette option doit être donnée lorsque Dnsmasq est le seul
serveur DHCP sur le réseau. Cela change le comportement par défaut qui est
Doit être spécifié lorsque dnsmasq est réellement le seul serveur DHCP
sur le réseau. Pour DHCPv4, cela change le comportement par défaut qui est
celui d'un strict respect des RFC, afin que les requêtes DHCP pour des baux
inconnus par des hôtes inconnus ne soient pas ignorées. Cela permet à de
nouveaux hôtes d'obtenir des baux sans tenir compte de fastidieuses
temporisations ("timeout"). Cela permet également à Dnsmasq de reconstruire
sa base de données contenant les baux sans que les clients n'aient besoin de
redemander un bail, si celle-ci est perdue.
Dans le cas de DHCPv6, cela positionne la priorité des réponses à 255 (le
maximum) au lieu de 0 (le minimum).
.TP
.B --dhcp-alternate-port[=<port serveur>[,<port client>]]
(IPv4 seulement) Change les ports utilisés par défaut pour le DHCP. Si cette
@@ -1319,6 +1430,9 @@ Pour IPv4 seulement :
DNSMASQ_CLIENT_ID, si l'hôte a fourni un identifiant de client.
DNSMASQ_CIRCUIT_ID, DNSMASQ_SUBSCRIBER_ID, DNSMASQ_REMOTE_ID si un relai DHCP a
rajouté l'une de ces options.
Si le client fournit une information de classe de vendeur, DNSMASQ_VENDOR_CLASS.
Pour IPv6 seulement :
@@ -1847,6 +1961,167 @@ supprime la nécessité des associations statiques). Le paramètre
que le label "bootp", permettant un certain contrôle sur les options retournées
aux différentes classes d'hôtes.
.SH CONFIGURATION EN TEMPS QUE SERVEUR FAISANT AUTORITÉ
.PP
Configurer dnsmasq pour agir en temps que serveur DNS faisant autorité est
compliqué par le fait que cela implique la configuration de serveurs DNS
externes pour mettre en place la délégation. Seront présentés ci-dessous trois
scénarios de complexité croissante. Le pré-requis pour chacun de ces scénarios
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
l'enregistrement A (ou AAAA) de l'adresse globalement accessible, et
notre.zone.com la zone pour laquelle dnsmasq fait autorité.
La configuration la plus simple consiste en deux lignes de configuration,
sous la forme :
.nf
.B auth-server=serveur.exemple.com,eth0
.B auth-zone=notre.zone.com,1.2.3.0/24
.fi
ainsi que deux enregistrements dans le DNS externe :
.nf
serveur.exemple.com A 192.0.43.10
notre.zone.com NS serveur.exemple.com
.fi
eth0 est l'interface réseau externe sur laquelle dnsmasq écoute, dont l'adresse
IP (globalement accessible) est 192.0.43.10.
A noter que l'adresse IP externe peut parfaitement être dynamique (par exemple
attribuée par un FAI via DHCP ou PPP). Dans ce cas, l'enregistrement de type A
doit être lié à cet enregistrement dynamique par l'une ou l'autre des techniques
habituelles de système DNS dynamique.
Un exemple plus complexe mais en pratique plus utile correspond au cas où
l'adresse IP globalement accessible se trouve dans la zone pour laquelle
dnsmasq fait autorité, le plus souvent à la racine. Dans ce cas nous avons :
.nf
.B auth-server=notre.zone.com,eth0
.B auth-zone=notre.zone.com,1.2.3.0/24
.fi
.nf
notre.zone.com A 1.2.3.4
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
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
le biais d'une entrée dans
.B /etc/hosts
ou via un
.B --host-record.
.nf
.B auth-server=notre.zone.com,eth0
.B host-record=notre.zone.com,1.2.3.4
.B auth-zone=notre.zone.com,1.2.3.0/24
.fi
Si l'adresse externe est dynamique, l'adresse associée à notre.zone.com doit
être dérivée de l'interface correspondante. Cela peut être fait en utilisant
.B interface-name
Sous la forme :
.nf
.B auth-server=notre.zone.com,eth0
.B interface-name=notre.zone.com,eth0
.B auth-zone=notre.zone.com,1.2.3.0/24
.fi
La configuration finale rajoute à cette base un serveur DNS secondaire. Il
s'agit d'un autre serveur DNS qui apprend les données DNS de la zone en
effectuant un transfert de zone, et qui joue le rôle de serveur de secours
au cas où le serveur principal devenait inaccessible. La configuration
de ce serveur secondaire sort du cadre de cette page de manuel. Les éléments
de configuration à rajouter dans dnsmasq sont les simples :
.nf
.B auth-sec-servers=secondaire.monfai.com
.fi
et
.nf
notre.zone.com NS secondaire.monfai.com
.fi
L'addition d'une option auth-sec-servers active les transferts de zone dans
dnsmasq, ce qui permet au serveur secondaire de venir collecter les données
DNS. Si vous souhaitez restreindre l'accès à ces données à des hôtes
spécifiques, vous pouvez le faire via :
.nf
.B auth-peer=<adresse IP du serveur secondaire>
.fi
Dnsmasq joue le rôle de serveur faisant autorité pour les domaines in-addr.arpa
et ipv6.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
adéquat. Par exemple, comme nous définissons plus haut les adresses
1.2.3.0/24 :
.nf
3.2.1.in-addr.arpa NS notre.zone.com
.fi
Veuillez noter que pour l'instant, les zones inverses ne sont pas
disponibles dans les transferts de zone, donc il est inutile de configurer
de serveur secondaire pour la résolution inverse.
.PP
Lorsque dnsmasq est configuré en temps que serveur faisant autorité,
les données suivantes sont utilisées pour peupler la zone considérée :
.PP
.B --mx-host, --srv-host, --dns-rr, --txt-record, --naptr-record
, pour autant que les noms des enregistrements se trouvent dans la zone en
question.
.PP
.B --cname
pour peu que le nom soit dans le domaine. Si la cible du CNAME n'est
pas pleinement qualifiée, alors elle est qualifiée avec le nom de la
zone pour laquelle le serveur fait autorité.
.PP
Les adresses IPv4 et IPv6 extraites de /etc/hosts (et
.B --addn-hosts
) ainsi que les options
.B --host-record
fournissant des adresses situées dans l'un des sous-réseaux spécifiés dans
.B --auth-zone.
.PP
Adresses spécifiées par
.B --interface-name.
Dans ce cas, l'adresse n'est pas limitée à l'un des sous-réseaux donné dans
.B --auth-zone.
.PP
Les adresses de baux DHCP, si l'adresse est située dans l'un des sous-réseaux de
.B --auth-zone
OU dans une plage DHCP construite. Dans le mode par défaut, où le bail
DHCP a un nom non qualifié, et éventuellement pour un nom qualifié construit
via
.B --domain
, alors le nom dans la zone faisant autorité est construit à partir du nom
non qualifié et du nom de domaine de la zone. Cela peut on non être égal
celui fourni par
.B --domain.
Si l'option
.B --dhcp-fqdn
est fournie, alors les noms pleinemenet qualifiés associés aux baux DHCP
sont utilisés, dès lors qu'ils correspondent au nom de domaine associé
à la zone.
.SH CODES DE SORTIE
.PP
0 - Dnsmasq s'est correctement lancé en tâche de fond, ou alors s'est
+70 -85
View File
@@ -4,10 +4,10 @@
# Translation completed by Gildas Le Nadan <3ntr0p13@gmail.com>
msgid ""
msgstr ""
"Project-Id-Version: dnsmasq 2.56\n"
"Project-Id-Version: dnsmasq 2.66\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-06-18 12:24+0100\n"
"PO-Revision-Date: 2012-03-02 16:26+0100\n"
"PO-Revision-Date: 2013-03-26 21:12+1100\n"
"Last-Translator: Gildas Le Nadan <3ntr0p13@gmail.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-1\n"
@@ -479,7 +479,7 @@ msgstr "D
#: option.c:373
msgid "Convert TFTP filenames to lowercase"
msgstr ""
msgstr "Convertis les noms de fichiers TFTP en minuscule"
#: option.c:374
msgid "Ephemeral port range for use by TFTP transfers."
@@ -582,54 +582,51 @@ msgstr "envoyer des annonces de routeurs pour toutes les interfaces faisant du D
#: option.c:398
msgid "Specify DUID_EN-type DHCPv6 server DUID"
msgstr ""
msgstr "Spécifie pour le serveur DHCPv6 un identifiant unique DHCP (DUID) basé sur un numéro unique de vendeur (DUID_EN)"
#: option.c:399
#, fuzzy
msgid "Specify host (A/AAAA and PTR) records"
msgstr "Spécifie un champ MX."
msgstr "Spécifie les enregistrements (A/AAAA et PTR) d'un hôte."
#: option.c:400
#, fuzzy
msgid "Specify arbitrary DNS resource record"
msgstr "Spécifie un champ DNS TXT"
msgstr "Définie une resource DNS d'un type spécifique"
#: option.c:401
#, fuzzy
msgid "Bind to interfaces in use - check for new interfaces"
msgstr "interface %s inconnue spécifiée comme interface de pont"
msgstr "Se lie aux interfaces préexistantes - vérifie l'apparition de nouvelles interfaces"
#: option.c:402
msgid "Export local names to global DNS"
msgstr ""
msgstr "Exporte les noms locaux dans le DNS global"
#: option.c:403
msgid "Domain to export to global DNS"
msgstr ""
msgstr "Domaine à exporter dans le DNS global"
#: option.c:404
msgid "Set TTL for authoritative replies"
msgstr ""
msgstr "Configure la durée de vie (Time To Live) pour les réponses faisant autorité"
#: option.c:405
msgid "Set authoritive zone information"
msgstr ""
msgstr "Configure les informations pour une zone de nom faisant autorité"
#: option.c:406
msgid "Secondary authoritative nameservers for forward domains"
msgstr ""
msgstr "Serveurs de noms secondaires faisant autorité pour les domaines délégués"
#: option.c:407
msgid "Peers which are allowed to do zone transfer"
msgstr ""
msgstr "Pairs autorisés à faire des transferts de zone"
#: option.c:408
msgid "Specify ipsets to which matching domains should be added"
msgstr ""
msgstr "Spécifie les ipsets auxquels les domaines correspondants doivent-être ajoutés"
#: option.c:410
msgid "Specify DHCPv6 prefix class"
msgstr ""
msgstr "Spécifie le préfixe de classe DHCPv6"
#: option.c:596
#, c-format
@@ -665,9 +662,8 @@ msgstr "nom d'interface invalide"
#
#: option.c:720
#, fuzzy
msgid "bad address"
msgstr "mauvaise adresse IP"
msgstr "mauvaise adresse"
#: option.c:847
msgid "unsupported encapsulation for IPv6 option"
@@ -750,14 +746,12 @@ 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:1631
#, fuzzy
msgid "bad prefix"
msgstr "numéro de port incorrect"
msgstr "mauvais préfixe"
#: option.c:2043
#, fuzzy
msgid "recompile with HAVE_IPSET defined to enable ipset directives"
msgstr "recompiler en définissant HAVE_LUASCRIPT pour permettre l'exécution de scripts LUA au changement de bail (lease-change)"
msgstr "recompiler en définissant HAVE_IPSET pour permettre l'utilisation de directives de groupes d'IP (IPset)"
#
#: option.c:2223
@@ -781,17 +775,16 @@ msgid "inconsistent DHCP range"
msgstr "plage d'adresses DHCP incohérente"
#: option.c:2402
#, fuzzy
msgid "prefix must be exactly 64 for RA subnets"
msgstr "la valeur de préfixe doit être au minimum 64"
msgstr "la taille du préfixe doit être exactement 64 pour les sous-réseaux d'annonces de routeurs (RA)"
#: option.c:2404
msgid "prefix must be exactly 64 for subnet constructors"
msgstr ""
msgstr "la taille du préfixe doit être exactement 64 pour le constructeur de sous-réseaux"
#: option.c:2407
msgid "prefix must be at least 64"
msgstr "la valeur de préfixe doit être au minimum 64"
msgstr "la taille de préfixe doit être au minimum 64"
#: option.c:2412
msgid "inconsistent DHCPv6 range"
@@ -806,9 +799,9 @@ msgid "cannot match tags in --dhcp-host"
msgstr "L'utilisation de labels est prohibée dans --dhcp-host"
#: option.c:2589
#, fuzzy, c-format
#, c-format
msgid "duplicate dhcp-host IP address %s"
msgstr "adresse IP %s dupliquée dans %s."
msgstr "adresse IP dhcp-host dupliquée dans %s."
#
#: option.c:2645
@@ -830,7 +823,7 @@ msgstr "adresse dhcp-proxy incorrecte"
#: option.c:3124
msgid "bad DUID"
msgstr ""
msgstr "mauvais identifiant unique DHCP (DUID)"
#
#: option.c:3166
@@ -857,9 +850,8 @@ msgstr "mauvais champ NAPTR"
#
#: option.c:3295
#, fuzzy
msgid "bad RR record"
msgstr "mauvais champ PTR"
msgstr "mauvais enregistrement RR"
#: option.c:3324
msgid "bad TXT record"
@@ -883,14 +875,12 @@ msgstr "poids invalide"
#
#: option.c:3417
#, fuzzy
msgid "Bad host-record"
msgstr "mauvais champ PTR"
msgstr "mauvais champ host-record"
#: option.c:3434
#, fuzzy
msgid "Bad name in host-record"
msgstr "mauvais nom dans %s"
msgstr "mauvais nom dans le champ host-record"
#: option.c:3464
msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DBus support)"
@@ -917,9 +907,9 @@ msgid "error"
msgstr "erreur"
#: option.c:3592
#, fuzzy, c-format
#, c-format
msgid " at line %d of %s"
msgstr "%s à la ligne %d de %%s"
msgstr "à la ligne %d de %s"
#: option.c:3656 tftp.c:648
#, c-format
@@ -1029,9 +1019,9 @@ msgid "failed to create listening socket for %s: %s"
msgstr "impossible de créer une socket d'écoute pour %s : %s"
#: network.c:743
#, fuzzy, c-format
#, c-format
msgid "interface %s failed to join DHCPv6 multicast group: %s"
msgstr "impossible de rejoindre le groupe de multicast DHCPv6 : %s"
msgstr "impossible de faire rejoindre l'interface %s dans le groupe multicast DHCPv6 %s"
#: network.c:937
#, c-format
@@ -1112,21 +1102,20 @@ msgid "asychronous logging is not available under Android"
msgstr "l'écriture de traces en mode asynchrone n'est pas disponible sous Android."
#: dnsmasq.c:154
#, fuzzy
msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
msgstr "DBus n'est pas disponible : activez HAVE_DBUS dans src/config.h"
msgstr "le mode « autorité DNS » n'est pas disponible : activez HAVE_AUTH dans src/config.h"
#: dnsmasq.c:164
msgid "zone serial must be configured in --auth-soa"
msgstr ""
msgstr "le numéro de série de la zone doit être configuré dans --auth-soa"
#: dnsmasq.c:186
msgid "dhcp-range constructor not available on this platform"
msgstr ""
msgstr "le constructeur de plage dhcp n'est pas disponible sur cette plate-forme"
#: dnsmasq.c:225
msgid "cannot set --bind-interfaces and --bind-dynamic"
msgstr ""
msgstr "--bind-interfaces et --bind-dynamic sont mutuellement exclusives"
#: dnsmasq.c:229
#, c-format
@@ -1283,7 +1272,7 @@ msgstr "impossible de charger le script Lua : %s"
#: dnsmasq.c:1031
#, c-format
msgid "TFTP directory %s inaccessible: %s"
msgstr ""
msgstr "répertoire TFTP %s inaccessible : %s"
#: dnsmasq.c:1095
#, c-format
@@ -1655,9 +1644,9 @@ msgid "cannot create DHCPv6 socket: %s"
msgstr "ne peut créer la socket DHCPv6: %s"
#: dhcp6.c:62
#, fuzzy, c-format
#, c-format
msgid "failed to set SO_REUSE{ADDR|PORT} on DHCPv6 socket: %s"
msgstr "impossible de déclarer SO_REUSE{ADDR|PORT} sur la socket DHCP : %s"
msgstr "impossible de déclarer SO_REUSE{ADDR|PORT} sur la socket DHCPv6 : %s"
#: dhcp6.c:74
#, c-format
@@ -1680,58 +1669,54 @@ msgid "%u available DHCPv6 subnet: %s/%d"
msgstr "%u sous-réseaux DHCPv6 disponibles : %s/%d"
#: rfc3315.c:350
#, fuzzy, c-format
#, c-format
msgid "%u vendor class: %u"
msgstr "%u Classe de vendeur ('Vendor Class') : %s"
msgstr "%u Classe de vendeur ('Vendor Class') : %u"
#: rfc3315.c:609
#, fuzzy, c-format
#, c-format
msgid "unknown prefix-class %d"
msgstr "bail inconnu"
msgstr "préfixe de classe inconnu %d"
#: rfc3315.c:741 rfc3315.c:854
msgid "success"
msgstr ""
msgstr "réussi"
#: rfc3315.c:756 rfc3315.c:758 rfc3315.c:862 rfc3315.c:864
#, fuzzy
msgid "no addresses available"
msgstr "pas d'adresse disponible"
#: rfc3315.c:806
#, fuzzy
msgid "address unavailable"
msgstr "adresse non disponible"
#: rfc3315.c:841
msgid "not on link"
msgstr ""
msgstr "pas sur ce lien"
#: rfc3315.c:915 rfc3315.c:1073 rfc3315.c:1150
msgid "no binding found"
msgstr ""
msgstr "aucune liaison trouvée"
#: rfc3315.c:948
msgid "deprecated"
msgstr ""
msgstr "obsolète"
#: rfc3315.c:951
#, fuzzy
msgid "address invalid"
msgstr "adresse déjà utilisée"
msgstr "adresse non valide"
#: rfc3315.c:992
msgid "confirm failed"
msgstr ""
msgstr "confirmation d'échec"
#: rfc3315.c:1003
#, fuzzy
msgid "all addresses still on link"
msgstr "mauvaise adresse dans %s ligne %d"
msgstr "toutes les adresses sont toujours sur le lien"
#: rfc3315.c:1082
msgid "release received"
msgstr ""
msgstr "libération reçue"
#: dhcp-common.c:145
#, c-format
@@ -1754,9 +1739,9 @@ 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:367
#, fuzzy, c-format
#, c-format
msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
msgstr "impossible de déclarer SO_REUSE{ADDR|PORT} sur la socket DHCP : %s"
msgstr "impossible de déclarer SO_BINDTODEVICE sur la socket DHCP : %s"
#: dhcp-common.c:489
#, c-format
@@ -1770,42 +1755,42 @@ msgstr "Options DHCPv6 connues :\n"
#: dhcp-common.c:693
msgid ", prefix deprecated"
msgstr ""
msgstr ", préfixe obsolète"
#: dhcp-common.c:696
#, c-format
msgid ", lease time "
msgstr ""
msgstr ", durée de bail "
#: dhcp-common.c:727
#, c-format
msgid "%s stateless on %s%.0s%.0s%s"
msgstr ""
msgstr "%s sans état (stateless) sur %s%.0s%.0s%s"
#: dhcp-common.c:729
#, fuzzy, c-format
#, c-format
msgid "%s, static leases only on %.0s%s%s%.0s"
msgstr "baux statiques DHCP seulement sur %.0s%s, durée de validité de bail %s"
msgstr "%s, baux statiques seulement sur %.0s%s%s%.0s"
#: dhcp-common.c:731
#, fuzzy, c-format
#, c-format
msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
msgstr "DHCP, proxy sur le sous-réseau %.0s%s%.0s"
msgstr "%s, proxy sur le sous-réseau %.0s%s%.0s"
#: dhcp-common.c:732
#, fuzzy, c-format
#, c-format
msgid "%s, IP range %s -- %s%s%.0s"
msgstr "DHCP, plage d'adresses %s -- %s, durée de bail %s"
msgstr "%s, plage d'adresses IP %s -- %s%s%.0s"
#: dhcp-common.c:739
#, c-format
msgid "DHCPv4-derived IPv6 names on %s%s"
msgstr ""
msgstr "noms IPv6 dérivés de DHCPv4 sur %s%s"
#: dhcp-common.c:742
#, fuzzy, c-format
#, c-format
msgid "router advertisement on %s%s"
msgstr "annonces de routeurs seulement sur %.0s%s, durée de validité %s"
msgstr "annonces de routeurs sur %s%s"
#: radv.c:87
#, c-format
@@ -1813,19 +1798,19 @@ msgid "cannot create ICMPv6 socket: %s"
msgstr "ne peut créer la socket ICMPv6: %s"
#: auth.c:402
#, fuzzy, c-format
#, c-format
msgid "ignoring zone transfer request from %s"
msgstr "requête de %s non supportée"
msgstr "la requête de transfert de zone en provenance de %s est ignorée"
#: ipset.c:71
#, fuzzy, c-format
#, c-format
msgid "failed to find kernel version: %s"
msgstr "impossible de lier la socket serveur DHCP : %s"
msgstr "impossible de trouver la version de noyau : %s"
#: ipset.c:90
#, fuzzy, c-format
#, c-format
msgid "failed to create IPset control socket: %s"
msgstr "impossible de créer une socket TFTP : %s"
msgstr "impossible de créer une socket de contrôle IPset : %s"
#~ msgid "no interface with address %s"
#~ msgstr "pas d'interface avec l'adresse %s"
+70 -84
View File
@@ -3,14 +3,14 @@
# This file is put in the public domain.
#
# Tomasz Sochański <nerdhero@gmail.com>, 2005.
# Jan Psota <jasiupsota@gmail.com>, 2008, 2009, 2010, 2011.
# Jan Psota <jasiupsota@gmail.com>, 2008, 2009, 2010, 2011, 2013.
#
msgid ""
msgstr ""
"Project-Id-Version: pl\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-06-10 20:57+0100\n"
"PO-Revision-Date: 2012-03-04 01:45+0100\n"
"PO-Revision-Date: 2013-04-02 01:44+0200\n"
"Last-Translator: Jan Psota <jasiupsota@gmail.com>\n"
"Language-Team: polski <>\n"
"Language: \n"
@@ -475,7 +475,7 @@ msgstr "Wyłączenie możliwości negocjowania wielkości bloku dla przesyłów
#: option.c:373
msgid "Convert TFTP filenames to lowercase"
msgstr ""
msgstr "Konwertowanie nazw plików żądanych przez TFTP do małych liter"
#: option.c:374
msgid "Ephemeral port range for use by TFTP transfers."
@@ -575,54 +575,51 @@ msgstr "Załączenie anonsowania (RA) na interfejsach serwujących DHCPv6"
#: option.c:398
msgid "Specify DUID_EN-type DHCPv6 server DUID"
msgstr ""
msgstr "Określenie DHCPv6 DUID"
#: option.c:399
#, fuzzy
msgid "Specify host (A/AAAA and PTR) records"
msgstr "Specyfikacja rekordu MX."
msgstr "Określenie rekordów A/AAAA i PTR"
#: option.c:400
#, fuzzy
msgid "Specify arbitrary DNS resource record"
msgstr "Specyfikacja rekordu DNS TXT."
msgstr "Określenie rekordu TXT"
#: option.c:401
#, fuzzy
msgid "Bind to interfaces in use - check for new interfaces"
msgstr "nieznany interfejs %s w bridge-u"
msgstr "Dynamiczne podpinanie do interfejsów sieciowych"
#: option.c:402
msgid "Export local names to global DNS"
msgstr ""
msgstr "Eksportowanie lokalnych nazw hostów do globalnego DNS-a"
#: option.c:403
msgid "Domain to export to global DNS"
msgstr ""
msgstr "Domena pod którą będą eksportowane lokalne nazwy"
#: option.c:404
msgid "Set TTL for authoritative replies"
msgstr ""
msgstr "Określenie TTL dla odpowiedzi autorytatywnych"
#: option.c:405
msgid "Set authoritive zone information"
msgstr ""
msgstr "Określenie danych strefy autorytatywnej (SOA)"
#: option.c:406
msgid "Secondary authoritative nameservers for forward domains"
msgstr ""
msgstr "Pomocnicze serwery autorytatywne dla forwardowanych domen"
#: option.c:407
msgid "Peers which are allowed to do zone transfer"
msgstr ""
msgstr "Wskazanie serwerów uprawnionych do transferu stref"
#: option.c:408
msgid "Specify ipsets to which matching domains should be added"
msgstr ""
msgstr "Wyszczególnienie ipset-ów, do których będą dopisywane adresy IP leżące we wskazanych domenach"
#: option.c:410
msgid "Specify DHCPv6 prefix class"
msgstr ""
msgstr "Określenie prefiksu klasy DHCPv6"
#: option.c:596
#, c-format
@@ -656,9 +653,8 @@ msgid "bad interface name"
msgstr "nieprawidłowa nazwa interfejsu"
#: option.c:720
#, fuzzy
msgid "bad address"
msgstr "zły adres IP"
msgstr "zły adres"
#: option.c:847
msgid "unsupported encapsulation for IPv6 option"
@@ -739,14 +735,12 @@ 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:1631
#, fuzzy
msgid "bad prefix"
msgstr "nieprawidłowy numer portu"
msgstr "zła maska"
#: option.c:2043
#, fuzzy
msgid "recompile with HAVE_IPSET defined to enable ipset directives"
msgstr "używanie skryptów Lua, wymaga skompilowania dnsmasq-a z flagą HAVE_LUASCRIPT"
msgstr "chcąc korzystać z ipsets przekompiluj dnsmasq-a z HAVE_IPSET"
#: option.c:2223
msgid "bad port range"
@@ -769,13 +763,12 @@ msgid "inconsistent DHCP range"
msgstr "niespójny zakres adresów DHCP"
#: option.c:2402
#, fuzzy
msgid "prefix must be exactly 64 for RA subnets"
msgstr "prefix musi mieć wartość >=64"
msgstr "prefix musi mieć wartość =64 dla podsieci RA"
#: option.c:2404
msgid "prefix must be exactly 64 for subnet constructors"
msgstr ""
msgstr "prefix dla podsieci musi wynosić równo 64"
#: option.c:2407
msgid "prefix must be at least 64"
@@ -794,9 +787,9 @@ msgid "cannot match tags in --dhcp-host"
msgstr "--dhcp-host nie dopuszcza dopasowywania na podstawie znaczników"
#: option.c:2589
#, fuzzy, c-format
#, c-format
msgid "duplicate dhcp-host IP address %s"
msgstr "powtórzony adres IP (%s) w pliku %s"
msgstr "powtórzony adres IP %s w specyfikacji dhcp-host"
#: option.c:2645
msgid "bad DHCP host name"
@@ -816,7 +809,7 @@ msgstr "zły adres dhcp-proxy"
#: option.c:3124
msgid "bad DUID"
msgstr ""
msgstr "zły DUID"
#: option.c:3166
msgid "invalid alias range"
@@ -839,9 +832,8 @@ msgid "bad NAPTR record"
msgstr "nieprawidłowy zapis rekordu NAPTR"
#: option.c:3295
#, fuzzy
msgid "bad RR record"
msgstr "nieprawidłowy zapis rekordu PTR"
msgstr "nieprawidłowy zapis rekordu RR"
#: option.c:3324
msgid "bad TXT record"
@@ -864,13 +856,12 @@ msgid "invalid weight"
msgstr "nieprawidłowa waga"
#: option.c:3417
#, fuzzy
msgid "Bad host-record"
msgstr "nieprawidłowy zapis rekordu PTR"
msgstr "nieprawidłowy zapis host-record"
#: option.c:3434
msgid "Bad name in host-record"
msgstr ""
msgstr "niedopuszczalna nazwa w host-record"
#: option.c:3464
msgid "unsupported option (check that dnsmasq was compiled with DHCP/TFTP/DBus support)"
@@ -897,9 +888,9 @@ msgid "error"
msgstr "błąd"
#: option.c:3592
#, fuzzy, c-format
#, c-format
msgid " at line %d of %s"
msgstr "%s w linii %d pliku %%s"
msgstr " w linii %d pliku %s"
#: option.c:3656 tftp.c:648
#, c-format
@@ -1009,9 +1000,9 @@ msgid "failed to create listening socket for %s: %s"
msgstr "nie udało się otworzyć gniazda %s: %s"
#: network.c:743
#, fuzzy, c-format
#, c-format
msgid "interface %s failed to join DHCPv6 multicast group: %s"
msgstr "nie udało się przyłączyć do grupy rozgłoszeniowej DHCPv6: %s"
msgstr "interfejs %s nie pozwolił się przyłączyć do grupy rozgłoszeniowej DHCPv6: %s"
#: network.c:937
#, c-format
@@ -1090,21 +1081,20 @@ msgid "asychronous logging is not available under Android"
msgstr "zapis do logów w trybie asynchronicznym nie jest dostępny w Androidzie"
#: dnsmasq.c:154
#, fuzzy
msgid "authoritative DNS not available: set HAVE_AUTH in src/config.h"
msgstr "Obsługa DBus nie została wkompilowana -- ustaw HAVE_DBUS w src/config.h"
msgstr "tryb autorytatywny DNS-a niedostępny - ustaw HAVE_AUTH w src/config.h"
#: dnsmasq.c:164
msgid "zone serial must be configured in --auth-soa"
msgstr ""
msgstr "za pomocą --auth-soa musi zostać ustawiony numer seryjny strefy"
#: dnsmasq.c:186
msgid "dhcp-range constructor not available on this platform"
msgstr ""
msgstr "konstrukcja dhcp-range nie jest dostępna w tym systemie"
#: dnsmasq.c:225
msgid "cannot set --bind-interfaces and --bind-dynamic"
msgstr ""
msgstr "--bind-interfaces i --bind-dynamic wzajemnie się wykluczają"
#: dnsmasq.c:229
#, c-format
@@ -1258,7 +1248,7 @@ msgstr "nie udało się wczytać skryptu Lua: %s"
#: dnsmasq.c:1031
#, c-format
msgid "TFTP directory %s inaccessible: %s"
msgstr ""
msgstr "katalog TFTP %s nie jest dostępny: %s"
#: dnsmasq.c:1095
#, c-format
@@ -1630,9 +1620,9 @@ msgid "cannot create DHCPv6 socket: %s"
msgstr "nie udało się utworzyć gniazda dla DHCPv6: %s"
#: dhcp6.c:62
#, fuzzy, c-format
#, c-format
msgid "failed to set SO_REUSE{ADDR|PORT} on DHCPv6 socket: %s"
msgstr "nie udało się ustawić SO_REUSE{ADDR|PORT} gniazda DHCP: %s"
msgstr "nie udało się ustawić SO_REUSE{ADDR|PORT} gniazda DHCPv6: %s"
#: dhcp6.c:74
#, c-format
@@ -1655,58 +1645,54 @@ msgid "%u available DHCPv6 subnet: %s/%d"
msgstr "%u dostępna podsieć DHCPv6: %s/%d"
#: rfc3315.c:350
#, fuzzy, c-format
#, c-format
msgid "%u vendor class: %u"
msgstr "%u klasa dostawcy: %s"
msgstr "%u klasa dostawcy: %u"
#: rfc3315.c:609
#, fuzzy, c-format
#, c-format
msgid "unknown prefix-class %d"
msgstr "nieznana dzierżawa"
msgstr "nieznana klasa sieci %d"
#: rfc3315.c:741 rfc3315.c:854
msgid "success"
msgstr ""
msgstr "udane"
#: rfc3315.c:756 rfc3315.c:758 rfc3315.c:862 rfc3315.c:864
#, fuzzy
msgid "no addresses available"
msgstr "brak dostępnego adresu"
msgstr "brak wolnych adresów"
#: rfc3315.c:806
#, fuzzy
msgid "address unavailable"
msgstr "adres niedostępny"
#: rfc3315.c:841
msgid "not on link"
msgstr ""
msgstr "poza zasięgiem"
#: rfc3315.c:915 rfc3315.c:1073 rfc3315.c:1150
msgid "no binding found"
msgstr ""
msgstr "brak powiązania"
#: rfc3315.c:948
msgid "deprecated"
msgstr ""
msgstr "przestarzały"
#: rfc3315.c:951
#, fuzzy
msgid "address invalid"
msgstr "adres jest w użyciu"
msgstr "niepoprawny adres"
#: rfc3315.c:992
msgid "confirm failed"
msgstr ""
msgstr "brak potwierdzenia"
#: rfc3315.c:1003
#, fuzzy
msgid "all addresses still on link"
msgstr "błędny adres w pliku %s, w linii %d"
msgstr "wszystkie adresy ciągle w użyciu"
#: rfc3315.c:1082
msgid "release received"
msgstr ""
msgstr "adres został zwolniony"
#: dhcp-common.c:145
#, c-format
@@ -1729,9 +1715,9 @@ msgid "duplicate IP address %s (%s) in dhcp-config directive"
msgstr "powtórzenie adresu IP %s (%s) w opcji dhcp-config"
#: dhcp-common.c:367
#, fuzzy, c-format
#, c-format
msgid "failed to set SO_BINDTODEVICE on DHCP socket: %s"
msgstr "nie udało się ustawić SO_REUSE{ADDR|PORT} gniazda DHCP: %s"
msgstr "nie udało się ustawić SO_BINDTODEVICE gniazda DHCP: %s"
#: dhcp-common.c:489
#, c-format
@@ -1745,42 +1731,42 @@ msgstr "Rozpoznawane opcje DHCPv6:\n"
#: dhcp-common.c:693
msgid ", prefix deprecated"
msgstr ""
msgstr ", przestarzały prefiks"
#: dhcp-common.c:696
#, c-format
msgid ", lease time "
msgstr ""
msgstr ", czas dzierżawy"
#: dhcp-common.c:727
#, c-format
msgid "%s stateless on %s%.0s%.0s%s"
msgstr ""
msgstr "%s bezstanowy na %s%.0s%.0s%s"
#: dhcp-common.c:729
#, fuzzy, c-format
#, c-format
msgid "%s, static leases only on %.0s%s%s%.0s"
msgstr "DHCP: tylko statyczne dzierżawy na %.0s%s, czas dzierżawy %s"
msgstr "%s, wyłącznie statyczne dzierżawy na %.0s%s%s%.0s"
#: dhcp-common.c:731
#, fuzzy, c-format
#, c-format
msgid "%s, proxy on subnet %.0s%s%.0s%.0s"
msgstr "DHCP: pośrednik na podsieci %.0s%s%.0s"
msgstr "%s, wykryto pośrednika na podsieci %.0s%s%.0s%.0s"
#: dhcp-common.c:732
#, fuzzy, c-format
#, c-format
msgid "%s, IP range %s -- %s%s%.0s"
msgstr "DHCP: zakres IP %s -- %s, czas dzierżawy %s"
msgstr "%s, zakres IP %s -- %s%s%.0s"
#: dhcp-common.c:739
#, c-format
msgid "DHCPv4-derived IPv6 names on %s%s"
msgstr ""
msgstr "pochodzące z DHCPv4 nazwy IPv6 na %s%s"
#: dhcp-common.c:742
#, fuzzy, c-format
#, c-format
msgid "router advertisement on %s%s"
msgstr "tylko anonsowanie routera na %.0s%s, czas życia %s"
msgstr "anonsowanie routera na %s%s"
#: radv.c:87
#, c-format
@@ -1788,19 +1774,19 @@ msgid "cannot create ICMPv6 socket: %s"
msgstr "nie udało się utworzyć gniazda dla ICMPv6: %s"
#: auth.c:402
#, fuzzy, c-format
#, c-format
msgid "ignoring zone transfer request from %s"
msgstr "nieobsługiwane żądanie od komputera %s"
msgstr "ignoruję żądanie transferu strefy od %s"
#: ipset.c:71
#, fuzzy, c-format
#, c-format
msgid "failed to find kernel version: %s"
msgstr "błąd przy przyznawaniu nazwy gniazdu serwera DHCP: %s"
msgstr "niezgodna wersja jądra: %s"
#: ipset.c:90
#, fuzzy, c-format
#, c-format
msgid "failed to create IPset control socket: %s"
msgstr "nie powiodło się otwieranie gniazda dla usługi TFTP: %s"
msgstr "nie powiodło się otwieranie gniazda sterującego IPset: %s"
#~ msgid "no interface with address %s"
#~ msgstr "brak interfejsu z adresem %s"
+93 -48
View File
@@ -54,6 +54,7 @@ static int filter_constructed_dhcp(struct auth_zone *zone, int flag, struct all_
if (flag & F_IPV6)
for (context = daemon->dhcp6; context; context = context->next)
if ((context->flags & CONTEXT_CONSTRUCTED) &&
!(context->flags & CONTEXT_NOAUTH) &&
is_same_net6(&(addr_u->addr.addr6), &context->start6, context->prefix))
return 1;
#endif
@@ -152,32 +153,55 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
auth = 0;
continue;
}
if (flag == F_IPV4)
{
for (intr = daemon->int_names; intr; intr = intr->next)
{
if (addr.addr.addr4.s_addr == get_ifaddr(intr->intr).s_addr)
break;
else
while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
intr = intr->next;
}
intr = NULL;
if (intr)
{
if (in_zone(zone, intr->name, NULL))
{
found = 1;
log_query(F_IPV4 | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL,
T_PTR, C_IN, "d", intr->name))
anscount++;
}
if (flag == F_IPV4)
for (intr = daemon->int_names; intr; intr = intr->next)
{
struct addrlist *addrlist;
for (addrlist = intr->addr4; addrlist; addrlist = addrlist->next)
if (addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr)
break;
if (addrlist)
break;
else
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->addr6; addrlist; addrlist = addrlist->next)
if (IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6))
break;
if (addrlist)
break;
else
while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
intr = intr->next;
}
#endif
if (intr)
{
if (in_zone(zone, intr->name, NULL))
{
found = 1;
log_query(flag| F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL,
T_PTR, C_IN, "d", intr->name))
anscount++;
}
}
if ((crecp = cache_find_by_addr(NULL, &addr, now, flag)))
do {
strcpy(name, cache_get_name(crecp));
@@ -321,20 +345,37 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
anscount++;
}
}
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))
{
struct addrlist *addrlist;
addrlist = intr->addr4;
#ifdef HAVE_IPV6
if (qtype == T_AAAA)
addrlist = intr->addr6;
#endif
nxdomain = 0;
if (qtype == T_A && (addr.addr.addr4 = get_ifaddr(intr->intr)).s_addr != (in_addr_t) -1)
{
found = 1;
log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, T_A, C_IN, "4", &addr))
anscount++;
}
for (; addrlist; addrlist = addrlist->next)
if (filter_constructed_dhcp(zone, flag, &addrlist->addr))
{
found = 1;
log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN,
qtype == T_A ? "4" : "6", &addrlist->addr))
anscount++;
}
}
for (a = daemon->cnames; a; a = a->next)
@@ -356,14 +397,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
goto cname_restart;
}
if (qtype == T_A)
flag = F_IPV4;
#ifdef HAVE_IPV6
if (qtype == T_AAAA)
flag = F_IPV6;
#endif
if (!cut)
{
nxdomain = 0;
@@ -488,10 +521,10 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
in_addr_t a = ntohl(subnet->addr4.s_addr) >> 8;
char *p = name;
if (subnet->prefixlen == 24)
if (subnet->prefixlen >= 24)
p += sprintf(p, "%d.", a & 0xff);
a = a >> 8;
if (subnet->prefixlen != 8)
if (subnet->prefixlen >= 16 )
p += sprintf(p, "%d.", a & 0xff);
a = a >> 8;
p += sprintf(p, "%d.in-addr.arpa", a & 0xff);
@@ -634,20 +667,32 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
}
for (intr = daemon->int_names; intr; intr = intr->next)
if (in_zone(zone, intr->name, &cut) && (addr.addr.addr4 = get_ifaddr(intr->intr)).s_addr != (in_addr_t) -1)
if (in_zone(zone, intr->name, &cut))
{
struct addrlist *addrlist;
if (cut)
*cut = 0;
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
daemon->auth_ttl, NULL, T_A, C_IN, "4", cut ? intr->name : NULL, &addr))
anscount++;
for (addrlist = intr->addr4; addrlist; addrlist = addrlist->next)
if (filter_constructed_dhcp(zone, F_IPV4, &addrlist->addr) &&
add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
daemon->auth_ttl, NULL, T_A, C_IN, "4", cut ? intr->name : NULL, &addrlist->addr))
anscount++;
#ifdef HAVE_IPV6
for (addrlist = intr->addr6; addrlist; addrlist = addrlist->next)
if (filter_constructed_dhcp(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)
*cut = '.';
}
for (a = daemon->cnames; a; a = a->next)
if (in_zone(zone, a->alias, &cut))
{
+3 -2
View File
@@ -111,7 +111,8 @@ int iface_enumerate(int family, void *parm, int (*callback)())
{
int iface_index = if_nametoindex(addrs->ifa_name);
if (iface_index == 0 || !addrs->ifa_addr || !addrs->ifa_netmask)
if (iface_index == 0 || !addrs->ifa_addr ||
(!addrs->ifa_netmask && family != AF_LINK))
continue;
if (family == AF_INET)
@@ -123,7 +124,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
broadcast = ((struct sockaddr_in *) addrs->ifa_broadaddr)->sin_addr;
else
broadcast.s_addr = 0;
if (!((*callback)(addr, iface_index, netmask, broadcast, parm)))
if (!((*callback)(addr, iface_index, NULL, netmask, broadcast, parm)))
goto err;
}
#ifdef HAVE_IPV6
-32
View File
@@ -971,38 +971,6 @@ void cache_reload(void)
total_size = read_hostsfile(ah->fname, ah->index, total_size, (struct crec **)daemon->packet, revhashsz);
}
char *get_domain(struct in_addr addr)
{
struct cond_domain *c;
for (c = daemon->cond_domain; c; c = c->next)
if (!c->is6 &&
ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
return c->domain;
return daemon->domain_suffix;
}
#ifdef HAVE_IPV6
char *get_domain6(struct in6_addr *addr)
{
struct cond_domain *c;
u64 addrpart = addr6part(addr);
for (c = daemon->cond_domain; c; c = c->next)
if (c->is6 &&
is_same_net6(addr, &c->start6, 64) &&
addrpart >= addr6part(&c->start6) &&
addrpart <= addr6part(&c->end6))
return c->domain;
return daemon->domain_suffix;
}
#endif
#ifdef HAVE_DHCP
struct in_addr a_record_from_hosts(char *name, time_t now)
{
+4 -4
View File
@@ -279,12 +279,12 @@ HAVE_SOCKADDR_SA_LEN
#if defined(INET6_ADDRSTRLEN) && defined(IPV6_V6ONLY)
# define HAVE_IPV6
# define ADDRSTRLEN INET6_ADDRSTRLEN
#elif defined(INET_ADDRSTRLEN)
#else
# if !defined(INET_ADDRSTRLEN)
# define INET_ADDRSTRLEN 16 /* 4*3 + 3 dots + NULL */
# endif
# undef HAVE_IPV6
# define ADDRSTRLEN INET_ADDRSTRLEN
#else
# undef HAVE_IPV6
# define ADDRSTRLEN 16 /* 4*3 + 3 dots + NULL */
#endif
+16 -7
View File
@@ -305,8 +305,6 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
const char *addr_err;
char *dup = NULL;
my_syslog(LOG_INFO, _("setting upstream servers from DBus"));
if (!dbus_message_iter_init(message, &iter))
{
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
@@ -478,6 +476,7 @@ DBusHandlerResult message_handler(DBusConnection *connection,
{
char *method = (char *)dbus_message_get_member(message);
DBusMessage *reply = NULL;
int clear_cache = 0, new_servers = 0;
if (dbus_message_is_method_call(message, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
{
@@ -501,24 +500,34 @@ DBusHandlerResult message_handler(DBusConnection *connection,
}
else if (strcmp(method, "SetServers") == 0)
{
my_syslog(LOG_INFO, _("setting upstream servers from DBus"));
dbus_read_servers(message);
check_servers();
new_servers = 1;
}
else if (strcmp(method, "SetServersEx") == 0)
{
reply = dbus_read_servers_ex(message, 0);
check_servers();
new_servers = 1;
}
else if (strcmp(method, "SetDomainServers") == 0)
{
reply = dbus_read_servers_ex(message, 1);
check_servers();
new_servers = 1;
}
else if (strcmp(method, "ClearCache") == 0)
clear_cache_and_reload(dnsmasq_time());
clear_cache = 1;
else
return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
if (new_servers)
{
my_syslog(LOG_INFO, _("setting upstream servers from DBus"));
check_servers();
if (option_bool(OPT_RELOAD))
clear_cache = 1;
}
if (clear_cache)
clear_cache_and_reload(dnsmasq_time());
method = user_data; /* no warning */
+29 -15
View File
@@ -91,6 +91,7 @@ struct dhcp_netid *option_filter(struct dhcp_netid *tags, struct dhcp_netid *con
{
struct dhcp_netid *tagif = run_tag_if(tags);
struct dhcp_opt *opt;
struct dhcp_opt *tmp;
/* flag options which are valid with the current tag set (sans context tags) */
for (opt = opts; opt; opt = opt->next)
@@ -135,7 +136,6 @@ struct dhcp_netid *option_filter(struct dhcp_netid *tags, struct dhcp_netid *con
for (opt = opts; opt; opt = opt->next)
if (!(opt->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR | DHOPT_RFC3925 | DHOPT_TAGOK)) && !opt->netid)
{
struct dhcp_opt *tmp;
for (tmp = opts; tmp; tmp = tmp->next)
if (tmp->opt == opt->opt && (tmp->flags & DHOPT_TAGOK))
break;
@@ -145,6 +145,13 @@ struct dhcp_netid *option_filter(struct dhcp_netid *tags, struct dhcp_netid *con
my_syslog(MS_DHCP | LOG_WARNING, _("Ignoring duplicate dhcp-option %d"), tmp->opt);
}
/* Finally, eliminate duplicate options later in the chain, and therefore earlier in the config file. */
for (opt = opts; opt; opt = opt->next)
if (opt->flags & DHOPT_TAGOK)
for (tmp = opt->next; tmp; tmp = tmp->next)
if (tmp->opt == opt->opt)
tmp->flags &= ~DHOPT_TAGOK;
return tagif;
}
@@ -340,21 +347,27 @@ void bindtodevice(int fd)
to that device. This is for the use case of (eg) OpenStack, which runs a new
dnsmasq instance for each VLAN interface it creates. Without the BINDTODEVICE,
individual processes don't always see the packets they should.
SO_BINDTODEVICE is only available Linux. */
SO_BINDTODEVICE is only available Linux.
Note that if wildcards are used in --interface, or a configured interface doesn't
yet exist, then more interfaces may arrive later, so we can't safely assert there
is only one interface and proceed.
*/
struct irec *iface, *found;
struct iname *if_tmp;
for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
if (if_tmp->name && (!if_tmp->used || strchr(if_tmp->name, '*')))
return;
for (found = NULL, iface = daemon->interfaces; iface; iface = iface->next)
if (iface->dhcp_ok)
{
if (!found)
found = iface;
else if (strcmp(found->name, iface->name) != 0)
{
/* more than one. */
found = NULL;
break;
}
return; /* more than one. */
}
if (found)
@@ -505,7 +518,7 @@ void display_opts6(void)
}
#endif
u16 lookup_dhcp_opt(int prot, char *name)
int lookup_dhcp_opt(int prot, char *name)
{
const struct opttab_t *t;
int i;
@@ -521,10 +534,10 @@ u16 lookup_dhcp_opt(int prot, char *name)
if (strcasecmp(t[i].name, name) == 0)
return t[i].val;
return 0;
return -1;
}
u16 lookup_dhcp_len(int prot, u16 val)
int lookup_dhcp_len(int prot, int val)
{
const struct opttab_t *t;
int i;
@@ -707,7 +720,7 @@ void log_context(int family, struct dhcp_context *context)
p += sprintf(p, ", ");
if (indextoname(daemon->doing_dhcp6 ? daemon->dhcp6fd : daemon->icmp6fd, context->if_index, ifrn_name))
sprintf(p, "constructed for %s", ifrn_name);
sprintf(p, "%s for %s", (context->flags & CONTEXT_OLD) ? "old prefix" : "constructed", ifrn_name);
}
else if (context->flags & CONTEXT_TEMPLATE)
{
@@ -718,7 +731,8 @@ void log_context(int family, struct dhcp_context *context)
}
#endif
if ((context->flags & CONTEXT_DHCP) || family == AF_INET)
if (!(context->flags & CONTEXT_OLD) &&
((context->flags & CONTEXT_DHCP) || family == AF_INET))
{
inet_ntop(family, start, daemon->dhcp_buff, 256);
inet_ntop(family, end, daemon->dhcp_buff3, 256);
@@ -735,9 +749,9 @@ void log_context(int family, struct dhcp_context *context)
}
#ifdef HAVE_DHCP6
if (context->flags & CONTEXT_RA_NAME)
if ((context->flags & CONTEXT_RA_NAME) && !(context->flags & CONTEXT_OLD))
my_syslog(MS_DHCP | LOG_INFO, _("DHCPv4-derived IPv6 names on %s%s"), daemon->addrbuff, template);
if ((context->flags & CONTEXT_RA) || (option_bool(OPT_RA) && (context->flags & CONTEXT_DHCP) && family == AF_INET6))
my_syslog(MS_DHCP | LOG_INFO, _("router advertisement on %s%s"), daemon->addrbuff, template);
#endif
+21 -9
View File
@@ -28,9 +28,9 @@ struct match_param {
struct in_addr netmask, broadcast, addr;
};
static int complete_context(struct in_addr local, int if_index,
static int complete_context(struct in_addr local, int if_index, char *label,
struct in_addr netmask, struct in_addr broadcast, void *vparam);
static int check_listen_addrs(struct in_addr local, int if_index,
static int check_listen_addrs(struct in_addr local, int if_index, char *label,
struct in_addr netmask, struct in_addr broadcast, void *vparam);
static int make_fd(int port)
@@ -65,14 +65,22 @@ static int make_fd(int port)
/* When bind-interfaces is set, there might be more than one dnmsasq
instance binding port 67. That's OK if they serve different networks.
Need to set REUSEADDR to make this posible, or REUSEPORT on *BSD. */
Need to set REUSEADDR|REUSEPORT to make this posible.
Handle the case that REUSEPORT is defined, but the kernel doesn't
support it. This handles the introduction of REUSEPORT on Linux. */
if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
{
int rc = -1, porterr = 0;
#ifdef SO_REUSEPORT
int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt));
#else
int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt));
if ((rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt))) == -1 &&
errno != ENOPROTOOPT)
porterr = 1;
#endif
if (rc == -1 && !porterr)
rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt));
if (rc == -1)
die(_("failed to set SO_REUSE{ADDR|PORT} on DHCP socket: %s"), NULL, EC_BADNET);
}
@@ -279,7 +287,7 @@ void dhcp_packet(time_t now, int pxe_fd)
iface_addr = match.addr;
/* make sure secondary address gets priority in case
there is more than one address on the interface in the same subnet */
complete_context(match.addr, iface_index, match.netmask, match.broadcast, &parm);
complete_context(match.addr, iface_index, NULL, match.netmask, match.broadcast, &parm);
}
if (!iface_enumerate(AF_INET, &parm, complete_context))
@@ -403,12 +411,14 @@ void dhcp_packet(time_t now, int pxe_fd)
}
/* check against secondary interface addresses */
static int check_listen_addrs(struct in_addr local, int if_index,
static int check_listen_addrs(struct in_addr local, int if_index, char *label,
struct in_addr netmask, struct in_addr broadcast, void *vparam)
{
struct match_param *param = vparam;
struct iname *tmp;
(void) label;
if (if_index == param->ind)
{
for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
@@ -436,11 +446,13 @@ static int check_listen_addrs(struct in_addr local, int if_index,
Note that the current chain may be superceded later for configured hosts or those coming via gateways. */
static int complete_context(struct in_addr local, int if_index,
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 iface_param *param = vparam;
(void)label;
for (context = daemon->dhcp; context; context = context->next)
{
+56 -24
View File
@@ -48,16 +48,24 @@ void dhcp6_init(void)
!set_ipv6pktinfo(fd))
die (_("cannot create DHCPv6 socket: %s"), NULL, EC_BADNET);
/* When bind-interfaces is set, there might be more than one dnmsasq
/* When bind-interfaces is set, there might be more than one dnmsasq
instance binding port 547. That's OK if they serve different networks.
Need to set REUSEADDR to make this posible, or REUSEPORT on *BSD. */
Need to set REUSEADDR|REUSEPORT to make this posible.
Handle the case that REUSEPORT is defined, but the kernel doesn't
support it. This handles the introduction of REUSEPORT on Linux. */
if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
{
int rc = -1, porterr = 0;
#ifdef SO_REUSEPORT
int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt));
#else
int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt));
if ((rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt))) == -1 &&
errno != ENOPROTOOPT)
porterr = 1;
#endif
if (rc == -1 && !porterr)
rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt));
if (rc == -1)
die(_("failed to set SO_REUSE{ADDR|PORT} on DHCPv6 socket: %s"), NULL, EC_BADNET);
}
@@ -212,7 +220,7 @@ static int complete_context6(struct in6_addr *local, int prefix,
for (context = daemon->dhcp6; context; context = context->next)
{
if ((context->flags & CONTEXT_DHCP) &&
!(context->flags & CONTEXT_TEMPLATE) &&
!(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
prefix == context->prefix &&
is_same_net6(local, &context->start6, prefix) &&
is_same_net6(local, &context->end6, prefix))
@@ -326,7 +334,7 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
} while (addr != start);
}
return 0;
return NULL;
}
/* can dynamically allocate addr */
@@ -530,7 +538,9 @@ static int construct_worker(struct in6_addr *local, int prefix,
}
}
else if (addr6part(local) == addr6part(&template->start6) && wildcard_match(template->template_interface, ifrn_name))
else if ((addr6part(local) == addr6part(&template->start6) ||
addr6part(local) == addr6part(&template->end6)) &&
wildcard_match(template->template_interface, ifrn_name))
{
start6 = *local;
setaddr6part(&start6, addr6part(&template->start6));
@@ -542,7 +552,10 @@ static int construct_worker(struct in6_addr *local, int prefix,
IN6_ARE_ADDR_EQUAL(&start6, &context->start6) &&
IN6_ARE_ADDR_EQUAL(&end6, &context->end6))
{
context->flags &= ~CONTEXT_GC;
int flags = context->flags;
context->flags &= ~(CONTEXT_GC | CONTEXT_OLD);
if (flags & CONTEXT_OLD)
log_context(AF_INET6, context);
break;
}
@@ -555,6 +568,7 @@ static int construct_worker(struct in6_addr *local, int prefix,
context->flags |= CONTEXT_CONSTRUCTED;
context->if_index = if_index;
context->local6 = *local;
context->saved_valid = 0;
context->next = daemon->dhcp6;
daemon->dhcp6 = context;
@@ -577,35 +591,53 @@ static int construct_worker(struct in6_addr *local, int prefix,
void dhcp_construct_contexts(time_t now)
{
struct dhcp_context *tmp, *context, **up;
struct dhcp_context *context, *tmp, **up;
struct cparam param;
param.newone = 0;
param.newname = 0;
param.now = now;
for (context = daemon->dhcp6; context; context = context->next)
{
context->if_index = 0;
if (context->flags & CONTEXT_CONSTRUCTED)
context->flags |= CONTEXT_GC;
}
if (context->flags & CONTEXT_CONSTRUCTED)
context->flags |= CONTEXT_GC;
iface_enumerate(AF_INET6, &param, construct_worker);
for (up = &daemon->dhcp6, context = daemon->dhcp6; context; context = tmp)
{
tmp = context->next;
if (context->flags & CONTEXT_GC)
tmp = context->next;
if (context->flags & CONTEXT_GC && !(context->flags & CONTEXT_OLD))
{
*up = context->next;
param.newone = 1; /* include deletion */
if (context->flags & CONTEXT_RA_NAME)
param.newname = 1;
free(context);
if ((context->flags & (CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)) ||
option_bool(OPT_RA))
{
/* previously constructed context has gone. advertise it's demise */
context->flags |= CONTEXT_OLD;
context->address_lost_time = now;
if (context->saved_valid > 7200) /* 2 hours */
context->saved_valid = 7200;
ra_start_unsolicted(now, context);
param.newone = 1; /* include deletion */
if (context->flags & CONTEXT_RA_NAME)
param.newname = 1;
log_context(AF_INET6, context);
up = &context->next;
}
else
{
/* we were never doing RA for this, so free now */
*up = context->next;
free(context);
}
}
else
up = &context->next;
up = &context->next;
}
if (param.newone)
+63 -52
View File
@@ -225,7 +225,7 @@ int main (int argc, char **argv)
die(_("cannot set --bind-interfaces and --bind-dynamic"), NULL, EC_BADCONF);
#endif
if (!enumerate_interfaces())
if (!enumerate_interfaces(1) || !enumerate_interfaces(0))
die(_("failed to find list of interfaces: %s"), NULL, EC_MISC);
if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
@@ -248,7 +248,7 @@ int main (int argc, char **argv)
#endif
#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP6)
if (daemon->dhcp6)
if (daemon->doing_dhcp6)
bindtodevice(daemon->dhcp6fd);
#endif
}
@@ -820,12 +820,15 @@ int main (int argc, char **argv)
now = dnsmasq_time();
check_log_writer(&wset);
/* prime. */
enumerate_interfaces(1);
/* Check the interfaces to see if any have exited DAD state
and if so, bind the address. */
if (is_dad_listeners())
{
enumerate_interfaces();
enumerate_interfaces(0);
/* NB, is_dad_listeners() == 1 --> we're binding interfaces */
create_bound_listeners(0);
}
@@ -1352,63 +1355,71 @@ static void check_dns_listeners(fd_set *set, time_t now)
if (confd == -1)
continue;
if (getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) == -1)
{
close(confd);
continue;
}
/* Make sure that the interface list is up-to-date.
We do this here as we may need the results below, and
the DNS code needs them for --interface-name stuff.
if (option_bool(OPT_NOWILD))
iface = listener->iface; /* May be NULL */
else
{
int if_index;
char intr_name[IF_NAMESIZE];
Multiple calls to enumerate_interfaces() per select loop are
inhibited, so calls to it in the child process (which doesn't select())
have no effect. This avoids two processes reading from the same
netlink fd and screwing the pooch entirely.
*/
/* In full wildcard mode, need to refresh interface list.
This happens automagically in CLEVERBIND */
if (!option_bool(OPT_CLEVERBIND))
enumerate_interfaces();
/* if we can find the arrival interface, check it's one that's allowed */
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;
enumerate_interfaces(0);
if (option_bool(OPT_NOWILD))
iface = listener->iface; /* May be NULL */
else
{
int if_index;
char intr_name[IF_NAMESIZE];
/* if we can find the arrival interface, check it's one that's allowed */
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
if (tcp_addr.sa.sa_family == AF_INET6)
addr.addr.addr6 = tcp_addr.in6.sin6_addr;
if (tcp_addr.sa.sa_family == AF_INET6)
addr.addr.addr6 = tcp_addr.in6.sin6_addr;
#endif
for (iface = daemon->interfaces; iface; iface = iface->next)
if (iface->index == if_index)
break;
if (!iface && !loopback_exception(listener->tcpfd, tcp_addr.sa.sa_family, &addr, intr_name))
client_ok = 0;
}
if (option_bool(OPT_CLEVERBIND))
iface = listener->iface; /* May be NULL */
else
{
/* Check for allowed interfaces when binding the wildcard address:
we do this by looking for an interface with the same address as
the local address of the TCP connection, then looking to see if that's
an allowed interface. As a side effect, we get the netmask of the
interface too, for localisation. */
for (iface = daemon->interfaces; iface; iface = iface->next)
if (sockaddr_isequal(&iface->addr, &tcp_addr))
break;
if (!iface)
client_ok = 0;
}
}
for (iface = daemon->interfaces; iface; iface = iface->next)
if (iface->index == if_index)
break;
if (!iface && !loopback_exception(listener->tcpfd, tcp_addr.sa.sa_family, &addr, intr_name))
client_ok = 0;
}
if (option_bool(OPT_CLEVERBIND))
iface = listener->iface; /* May be NULL */
else
{
/* Check for allowed interfaces when binding the wildcard address:
we do this by looking for an interface with the same address as
the local address of the TCP connection, then looking to see if that's
an allowed interface. As a side effect, we get the netmask of the
interface too, for localisation. */
for (iface = daemon->interfaces; iface; iface = iface->next)
if (sockaddr_isequal(&iface->addr, &tcp_addr))
break;
if (!iface)
client_ok = 0;
}
}
if (!client_ok)
{
shutdown(confd, SHUT_RDWR);
+27 -12
View File
@@ -307,6 +307,13 @@ struct host_record {
struct interface_name {
char *name; /* domain name */
char *intr; /* interface name */
struct addrlist {
struct all_addr addr;
struct addrlist *next;
} *addr4;
#ifdef HAVE_IPV6
struct addrlist *addr6;
#endif
struct interface_name *next;
};
@@ -543,6 +550,7 @@ struct dhcp_lease {
int backoff; /* zero -> confirmed */
struct slaac_address *next;
} *slaac_address;
int vendorclass_count;
#endif
struct dhcp_lease *next;
};
@@ -672,7 +680,7 @@ struct dhcp_bridge {
};
struct cond_domain {
char *domain;
char *domain, *prefix;
struct in_addr start, end;
#ifdef HAVE_IPV6
struct in6_addr start6, end6;
@@ -698,8 +706,8 @@ struct dhcp_context {
struct in6_addr start6, end6; /* range of available addresses */
struct in6_addr local6;
int prefix, if_index;
unsigned int valid, preferred;
time_t ra_time, ra_short_period_start;
unsigned int valid, preferred, saved_valid;
time_t ra_time, ra_short_period_start, address_lost_time;
char *template_interface;
#endif
int flags;
@@ -723,6 +731,9 @@ struct dhcp_context {
#define CONTEXT_RA 8192
#define CONTEXT_CONF_USED 16384
#define CONTEXT_USED 32768
#define CONTEXT_NOAUTH 65536
#define CONTEXT_OLD 131072
struct ping_result {
struct in_addr addr;
@@ -788,7 +799,7 @@ extern struct daemon {
struct name_list *secondary_forward_server;
int group_set, osport;
char *domain_suffix;
struct cond_domain *cond_domain;
struct cond_domain *cond_domain, *synth_domains;
char *runfile;
char *lease_change_command;
struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers;
@@ -906,15 +917,19 @@ void cache_unhash_dhcp(void);
void dump_cache(time_t now);
char *cache_get_name(struct crec *crecp);
struct crec *cache_enumerate(int init);
char *get_domain(struct in_addr addr);
#ifdef HAVE_IPV6
char *get_domain6(struct in6_addr *addr);
#endif
#ifdef HAVE_DNSSEC
struct keydata *keydata_alloc(char *data, size_t len);
void keydata_free(struct keydata *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);
/* rfc1035.c */
unsigned int extract_request(struct dns_header *header, size_t qlen,
char *name, unsigned short *typep);
@@ -1019,15 +1034,15 @@ int random_sock(int family);
void pre_allocate_sfds(void);
int reload_servers(char *fname);
void check_servers(void);
int enumerate_interfaces();
int enumerate_interfaces(int reset);
void create_wildcard_listeners(void);
void create_bound_listeners(int die);
int is_dad_listeners(void);
int iface_check(int family, struct all_addr *addr, char *name, int *auth_dns);
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 fix_fd(int fd);
int tcp_interface(int fd, int af);
struct in_addr get_ifaddr(char *intr);
#ifdef HAVE_IPV6
int set_ipv6pktinfo(int fd);
#endif
@@ -1215,8 +1230,8 @@ void log_tags(struct dhcp_netid *netid, u32 xid);
int match_bytes(struct dhcp_opt *o, unsigned char *p, int len);
void dhcp_update_configs(struct dhcp_config *configs);
void display_opts(void);
u16 lookup_dhcp_opt(int prot, char *name);
u16 lookup_dhcp_len(int prot, u16 val);
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);
#ifdef HAVE_LINUX_NETWORK
+232
View File
@@ -0,0 +1,232 @@
/* dnsmasq is Copyright (c) 2000-2013 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"
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)
{
char *p;
struct cond_domain *c = NULL;
int prot = AF_INET;
#ifdef HAVE_IPV6
if (flags & F_IPV6)
prot = AF_INET6;
#endif
for (c = daemon->synth_domains; c; c = c->next)
{
int found = 0;
char *tail, *pref;
for (tail = name, pref = c->prefix; *tail != 0 && pref && *pref != 0; tail++, pref++)
{
unsigned int c1 = (unsigned char) *pref;
unsigned int c2 = (unsigned char) *tail;
if (c1 >= 'A' && c1 <= 'Z')
c1 += 'a' - 'A';
if (c2 >= 'A' && c2 <= 'Z')
c2 += 'a' - 'A';
if (c1 != c2)
break;
}
if (pref && *pref != 0)
continue; /* prefix match fail */
/* NB, must not alter name if we return zero */
for (p = tail; *p; p++)
{
char c = *p;
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;
}
if (*p != '.')
continue;
*p = 0;
/* swap . or : for - */
for (p = tail; *p; p++)
if (*p == '-')
{
if (prot == AF_INET)
*p = '.';
#ifdef HAVE_IPV6
else
*p = ':';
#endif
}
if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, 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))
found = 1;
}
#ifdef HAVE_IPV6
else
{
u64 addrpart = addr6part(&addr->addr.addr6);
if (c->is6 &&
is_same_net6(&addr->addr.addr6, &c->start6, 64) &&
addrpart >= addr6part(&c->start6) &&
addrpart <= addr6part(&c->end6))
found = 1;
}
#endif
}
/* restore name */
for (p = tail; *p; p++)
if (*p == '.' || *p == ':')
*p = '-';
*p = '.';
if (found)
return 1;
}
return 0;
}
int is_rev_synth(int flag, struct all_addr *addr, char *name)
{
struct cond_domain *c;
if (flag & F_IPV4 && (c = search_domain(addr->addr.addr4, daemon->synth_domains)))
{
char *p;
*name = 0;
if (c->prefix)
strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
inet_ntop(AF_INET, &addr->addr.addr4, name + strlen(name), ADDRSTRLEN);
for (p = name; *p; p++)
if (*p == '.')
*p = '-';
strncat(name, ".", MAXDNAME);
strncat(name, c->domain, MAXDNAME);
return 1;
}
#ifdef HAVE_IPV6
if (flag & F_IPV6 && (c = search_domain6(&addr->addr.addr6, daemon->synth_domains)))
{
char *p;
*name = 0;
if (c->prefix)
strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
inet_ntop(AF_INET6, &addr->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);
}
for (p = name; *p; p++)
if (*p == ':')
*p = '-';
strncat(name, ".", MAXDNAME);
strncat(name, c->domain, MAXDNAME);
return 1;
}
#endif
return 0;
}
static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c)
{
for (; c; c = c->next)
if (!c->is6 &&
ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
return c;
return NULL;
}
char *get_domain(struct in_addr addr)
{
struct cond_domain *c;
if ((c = search_domain(addr, daemon->cond_domain)))
return c->domain;
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);
for (; c; c = c->next)
if (c->is6 &&
is_same_net6(addr, &c->start6, 64) &&
addrpart >= addr6part(&c->start6) &&
addrpart <= addr6part(&c->end6))
return c;
return NULL;
}
char *get_domain6(struct in6_addr *addr)
{
struct cond_domain *c;
if ((c = search_domain6(addr, daemon->cond_domain)))
return c->domain;
return daemon->domain_suffix;
}
#endif
+30 -25
View File
@@ -328,8 +328,8 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
struct server *firstsentto = start;
int forwarded = 0;
if (udpaddr && option_bool(OPT_ADD_MAC))
plen = add_mac(header, plen, ((char *) header) + PACKETSZ, udpaddr);
if (option_bool(OPT_ADD_MAC))
plen = add_mac(header, plen, ((char *) header) + PACKETSZ, &forward->source);
while (1)
{
@@ -372,7 +372,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
if (option_bool(OPT_CONNTRACK))
{
unsigned int mark;
if (get_incoming_mark(udpaddr, dst_addr, 0, &mark))
if (get_incoming_mark(&forward->source, &forward->dest, 0, &mark))
setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
}
#endif
@@ -680,7 +680,7 @@ void receive_query(struct listener *listen, time_t now)
dst_addr_4.s_addr = 0;
netmask.s_addr = 0;
if (listen->iface && option_bool(OPT_NOWILD))
if (option_bool(OPT_NOWILD) && listen->iface)
{
auth_dns = listen->iface->dns_auth;
@@ -788,8 +788,9 @@ void receive_query(struct listener *listen, time_t now)
if (!iface_check(listen->family, &dst_addr, ifr.ifr_name, &auth_dns))
{
if (!option_bool(OPT_CLEVERBIND))
enumerate_interfaces();
if (!loopback_exception(listen->fd, listen->family, &dst_addr, ifr.ifr_name))
enumerate_interfaces(0);
if (!loopback_exception(listen->fd, listen->family, &dst_addr, ifr.ifr_name) &&
!label_exception(if_index, listen->family, &dst_addr))
return;
}
@@ -807,7 +808,7 @@ void receive_query(struct listener *listen, time_t now)
/* interface may be new */
if (!iface && !option_bool(OPT_CLEVERBIND))
enumerate_interfaces();
enumerate_interfaces(0);
for (iface = daemon->interfaces; iface; iface = iface->next)
if (iface->addr.sa.sa_family == AF_INET &&
@@ -880,9 +881,12 @@ unsigned char *tcp_request(int confd, time_t now,
unsigned short qtype;
unsigned int gotname;
unsigned char c1, c2;
/* Max TCP packet + slop */
unsigned char *packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ);
struct dns_header *header;
/* Max TCP packet + slop + size */
unsigned char *packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ + sizeof(u16));
unsigned char *payload = &packet[2];
/* largest field in header is 16-bits, so this is still sufficiently aligned */
struct dns_header *header = (struct dns_header *)payload;
u16 *length = (u16 *)packet;
struct server *last_server;
struct in_addr dst_addr_4;
union mysockaddr peer_addr;
@@ -896,14 +900,12 @@ unsigned char *tcp_request(int confd, time_t now,
if (!packet ||
!read_write(confd, &c1, 1, 1) || !read_write(confd, &c2, 1, 1) ||
!(size = c1 << 8 | c2) ||
!read_write(confd, packet, size, 1))
!read_write(confd, payload, size, 1))
return packet;
if (size < (int)sizeof(struct dns_header))
continue;
header = (struct dns_header *)packet;
/* save state of "cd" flag in query */
checking_disabled = header->hb4 & HB4_CD;
@@ -1020,12 +1022,9 @@ unsigned char *tcp_request(int confd, time_t now,
#endif
}
c1 = size >> 8;
c2 = size;
*length = htons(size);
if (!read_write(last_server->tcpfd, &c1, 1, 0) ||
!read_write(last_server->tcpfd, &c2, 1, 0) ||
!read_write(last_server->tcpfd, packet, size, 0) ||
if (!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))
{
@@ -1035,7 +1034,7 @@ unsigned char *tcp_request(int confd, time_t now,
}
m = (c1 << 8) | c2;
if (!read_write(last_server->tcpfd, packet, m, 1))
if (!read_write(last_server->tcpfd, payload, m, 1))
return packet;
if (!gotname)
@@ -1071,12 +1070,9 @@ unsigned char *tcp_request(int confd, time_t now,
check_log_writer(NULL);
c1 = m>>8;
c2 = m;
if (m == 0 ||
!read_write(confd, &c1, 1, 0) ||
!read_write(confd, &c2, 1, 0) ||
!read_write(confd, packet, m, 0))
*length = htons(m);
if (m == 0 || !read_write(confd, packet, m + sizeof(u16), 0))
return packet;
}
}
@@ -1209,8 +1205,17 @@ struct frec *get_new_frec(time_t now, int *wait)
/* none available, calculate time 'till oldest record expires */
if (count > daemon->ftabsize)
{
static time_t last_log = 0;
if (oldest && wait)
*wait = oldest->time + (time_t)TIMEOUT - now;
if ((int)difftime(now, last_log) > 5)
{
last_log = now;
my_syslog(LOG_WARNING, _("Maximum number of concurrent DNS queries reached (max: %d)"), daemon->ftabsize);
}
return NULL;
}
+8 -2
View File
@@ -655,8 +655,9 @@ void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t n
unsigned char *p;
unsigned int hostname_len = 0, clid_len = 0, ed_len = 0;
int fd = daemon->dhcpfd;
#ifdef HAVE_DHCP6
int is6 = !!(lease->flags & (LEASE_TA | LEASE_NA));
#ifdef HAVE_DHCP6
if (!daemon->dhcp)
fd = daemon->dhcp6fd;
#endif
@@ -676,7 +677,12 @@ void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t n
buf->action = action;
buf->flags = lease->flags;
buf->hwaddr_len = lease->hwaddr_len;
#ifdef HAVE_DHCP6
if (is6)
buf->hwaddr_len = lease->vendorclass_count;
else
#endif
buf->hwaddr_len = lease->hwaddr_len;
buf->hwaddr_type = lease->hwaddr_type;
buf->clid_len = clid_len;
buf->ed_len = ed_len;
+40 -16
View File
@@ -26,9 +26,12 @@
#include <arpa/inet.h>
#include <linux/version.h>
#include <linux/netlink.h>
#include <linux/netfilter/nfnetlink.h>
#ifndef NFNL_SUBSYS_IPSET
/* We want to be able to compile against old header files
Kernel version is handled at run-time. */
#define NFNL_SUBSYS_IPSET 6
#define IPSET_ATTR_DATA 7
#define IPSET_ATTR_IP 1
#define IPSET_ATTR_IPADDR_IPV4 1
@@ -39,10 +42,31 @@
#define IPSET_CMD_DEL 10
#define IPSET_MAXNAMELEN 32
#define IPSET_PROTOCOL 6
#else
#include <linux/netfilter/ipset/ip_set.h>
#ifndef NFNETLINK_V0
#define NFNETLINK_V0 0
#endif
#ifndef NLA_F_NESTED
#define NLA_F_NESTED (1 << 15)
#endif
#ifndef NLA_F_NET_BYTEORDER
#define NLA_F_NET_BYTEORDER (1 << 14)
#endif
struct my_nlattr {
__u16 nla_len;
__u16 nla_type;
};
struct my_nfgenmsg {
__u8 nfgen_family; /* AF_xxx */
__u8 version; /* nfnetlink version */
__be16 res_id; /* resource id */
};
/* data structure size in here is fixed */
#define BUFF_SZ 256
@@ -53,11 +77,11 @@ static char *buffer;
static inline void add_attr(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data)
{
struct nlattr *attr = (void *)nlh + NL_ALIGN(nlh->nlmsg_len);
uint16_t payload_len = NL_ALIGN(sizeof(struct nlattr)) + len;
struct my_nlattr *attr = (void *)nlh + NL_ALIGN(nlh->nlmsg_len);
uint16_t payload_len = NL_ALIGN(sizeof(struct my_nlattr)) + len;
attr->nla_type = type;
attr->nla_len = payload_len;
memcpy((void *)attr + NL_ALIGN(sizeof(struct nlattr)), data, len);
memcpy((void *)attr + NL_ALIGN(sizeof(struct my_nlattr)), data, len);
nlh->nlmsg_len += NL_ALIGN(payload_len);
}
@@ -93,8 +117,8 @@ void ipset_init(void)
static int new_add_to_ipset(const char *setname, const struct all_addr *ipaddr, int af, int remove)
{
struct nlmsghdr *nlh;
struct nfgenmsg *nfg;
struct nlattr *nested[2];
struct my_nfgenmsg *nfg;
struct my_nlattr *nested[2];
uint8_t proto;
int addrsz = INADDRSZ;
ssize_t rc;
@@ -110,15 +134,15 @@ static int new_add_to_ipset(const char *setname, const struct all_addr *ipaddr,
return -1;
}
memset(buffer, 0, sizeof(buffer));
memset(buffer, 0, BUFF_SZ);
nlh = (struct nlmsghdr *)buffer;
nlh->nlmsg_len = NL_ALIGN(sizeof(struct nlmsghdr));
nlh->nlmsg_type = (remove ? IPSET_CMD_DEL : IPSET_CMD_ADD) | (NFNL_SUBSYS_IPSET << 8);
nlh->nlmsg_flags = NLM_F_REQUEST;
nfg = (struct nfgenmsg *)(buffer + nlh->nlmsg_len);
nlh->nlmsg_len += NL_ALIGN(sizeof(struct nfgenmsg));
nfg = (struct my_nfgenmsg *)(buffer + nlh->nlmsg_len);
nlh->nlmsg_len += NL_ALIGN(sizeof(struct my_nfgenmsg));
nfg->nfgen_family = af;
nfg->version = NFNETLINK_V0;
nfg->res_id = htons(0);
@@ -126,11 +150,11 @@ static int new_add_to_ipset(const char *setname, const struct all_addr *ipaddr,
proto = IPSET_PROTOCOL;
add_attr(nlh, IPSET_ATTR_PROTOCOL, sizeof(proto), &proto);
add_attr(nlh, IPSET_ATTR_SETNAME, strlen(setname) + 1, setname);
nested[0] = (struct nlattr *)(buffer + NL_ALIGN(nlh->nlmsg_len));
nlh->nlmsg_len += NL_ALIGN(sizeof(struct nlattr));
nested[0] = (struct my_nlattr *)(buffer + NL_ALIGN(nlh->nlmsg_len));
nlh->nlmsg_len += NL_ALIGN(sizeof(struct my_nlattr));
nested[0]->nla_type = NLA_F_NESTED | IPSET_ATTR_DATA;
nested[1] = (struct nlattr *)(buffer + NL_ALIGN(nlh->nlmsg_len));
nlh->nlmsg_len += NL_ALIGN(sizeof(struct nlattr));
nested[1] = (struct my_nlattr *)(buffer + NL_ALIGN(nlh->nlmsg_len));
nlh->nlmsg_len += NL_ALIGN(sizeof(struct my_nlattr));
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,
+16 -6
View File
@@ -115,7 +115,7 @@ void lease_init(time_t now)
s++;
}
hw_type = atoi(s);
hw_type = strtoul(s, NULL, 10);
if ((lease = lease6_allocate(&addr.addr.addr6, lease_type)))
{
@@ -345,11 +345,12 @@ void lease_update_file(time_t now)
}
static int find_interface_v4(struct in_addr local, int if_index,
static int find_interface_v4(struct in_addr local, int if_index, char *label,
struct in_addr netmask, struct in_addr broadcast, void *vparam)
{
struct dhcp_lease *lease;
(void) label;
(void) broadcast;
(void) vparam;
@@ -595,6 +596,8 @@ struct dhcp_lease *lease6_find_by_client(struct dhcp_lease *first, int lease_typ
if (!first)
first = leases;
else
first = first->next;
for (lease = first; lease; lease = lease->next)
{
@@ -701,8 +704,11 @@ static struct dhcp_lease *lease_allocate(void)
struct dhcp_lease *lease4_allocate(struct in_addr addr)
{
struct dhcp_lease *lease = lease_allocate();
lease->addr = addr;
lease->hwaddr_len = 256; /* illegal value */
if (lease)
{
lease->addr = addr;
lease->hwaddr_len = 256; /* illegal value */
}
return lease;
}
@@ -711,8 +717,12 @@ struct dhcp_lease *lease4_allocate(struct in_addr addr)
struct dhcp_lease *lease6_allocate(struct in6_addr *addrp, int lease_type)
{
struct dhcp_lease *lease = lease_allocate();
memcpy(lease->hwaddr, addrp, sizeof(*addrp)) ;
lease->flags |= lease_type;
if (lease)
{
memcpy(lease->hwaddr, addrp, sizeof(*addrp)) ;
lease->flags |= lease_type;
}
return lease;
}
+10 -4
View File
@@ -193,7 +193,10 @@ int iface_enumerate(int family, void *parm, int (*callback)())
{
/* May be multicast arriving async */
if (nl_async(h))
newaddr = 1;
{
newaddr = 1;
enumerate_interfaces(1); /* reset */
}
}
else if (h->nlmsg_type == NLMSG_DONE)
{
@@ -215,7 +218,8 @@ int iface_enumerate(int family, void *parm, int (*callback)())
if (ifa->ifa_family == AF_INET)
{
struct in_addr netmask, addr, broadcast;
char *label = NULL;
netmask.s_addr = htonl(0xffffffff << (32 - ifa->ifa_prefixlen));
addr.s_addr = 0;
broadcast.s_addr = 0;
@@ -226,12 +230,14 @@ int iface_enumerate(int family, void *parm, int (*callback)())
addr = *((struct in_addr *)(rta+1));
else if (rta->rta_type == IFA_BROADCAST)
broadcast = *((struct in_addr *)(rta+1));
else if (rta->rta_type == IFA_LABEL)
label = RTA_DATA(rta);
rta = RTA_NEXT(rta, len1);
}
if (addr.s_addr && callback_ok)
if (!((*callback)(addr, ifa->ifa_index, netmask, broadcast, parm)))
if (!((*callback)(addr, ifa->ifa_index, label, netmask, broadcast, parm)))
callback_ok = 0;
}
#ifdef HAVE_IPV6
@@ -394,7 +400,7 @@ static int nl_async(struct nlmsghdr *h)
static void nl_newaddress(time_t now)
{
if (option_bool(OPT_CLEVERBIND) || daemon->doing_dhcp6 || daemon->doing_ra)
enumerate_interfaces();
enumerate_interfaces(0);
if (option_bool(OPT_CLEVERBIND))
create_bound_listeners(0);
+157 -59
View File
@@ -99,6 +99,8 @@ int indextoname(int fd, int index, char *name)
int indextoname(int fd, int index, char *name)
{
(void)fd;
if (index == 0 || !if_indextoname(index, name))
return 0;
@@ -204,11 +206,36 @@ int loopback_exception(int fd, int family, struct all_addr *addr, char *name)
return 0;
}
static int iface_allowed(struct irec **irecp, int if_index,
/* If we're configured with something like --interface=eth0:0 then we'll listen correctly
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)
{
struct irec *iface;
/* labels only supported on IPv4 addresses. */
if (family != AF_INET)
return 0;
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)
return 1;
return 0;
}
struct iface_param {
struct addrlist *spare;
int fd;
};
static int iface_allowed(struct iface_param *param, int if_index, char *label,
union mysockaddr *addr, struct in_addr netmask, int dad)
{
struct irec *iface;
int fd, mtu = 0, loopback;
int mtu = 0, loopback;
struct ifreq ifr;
int tftp_ok = !!option_bool(OPT_TFTP);
int dhcp_ok = 1;
@@ -217,39 +244,72 @@ static int iface_allowed(struct irec **irecp, int if_index,
struct iname *tmp;
#endif
if (!indextoname(param->fd, if_index, ifr.ifr_name) ||
ioctl(param->fd, SIOCGIFFLAGS, &ifr) == -1)
return 0;
loopback = ifr.ifr_flags & IFF_LOOPBACK;
if (loopback)
dhcp_ok = 0;
if (ioctl(param->fd, SIOCGIFMTU, &ifr) != -1)
mtu = ifr.ifr_mtu;
if (!label)
label = ifr.ifr_name;
/* Update addresses from interface_names. These are a set independent
of the set we're listening on. */
#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;
for (int_name = daemon->int_names; int_name; int_name = int_name->next)
if (strncmp(label, int_name->intr, IF_NAMESIZE) == 0)
{
if (param->spare)
{
al = param->spare;
param->spare = al->next;
}
else
al = whine_malloc(sizeof(struct addrlist));
if (al)
{
if (addr->sa.sa_family == AF_INET)
{
al->addr.addr.addr4 = addr->in.sin_addr;
al->next = int_name->addr4;
int_name->addr4 = al;
}
#ifdef HAVE_IPV6
else
{
al->addr.addr.addr6 = addr->in6.sin6_addr;
al->next = int_name->addr6;
int_name->addr6 = al;
}
#endif
}
}
}
/* check whether the interface IP has been added already
we call this routine multiple times. */
for (iface = *irecp; iface; iface = iface->next)
for (iface = daemon->interfaces; iface; iface = iface->next)
if (sockaddr_isequal(&iface->addr, addr))
{
iface->dad = dad;
return 1;
}
if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1 ||
!indextoname(fd, if_index, ifr.ifr_name) ||
ioctl(fd, SIOCGIFFLAGS, &ifr) == -1)
{
if (fd != -1)
{
int errsave = errno;
close(fd);
errno = errsave;
}
return 0;
}
loopback = ifr.ifr_flags & IFF_LOOPBACK;
if (loopback)
dhcp_ok = 0;
if (ioctl(fd, SIOCGIFMTU, &ifr) != -1)
mtu = ifr.ifr_mtu;
close(fd);
/* If we are restricting the set of interfaces to use, make
/* If we are restricting the set of interfaces to use, make
sure that loopback interfaces are in that set. */
if (daemon->if_names && loopback)
{
@@ -273,12 +333,12 @@ static int iface_allowed(struct irec **irecp, int if_index,
}
if (addr->sa.sa_family == AF_INET &&
!iface_check(AF_INET, (struct all_addr *)&addr->in.sin_addr, ifr.ifr_name, &auth_dns))
!iface_check(AF_INET, (struct 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, ifr.ifr_name, &auth_dns))
!iface_check(AF_INET6, (struct all_addr *)&addr->in6.sin6_addr, label, &auth_dns))
return 1;
#endif
@@ -313,8 +373,8 @@ static int iface_allowed(struct irec **irecp, int if_index,
if ((iface->name = whine_malloc(strlen(ifr.ifr_name)+1)))
{
strcpy(iface->name, ifr.ifr_name);
iface->next = *irecp;
*irecp = iface;
iface->next = daemon->interfaces;
daemon->interfaces = iface;
return 1;
}
free(iface);
@@ -348,11 +408,11 @@ static int iface_allowed_v6(struct in6_addr *local, int prefix,
addr.in6.sin6_port = htons(daemon->port);
addr.in6.sin6_scope_id = if_index;
return iface_allowed((struct irec **)vparam, if_index, &addr, netmask, !!(flags & IFACE_TENTATIVE));
return iface_allowed((struct iface_param *)vparam, if_index, NULL, &addr, netmask, !!(flags & IFACE_TENTATIVE));
}
#endif
static int iface_allowed_v4(struct in_addr local, int if_index,
static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
struct in_addr netmask, struct in_addr broadcast, void *vparam)
{
union mysockaddr addr;
@@ -366,17 +426,75 @@ static int iface_allowed_v4(struct in_addr local, int if_index,
addr.in.sin_addr = local;
addr.in.sin_port = htons(daemon->port);
return iface_allowed((struct irec **)vparam, if_index, &addr, netmask, 0);
return iface_allowed((struct iface_param *)vparam, if_index, label, &addr, netmask, 0);
}
int enumerate_interfaces(void)
int enumerate_interfaces(int reset)
{
static struct addrlist *spare = NULL;
static int done = 0;
struct iface_param param;
int errsave, ret = 1;
struct addrlist *addr, *tmp;
struct interface_name *intname;
/* Do this max once per select cycle - also inhibits netlink socket use
in TCP child processes. */
if (reset)
{
done = 0;
return 1;
}
if (done)
return 1;
done = 1;
if ((param.fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
return 0;
/* remove addresses stored against interface_names */
for (intname = daemon->int_names; intname; intname = intname->next)
{
for (addr = intname->addr4; addr; addr = tmp)
{
tmp = addr->next;
addr->next = spare;
spare = addr;
}
intname->addr4 = NULL;
#ifdef HAVE_IPV6
if (!iface_enumerate(AF_INET6, &daemon->interfaces, iface_allowed_v6))
return 0;
for (addr = intname->addr6; addr; addr = tmp)
{
tmp = addr->next;
addr->next = spare;
spare = addr;
}
intname->addr6 = NULL;
#endif
}
param.spare = spare;
#ifdef HAVE_IPV6
ret = iface_enumerate(AF_INET6, &param, iface_allowed_v6);
#endif
return iface_enumerate(AF_INET, &daemon->interfaces, iface_allowed_v4);
if (ret)
ret = iface_enumerate(AF_INET, &param, iface_allowed_v4);
errsave = errno;
close(param.fd);
errno = errsave;
spare = param.spare;
return ret;
}
/* set NONBLOCK bit on fd: See Stevens 16.6 */
@@ -948,7 +1066,7 @@ void check_servers(void)
/* interface may be new since startup */
if (!option_bool(OPT_NOWILD))
enumerate_interfaces();
enumerate_interfaces(0);
for (new = daemon->servers; new; new = tmp)
{
@@ -1156,27 +1274,7 @@ int reload_servers(char *fname)
}
/* Use an IPv4 listener socket for ioctling */
struct in_addr get_ifaddr(char *intr)
{
struct listener *l;
struct ifreq ifr;
struct sockaddr_in ret;
ret.sin_addr.s_addr = -1;
for (l = daemon->listeners;
l && (l->family != AF_INET || l->fd == -1);
l = l->next);
strncpy(ifr.ifr_name, intr, IF_NAMESIZE);
ifr.ifr_addr.sa_family = AF_INET;
if (l && ioctl(l->fd, SIOCGIFADDR, &ifr) != -1)
memcpy(&ret, &ifr.ifr_addr, sizeof(ret));
return ret.sin_addr;
}
+107 -65
View File
@@ -128,8 +128,9 @@ struct myoption {
#define LOPT_AUTHSFS 317
#define LOPT_AUTHPEER 318
#define LOPT_IPSET 319
#define LOPT_SYNTH 320
#ifdef OPTION6_PREFIX_CLASS
#define LOPT_PREF_CLSS 320
#define LOPT_PREF_CLSS 321
#endif
#ifdef HAVE_GETOPT_LONG
@@ -264,6 +265,7 @@ static const struct myoption opts[] =
{ "auth-sec-servers", 1, 0, LOPT_AUTHSFS },
{ "auth-peer", 1, 0, LOPT_AUTHPEER },
{ "ipset", 1, 0, LOPT_IPSET },
{ "synth-domain", 1, 0, LOPT_SYNTH },
#ifdef OPTION6_PREFIX_CLASS
{ "dhcp-prefix-class", 1, 0, LOPT_PREF_CLSS },
#endif
@@ -406,6 +408,7 @@ static struct {
{ LOPT_AUTHSFS, ARG_DUP, "<NS>[,<NS>...]", gettext_noop("Secondary authoritative nameservers for forward domains"), NULL },
{ LOPT_AUTHPEER, ARG_DUP, "<ipaddr>[,<ipaddr>...]", gettext_noop("Peers which are allowed to do zone transfer"), NULL },
{ LOPT_IPSET, ARG_DUP, "/<domain>/<ipset>[,<ipset>...]", gettext_noop("Specify ipsets to which matching domains should be added"), NULL },
{ LOPT_SYNTH, ARG_DUP, "<domain>,<range>,[<prefix>]", gettext_noop("Specify a domain and address range for sythesised names"), NULL },
#ifdef OPTION6_PREFIX_CLASS
{ LOPT_PREF_CLSS, ARG_DUP, "set:tag,<class>", gettext_noop("Specify DHCPv6 prefix class"), NULL },
#endif
@@ -657,7 +660,7 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
scope_id = split_chr(arg, '%');
#endif
if ((addr->in.sin_addr.s_addr = inet_addr(arg)) != (in_addr_t) -1)
if (inet_pton(AF_INET, arg, &addr->in.sin_addr) > 0)
{
addr->in.sin_port = htons(serv_port);
addr->sa.sa_family = source_addr->sa.sa_family = AF_INET;
@@ -672,7 +675,7 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
if (flags)
*flags |= SERV_HAS_SOURCE;
source_addr->in.sin_port = htons(source_port);
if ((source_addr->in.sin_addr.s_addr = inet_addr(source)) == (in_addr_t) -1)
if (!(inet_pton(AF_INET, source, &source_addr->in.sin_addr) > 0))
{
#if defined(SO_BINDTODEVICE)
source_addr->in.sin_addr.s_addr = INADDR_ANY;
@@ -750,6 +753,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
struct dhcp_netid *np = NULL;
u16 opt_len = 0;
int is6 = 0;
int option_ok = 0;
new->len = 0;
new->flags = flags;
@@ -769,16 +773,19 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
{
new->opt = atoi(arg);
opt_len = 0;
option_ok = 1;
break;
}
if (strstr(arg, "option:") == arg)
{
new->opt = lookup_dhcp_opt(AF_INET, arg+7);
opt_len = lookup_dhcp_len(AF_INET, new->opt);
/* option:<optname> must follow tag and vendor string. */
if ((opt_len & OT_INTERNAL) && flags != DHOPT_MATCH)
new->opt = 0;
if ((new->opt = lookup_dhcp_opt(AF_INET, arg+7)) != -1)
{
opt_len = lookup_dhcp_len(AF_INET, new->opt);
/* option:<optname> must follow tag and vendor string. */
if (!(opt_len & OT_INTERNAL) || flags == DHOPT_MATCH)
option_ok = 1;
}
break;
}
#ifdef HAVE_DHCP6
@@ -792,13 +799,16 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
{
new->opt = atoi(arg+8);
opt_len = 0;
option_ok = 1;
}
else
{
new->opt = lookup_dhcp_opt(AF_INET6, arg+8);
opt_len = lookup_dhcp_len(AF_INET6, new->opt);
if ((opt_len & OT_INTERNAL) && flags != DHOPT_MATCH)
new->opt = 0;
if ((new->opt = lookup_dhcp_opt(AF_INET6, arg+8)) != -1)
{
opt_len = lookup_dhcp_len(AF_INET6, new->opt);
if (!(opt_len & OT_INTERNAL) || flags == DHOPT_MATCH)
option_ok = 1;
}
}
/* option6:<opt>|<optname> must follow tag and vendor string. */
is6 = 1;
@@ -821,7 +831,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
new->flags |= DHOPT_RFC3925;
if (flags == DHOPT_MATCH)
{
new->opt = 1; /* avoid error below */
option_ok = 1;
break;
}
}
@@ -848,16 +858,16 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
if (opt_len == 0 &&
!(new->flags & DHOPT_RFC3925))
opt_len = lookup_dhcp_len(AF_INET6 ,new->opt);
opt_len = lookup_dhcp_len(AF_INET6, new->opt);
}
else
#endif
if (opt_len == 0 &&
!(new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE | DHOPT_RFC3925)))
opt_len = lookup_dhcp_len(AF_INET ,new->opt);
opt_len = lookup_dhcp_len(AF_INET, new->opt);
/* option may be missing with rfc3925 match */
if (new->opt == 0)
if (!option_ok)
ret_err(_("bad dhcp-option"));
if (comma)
@@ -1021,7 +1031,7 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
cp = comma;
comma = split(cp);
slash = split_chr(cp, '/');
in.s_addr = inet_addr(cp);
inet_pton(AF_INET, cp, &in);
if (!slash)
{
memcpy(op, &in, INADDRSZ);
@@ -1566,7 +1576,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
comma = split(arg);
new->name = NULL;
unhide_metas(arg);
if ((new->addr.in.sin_addr.s_addr = inet_addr(arg)) != (in_addr_t)-1)
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)
@@ -1627,8 +1637,6 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
if (inet_pton(AF_INET, arg, &subnet->addr4))
{
if ((prefixlen & 0x07) != 0 || prefixlen > 24)
ret_err(_("bad prefix"));
subnet->prefixlen = (prefixlen == 0) ? 24 : prefixlen;
subnet->is6 = 0;
}
@@ -1680,7 +1688,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
break;
case 's': /* --domain */
case 's': /* --domain */
case LOPT_SYNTH: /* --synth-domain */
if (strcmp (arg, "#") == 0)
set_option_bool(OPT_RESOLV_DOMAIN);
else
@@ -1695,6 +1704,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
{
struct cond_domain *new = opt_malloc(sizeof(struct cond_domain));
char *netpart;
new->prefix = NULL;
unhide_metas(comma);
if ((netpart = split_chr(comma, '/')))
@@ -1712,25 +1723,30 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
new->end.s_addr = new->start.s_addr | htonl(mask);
if (arg)
{
/* generate the equivalent of
local=/<domain>/
local=/xxx.yyy.zzz.in-addr.arpa/ */
if (strcmp(arg, "local") != 0 ||
(msize != 8 && msize != 16 && msize != 24))
if (option != 's')
{
if (!(new->prefix = canonicalise_opt(arg)) ||
strlen(new->prefix) > MAXLABEL - INET_ADDRSTRLEN)
ret_err(_("bad prefix"));
}
else if (strcmp(arg, "local") != 0 ||
(msize != 8 && msize != 16 && msize != 24))
ret_err(gen_err);
else
{
/* generate the equivalent of
local=/<domain>/
local=/xxx.yyy.zzz.in-addr.arpa/ */
struct server *serv = opt_malloc(sizeof(struct server));
in_addr_t a = ntohl(new->start.s_addr) >> 8;
char *p;
memset(serv, 0, sizeof(struct server));
serv->domain = d;
serv->flags = SERV_HAS_DOMAIN | SERV_NO_ADDR;
serv->next = daemon->servers;
daemon->servers = serv;
serv = opt_malloc(sizeof(struct server));
memset(serv, 0, sizeof(struct server));
p = serv->domain = opt_malloc(25); /* strlen("xxx.yyy.zzz.in-addr.arpa")+1 */
@@ -1742,7 +1758,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
p += sprintf(p, "%d.", a & 0xff);
a = a >> 8;
p += sprintf(p, "%d.in-addr.arpa", a & 0xff);
serv->flags = SERV_HAS_DOMAIN | SERV_NO_ADDR;
serv->next = daemon->servers;
daemon->servers = serv;
@@ -1755,11 +1771,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
u64 mask = (1LLU << (128 - msize)) - 1LLU;
u64 addrpart = addr6part(&new->start6);
new->is6 = 1;
/* prefix==64 overflows the mask calculation above */
if (msize == 64)
mask = (u64)-1LL;
new->end6 = new->start6;
setaddr6part(&new->start6, addrpart & ~mask);
setaddr6part(&new->end6, addrpart | mask);
@@ -1768,14 +1784,19 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
ret_err(gen_err);
else if (arg)
{
/* generate the equivalent of
local=/<domain>/
local=/xxx.yyy.zzz.ip6.arpa/ */
if (strcmp(arg, "local") != 0 || ((msize & 4) != 0))
if (option != 's')
{
if (!(new->prefix = canonicalise_opt(arg)) ||
strlen(new->prefix) > MAXLABEL - INET6_ADDRSTRLEN)
ret_err(_("bad prefix"));
}
else if (strcmp(arg, "local") != 0 || ((msize & 4) != 0))
ret_err(gen_err);
else
{
/* generate the equivalent of
local=/<domain>/
local=/xxx.yyy.zzz.ip6.arpa/ */
struct server *serv = opt_malloc(sizeof(struct server));
char *p;
@@ -1806,7 +1827,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
else
ret_err(gen_err);
}
else
else
{
arg = split(comma);
if (inet_pton(AF_INET, comma, &new->start))
@@ -1832,11 +1853,21 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
new->domain = d;
new->next = daemon->cond_domain;
daemon->cond_domain = new;
if (option == 's')
{
new->next = daemon->cond_domain;
daemon->cond_domain = new;
}
else
{
new->next = daemon->synth_domains;
daemon->synth_domains = new;
}
}
else
else if (option == 's')
daemon->domain_suffix = d;
else
ret_err(gen_err);
}
}
break;
@@ -1894,7 +1925,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
{
struct in_addr addr;
unhide_metas(arg);
if (arg && (addr.s_addr = inet_addr(arg)) != (in_addr_t)-1)
if (arg && (inet_pton(AF_INET, arg, &addr) > 0))
{
struct bogus_addr *baddr = opt_malloc(sizeof(struct bogus_addr));
baddr->next = daemon->bogus_addr;
@@ -1912,7 +1943,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
struct iname *new = opt_malloc(sizeof(struct iname));
comma = split(arg);
unhide_metas(arg);
if (arg && (new->addr.in.sin_addr.s_addr = inet_addr(arg)) != (in_addr_t)-1)
if (arg && (inet_pton(AF_INET, arg, &new->addr.in.sin_addr) > 0))
{
new->addr.sa.sa_family = AF_INET;
new->addr.in.sin_port = 0;
@@ -2336,7 +2367,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
if (k >= 3 && strchr(a[2], '.') &&
((new->netmask.s_addr = inet_addr(a[2])) != (in_addr_t)-1))
(inet_pton(AF_INET, a[2], &new->netmask) > 0))
{
new->flags |= CONTEXT_NETMASK;
leasepos = 3;
@@ -2345,7 +2376,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
if (k >= 4 && strchr(a[3], '.') &&
((new->broadcast.s_addr = inet_addr(a[3])) != (in_addr_t)-1))
(inet_pton(AF_INET, a[3], &new->broadcast) > 0))
{
new->flags |= CONTEXT_BRDCAST;
leasepos = 4;
@@ -2378,6 +2409,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
new->template_interface = opt_string_alloc(a[leasepos] + 12);
new->flags |= CONTEXT_TEMPLATE;
}
else if (strstr(a[leasepos], "constructor-noauth:") == a[leasepos])
{
new->template_interface = opt_string_alloc(a[leasepos] + 19);
new->flags |= CONTEXT_TEMPLATE | CONTEXT_NOAUTH;
}
else
break;
}
@@ -2418,6 +2454,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
}
#endif
else
ret_err(_("bad dhcp-range"));
if (leasepos < k)
{
@@ -2475,7 +2513,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
case 'G': /* --dhcp-host */
{
int j, k = 0;
char *a[6] = { NULL, NULL, NULL, NULL, NULL, NULL };
char *a[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
struct dhcp_config *new;
struct in_addr in;
@@ -2487,7 +2525,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
new->netid = NULL;
if ((a[0] = arg))
for (k = 1; k < 6; k++)
for (k = 1; k < 7; k++)
if (!(a[k] = split(a[k-1])))
break;
@@ -2573,7 +2611,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
}
}
else if (strchr(a[j], '.') && (in.s_addr = inet_addr(a[j])) != (in_addr_t)-1)
else if (strchr(a[j], '.') && (inet_pton(AF_INET, a[j], &in) > 0))
{
struct dhcp_config *configs;
@@ -2770,17 +2808,17 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
if (comma)
{
unhide_metas(comma);
if ((dhcp_next_server.s_addr = inet_addr(comma)) == (in_addr_t)-1) {
/*
* The user may have specified the tftp hostname here.
* save it so that it can be resolved/looked up during
* actual dhcp_reply().
*/
tftp_sname = opt_string_alloc(comma);
dhcp_next_server.s_addr = 0;
}
if (!(inet_pton(AF_INET, comma, &dhcp_next_server) > 0))
{
/*
* The user may have specified the tftp hostname here.
* save it so that it can be resolved/looked up during
* actual dhcp_reply().
*/
tftp_sname = opt_string_alloc(comma);
dhcp_next_server.s_addr = 0;
}
}
}
@@ -2793,7 +2831,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
new->next = daemon->boot_config;
daemon->boot_config = new;
}
break;
}
@@ -3109,7 +3147,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
while (arg) {
struct addr_list *new = opt_malloc(sizeof(struct addr_list));
comma = split(arg);
if ((new->addr.s_addr = inet_addr(arg)) == (in_addr_t)-1)
if (!(inet_pton(AF_INET, arg, &new->addr) > 0))
ret_err(_("bad dhcp-proxy address"));
new->next = daemon->override_relays;
daemon->override_relays = new;
@@ -3152,15 +3190,15 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
dash = split_chr(a[0], '-');
if ((k < 2) ||
((new->in.s_addr = inet_addr(a[0])) == (in_addr_t)-1) ||
((new->out.s_addr = inet_addr(a[1])) == (in_addr_t)-1))
(!(inet_pton(AF_INET, a[0], &new->in) > 0)) ||
(!(inet_pton(AF_INET, a[1], &new->out) > 0)))
option = '?';
if (k == 3)
new->mask.s_addr = inet_addr(a[2]);
inet_pton(AF_INET, a[2], &new->mask);
if (dash &&
((new->end.s_addr = inet_addr(dash)) == (in_addr_t)-1 ||
(!(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"));
@@ -3180,6 +3218,10 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
new = opt_malloc(sizeof(struct interface_name));
new->next = NULL;
new->addr4 = NULL;
#ifdef HAVE_IPV6
new->addr6 = NULL;
#endif
/* Add to the end of the list, so that first name
of an interface is used for PTR lookups. */
for (up = &daemon->int_names; *up; up = &((*up)->next));
+99 -29
View File
@@ -47,6 +47,7 @@ static int iface_search(struct in6_addr *local, int prefix,
int scope, int if_index, int flags,
int prefered, int valid, void *vparam);
static int add_lla(int index, unsigned int type, char *mac, size_t maclen, void *parm);
static void new_timeout(struct dhcp_context *context, time_t now);
static int hop_limit;
@@ -187,9 +188,8 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
{
struct ra_packet *ra;
struct ra_param parm;
struct ifreq ifr;
struct sockaddr_in6 addr;
struct dhcp_context *context;
struct dhcp_context *context, *tmp, **up;
struct dhcp_netid iface_id;
struct dhcp_opt *opt_cfg;
int done_dns = 0;
@@ -228,12 +228,66 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
context->netid.next = &context->netid;
}
if (!iface_enumerate(AF_INET6, &parm, add_prefixes) ||
!parm.found_context)
if (!iface_enumerate(AF_INET6, &parm, add_prefixes))
return;
strncpy(ifr.ifr_name, iface_name, IF_NAMESIZE);
/* Look for constructed contexts associated with addresses which have gone,
and advertise them with preferred_time == 0 RFC 6204 4.3 L-13 */
for (up = &daemon->dhcp6, context = daemon->dhcp6; context; context = tmp)
{
tmp = context->next;
if (context->if_index == iface && (context->flags & CONTEXT_OLD))
{
unsigned int old = difftime(now, context->address_lost_time);
if (old > context->saved_valid)
{
/* We've advertised this enough, time to go */
*up = context->next;
free(context);
}
else
{
struct prefix_opt *opt;
struct in6_addr local = context->start6;
int do_slaac = 0;
parm.found_context = 1;
/* zero net part of address */
setaddr6part(&local, addr6part(&local) & ~((context->prefix == 64) ? (u64)-1LL : (1LLU << (128 - context->prefix)) - 1LLU));
if ((context->flags &
(CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)))
do_slaac = 1;
if ((opt = expand(sizeof(struct prefix_opt))))
{
opt->type = ICMP6_OPT_PREFIX;
opt->len = 4;
opt->prefix_len = context->prefix;
/* autonomous only if we're not doing dhcp, always set "on-link" */
opt->flags = do_slaac ? 0xC0 : 0x80;
opt->valid_lifetime = htonl(context->saved_valid - old);
opt->preferred_lifetime = htonl(0);
opt->reserved = 0;
opt->prefix = local;
inet_ntop(AF_INET6, &local, daemon->addrbuff, ADDRSTRLEN);
my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s old prefix", iface_name, daemon->addrbuff);
}
up = &context->next;
}
}
else
up = &context->next;
}
if (!parm.found_context)
return;
#ifdef HAVE_LINUX_NETWORK
/* Note that IPv6 MTU is not necessarilly the same as the IPv4 MTU
available from SIOCGIFMTU */
@@ -291,7 +345,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
put_opt6_char(ICMP6_OPT_DNSSL);
put_opt6_char(len + 1);
put_opt6_short(0);
put_opt6_long(1800); /* lifetime - twice RA retransmit */
put_opt6_long(RA_INTERVAL * 2); /* lifetime - twice RA retransmit */
put_opt6(opt_cfg->val, opt_cfg->len);
/* pad */
@@ -300,9 +354,9 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
}
}
if (!done_dns)
if (daemon->port == NAMESERVER_PORT && !done_dns)
{
/* default == us. */
/* default == us, as long as we are supplying DNS service. */
put_opt6_char(ICMP6_OPT_RDNSS);
put_opt6_char(3);
put_opt6_short(0);
@@ -361,11 +415,13 @@ static int add_prefixes(struct in6_addr *local, int prefix,
struct dhcp_context *context;
for (context = daemon->dhcp6; context; context = context->next)
if (!(context->flags & CONTEXT_TEMPLATE) &&
if (!(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
prefix == context->prefix &&
is_same_net6(local, &context->start6, prefix) &&
is_same_net6(local, &context->end6, prefix))
{
context->saved_valid = valid;
if ((context->flags &
(CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)))
{
@@ -386,12 +442,12 @@ static int add_prefixes(struct in6_addr *local, int prefix,
param->other = 1;
}
/* find floor time, don't reduce below RA interval. */
/* find floor time, don't reduce below 3 * RA interval. */
if (time > context->lease_time)
{
time = context->lease_time;
if (time < ((unsigned int)RA_INTERVAL))
time = RA_INTERVAL;
if (time < ((unsigned int)(3 * RA_INTERVAL)))
time = 3 * RA_INTERVAL;
}
if (context->flags & CONTEXT_DEPRECATE)
@@ -466,6 +522,7 @@ static int add_prefixes(struct in6_addr *local, int prefix,
inet_ntop(AF_INET6, local, daemon->addrbuff, ADDRSTRLEN);
my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s", param->if_name, daemon->addrbuff);
}
}
}
}
@@ -520,16 +577,25 @@ time_t periodic_ra(time_t now)
if (!context)
break;
/* There's a context overdue, but we can't find an interface
associated with it, because it's for a subnet we dont
have an interface on. Probably we're doing DHCP on
a remote subnet via a relay. Zero the timer, since we won't
ever be able to send ra's and satistfy it. */
if (iface_enumerate(AF_INET6, &param, iface_search))
if ((context->flags & CONTEXT_OLD) && context->if_index != 0)
{
/* A context for an old address. We'll not find the interface by
looking for addresses, but we know it anyway, as long as we
sent at least one RA whilst the address was current. */
param.iface = context->if_index;
new_timeout(context, now);
}
else if (iface_enumerate(AF_INET6, &param, iface_search))
/* There's a context overdue, but we can't find an interface
associated with it, because it's for a subnet we dont
have an interface on. Probably we're doing DHCP on
a remote subnet via a relay. Zero the timer, since we won't
ever be able to send ra's and satistfy it. */
context->ra_time = 0;
else if (param.iface != 0 &&
indextoname(daemon->icmp6fd, param.iface, interface) &&
iface_check(AF_LOCAL, NULL, interface, NULL))
if (param.iface != 0 &&
indextoname(daemon->icmp6fd, param.iface, interface) &&
iface_check(AF_LOCAL, NULL, interface, NULL))
{
struct iname *tmp;
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
@@ -554,7 +620,7 @@ static int iface_search(struct in6_addr *local, int prefix,
(void)valid;
for (context = daemon->dhcp6; context; context = context->next)
if (!(context->flags & CONTEXT_TEMPLATE) &&
if (!(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
prefix == context->prefix &&
is_same_net6(local, &context->start6, prefix) &&
is_same_net6(local, &context->end6, prefix) &&
@@ -568,12 +634,7 @@ static int iface_search(struct in6_addr *local, int prefix,
if (!(flags & IFACE_TENTATIVE))
param->iface = if_index;
if (difftime(param->now, context->ra_short_period_start) < 60.0)
/* range 5 - 20 */
context->ra_time = param->now + 5 + (rand16()/4400);
else
/* range 3/4 - 1 times RA_INTERVAL */
context->ra_time = param->now + (3 * RA_INTERVAL)/4 + ((RA_INTERVAL * (unsigned int)rand16()) >> 18);
new_timeout(context, param->now);
/* zero timers for other contexts on the same subnet, so they don't timeout
independently */
@@ -588,6 +649,15 @@ static int iface_search(struct in6_addr *local, int prefix,
return 1; /* keep searching */
}
static void new_timeout(struct dhcp_context *context, time_t now)
{
if (difftime(now, context->ra_short_period_start) < 60.0)
/* range 5 - 20 */
context->ra_time = now + 5 + (rand16()/4400);
else
/* range 3/4 - 1 times RA_INTERVAL */
context->ra_time = now + (3 * RA_INTERVAL)/4 + ((RA_INTERVAL * (unsigned int)rand16()) >> 18);
}
#endif
+78 -23
View File
@@ -1450,19 +1450,42 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
if (is_arpa == F_IPV4)
for (intr = daemon->int_names; intr; intr = intr->next)
{
if (addr.addr.addr4.s_addr == get_ifaddr(intr->intr).s_addr)
struct addrlist *addrlist;
for (addrlist = intr->addr4; addrlist; addrlist = addrlist->next)
if (addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr)
break;
if (addrlist)
break;
else
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->addr6; addrlist; addrlist = addrlist->next)
if (IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6))
break;
if (addrlist)
break;
else
while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
intr = intr->next;
}
#endif
if (intr)
{
ans = 1;
if (!dryrun)
{
log_query(F_IPV4 | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
log_query(is_arpa | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->local_ttl, NULL,
T_PTR, C_IN, "d", intr->name))
@@ -1517,6 +1540,19 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
}
}
} while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
else if (is_rev_synth(is_arpa, &addr, name))
{
ans = 1;
if (!dryrun)
{
log_query(F_CONFIG | F_REVERSE | is_arpa, name, &addr, NULL);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->local_ttl, NULL,
T_PTR, C_IN, "d", name))
anscount++;
}
}
else if (is_arpa == F_IPV4 &&
option_bool(OPT_BOGUSPRIV) &&
private_net(addr.addr.addr4, 1))
@@ -1533,7 +1569,8 @@ 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;
struct interface_name *intr;
if (flag == F_IPV6)
#ifdef HAVE_IPV6
type = T_AAAA;
@@ -1582,31 +1619,38 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
}
/* interface name stuff */
if (qtype == T_A)
for (intr = daemon->int_names; intr; intr = intr->next)
if (hostname_isequal(name, intr->name))
break;
if (intr)
{
struct interface_name *intr;
struct addrlist *addrlist;
for (intr = daemon->int_names; intr; intr = intr->next)
if (hostname_isequal(name, intr->name))
break;
enumerate_interfaces(0);
if (intr)
addrlist = intr->addr4;
#ifdef HAVE_IPV6
if (type == T_AAAA)
addrlist = intr->addr6;
#endif
ans = 1;
if (!dryrun)
{
ans = 1;
if (!dryrun)
{
if ((addr.addr.addr4 = get_ifaddr(intr->intr)).s_addr == (in_addr_t) -1)
log_query(F_FORWARD | F_CONFIG | F_IPV4 | F_NEG, name, NULL, NULL);
else
{
log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->local_ttl, NULL, type, C_IN, "4", &addr))
anscount++;
}
}
continue;
if (!addrlist)
log_query(F_FORWARD | F_CONFIG | flag | F_NEG, name, NULL, NULL);
else
for (; addrlist; addrlist = addrlist->next)
{
log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->local_ttl, NULL, type, C_IN,
type == T_A ? "4" : "6", &addrlist->addr))
anscount++;
}
}
continue;
}
cname_restart:
@@ -1687,6 +1731,17 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
}
} while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
}
else if (is_name_synthetic(flag, name, &addr))
{
ans = 1;
if (!dryrun)
{
log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->local_ttl, NULL, type, C_IN, type == T_A ? "4" : "6", &addr))
anscount++;
}
}
}
if (qtype == T_CNAME || qtype == T_ANY)
+139 -121
View File
@@ -39,6 +39,7 @@ static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt
static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize);
static size_t dhcp_packet_size(struct dhcp_packet *mess, unsigned char *agent_id, unsigned char *real_end);
static void clear_packet(struct dhcp_packet *mess, unsigned char *end);
static int in_list(unsigned char *list, int opt);
static void do_options(struct dhcp_context *context,
struct dhcp_packet *mess,
unsigned char *real_end,
@@ -354,6 +355,117 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
ntohl(mess->xid), daemon->namebuff, inet_ntoa(context_tmp->end));
}
}
/* dhcp-match. If we have hex-and-wildcards, look for a left-anchored match.
Otherwise assume the option is an array, and look for a matching element.
If no data given, existance of the option is enough. This code handles
rfc3925 V-I classes too. */
for (o = daemon->dhcp_match; o; o = o->next)
{
unsigned int len, elen, match = 0;
size_t offset, o2;
if (o->flags & DHOPT_RFC3925)
{
if (!(opt = option_find(mess, sz, OPTION_VENDOR_IDENT, 5)))
continue;
for (offset = 0; offset < (option_len(opt) - 5u); offset += len + 5)
{
len = option_uint(opt, offset + 4 , 1);
/* Need to take care that bad data can't run us off the end of the packet */
if ((offset + len + 5 <= (option_len(opt))) &&
(option_uint(opt, offset, 4) == (unsigned int)o->u.encap))
for (o2 = offset + 5; o2 < offset + len + 5; o2 += elen + 1)
{
elen = option_uint(opt, o2, 1);
if ((o2 + elen + 1 <= option_len(opt)) &&
(match = match_bytes(o, option_ptr(opt, o2 + 1), elen)))
break;
}
if (match)
break;
}
}
else
{
if (!(opt = option_find(mess, sz, o->opt, 1)))
continue;
match = match_bytes(o, option_ptr(opt, 0), option_len(opt));
}
if (match)
{
o->netid->next = netid;
netid = o->netid;
}
}
/* user-class options are, according to RFC3004, supposed to contain
a set of counted strings. Here we check that this is so (by seeing
if the counts are consistent with the overall option length) and if
so zero the counts so that we don't get spurious matches between
the vendor string and the counts. If the lengths don't add up, we
assume that the option is a single string and non RFC3004 compliant
and just do the substring match. dhclient provides these broken options.
The code, later, which sends user-class data to the lease-change script
relies on the transformation done here.
*/
if ((opt = option_find(mess, sz, OPTION_USER_CLASS, 1)))
{
unsigned char *ucp = option_ptr(opt, 0);
int tmp, j;
for (j = 0; j < option_len(opt); j += ucp[j] + 1);
if (j == option_len(opt))
for (j = 0; j < option_len(opt); j = tmp)
{
tmp = j + ucp[j] + 1;
ucp[j] = 0;
}
}
for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
{
int mopt;
if (vendor->match_type == MATCH_VENDOR)
mopt = OPTION_VENDOR_ID;
else if (vendor->match_type == MATCH_USER)
mopt = OPTION_USER_CLASS;
else
continue;
if ((opt = option_find(mess, sz, mopt, 1)))
{
int i;
for (i = 0; i <= (option_len(opt) - vendor->len); i++)
if (memcmp(vendor->data, option_ptr(opt, i), vendor->len) == 0)
{
vendor->netid.next = netid;
netid = &vendor->netid;
break;
}
}
}
/* mark vendor-encapsulated options which match the client-supplied vendor class,
save client-supplied vendor class */
if ((opt = option_find(mess, sz, OPTION_VENDOR_ID, 1)))
{
memcpy(daemon->dhcp_buff3, option_ptr(opt, 0), option_len(opt));
vendor_class_len = option_len(opt);
}
match_vendor_opts(opt, daemon->dhcp_opts);
if (option_bool(OPT_LOG_OPTS))
{
if (sanitise(opt, daemon->namebuff))
my_syslog(MS_DHCP | LOG_INFO, _("%u vendor class: %s"), ntohl(mess->xid), daemon->namebuff);
if (sanitise(option_find(mess, sz, OPTION_USER_CLASS, 1), daemon->namebuff))
my_syslog(MS_DHCP | LOG_INFO, _("%u user class: %s"), ntohl(mess->xid), daemon->namebuff);
}
mess->op = BOOTREPLY;
@@ -493,9 +605,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
lease_set_interface(lease, int_index, now);
clear_packet(mess, end);
match_vendor_opts(NULL, daemon->dhcp_opts); /* clear flags */
do_options(context, mess, end, NULL, hostname, get_domain(mess->yiaddr),
netid, subnet_addr, 0, 0, -1, NULL, 0, now);
netid, subnet_addr, 0, 0, -1, NULL, vendor_class_len, now);
}
}
@@ -504,7 +615,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
return message ? 0 : dhcp_packet_size(mess, agent_id, real_end);
}
if ((opt = option_find(mess, sz, OPTION_CLIENT_FQDN, 4)))
if ((opt = option_find(mess, sz, OPTION_CLIENT_FQDN, 3)))
{
/* http://tools.ietf.org/wg/dhc/draft-ietf-dhc-fqdn-option/draft-ietf-dhc-fqdn-option-10.txt */
int len = option_len(opt);
@@ -534,7 +645,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
}
if (fqdn_flags & 0x04)
while (*op != 0 && ((op + (*op) + 1) - pp) < len)
while (*op != 0 && ((op + (*op)) - pp) < len)
{
memcpy(pq, op+1, *op);
pq += *op;
@@ -622,119 +733,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
}
}
/* dhcp-match. If we have hex-and-wildcards, look for a left-anchored match.
Otherwise assume the option is an array, and look for a matching element.
If no data given, existance of the option is enough. This code handles
rfc3925 V-I classes too. */
for (o = daemon->dhcp_match; o; o = o->next)
{
unsigned int len, elen, match = 0;
size_t offset, o2;
if (o->flags & DHOPT_RFC3925)
{
if (!(opt = option_find(mess, sz, OPTION_VENDOR_IDENT, 5)))
continue;
for (offset = 0; offset < (option_len(opt) - 5u); offset += len + 5)
{
len = option_uint(opt, offset + 4 , 1);
/* Need to take care that bad data can't run us off the end of the packet */
if ((offset + len + 5 <= (option_len(opt))) &&
(option_uint(opt, offset, 4) == (unsigned int)o->u.encap))
for (o2 = offset + 5; o2 < offset + len + 5; o2 += elen + 1)
{
elen = option_uint(opt, o2, 1);
if ((o2 + elen + 1 <= option_len(opt)) &&
(match = match_bytes(o, option_ptr(opt, o2 + 1), elen)))
break;
}
if (match)
break;
}
}
else
{
if (!(opt = option_find(mess, sz, o->opt, 1)))
continue;
match = match_bytes(o, option_ptr(opt, 0), option_len(opt));
}
if (match)
{
o->netid->next = netid;
netid = o->netid;
}
}
/* user-class options are, according to RFC3004, supposed to contain
a set of counted strings. Here we check that this is so (by seeing
if the counts are consistent with the overall option length) and if
so zero the counts so that we don't get spurious matches between
the vendor string and the counts. If the lengths don't add up, we
assume that the option is a single string and non RFC3004 compliant
and just do the substring match. dhclient provides these broken options.
The code, later, which sends user-class data to the lease-change script
relies on the transformation done here.
*/
if ((opt = option_find(mess, sz, OPTION_USER_CLASS, 1)))
{
unsigned char *ucp = option_ptr(opt, 0);
int tmp, j;
for (j = 0; j < option_len(opt); j += ucp[j] + 1);
if (j == option_len(opt))
for (j = 0; j < option_len(opt); j = tmp)
{
tmp = j + ucp[j] + 1;
ucp[j] = 0;
}
}
for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
{
int mopt;
if (vendor->match_type == MATCH_VENDOR)
mopt = OPTION_VENDOR_ID;
else if (vendor->match_type == MATCH_USER)
mopt = OPTION_USER_CLASS;
else
continue;
if ((opt = option_find(mess, sz, mopt, 1)))
{
int i;
for (i = 0; i <= (option_len(opt) - vendor->len); i++)
if (memcmp(vendor->data, option_ptr(opt, i), vendor->len) == 0)
{
vendor->netid.next = netid;
netid = &vendor->netid;
break;
}
}
}
/* mark vendor-encapsulated options which match the client-supplied vendor class,
save client-supplied vendor class */
if ((opt = option_find(mess, sz, OPTION_VENDOR_ID, 1)))
{
memcpy(daemon->dhcp_buff3, option_ptr(opt, 0), option_len(opt));
vendor_class_len = option_len(opt);
}
match_vendor_opts(opt, daemon->dhcp_opts);
if (option_bool(OPT_LOG_OPTS))
{
if (sanitise(opt, daemon->namebuff))
my_syslog(MS_DHCP | LOG_INFO, _("%u vendor class: %s"), ntohl(mess->xid), daemon->namebuff);
if (sanitise(option_find(mess, sz, OPTION_USER_CLASS, 1), daemon->namebuff))
my_syslog(MS_DHCP | LOG_INFO, _("%u user class: %s"), ntohl(mess->xid), daemon->namebuff);
}
tagif_netid = run_tag_if(netid);
/* if all the netids in the ignore list are present, ignore this client */
for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
if (match_netid(id_list->list, tagif_netid, 0))
@@ -1072,7 +1072,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
Have to set override to make sure we echo back the correct server-id */
struct irec *intr;
enumerate_interfaces();
enumerate_interfaces(0);
for (intr = daemon->interfaces; intr; intr = intr->next)
if (intr->addr.sa.sa_family == AF_INET &&
@@ -1410,7 +1410,21 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
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));
/* RFC 2131 says that DHCPINFORM shouldn't include lease-time parameters, but
we supply a utility which makes DHCPINFORM requests to get this information.
Only include lease time if OPTION_LEASE_TIME is in the parameter request list,
which won't be true for ordinary clients, but will be true for the
dhcp_lease_time utility. */
if (lease && in_list(req_options, OPTION_LEASE_TIME))
{
if (lease->expires == 0)
time = 0xffffffff;
else
time = (unsigned int)difftime(lease->expires, now);
option_put(mess, end, OPTION_LEASE_TIME, 4, time);
}
do_options(context, mess, end, req_options, hostname, get_domain(mess->ciaddr),
netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now);
@@ -2275,7 +2289,9 @@ static void do_options(struct dhcp_context *context,
if (domain)
len += strlen(domain) + 1;
else if (fqdn_flags & 0x04)
len--;
if ((p = free_space(mess, end, OPTION_CLIENT_FQDN, len)))
{
*(p++) = fqdn_flags & 0x0f; /* MBZ bits to zero */
@@ -2286,8 +2302,10 @@ static void do_options(struct dhcp_context *context,
{
p = do_rfc1035_name(p, hostname);
if (domain)
p = do_rfc1035_name(p, domain);
*p++ = 0;
{
p = do_rfc1035_name(p, domain);
*p++ = 0;
}
}
else
{
+12 -9
View File
@@ -120,10 +120,11 @@ static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **
!IN6_IS_ADDR_MULTICAST(link_address))
for (c = daemon->dhcp6; c; c = c->next)
if ((c->flags & CONTEXT_DHCP) &&
!(c->flags & CONTEXT_TEMPLATE) &&
!(c->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
is_same_net6(link_address, &c->start6, c->prefix) &&
is_same_net6(link_address, &c->end6, c->prefix))
{
c->preferred = c->valid = 0xffffffff;
c->current = context;
context = c;
}
@@ -693,7 +694,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
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, requested_time, &min_time, &addr, rapid_commit != NULL, now);
add_address(&state, c, lease_time, lease_time, &min_time, &addr, rapid_commit != NULL, now);
mark_context_used(&state, context, &addr);
get_context_tag(&state, c);
address_assigned = 1;
@@ -1298,16 +1299,18 @@ struct dhcp_netid *add_options(struct state *state, struct in6_addr *fallback, s
size_t len = strlen(state->hostname);
if (state->send_domain)
len += strlen(state->send_domain) + 1;
len += strlen(state->send_domain) + 2;
o = new_opt6(OPTION6_FQDN);
if ((p = expand(len + 3)))
if ((p = expand(len + 2)))
{
*(p++) = state->fqdn_flags;
p = do_rfc1035_name(p, state->hostname);
if (state->send_domain)
p = do_rfc1035_name(p, state->send_domain);
*p = 0;
{
p = do_rfc1035_name(p, state->send_domain);
*p = 0;
}
}
end_opt6(o);
}
@@ -1608,12 +1611,12 @@ static void update_leases(struct state *state, struct dhcp_context *context, str
free(lease->extradata);
lease->extradata = NULL;
lease->extradata_size = lease->extradata_len = 0;
lease->hwaddr_len = 0; /* surrogate for no of vendor classes */
lease->vendorclass_count = 0;
if ((class_opt = opt6_find(state->packet_options, state->end, OPTION6_VENDOR_CLASS, 4)))
{
void *enc_opt, *enc_end = opt6_ptr(class_opt, opt6_len(class_opt));
lease->hwaddr_len++;
lease->vendorclass_count++;
/* send enterprise number first */
sprintf(daemon->dhcp_buff2, "%u", opt6_uint(class_opt, 0, 4));
lease_add_extradata(lease, (unsigned char *)daemon->dhcp_buff2, strlen(daemon->dhcp_buff2), 0);
@@ -1621,7 +1624,7 @@ static void update_leases(struct state *state, struct dhcp_context *context, str
if (opt6_len(class_opt) >= 6)
for (enc_opt = opt6_ptr(class_opt, 4); enc_opt; enc_opt = opt6_next(enc_opt, enc_end))
{
lease->hwaddr_len++;
lease->vendorclass_count++;
lease_add_extradata(lease, opt6_ptr(enc_opt, 0), opt6_len(enc_opt), 0);
}
}
+4 -2
View File
@@ -38,7 +38,9 @@ void slaac_add_addrs(struct dhcp_lease *lease, time_t now, int force)
lease->slaac_address = NULL;
for (context = daemon->dhcp6; context; context = context->next)
if ((context->flags & CONTEXT_RA_NAME) && lease->last_interface == context->if_index)
if ((context->flags & CONTEXT_RA_NAME) &&
!(context->flags & CONTEXT_OLD) &&
lease->last_interface == context->if_index)
{
struct in6_addr addr = context->start6;
if (lease->hwaddr_len == 6 &&
@@ -123,7 +125,7 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
time_t next_event = 0;
for (context = daemon->dhcp6; context; context = context->next)
if ((context->flags & CONTEXT_RA_NAME))
if ((context->flags & CONTEXT_RA_NAME) && !(context->flags & CONTEXT_OLD))
break;
/* nothing configured */
+4 -3
View File
@@ -201,8 +201,9 @@ void tftp_request(struct listener *listen, time_t now)
if (!iface_check(listen->family, &addra, name, NULL))
{
if (!option_bool(OPT_CLEVERBIND))
enumerate_interfaces();
if (!loopback_exception(listen->tftpfd, listen->family, &addra, name))
enumerate_interfaces(0);
if (!loopback_exception(listen->tftpfd, listen->family, &addra, name) &&
!label_exception(if_index, listen->family, &addra) )
return;
}
@@ -554,7 +555,7 @@ void check_tftp_listeners(fd_set *rset, time_t now)
}
/* don't complain about timeout when we're awaiting the last
ACK, some clients never send it */
else if (++transfer->backoff > 5 && len != 0)
else if (++transfer->backoff > 7 && len != 0)
{
endcon = 1;
len = 0;
+6 -3
View File
@@ -142,17 +142,20 @@ static int check_name(char *in)
int legal_hostname(char *name)
{
char c;
int first;
if (!check_name(name))
return 0;
for (; (c = *name); name++)
for (first = 1; (c = *name); name++, first = 0)
/* check for legal char a-z A-Z 0-9 - _ . */
{
if ((c >= 'A' && c <= 'Z') ||
(c >= 'a' && c <= 'z') ||
(c >= '0' && c <= '9') ||
c == '-' || c == '_')
(c >= '0' && c <= '9'))
continue;
if (!first && (c == '-' || c == '_'))
continue;
/* end of hostname part */