Compare commits

...

58 Commits

Author SHA1 Message Date
Simon Kelley
4bb68866a8 Tweak ICMP ping check logic for DHCPv4. 2017-06-15 23:23:25 +01:00
Chris Novakovic
2446514e71 Fix logic of appending ".<layer>" to PXE basename
Commit f77700aa, which fixes a compiler warning, also breaks the
behaviour of prepending ".<layer>" to basenames in --pxe-service: in
situations where the basename contains a ".", the ".<layer>" suffix is
erroneously added, and in situations where the basename doesn't contain
a ".", the ".<layer>" suffix is erroneously omitted.

A patch against the git HEAD is attached that inverts this logic and
restores the expected behaviour of --pxe-service.
2017-06-06 23:02:59 +01:00
Simon Kelley
109d0e74f1 Debian: improve regexp for parsing root.ds. 2017-06-05 20:50:54 +01:00
Simon Kelley
74ea91531a Fix typo and format in CHANGELOG 2017-05-22 22:58:46 +01:00
Matthias Andree
9828ab115e Fix compiler warning. 2017-05-21 22:41:16 +01:00
Matthias Andree
f77700aa27 Fix compiler warning. 2017-05-21 22:36:09 +01:00
Simon Kelley
0fbd980639 Fix compiler warning. 2017-05-21 22:24:43 +01:00
Simon Kelley
43cdf1c3d0 Remove automatic IDN support when building i18n.
Remove historic automatic inclusion of IDN support when
building internationalisation support. This doesn't
fit now there is a choice of IDN libraries. Be sure
to include either -DHAVE_IDN or _DHAVE_LIBIDN2 for
IDN support
2017-05-21 22:12:44 +01:00
Simon Kelley
ff19b1a97d Fix &/&& confusion. 2017-05-21 21:15:32 +01:00
Conrad Kostecki
1835343acd Update German translation. 2017-05-12 15:16:02 +01:00
Simon Kelley
2aaea18f43 Add .gitattributes to substitute VERSION on export. 2017-05-12 13:14:17 +01:00
Simon Kelley
7ab78b937f Fix c7be0164ce 2017-05-11 20:33:21 +01:00
Simon Kelley
c7be0164ce Suppress DHCP ping checks when allocating on the loopback interface. 2017-05-10 22:21:53 +01:00
Petr Menšík
d203af4a02 Add optional support for libidn2 and therefore IDNA2008. 2017-05-10 21:41:57 +01:00
Simon Kelley
05f76dab89 Don't die() on failing to parse lease-script output. 2017-05-09 22:57:04 +01:00
Simon Kelley
bf05f8ff20 Fix crash introduced by 09f3b2cd9c. 2017-05-09 22:37:46 +01:00
Simon Kelley
09f3b2cd9c Fix case of DS queries to domains marked as not doing DNSSEC.
This was causing confusion: DNSSEC queries would be sent to
servers for domains that don't do DNSSEC, but because of that status
the answers would be treated as answers to ordinary queries,
sometimes resulting in a crash.
2017-05-09 01:34:02 +01:00
Simon Kelley
22827870fa Fix botch introduced by 561441320f 2017-05-08 21:39:04 +01:00
Vladislav Grishenko
4583dd9e42 Replace obsolete utime() usage with utimes().
This fixes build time warnings with POSIX.1-2008-aware c libraries.
2017-05-03 23:16:51 +01:00
Simon Kelley
561441320f Fix a couple of crashes on malformed config files.
Thanks to Stephan Zeisberg and
american fuzzy lop http://lcamtuf.coredump.cx/afl/
2017-05-03 22:54:09 +01:00
Simon Kelley
b2a9c571eb Add "known-othernet" DHCP tag. 2017-04-30 18:21:31 +01:00
Simon Kelley
efff74c1ae Tweak logging introduced in 3a8b0f6fcc 2017-04-28 23:01:23 +01:00
Simon Kelley
a9df0e30b0 Revert "Implement RFC-6842 (Client-ids in DHCP replies.)"
This reverts commit 88a77a78ad.

A least one client has been found which breaks with this change. Since
the use-case is not clear, I'm reverting the change, at least for now.
2017-04-28 22:44:24 +01:00
Simon Kelley
5ce3e76fbf DHCPv4: do ICMP-ping check in all cases other that current lease. 2017-04-28 22:14:20 +01:00
Vladislav Grishenko
6ec5f5c427 Extend --ra-param mtu: field to allow an interface name. 2017-04-24 22:34:45 +01:00
Vladislav Grishenko
5a7212c70e Make --rev-server work in the presence of --bogus-priv. 2017-04-24 22:21:04 +01:00
Petr Menšík
3a8b0f6fcc Improve error handling with shcp-script "init" mode. 2017-04-23 14:12:37 +01:00
Simon Kelley
a24c31e023 Debian: enable PIE and BINDNOW hardening in build. 2017-04-16 22:45:53 +01:00
Simon Kelley
f5a3679f1d Merge branch 'master' of ssh://thekelleys.org.uk/var/cache/git/dnsmasq 2017-04-16 22:27:51 +01:00
Simon Kelley
5ac813cb86 Bump Lua version to 5.2. 2017-04-16 20:47:11 +01:00
Simon Kelley
a93b02e321 Compile option string: show script-support independent of DHCP. 2017-04-16 20:38:22 +01:00
Petr Menšík
c77fb9d8f0 Capture and log STDOUT and STDERR output from dhcp-script. 2017-04-16 20:20:08 +01:00
Simon Kelley
facc18f2a8 Bump Debian standards version. 2017-04-11 18:52:36 +01:00
Simon Kelley
bc515b71ec Merge branch 'master' of ssh://thekelleys.org.uk/var/cache/git/dnsmasq 2017-04-11 18:49:59 +01:00
Simon Kelley
7bfa26399b FreeBSD compilation tweak. 2017-04-11 18:49:27 +01:00
Simon Kelley
461b7b43b4 Debian: readme typos. 2017-04-11 18:06:13 +01:00
Simon Kelley
b1cefa57f1 Debian: strip dhcp_release6 binary. 2017-04-11 15:55:26 +01:00
Simon Kelley
ce9a9704c6 Debian: add lsb-base dep. 2017-04-11 15:34:25 +01:00
Simon Kelley
93a9a55055 Debian changelog format fixup. 2017-04-11 15:21:30 +01:00
Simon Kelley
44eb875a5a Handle change in format of Debian /usr/share/dns/root.ds. 2017-04-11 15:13:09 +01:00
Floris Bos
bc87e609c2 Debian initscript tweak.
Dnsmasq's startup script seems to assume users always want to use
dnsmasq as local DNS resolver, and tells resolvconf to put
"nameserver 127.0.0.1" in /etc/resolv.conf
The problem with this is that if users just want to use dnsmasq
as DHCP server, and put port=0 in /etc/dnsmasq.conf to disable
the DNS functionality, they end up with broken name resolving.

Put a basic check in the startup script that skips resolvconf
configuration if a line starting with port=0 is in /etc/dnsmasq.conf
This doesn't cover all cases (e.g. configuration could also be in
different file in /etc/dnsmasq.d), but is better than current
situation.
2017-04-11 14:19:57 +01:00
David Flamand
005c46d6f5 Add mtu facility to --ra-param. 2017-04-11 11:49:54 +01:00
Floris Bos
503c609149 --dhcp-reply-delay option to workaround PXE client bugs.
Adds option to delay replying to DHCP packets by one or more seconds.
This provides a workaround for a PXE boot firmware implementation
that has a bug causing it to fail if it receives a (proxy) DHCP
reply instantly.

On Linux it looks up the exact receive time of the UDP packet with
the SIOCGSTAMP ioctl to prevent multiple delays if multiple packets
come in around the same time.
2017-04-09 23:07:13 +01:00
Floris Bos
60704f5e2e Add support for unique TFTP root per MAC.
It is currently only possible to let the TFTP server serve a different
folder depending on the client's IP address.
However it isn't always possible to predict what the client's
IP address will be, especially in situations in which we are not
responsible for handing them out (e.g. proxy dhcp setups).

Extend the current --tftp-unique-root parameter to support having a
separate folder per MAC address instead.
2017-04-09 22:22:49 +01:00
Kristian Evensen
4e7694d710 Allow binding to both source address and interface in server specs.
The current --server syntax allows for binding to interface or
address. However, in some (admittedly special) cases it is useful to
be able to specify both. This commit introduces the following syntax
to support binding to both interface and address:

--server X.X.X.X@IP@interface#port

Based on my tests, the syntax is backwards compatible with the current
@IP/interface#port. The code will fail if two interface names are given.

v1->v2:
* Add man page description of the extended server syntax (thanks Simon Kelley)

Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com>
2017-03-22 21:32:50 +00:00
James Bottomley
e33b48700e When forwarding a query to a non-DNSSEC nameserver, don't verify the lack of DNSSEC.
The man page says that we don't do DNSSEC on forwarded domains, but if
you turn on dnssec_check_signatures this turns out to be untrue,
because we try to build up a DS chain to them.  Since forwarded domains
are usually used for split DNS to hidden domains, they're unlikely to
verify to the DNS root anyway, so the way to do DNSSEC for them (as the
manual says) is to provide a trust anchor for each forwarder.

The problem I've run into is a split DNS setup where I want DNSSEC to
work mostly, but one of the forwarding domains doesn't have an internal
DNSSEC capable resolver. Without this patch the entire domain goes
unresolvable because the DS record query to the internal resolver
returns a failure which is interpreted as the domain being BOGUS.

The fix is not to do the DS record chase for forwarded domains.
2017-03-17 21:44:10 +00:00
Petr Menšík
ad59f278c6 Fix man page re interface labels and add warning when used badly. 2017-03-17 17:22:19 +00:00
Bert Gijsbers
16f03e7139 Check for failure of "git describe" in get-version. 2017-03-06 23:07:32 +00:00
Olivier Gayot
dc99058d83 Improve error checking for --rev-server.
The rev-server directive only handles the following CIDR prefixes
properly: /8, /16, /24, /32.

Any other value was silently converted to /16 which could result in
unexpected behaviour.

This patch rejects any other value instead of making a silent
conversion.
2017-03-06 22:17:21 +00:00
Olivier Gayot
916959c188 Fix rev-server with /32 prefix.
[ excerpt from the man page ]
The rev-server directive provides a syntactic sugar to make specifying
address-to-name queries easier. For example
--rev-server=1.2.3.0/24,192.168.0.1 is exactly equivalent to
--server=/3.2.1.in-addr.arpa/192.168.0.1

It is not mentioned in the man page but the only prefixes that the
directive properly handles when dealing with IPv4 are /8, /16 and /24.
Specifying anything else as the same effect as specifying /16.

It is not a big deal for subnets on non-octet boundaries since they
cannot be represented using a single in-addr.arpa address. However, it
is unconvenient for /32 prefix while the analogous server directive
behaves as expected. E.g. the following server directive work
as expected:

    server=/42.10.168.192.in-addr.arpa/1.2.3.4

but the following does not:

    rev-server=192.168.10.42/32,1.2.3.4

and, in practice, the later behaves the same as:

    server=/168.192.in-addr.arpa/1.2.3.4

This strange behaviour is fixed by accepting /32 CIDR prefixes as a
valid value. Any other value will still be considered the same as /16.
2017-03-06 22:14:50 +00:00
Simon Kelley
864913c0f3 Man page typo. 2017-02-28 18:07:18 +00:00
Simon Kelley
13dee6f49e Compilation warning fixes. 2017-02-28 16:51:58 +00:00
Simon Kelley
62f9c0d470 Fix CNAME wildcard in auth-mode.
A domain can only have a CNAME if it has not other records.

Don't return a CNAME when there are records of other types on the name.
2017-02-19 23:07:01 +00:00
Simon Kelley
54bb3639d4 Update FAQ to fix a couple of dead links.
Thanks to Federico Bianchi for reporting this.
2017-02-19 22:13:36 +00:00
Simon Kelley
fca008d8d4 Make --bogus-priv apply to IPv6. 2017-02-19 18:50:41 +00:00
klemens
43517fcaf5 Spelling fixes. 2017-02-19 15:53:37 +00:00
Simon Kelley
88a77a78ad Implement RFC-6842 (Client-ids in DHCP replies.) 2017-02-11 17:02:02 +00:00
Hannu Nyman
3e2496fb16 Decrease the number of individual sites listed in log.
By default 30 first servers are listed individually to system log, and
then a count of the remaining items. With e.g. a NXDOMAIN based adblock
service, dnsmasq lists 30 unnecessary ad sites every time when dnsmasq
evaluates the list. But the actual nameservers in use are evaluated last
and are not displayed as they get included in the "remaining items" total.

Handle the "local addresses only" separately and list only a few of them.
Remove the "local addresses only" from the general count.
2017-02-11 13:44:08 +00:00
37 changed files with 1286 additions and 718 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
VERSION export-subst

485
CHANGELOG
View File

@@ -21,8 +21,8 @@ version 2.77
Thanks to Ivan Kokshaysky for the diagnosis and
patch.
Fix problem with --dnssec-timestamp whereby receipt
of SIGHUP would erroneously engage timestamp checking.
Fix problem with --dnssec-timestamp whereby receipt
of SIGHUP would erroneously engage timestamp checking.
Thanks to Kevin Darbyshire-Bryant for this work.
Bump zone serial on reloading /etc/hosts and friends
@@ -51,35 +51,86 @@ version 2.77
Add DNSMASQ_REQUESTED_OPTIONS environment variable to the
lease-change script. Thanks to ZHAO Yu for the patch.
Fix foobar in rrfilter code, that could cause misformed
Fix foobar in rrfilter code, that could cause malformed
replies, especially when DNSSEC validation on, and
the upstream server returns answer with the RRs in a
particular order. The only DNS server known to tickle
this is Nominum's. Thanks to Dave Täht for spotting the
bug and assisting in the fix.
Fix the manpage which lied that only the primary address
Fix the manpage which lied that only the primary address
of an interface is used by --interface-name.
Make --localise-queries apply to names from --interface-name.
Thanks to Kevin Darbyshire-Bryant and Eric Luehrsen
for pushing this.
Improve connection handling when talking to TCP upsteam
Improve connection handling when talking to TCP upstream
servers. Specifically, be prepared to open a new TCP
connection when we want to make multiple queries
but the upstream server accepts fewer queries per connection.
but the upstream server accepts fewer queries per connection.
Improve logging of upstream servers when there are a lot
of "local addresses only" entries. Thanks to Hannu Nyman for
the patch.
Make --bogus-priv apply to IPv6, for the prefixes specified
in RFC6303. Thanks to Kevin Darbyshire-Bryant for work on this.
Allow use of MAC addresses with --tftp-unique-root. Thanks
to Floris Bos for the patch.
Add --dhcp-reply-delay option. Thanks to Floris Bos
for the patch.
Add mtu setting facility to --ra-param. Thanks to David
Flamand for the patch.
Capture STDOUT and STDERR output from dhcp-script and log
it as part of the dnsmasq log stream. Makes life easier
for diagnosing unexpected problems in scripts.
Thanks to Petr Mensik for the patch.
Generate fatal errors when failing to parse the output
of the dhcp-script in "init" mode. Avoids strange errors
when the script accidentally emits error messages.
Thanks to Petr Mensik for the patch.
Make --rev-server for an RFC1918 subnet work even in the
presence of the --bogus-priv flag. Thanks to
Vladislav Grishenko for the patch.
Extend --ra-param mtu: field to allow an interface name.
This allows the MTU of a WAN interface to be advertised on
the internal interfaces of a router. Thanks to
Vladislav Grishenko for the patch.
Do ICMP-ping check for address-in-use for DHCPv4 when
the client specifies an address in DHCPDISCOVER, and when
an address in configured locally. Thanks to Alin Năstac
for spotting the problem.
Add new DHCP tag "known-othernet" which is set when only a
dhcp-host exists for another subnet. Can be used to ensure
that privileged hosts are not given "guest" addresses by
accident. Thanks to Todd Sanket for the suggestion.
Remove historic automatic inclusion of IDN support when
building internationalisation support. This doesn't
fit now there is a choice of IDN libraries. Be sure
to include either -DHAVE_IDN or -DHAVE_LIBIDN2 for
IDN support.
version 2.76
Include 0.0.0.0/8 in DNS rebind checks. This range
Include 0.0.0.0/8 in DNS rebind checks. This range
translates to hosts on the local network, or, at
least, 0.0.0.0 accesses the local host, so could
be targets for DNS rebinding. See RFC 5735 section 3
for details. Thanks to Stephen Röttger for the bug report.
Enhance --add-subnet to allow arbitrary subnet addresses.
Thanks to Ed Barsley for the patch.
Thanks to Ed Barsley for the patch.
Respect the --no-resolv flag in inotify code. Fixes bug
which caused dnsmasq to fail to start if a resolv-file
@@ -104,7 +155,7 @@ version 2.76
Return REFUSED when running out of forwarding table slots,
not SERVFAIL.
Add --max-port configuration. Thanks to Hans Dedecker for
Add --max-port configuration. Thanks to Hans Dedecker for
the patch.
Add --script-arp and two new functions for the dhcp-script.
@@ -116,7 +167,7 @@ version 2.76
Add --add-cpe-id option.
Don't crash with divide-by-zero if an IPv6 dhcp-range
Don't crash with divide-by-zero if an IPv6 dhcp-range
is declared as a whole /64.
(ie xx::0 to xx::ffff:ffff:ffff:ffff)
Thanks to Laurent Bendel for spotting this problem.
@@ -157,7 +208,7 @@ version 2.76
Add ARM32_EFI and ARM64_EFI as valid architectures in
--pxe-service.
Fix PXE booting for UEFI architectures. Modify PXE boot
Fix PXE booting for UEFI architectures. Modify PXE boot
sequence in this case to force the client to talk to dnsmasq
over port 4011. This makes PXE and especially proxy-DHCP PXE
work with these architectures.
@@ -169,7 +220,7 @@ version 2.76
will be booted directly, rather then sending a
single-item boot menu.
Many thanks to Jarek Polok, Michael Kuron and Dreamcat4
Many thanks to Jarek Polok, Michael Kuron and Dreamcat4
for their work on the long-standing UEFI PXE problem.
Subtle change in the semantics of "basename" in
@@ -192,13 +243,13 @@ version 2.76
version 2.75
Fix reversion on 2.74 which caused 100% CPU use when a
Fix reversion on 2.74 which caused 100% CPU use when a
dhcp-script is configured. Thanks to Adrian Davey for
reporting the bug and testing the fix.
version 2.74
Fix reversion in 2.73 where --conf-file would attempt to
Fix reversion in 2.73 where --conf-file would attempt to
read the default file, rather than no file.
Fix inotify code to handle dangling symlinks better and
@@ -206,11 +257,11 @@ version 2.74
DNSSEC fix. In the case of a signed CNAME generated by a
wildcard which pointed to an unsigned domain, the wrong
status would be logged, and some necessary checks omitted.
status would be logged, and some necessary checks omitted.
version 2.73
Fix crash at startup when an empty suffix is supplied to
Fix crash at startup when an empty suffix is supplied to
--conf-dir, also trivial memory leak. Thanks to
Tomas Hozza for spotting this.
@@ -242,7 +293,7 @@ version 2.73
reply. This is useful to defeat blocking strategies which
rely on quickly supplying a forged answer to a DNS
request for certain domains, before the correct answer can
arrive. Thanks to Glen Huang for the patch.
arrive. Thanks to Glen Huang for the patch.
Revisit the part of DNSSEC validation which determines if an
unsigned answer is legit, or is in some part of the DNS
@@ -299,7 +350,7 @@ version 2.73
memory to be read by an attacker under certain
circumstances, so it has a CVE, CVE-2015-3294
Fix crash in authoritative DNS code, if a .arpa zone
Fix crash in authoritative DNS code, if a .arpa zone
is declared as authoritative, and then a PTR query which
is not to be treated as authoritative arrived. Normally,
directly declaring .arpa zone as authoritative is not
@@ -314,7 +365,7 @@ version 2.73
Previously we provided correct answers to PTR queries
in such zones (including NS and SOA) but not direct
NS and SOA queries. Thanks to Johnny S. Lee for
pointing out the problem.
pointing out the problem.
Fix logging of DHCPREPLY which should be suppressed
by quiet-dhcp6. Thanks to J. Pablo Abonia for
@@ -322,7 +373,7 @@ version 2.73
Try and handle net connections with broken fragmentation
that lose large UDP packets. If a server times out,
reduce the maximum UDP packet size field in the EDNS0
reduce the maximum UDP packet size field in the EDNS0
header to 1280 bytes. If it then answers, make that
change permanent.
@@ -332,7 +383,7 @@ version 2.73
Allow DHCPv4 options T1 and T2 to be set using --dhcp-option.
Thanks to Kevin Benton for patches and work on this.
Fix code for DHCPCONFIRM DHCPv6 messages to confirm addresses
Fix code for DHCPCONFIRM DHCPv6 messages to confirm addresses
in the correct subnet, even of not in dynamic address
allocation range. Thanks to Steve Hirsch for spotting
the problem.
@@ -348,7 +399,7 @@ version 2.73
version 2.72
Add ra-advrouter mode, for RFC-3775 mobile IPv6 support.
Add ra-advrouter mode, for RFC-3775 mobile IPv6 support.
Add support for "ipsets" in *BSD, using pf. Thanks to
Sven Falempin for the patch.
@@ -380,19 +431,19 @@ version 2.72
--conf-dir=/etc/dnsmasq.d,\*.conf
will load all the files in /etc/dnsmasq.d which end in .conf
Fix bug when resulted in NXDOMAIN answers instead of NODATA in
some circumstances.
Fix bug when resulted in NXDOMAIN answers instead of NODATA in
some circumstances.
Fix bug which caused dnsmasq to become unresponsive if it
failed to send packets due to a network interface disappearing.
Thanks to Niels Peen for spotting this.
Fix problem with --local-service option on big-endian platforms
Fix problem with --local-service option on big-endian platforms
Thanks to Richard Genoud for the patch.
version 2.71
Subtle change to error handling to help DNSSEC validation
Subtle change to error handling to help DNSSEC validation
when servers fail to provide NODATA answers for
non-existent DS records.
@@ -410,7 +461,7 @@ version 2.71
version 2.70
Fix crash, introduced in 2.69, on TCP request when dnsmasq
Fix crash, introduced in 2.69, on TCP request when dnsmasq
compiled with DNSSEC support, but running without DNSSEC
enabled. Thanks to Manish Sing for spotting that one.
@@ -461,7 +512,7 @@ version 2.69
conf-file=/path/to/trust-anchors.conf
dnssec
to your config is all thats needed to get things
to your config is all that's needed to get things
working. The upstream nameservers have to be DNSSEC-capable
too, of course. Many ISP nameservers aren't, but the
Google public nameservers (8.8.8.8 and 8.8.4.4) are.
@@ -518,12 +569,12 @@ version 2.69
full access to configuration.
Add --local-service. Accept DNS queries only from hosts
whose address is on a local subnet, ie a subnet for which
an interface exists on the server. This option
only has effect if there are no --interface --except-interface,
--listen-address or --auth-server options. It is intended
to be set as a default on installation, to allow
unconfigured installations to be useful but also safe from
whose address is on a local subnet, ie a subnet for which
an interface exists on the server. This option
only has effect if there are no --interface --except-interface,
--listen-address or --auth-server options. It is intended
to be set as a default on installation, to allow
unconfigured installations to be useful but also safe from
being used for DNS amplification attacks.
Fix crashes in cache_get_cname_target() when dangling CNAMEs
@@ -539,9 +590,9 @@ version 2.69
version 2.68
Use random addresses for DHCPv6 temporary address
allocations, instead of algorithmically determined stable
addresses.
Use random addresses for DHCPv6 temporary address
allocations, instead of algorithmically determined stable
addresses.
Fix bug which meant that the DHCPv6 DUID was not available
in DHCP script runs during the lifetime of the dnsmasq
@@ -649,7 +700,7 @@ version 2.67
we can't use SO_BINDTODEVICE. Thanks to Natrio for the bug
report.
Increase timeout/number of retries in TFTP to accomodate
Increase timeout/number of retries in TFTP to accommodate
AudioCodes Voice Gateways doing streaming writes to flash.
Thanks to Damian Kaczkowski for spotting the problem.
@@ -680,7 +731,7 @@ version 2.67
Support RFC-4242 information-refresh-time options in the
reply to DHCPv6 information-request. The lease time of the
smallest valid dhcp-range is sent. Thanks to Uwe Schindler
smallest valid dhcp-range is sent. Thanks to Uwe Schindler
for suggesting this.
Make --listen-address higher priority than --except-interface
@@ -721,7 +772,7 @@ version 2.67
Fix problem in DHCPv6 vendorclass/userclass matching
code. Thanks to Tanguy Bouzeloc for the patch.
Update Spanish translation. Thanks to Vicente Soriano.
Update Spanish translation. Thanks to Vicente Soriano.
Add --ra-param option. Thanks to Vladislav Grishenko for
inspiration on this.
@@ -747,12 +798,12 @@ version 2.67
version 2.66
Add the ability to act as an authoritative DNS
server. Dnsmasq can now answer queries from the wider 'net
with local data, as long as the correct NS records are set
up. Only local data is provided, to avoid creating an open
DNS relay. Zone transfer is supported, to allow secondary
servers to be configured.
Add the ability to act as an authoritative DNS
server. Dnsmasq can now answer queries from the wider 'net
with local data, as long as the correct NS records are set
up. Only local data is provided, to avoid creating an open
DNS relay. Zone transfer is supported, to allow secondary
servers to be configured.
Add "constructed DHCP ranges" for DHCPv6. This is intended
for IPv6 routers which get prefixes dynamically via prefix
@@ -779,12 +830,12 @@ version 2.66
the local DNS server if dnsmasq is configured to not act
as DNS server, or it's configured to a non-standard port.
Add DNSMASQ_CIRCUIT_ID, DNSMASQ_SUBSCRIBER_ID,
DNSMASQ_REMOTE_ID variables to the environment of the
lease-change script (and the corresponding Lua). These hold
information inserted into the DHCP request by a DHCP relay
agent. Thanks to Lakefield Communications for providing a
bounty for this addition.
Add DNSMASQ_CIRCUIT_ID, DNSMASQ_SUBSCRIBER_ID,
DNSMASQ_REMOTE_ID variables to the environment of the
lease-change script (and the corresponding Lua). These hold
information inserted into the DHCP request by a DHCP relay
agent. Thanks to Lakefield Communications for providing a
bounty for this addition.
Fixed crash, introduced in 2.64, whilst handling DHCPv6
information-requests with some common configurations.
@@ -826,9 +877,9 @@ version 2.65
version 2.64
Handle DHCP FQDN options with all flag bits zero and
--dhcp-client-update set. Thanks to Bernd Krumbroeck for
spotting the problem.
Handle DHCP FQDN options with all flag bits zero and
--dhcp-client-update set. Thanks to Bernd Krumbroeck for
spotting the problem.
Finesse the check for /etc/hosts names which conflict with
DHCP names. Previously a name/address pair in /etc/hosts
@@ -897,7 +948,7 @@ version 2.64
version 2.63
Do duplicate dhcp-host address check in --test mode.
Do duplicate dhcp-host address check in --test mode.
Check that tftp-root directories are accessible before
start-up. Thanks to Daniel Veillard for the initial patch.
@@ -917,7 +968,7 @@ version 2.63
still-born attempt to allow automatic isolated
configuration by libvirt, but have never (to my knowledge)
been used, had very strange semantics, and have been
superceded by other mechanisms.
superseded by other mechanisms.
Fixed bug logging filenames when duplicate dhcp-host
addresses are found. Thanks to John Hanks for the patch.
@@ -927,7 +978,7 @@ version 2.63
Allow the target of a --cname flag to be another --cname.
Teach DHCPv6 about the RFC 4242 information-refresh-time
Teach DHCPv6 about the RFC 4242 information-refresh-time
option, and add parsing if the minutes, hours and days
format for options. Thanks to Francois-Xavier Le Bail for
the suggestion.
@@ -948,9 +999,9 @@ version 2.63
version 2.62
Update German translation. Thanks to Conrad Kostecki.
Update German translation. Thanks to Conrad Kostecki.
Cope with router-solict packets wich don't have a valid
Cope with router-solict packets which don't have a valid
source address. Thanks to Vladislav Grishenko for the patch.
Fixed bug which caused missing periodic router
@@ -979,7 +1030,7 @@ version 2.61
Add ra-names, ra-stateless and slaac keywords for DHCPv6.
Dnsmasq can now synthesise AAAA records for dual-stack
hosts which get IPv6 addresses via SLAAC. It is also now
hosts which get IPv6 addresses via SLAAC. It is also now
possible to use SLAAC and stateless DHCPv6, and to
tell clients to use SLAAC addresses as well as DHCP ones.
Thanks to Dave Taht for help with this.
@@ -1037,7 +1088,7 @@ version 2.61
preferred lease time for both DHCP and RA to zero. The
effect is that clients can continue to use the address
for existing connections, but new connections will use
other addresses, if they exist. This makes hitless
other addresses, if they exist. This makes hitless
renumbering at least possible.
Fix bug in address6_available() which caused DHCPv6 lease
@@ -1079,8 +1130,8 @@ version 2.61
version 2.60
Fix compilation problem in Mac OS X Lion. Thanks to Olaf
Flebbe for the patch.
Fix compilation problem in Mac OS X Lion. Thanks to Olaf
Flebbe for the patch.
Fix DHCP when using --listen-address with an IP address
which is not the primary address of an interface.
@@ -1122,7 +1173,7 @@ version 2.60
Allow the TFP server or boot server in --pxe-service, to
be a domain name instead of an IP address. This allows for
round-robin to multiple servers, in the same way as
round-robin to multiple servers, in the same way as
--dhcp-boot. A good suggestion from Cristiano Cumer.
Support BUILDDIR variable in the Makefile. Allows builds
@@ -1156,26 +1207,26 @@ version 2.60
via an interface other than the expected one. Thanks to
Lorenzo Milesi and John Hanks for spotting this one.
Update French translation. Thanks to Gildas Le Nadan.
Update French translation. Thanks to Gildas Le Nadan.
Update Polish translation. Thanks to Jan Psota.
version 2.59
Fix regression in 2.58 which caused failure to start up
with some combinations of dnsmasq config and IPv6 kernel
network config. Thanks to Brielle Bruns for the bug
report.
Fix regression in 2.58 which caused failure to start up
with some combinations of dnsmasq config and IPv6 kernel
network config. Thanks to Brielle Bruns for the bug
report.
Improve dnsmasq's behaviour when network interfaces are
still doing duplicate address detection (DAD). Previously,
dnsmasq would wait up to 20 seconds at start-up for the
DAD state to terminate. This is broken for bridge
interfaces on recent Linux kernels, which don't start DAD
until the bridge comes up, and so can take arbitrary
time. The new behaviour lets dnsmasq poll for an arbitrary
time whilst providing service on other interfaces. Thanks
to Stephen Hemminger for pointing out the problem.
Improve dnsmasq's behaviour when network interfaces are
still doing duplicate address detection (DAD). Previously,
dnsmasq would wait up to 20 seconds at start-up for the
DAD state to terminate. This is broken for bridge
interfaces on recent Linux kernels, which don't start DAD
until the bridge comes up, and so can take arbitrary
time. The new behaviour lets dnsmasq poll for an arbitrary
time whilst providing service on other interfaces. Thanks
to Stephen Hemminger for pointing out the problem.
version 2.58
@@ -1204,7 +1255,7 @@ version 2.58
Relax the need to supply a netmask in --dhcp-range for
networks which use a DHCP relay. Whilst this is still
desireable, in the absence of a netmask dnsmasq will use
desirable, in the absence of a netmask dnsmasq will use
a default based on the class (A, B, or C) of the address.
This should at least remove a cause of mysterious failure
for people using RFC1918 addresses and relays.
@@ -1245,7 +1296,7 @@ version 2.58
--dhcp-option=tag:interface1,option:nis-domain,"domain1"
--dhcp-option=tag:myhost,option:nis-domain,"domain2"
will set the NIS-domain to domain1 for hosts in the range, but
override that to domain2 for a particular host.
override that to domain2 for a particular host.
Fix bug which resulted in truncated files and timeouts for
some TFTP transfers. The bug only occurs with netascii
@@ -1287,9 +1338,9 @@ version 2.57
spotting this.
Allow build with IDN support independently from i18n.
IDN support continues to be included automatically
IDN support continues to be included automatically
when i18n is included.
'make COPTS=-DHAVE_IDN' is the magic incantation.
'make COPTS=-DHAVE_IDN' is the magic incantation.
Modify check on extraneous command line junk (added in
2.56) so that it doesn't complain about extra _empty_
@@ -1297,8 +1348,8 @@ version 2.57
version 2.56
Add a patch to allow dnsmasq to get interface names right in a
Solaris zone. Thanks to Dj Padzensky for this.
Add a patch to allow dnsmasq to get interface names right in a
Solaris zone. Thanks to Dj Padzensky for this.
Improve data-type parsing heuristics so that
--dhcp-option=option:domain-search,.
@@ -1312,20 +1363,20 @@ version 2.56
LOG_DEBUG. This makes things consistent with DHCP
logging. Thanks to Adam Pribyl for spotting the problem.
Ensure that dnsmasq terminates cleanly when using
--syslog-async even if it cannot make a connection to the
syslogd.
Ensure that dnsmasq terminates cleanly when using
--syslog-async even if it cannot make a connection to the
syslogd.
Add --add-mac option. This is to support currently
experimental DNS filtering facilities. Thanks to Benjamin
Petrin for the orignal patch.
Petrin for the original patch.
Fix bug which meant that tags were ignored in dhcp-range
configuration specifying PXE-proxy service. Thanks to
Cristiano Cumer for spotting this.
Raise an error if there is extra junk, not part of an
option, on the command line.
option, on the command line.
Flag a couple of log messages in cache.c as coming from
the DHCP subsystem. Thanks to Olaf Westrik for the patch.
@@ -1349,7 +1400,7 @@ version 2.56
A good suggestion from Ferenc Wagner: extend
the --domain option to allow this sort of thing:
--domain=thekelleys.org.uk,192.168.0.0/24,local
--domain=thekelleys.org.uk,192.168.0.0/24,local
which automatically creates
--local=/thekelleys.org.uk/
--local=/0.168.192.in-addr.arpa/
@@ -1380,7 +1431,7 @@ version 2.56
Rotate the order of SRV records in replies, to provide
round-robin load balancing when all the priorities are
equal. Thanks to Peter McKinney for the suggestion.
equal. Thanks to Peter McKinney for the suggestion.
Edit
contrib/MacOSX-launchd/uk.org.thekelleys.dnsmasq.plist
@@ -1415,13 +1466,13 @@ version 2.56
request meant for another DHCP server. NAKing this is
wrong. Thanks to Brad D'Hondt for assistance with this.
Fix cosmetic bug which produced strange output when
dumping cache statistics with some configurations. Thanks
to Fedor Kozhevnikov for spotting this.
Fix cosmetic bug which produced strange output when
dumping cache statistics with some configurations. Thanks
to Fedor Kozhevnikov for spotting this.
version 2.55
Fix crash when /etc/ethers is in use. Thanks to
Fix crash when /etc/ethers is in use. Thanks to
Gianluigi Tiesi for finding this.
Fix crash in netlink_multicast(). Thanks to Arno Wald for
@@ -1432,12 +1483,12 @@ version 2.55
version 2.54
There is no version 2.54 to avoid confusion with 2.53,
which incorrectly identifies itself as 2.54.
There is no version 2.54 to avoid confusion with 2.53,
which incorrectly identifies itself as 2.54.
version 2.53
Fix failure to compile on Debian/kFreeBSD. Thanks to
Fix failure to compile on Debian/kFreeBSD. Thanks to
Axel Beckert and Petr Salinger.
Fix code to avoid scary strict-aliasing warnings
@@ -1492,13 +1543,13 @@ version 2.53
Added interface:<iface name> part to dhcp-range. The
semantics of this are very odd at first sight, but it
allows a single line of the form
dhcp-range=interface:virt0,192.168.0.4,192.168.0.200
dhcp-range=interface:virt0,192.168.0.4,192.168.0.200
to be added to dnsmasq configuration which then supplies
DHCP and DNS services to that interface, without affecting
what services are supplied to other interfaces and
irrespective of the existence or lack of
interface=<interface>
lines elsewhere in the dnsmasq configuration. The idea is
interface=<interface>
lines elsewhere in the dnsmasq configuration. The idea is
that such a line can be added automatically by libvirt
or equivalent systems, without disturbing any manual
configuration.
@@ -1506,12 +1557,12 @@ version 2.53
Similarly to the above, allow --enable-tftp=<interface>
Allow a TFTP root to be set separately for requests via
different interfaces, --tftp-root=<path>,<interface>
different interfaces, --tftp-root=<path>,<interface>
Correctly handle and log clashes between CNAMES and
DNS names being given to DHCP leases. This fixes a bug
which caused nonsense IP addresses to be logged. Thanks to
Sergei Zhirikov for finding and analysing the problem.
Sergei Zhirikov for finding and analysing the problem.
Tweak flush_log so as to avoid leaving the log
file in non-blocking mode. O_NONBLOCK is a property of the
@@ -1550,14 +1601,14 @@ version 2.53
then adding --bridge-interface=eth0:dhcp,eth0 will use
the address of eth0:dhcp to determine the correct subnet
for DHCP address allocation. Thanks to Pawel Golaszewski
for prompting this and Eric Cooper for further testing.
for prompting this and Eric Cooper for further testing.
Add --dhcp-generate-names. Suggestion by Ferenc Wagner.
Tweak DNS server selection algorithm when there is more
than one server available for a domain, eg.
--server=/mydomain/1.1.1.1
--server=/mydomain/2.2.2.2
--server=/mydomain/1.1.1.1
--server=/mydomain/2.2.2.2
Thanks to Alberto Cuesta-Canada for spotting a weakness
here.
@@ -1572,7 +1623,7 @@ version 2.53
long time, but it should be accepted for backward
compatibility. Thanks to Andrew Burcin for spotting this.
Add --rebind-domain-ok and --rebind-localhost-ok.
Add --rebind-domain-ok and --rebind-localhost-ok.
Suggestion from Clemens Fischer.
Log replies to queries of type TXT, when --log-queries
@@ -1581,7 +1632,7 @@ version 2.53
Fix compiler warnings when compiled with -DNO_DHCP. Thanks
to Shantanu Gadgil for the patch.
Updated French translation. Thanks to Gildas Le Nadan.
Updated French translation. Thanks to Gildas Le Nadan.
Updated Polish translation. Thanks to Jan Psota.
@@ -1593,14 +1644,14 @@ version 2.53
overrides one supplied by a DHCP client. Thanks to Fedor
Kozhevnikov for spotting the problem.
Updated Spanish translation. Thanks to Chris Chatham.
Updated Spanish translation. Thanks to Chris Chatham.
version 2.52
Work around a Linux kernel bug which insists that the
Work around a Linux kernel bug which insists that the
length of the option passed to setsockopt must be at least
sizeof(int) bytes, even if we're calling SO_BINDTODEVICE
and the device name is "lo". Note that this is fixed
sizeof(int) bytes, even if we're calling SO_BINDTODEVICE
and the device name is "lo". Note that this is fixed
in kernel 2.6.31, but the workaround is harmless and
allows earlier kernels to be used. Also fix dnsmasq
bug which reported the wrong address when this failed.
@@ -1643,14 +1694,14 @@ version 2.52
Added extract packaging stuff from Lee Essen to
contrib/Solaris10.
Increased the default limit on number of leases to 1000
(from 150). This is mainly a defence against DoS attacks,
and for the average "one for two class C networks"
installation, IP address exhaustion does that just as
well. Making the limit greater than the number of IP
addresses available in such an installation removes a
surprise which otherwise can catch people out.
Increased the default limit on number of leases to 1000
(from 150). This is mainly a defence against DoS attacks,
and for the average "one for two class C networks"
installation, IP address exhaustion does that just as
well. Making the limit greater than the number of IP
addresses available in such an installation removes a
surprise which otherwise can catch people out.
Removed extraneous trailing space in the value of the
DNSMASQ_TIME_REMAINING DNSMASQ_LEASE_LENGTH and
@@ -1693,9 +1744,9 @@ version 2.52
Fix link error when including Dbus but excluding DHCP.
Thanks to Oschtan for the bug report.
Updated French translation. Thanks to Gildas Le Nadan.
Updated French translation. Thanks to Gildas Le Nadan.
Updated Polish translation. Thanks to Jan Psota.
Updated Polish translation. Thanks to Jan Psota.
Updated Spanish translation. Thanks to Chris Chatham.
@@ -1706,30 +1757,30 @@ version 2.52
version 2.51
Add support for internationalised DNS. Non-ASCII characters
in domain names found in /etc/hosts, /etc/ethers and
Add support for internationalised DNS. Non-ASCII characters
in domain names found in /etc/hosts, /etc/ethers and
/etc/dnsmasq.conf will be correctly handled by translation to
punycode, as specified in RFC3490. This function is only
available if dnsmasq is compiled with internationalisation
support, and adds a dependency on GNU libidn. Without i18n
support, dnsmasq continues to be compilable with just
standard tools. Thanks to Yves Dorfsman for the
suggestion.
punycode, as specified in RFC3490. This function is only
available if dnsmasq is compiled with internationalisation
support, and adds a dependency on GNU libidn. Without i18n
support, dnsmasq continues to be compilable with just
standard tools. Thanks to Yves Dorfsman for the
suggestion.
Add two more environment variables for lease-change scripts:
Add two more environment variables for lease-change scripts:
First, DNSMASQ_SUPPLIED_HOSTNAME; this is set to the hostname
supplied by a client, even if the actual hostname used is
over-ridden by dhcp-host or dhcp-ignore-names directives.
Also DNSMASQ_RELAY_ADDRESS which gives the address of
a DHCP relay, if used.
a DHCP relay, if used.
Suggestions from Michael Rack.
Fix regression which broke echo of relay-agent
options. Thanks to Michael Rack for spotting this.
Don't treat option 67 as being interchangeable with
dhcp-boot parameters if it's specified as
dhcp-option-force.
Don't treat option 67 as being interchangeable with
dhcp-boot parameters if it's specified as
dhcp-option-force.
Make the code to call scripts on lease-change compile-time
optional. It can be switched off by editing src/config.h
@@ -1756,16 +1807,16 @@ version 2.51
dhcp-optsfile.
Test which upstream nameserver to use every 10 seconds
or 50 queries and not just when a query times out and
is retried. This should improve performance when there
is a slow nameserver in the list. Thanks to Joe for the
suggestion.
or 50 queries and not just when a query times out and
is retried. This should improve performance when there
is a slow nameserver in the list. Thanks to Joe for the
suggestion.
Don't do any PXE processing, even for clients with the
correct vendorclass, unless at least one pxe-prompt or
pxe-service option is given. This stops dnsmasq
interfering with proxy PXE subsystems when it is just
the DHCP server. Thanks to Spencer Clark for spotting this.
pxe-service option is given. This stops dnsmasq
interfering with proxy PXE subsystems when it is just
the DHCP server. Thanks to Spencer Clark for spotting this.
Limit the blocksize used for TFTP transfers to a value
which avoids packet fragmentation, based on the MTU of the
@@ -1775,27 +1826,27 @@ version 2.51
Honour dhcp-ignore configuration for PXE and proxy-PXE
requests. Thanks to Niels Basjes for the bug report.
Updated French translation. Thanks to Gildas Le Nadan.
Updated French translation. Thanks to Gildas Le Nadan.
version 2.50
Fix security problem which allowed any host permitted to
do TFTP to possibly compromise dnsmasq by remote buffer
overflow when TFTP enabled. Thanks to Core Security
do TFTP to possibly compromise dnsmasq by remote buffer
overflow when TFTP enabled. Thanks to Core Security
Technologies and Iván Arce, Pablo Hernán Jorge, Alejandro
Pablo Rodriguez, Martín Coco, Alberto Soliño Testa and
Pablo Annetta. This problem has Bugtraq id: 36121
and CVE: 2009-2957
and CVE: 2009-2957
Fix a problem which allowed a malicious TFTP client to
crash dnsmasq. Thanks to Steve Grubb at Red Hat for
spotting this. This problem has Bugtraq id: 36120 and
CVE: 2009-2958
Fix a problem which allowed a malicious TFTP client to
crash dnsmasq. Thanks to Steve Grubb at Red Hat for
spotting this. This problem has Bugtraq id: 36120 and
CVE: 2009-2958
version 2.49
Fix regression in 2.48 which disables the lease-change
script. Thanks to Jose Luis Duran for spotting this.
Fix regression in 2.48 which disables the lease-change
script. Thanks to Jose Luis Duran for spotting this.
Log TFTP "file not found" errors. These were not logged,
since a normal PXELinux boot generates many of them, but
@@ -1806,9 +1857,9 @@ version 2.49
version 2.48
Archived the extensive, backwards, changelog to
CHANGELOG.archive. The current changelog now runs from
version 2.43 and runs conventionally.
Archived the extensive, backwards, changelog to
CHANGELOG.archive. The current changelog now runs from
version 2.43 and runs conventionally.
Fixed bug which broke binding of servers to physical
interfaces when interface names were longer than four
@@ -1821,7 +1872,7 @@ version 2.48
Maintainability drive: removed bug and missing feature
workarounds for some old platforms. Solaris 9, OpenBSD
older than 4.1, Glibc older than 2.2, Linux 2.2.x and
DBus older than 1.1.x are no longer supported.
DBus older than 1.1.x are no longer supported.
Don't read included configuration files more than once:
allows complex configuration structures without problems.
@@ -1841,15 +1892,15 @@ version 2.48
Support --bridge-interface on all platforms, not just BSD.
Added support for advanced PXE functions. It's now
possible to define a prompt and menu options which will
be displayed when a client PXE boots. It's also possible to
hand-off booting to other boot servers. Proxy-DHCP, where
dnsmasq just supplies the PXE information and another DHCP
server does address allocation, is also allowed. See the
--pxe-prompt and --pxe-service keywords. Thanks to
Added support for advanced PXE functions. It's now
possible to define a prompt and menu options which will
be displayed when a client PXE boots. It's also possible to
hand-off booting to other boot servers. Proxy-DHCP, where
dnsmasq just supplies the PXE information and another DHCP
server does address allocation, is also allowed. See the
--pxe-prompt and --pxe-service keywords. Thanks to
Alkis Georgopoulos for the suggestion and Guilherme Moro
and Michael Brown for assistance.
and Michael Brown for assistance.
Improvements to DHCP logging. Thanks to Tom Metro for
useful suggestions.
@@ -1861,7 +1912,7 @@ version 2.48
Added --test command-line switch - syntax check
configuration files only.
Updated French translation. Thanks to Gildas Le Nadan.
Updated French translation. Thanks to Gildas Le Nadan.
version 2.47
@@ -1874,32 +1925,32 @@ version 2.47
file on NetBSD as the other *BSD variants. Also allow
LEASEFILE and CONFFILE symbols to be overridden in CFLAGS.
Handle duplicate address detection on IPv6 more
intelligently. In IPv6, an interface can have an address
which is not usable, because it is still undergoing DAD
(such addresses are marked "tentative"). Attempting to
bind to an address in this state returns an error,
EADDRNOTAVAIL. Previously, on getting such an error,
dnsmasq would silently abandon the address, and never
listen on it. Now, it retries once per second for 20
seconds before generating a fatal error. 20 seconds should
be long enough for any DAD process to complete, but can be
adjusted in src/config.h if necessary. Thanks to Martin
Krafft for the bug report.
Handle duplicate address detection on IPv6 more
intelligently. In IPv6, an interface can have an address
which is not usable, because it is still undergoing DAD
(such addresses are marked "tentative"). Attempting to
bind to an address in this state returns an error,
EADDRNOTAVAIL. Previously, on getting such an error,
dnsmasq would silently abandon the address, and never
listen on it. Now, it retries once per second for 20
seconds before generating a fatal error. 20 seconds should
be long enough for any DAD process to complete, but can be
adjusted in src/config.h if necessary. Thanks to Martin
Krafft for the bug report.
Add DBus introspection. Patch from Jeremy Laine.
Update Dbus configuration file. Patch from Colin Walters.
Fix for this bug:
http://bugs.freedesktop.org/show_bug.cgi?id=18961
http://bugs.freedesktop.org/show_bug.cgi?id=18961
Support arbitrarily encapsulated DHCP options, suggestion
and initial patch from Samium Gromoff. This is useful for
(eg) gPXE, which expect all its private options to be
encapsulated inside a single option 175. So, eg,
dhcp-option = encap:175, 190, "iscsi-client0"
dhcp-option = encap:175, 191, "iscsi-client0-secret"
dhcp-option = encap:175, 190, "iscsi-client0"
dhcp-option = encap:175, 191, "iscsi-client0-secret"
will provide iSCSI parameters to gPXE.
@@ -1967,13 +2018,13 @@ version 2.46
long-standing request. Clients are assigned to a domain
based in their IP address.
Add --dhcp-fqdn flag, which changes behaviour if DNS names
assigned to DHCP clients. When this is set, there must be
a domain associated with each client, and only
fully-qualified domain names are added to the DNS. The
advantage is that the only the FQDN needs to be unique,
so that two or more DHCP clients can share a hostname, as
long as they are in different domains.
Add --dhcp-fqdn flag, which changes behaviour if DNS names
assigned to DHCP clients. When this is set, there must be
a domain associated with each client, and only
fully-qualified domain names are added to the DNS. The
advantage is that the only the FQDN needs to be unique,
so that two or more DHCP clients can share a hostname, as
long as they are in different domains.
Set environment variable DNSMASQ_DOMAIN when invoking
lease-change script. This may be useful information to
@@ -2008,7 +2059,7 @@ version 2.46
asks for an address. This is useful to give a fixed
address to a host which has two network interfaces
(say, a laptop with wired and wireless interfaces.)
It's very important to ensure that only one interface
It's very important to ensure that only one interface
at a time is up, since dnsmasq abandons the first lease
and re-uses the address before the leased time has
elapsed. John Gray suggested this.
@@ -2038,23 +2089,23 @@ version 2.46
version 2.45
Fix total DNS failure in release 2.44 unless --min-port
specified. Thanks to Steven Barth and Grant Coady for
bugreport. Also reject out-of-range port spec, which could
break things too: suggestion from Gilles Espinasse.
Fix total DNS failure in release 2.44 unless --min-port
specified. Thanks to Steven Barth and Grant Coady for
bugreport. Also reject out-of-range port spec, which could
break things too: suggestion from Gilles Espinasse.
version 2.44
Fix crash when unknown client attempts to renew a DHCP
lease, problem introduced in version 2.43. Thanks to
Carlos Carvalho for help chasing this down.
Fix crash when unknown client attempts to renew a DHCP
lease, problem introduced in version 2.43. Thanks to
Carlos Carvalho for help chasing this down.
Fix potential crash when a host which doesn't have a lease
does DHCPINFORM. Again introduced in 2.43. This bug has
never been reported in the wild.
Fix crash in netlink code introduced in 2.43. Thanks to
Jean Wolter for finding this.
Fix crash in netlink code introduced in 2.43. Thanks to
Jean Wolter for finding this.
Change implementation of min_port to work even if min-port
is large.
@@ -2100,10 +2151,10 @@ version 2.43
Improve error checking during startup. Previously, some
errors which occurred during startup would be worked
around, with dnsmasq still starting up. Some were logged,
some silent. Now, they all cause a fatal error and dnsmasq
terminates with a non-zero exit code. The errors are those
associated with changing uid and gid, setting process
capabilities and writing the pidfile. Thanks to Uwe
some silent. Now, they all cause a fatal error and dnsmasq
terminates with a non-zero exit code. The errors are those
associated with changing uid and gid, setting process
capabilities and writing the pidfile. Thanks to Uwe
Gansert and the Suse security team for pointing out
this improvement, and Bill Reimers for good implementation
suggestions.
@@ -2112,16 +2163,16 @@ version 2.43
support when compiling against versions of uclibc which
don't support it. Thanks to Stephane Billiart for the patch.
Implement random source ports for interactions with
upstream nameservers. New spoofing attacks have been found
against nameservers which do not do this, though it is not
clear if dnsmasq is vulnerable, since to doesn't implement
recursion. By default dnsmasq will now use a different
source port (and socket) for each query it sends
upstream. This behaviour can suppressed using the
--query-port option, and the old default behaviour
restored using --query-port=0. Explicit source-port
specifications in --server configs are still honoured.
Implement random source ports for interactions with
upstream nameservers. New spoofing attacks have been found
against nameservers which do not do this, though it is not
clear if dnsmasq is vulnerable, since to doesn't implement
recursion. By default dnsmasq will now use a different
source port (and socket) for each query it sends
upstream. This behaviour can suppressed using the
--query-port option, and the old default behaviour
restored using --query-port=0. Explicit source-port
specifications in --server configs are still honoured.
Replace the random number generator, for better
security. On most BSD systems, dnsmasq uses the
@@ -2141,5 +2192,5 @@ version 2.43
version 2.42
The changelog for version 2.42 and earlier is
available in CHANGELOG.archive.
The changelog for version 2.42 and earlier is
available in CHANGELOG.archive.

View File

@@ -78,7 +78,7 @@ release 0.98 Some enhancements and bug-fixes.
ids, to thwart DNS spoofers.
(7) Dnsmasq no longer forwards queries when the
"recursion desired" bit is not set in the header.
(8) Fixed getopt code to work on compliers with unsigned char.
(8) Fixed getopt code to work on compilers with unsigned char.
release 0.991 Added -b flag: when set causes dnsmasq to always answer
reverse queries on the RFC 1918 private IP space itself and
@@ -319,7 +319,7 @@ release 1.9 Fixes to rpm .spec files.
uClinux. Thanks to Matthew Natalier for uClinux stuff.
release 1.10 Log warnings if resolv.conf or dhcp.leases are not
accessable for any reason, as suggested by Hinrich Eilts.
accessible for any reason, as suggested by Hinrich Eilts.
Fixed wrong address printing in error message about
no interface with address.
@@ -975,7 +975,7 @@ release 2.8
configuration. Specifically: (1) options are matched on
the netids from dhcp-range, dhcp-host, vendor class and
user class(es). Multiple net-ids are allowed and options
are searched on them all. (2) matches agains vendor class
are searched on them all. (2) matches against vendor class
and user class are now on a substring, if the given
string is a substring of the vendor/user class, then a
match occurs. Thanks again to Richard Musil for prompting
@@ -1019,7 +1019,7 @@ release 2.9
broken. The new algorithm is to pick as before for the
first try, but if a query is retried, to send to all
available servers in parallel. The first one to reply
then becomes prefered for the next query. This should
then becomes preferred for the next query. This should
improve reliability without generating significant extra
upstream load.
@@ -1229,7 +1229,7 @@ version 2.16
Set NONBLOCK on all listening sockets to workaround non-POSIX
compliance in Linux 2.4 and 2.6. This fixes rare hangs which
occured when corrupted packets were received. Thanks to
occurred when corrupted packets were received. Thanks to
Joris van Rantwijk for chasing that down.
Updated config.h for NetBSD. Thanks to Martin Lambers.
@@ -1297,7 +1297,7 @@ version 2.18
interfaces with more than one IPv6 address. Thanks to
Martin Pels for help with that.
Fix problems which occured when more than one dhcp-range
Fix problems which occurred when more than one dhcp-range
was specified in the same subnet: sometimes parameters
(lease time, network-id tag) from the wrong one would be
used. Thanks to Rory Campbell-Lange for the bug report.
@@ -1740,7 +1740,7 @@ version 2.28
Fixed regression in netlink code under 2.2.x kernels which
occurred in 2.27. Erik Jan Tromp is the vintage kernel fan
who found this. P.S. It looks like this "netlink bind:
permission denied" problem occured in kernels at least as
permission denied" problem occurred in kernels at least as
late a 2.4.18. Good information from Alain Richoux.
Added a warning when it's impossible to give a host its

62
FAQ
View File

@@ -156,7 +156,7 @@ A: [note: this was written in September 2003, things may well change.]
If you get "jlsdajkdalld.com" does not exist, then all is fine, if
host returns an IP address, then the DNS is broken. (Try a few
different unlikely domains, just in case you picked a wierd one
different unlikely domains, just in case you picked a weird one
which really _is_ registered.)
Assuming that your DNS is broken, and you want to fix it, simply
@@ -320,8 +320,18 @@ A: Yes, new releases of dnsmasq are always announced through
Q: What does the dhcp-authoritative option do?
A: See http://www.isc.org/files/auth.html - that's
for the ISC daemon, but the same applies to dnsmasq.
A: The DHCP spec says that when a DHCP server recieves a renewal request
from a client it has no knowledge of, it should just ignore it.
This is because it's supported to have more than one DHCP server
on a network, and another DHCP server may be dealing with the client.
This has the unfortunate effect that when _no_ DHCP replies to
the client, it takes some time for the client to time-out and start
to get a new lease. Setting this option makes dnsmasq violate the
standard to the extent that it will send a NAK reply to the client,
causing it to immediately start to get a new lease. This improves
behaviour when machines move networks, and in the case that the DHCP
lease database is lost. As long as there are not more tha one DHCP
server on the network, it's safe to enable the option.
Q: Why does my Gentoo box pause for a minute before getting a new
lease?
@@ -349,6 +359,7 @@ A: By default, the identity of a machine is determined by using the
method for setting the client-id varies with DHCP client software,
dhcpcd uses the "-I" flag. Windows uses a registry setting,
see http://www.jsiinc.com/SUBF/TIP2800/rh2845.htm
Addendum:
From version 2.46, dnsmasq has a solution to this which doesn't
involve setting client-IDs. It's possible to put more than one MAC
@@ -361,6 +372,51 @@ Addendum:
constraint: if you configure multiple MAC addresses and violate
this rule, bad things will happen.
Addendum-II: The link above is dead, the former contents of the link are:
------------------------------------------------------------------------------
How can I keep the same DHCP client reservation, if the MAC address changes?
When you reserve an IP address for a DHCP client, you provide the
MAC address of the client's NIC.
It is possible to use a custom identifier, which is sent as
option 61 in the client's DHCP Discover and Request packet.
The DhcpClientIdentifier is a REG_DWORD value that is located at:
Windows NT 4.0 SP2+
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<Adapter Name>'X'\Parameters\Tcpip
where <Adapter Name> is the NIC driver name and 'X' is the number of the NIC.
Windows 2000
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TcpIp\Parameters\Interfaces\<NIC GUID>
where <NIC GUID> is the GUID of the NIC.
The valid range of data is 0x0 - 0xFFFFFFFF. The custom identifier is send as 4 bytes,
8 hexadecimal character, in groups of 2 hexadecimal characters, with the groups being
sent in reverse order. If the custom identifier is less than 8 hexadeciaml characters,
it is zero padded at the end. Examples:
Custom Client Client Reservation
Identifier on DHCP Server
12345678 78563412
123456 56341200
1234 34120000
1234567 67452301
12345 45230100
123 23010000
A18F42 428FA100
CF432 32F40C00
C32D1BE BED1320C
-------------------------------------------------------------------------------------------------------
Q: Can dnsmasq do DHCP on IP-alias interfaces?
A: Yes, from version-2.21. The support is only available running under

View File

@@ -55,10 +55,12 @@ dbus_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG)
dbus_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG) --libs dbus-1`
idn_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) --cflags libidn`
idn_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) --libs libidn`
idn2_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LIBIDN2 $(PKG_CONFIG) --cflags libidn2`
idn2_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LIBIDN2 $(PKG_CONFIG) --libs libidn2`
ct_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --cflags libnetfilter_conntrack`
ct_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --libs libnetfilter_conntrack`
lua_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --cflags lua5.1`
lua_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --libs lua5.1`
lua_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --cflags lua5.2`
lua_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --libs lua5.2`
nettle_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --cflags nettle hogweed`
nettle_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --libs nettle hogweed`
gmp_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC NO_GMP --copy -lgmp`
@@ -82,8 +84,8 @@ hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
all : $(BUILDDIR)
@cd $(BUILDDIR) && $(MAKE) \
top="$(top)" \
build_cflags="$(version) $(dbus_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \
build_libs="$(dbus_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs)" \
build_cflags="$(version) $(dbus_cflags) $(idn2_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \
build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs)" \
-f $(top)/Makefile dnsmasq
mostly_clean :
@@ -106,8 +108,8 @@ all-i18n : $(BUILDDIR)
@cd $(BUILDDIR) && $(MAKE) \
top="$(top)" \
i18n=-DLOCALEDIR=\'\"$(LOCALEDIR)\"\' \
build_cflags="$(version) $(dbus_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags) `$(PKG_CONFIG) --cflags libidn`" \
build_libs="$(dbus_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs) `$(PKG_CONFIG) --libs libidn`" \
build_cflags="$(version) $(dbus_cflags) $(idn2_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \
build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs)" \
-f $(top)/Makefile dnsmasq
for f in `cd $(PO); echo *.po`; do \
cd $(top) && cd $(BUILDDIR) && $(MAKE) top="$(top)" -f $(top)/Makefile $${f%.po}.mo; \

View File

@@ -11,11 +11,18 @@
# If there is more than one v[0-9].* tag, sort them and use the
# first. This favours, eg v2.63 over 2.63rc6.
# Change directory to the toplevel source directory.
if test -z "$1" || ! test -d "$1" || ! cd "$1"; then
echo "$0: First argument $1 must be toplevel dir." >&2
exit 1
fi
if which git >/dev/null 2>&1 && \
([ -d $1/.git ] || grep '^gitdir:' $1/.git >/dev/null 2>&1); then
cd $1; git describe | sed 's/^v//'
([ -d .git ] || grep '^gitdir:' .git >/dev/null 2>&1) && \
git describe >/dev/null 2>&1; then
git describe | sed 's/^v//'
elif grep '\$Format:%d\$' $1/VERSION >/dev/null 2>&1; then
# unsubstituted VERSION, but no git available.
# unsubstituted VERSION, but no git available.
echo UNKNOWN
else
vers=`cat $1/VERSION | sed 's/[(), ]/,/ g' | tr ',' '\n' | grep ^v[0-9]`

View File

@@ -20,7 +20,7 @@
The iaid argument is numeric string and mandatory. Normally
it can be found in leases file both on client and server.
IP is an IPv6 adress to release
IP is an IPv6 address to release
If --dry-run is specified, dhcp_release6 just prints hexadecimal representation of
packet to send to stdout and exits.

13
debian/changelog vendored
View File

@@ -1,8 +1,19 @@
dnsmasq (2.77-2) unstable; urgency=low
* Improve sed regexp for parsing root.ds.
-- Simon Kelley <simon@thekelleys.org.uk> Mon, 5 Jun 2017 20:46:32 +0000
dnsmasq (2.77-1) unstable; urgency=low
* New upstream.
* Don't register as a resolvconf source when config file
includes port=0 to disable DNS.
* Handle gratuitous format change in /usr/share/dns/root.ds
(closes: #858506) (closes: #860064)
* Add lsb-base dependancy.
-- Simon Kelley <simon@thekelleys.org.uk> Wed, 14 Dec 2016 18:01:40 +0000
-- Simon Kelley <simon@thekelleys.org.uk> Tue, 11 Apr 2017 14:19:20 +0000
dnsmasq (2.76-5) unstable; urgency=medium

4
debian/control vendored
View File

@@ -5,12 +5,12 @@ Build-depends: gettext, libnetfilter-conntrack-dev [linux-any],
libidn11-dev, libdbus-1-dev (>=0.61), libgmp-dev,
nettle-dev (>=2.4-3), libbsd-dev [!linux-any]
Maintainer: Simon Kelley <simon@thekelleys.org.uk>
Standards-Version: 3.9.5
Standards-Version: 3.9.8
Package: dnsmasq
Architecture: all
Depends: netbase, dnsmasq-base(>= ${binary:Version}),
init-system-helpers (>= 1.18~)
init-system-helpers (>= 1.18~), lsb-base (>= 3.0-6)
Suggests: resolvconf
Conflicts: resolvconf (<<1.15)
Description: Small caching DNS proxy and DHCP/TFTP server

7
debian/init vendored
View File

@@ -111,7 +111,7 @@ DNSMASQ_OPTS="$DNSMASQ_OPTS --local-service"
ROOT_DS="/usr/share/dns/root.ds"
if [ -f $ROOT_DS ]; then
DNSMASQ_OPTS="$DNSMASQ_OPTS `sed -e s/". IN DS "/--trust-anchor=.,/ -e s/" "/,/g $ROOT_DS | tr '\n' ' '`"
DNSMASQ_OPTS="$DNSMASQ_OPTS `sed -rne "s/^([.a-ZA-Z0-9]+)([[:space:]]+[0-9]+)*([[:space:]]+IN)*[[:space:]]+DS[[:space:]]+/--trust-anchor=\1,/;s/[[:space:]]+/,/gp" $ROOT_DS | tr '\n' ' '`"
fi
start()
@@ -154,6 +154,11 @@ start_resolvconf()
[ $interface = lo ] && return
done
# Also skip this if DNS functionality is disabled in /etc/dnsmasq.conf
if grep -qs '^port=0' /etc/dnsmasq.conf; then
return
fi
if [ -x /sbin/resolvconf ] ; then
echo "nameserver 127.0.0.1" | /sbin/resolvconf -a lo.$NAME
fi

4
debian/readme vendored
View File

@@ -31,7 +31,7 @@ Notes on configuring dnsmasq as packaged for Debian.
as the first nameserver address in /etc/resolv.conf.
(6) In the absence of resolvconf, dns-nameservers lines in
/etc/network/interfaces are ignored. If you do do not use
/etc/network/interfaces are ignored. If you do not use
resolvconf, list 127.0.0.1 as the first nameserver address
in /etc/resolv.conf and configure your nameservers using
"server=<IP-address>" lines in /etc/dnsmasq.conf.
@@ -66,7 +66,7 @@ Notes on configuring dnsmasq as packaged for Debian.
combined with noi18n to be effective.
gitversion : set the version of the produced packages from the
git-derived versioning information on the source,
rather the the debian changelog.
rather than the debian changelog.
(9) Dnsmasq comes as three packages - dnsmasq-utils, dnsmasq-base and
dnsmasq. Dnsmasq-base provides the dnsmasq executable and

10
debian/rules vendored
View File

@@ -11,7 +11,7 @@
package=dnsmasq-base
dpkg_buildflags := DEB_BUILD_MAINT_OPTIONS="hardening=+all" dpkg-buildflags
dpkg_buildflags := DEB_BUILD_MAINT_OPTIONS="hardening=+all,+pie,+bindnow" dpkg-buildflags
CFLAGS = $(shell $(dpkg_buildflags) --get CFLAGS)
CFLAGS += $(shell $(dpkg_buildflags) --get CPPFLAGS)
@@ -48,6 +48,10 @@ ifeq (,$(filter nodbus,$(DEB_BUILD_OPTIONS)))
DEB_COPTS += -DHAVE_DBUS
endif
ifeq (,$(filter noidn, $(DEB_BUILD_OPTIONS)))
DEB_COPTS += -DHAVE_IDN
endif
ifeq (,$(filter noconntrack,$(DEB_BUILD_OPTIONS)))
ifeq ($(DEB_HOST_ARCH_OS),linux)
DEB_COPTS += -DHAVE_CONNTRACK
@@ -84,9 +88,6 @@ endif
ifneq (,$(filter noi18n,$(DEB_BUILD_OPTIONS)))
TARGET = install
ifeq (,$(filter noidn, $(DEB_BUILD_OPTIONS)))
DEB_COPTS += -DHAVE_IDN
endif
endif
ifneq (,$(filter uselua,$(DEB_BUILD_OPTIONS)))
@@ -214,6 +215,7 @@ ifeq ($(DEB_HOST_ARCH_OS),linux)
gzip -9n debian/utils/usr/share/man/man1/dhcp_lease_time.1
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
$(DEB_HOST_GNU_TYPE)-strip -R .note -R .comment debian/utils/usr/bin/dhcp_release
$(DEB_HOST_GNU_TYPE)-strip -R .note -R .comment debian/utils/usr/bin/dhcp_release6
$(DEB_HOST_GNU_TYPE)-strip -R .note -R .comment debian/utils/usr/bin/dhcp_lease_time
endif
cd debian/utils && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | LC_ALL=C sort -z | xargs -r0 md5sum > DEBIAN/md5sums

View File

@@ -203,12 +203,17 @@ or
options are given dnsmasq listens on all available interfaces except any
given in
.B \--except-interface
options. IP alias interfaces (eg "eth1:0") cannot be used with
.B --interface
options. On Linux, when
.B \--bind-interfaces
or
.B --except-interface
options, use --listen-address instead. A simple wildcard, consisting
of a trailing '*', can be used in
.B \--bind-dynamic
are in effect, IP alias interface labels (eg "eth1:0") are checked, rather than
interface names. In the degenerate case when an interface has one address, this amounts to the same thing but when an interface has multiple addresses it
allows control over which of those addresses are accepted.
The same effect is achievable in default mode by using
.B \--listen-address.
A simple wildcard, consisting of a trailing '*',
can be used in
.B \--interface
and
.B \--except-interface
@@ -222,7 +227,9 @@ and
.B --except-interface
options does not matter and that
.B --except-interface
options always override the others.
options always override the others. The comments about interface labels for
.B --listen-address
apply here.
.TP
.B --auth-server=<domain>,<interface>|<ip-address>
Enable DNS authoritative mode for queries arriving at an interface or address. Note that the interface or address
@@ -301,7 +308,8 @@ attached to. Currently this facility is limited to IPv4.
.B \-b, --bogus-priv
Bogus private reverse lookups. All reverse lookups for private IP ranges (ie 192.168.x.x, etc)
which are not found in /etc/hosts or the DHCP leases file are answered
with "no such domain" rather than being forwarded upstream.
with "no such domain" rather than being forwarded upstream. The
set of prefixes affected is the list given in RFC6303, for IPv4 and IPv6.
.TP
.B \-V, --alias=[<old-ip>]|[<start-ip>-<end-ip>],<new-ip>[,<mask>]
Modify IPv4 addresses returned from upstream nameservers; old-ip is
@@ -459,14 +467,14 @@ to make configuration files clearer in this case.
IPv6 addresses may include a %interface scope-id, eg
fe80::202:a412:4512:7bbf%eth0.
The optional string after the @ character tells
dnsmasq how to set the source of the queries to this
nameserver. It should be an ip-address, which should belong to the machine on which
dnsmasq is running otherwise this server line will be logged and then
ignored, or an interface name. If an interface name is given, then
queries to the server will be forced via that interface; if an
ip-address is given then the source address of the queries will be set
to that address.
The optional string after the @ character tells dnsmasq how to set the source of
the queries to this nameserver. It can either be an ip-address, an interface
name or both. The ip-address should belong to the machine on which dnsmasq is
running, otherwise this server line will be logged and then ignored. If an
interface name is given, then queries to the server will be forced via that
interface; if an ip-address is given then the source address of the queries will
be set to that address; and if both are given then a combination of ip-address
and interface name will be used to steer requests to the server.
The query-port flag is ignored for any servers which have a
source address specified but the port may be specified directly as
part of the source address. Forcing queries to an interface is not
@@ -961,7 +969,7 @@ subnets which don't need a pool of dynamically allocated addresses,
use the "static" keyword in the dhcp-range declaration.
It is allowed to use client identifiers (called client
DUID in IPv6-land rather than
DUID in IPv6-land) rather than
hardware addresses to identify hosts by prefixing with 'id:'. Thus:
.B --dhcp-host=id:01:02:03:04,.....
refers to the host with client identifier 01:02:03:04. It is also
@@ -1013,6 +1021,8 @@ dhcp-host directive (or one implied by /etc/ethers) then the special
tag "known" is set. This allows dnsmasq to be configured to
ignore requests from unknown machines using
.B --dhcp-ignore=tag:!known
If the host matches only a dhcp-host directive which cannot
be used because it specifies an address on different subnet, the tag "known-othernet" is set.
Ethernet addresses (but not client-ids) may have
wildcard bytes, so for example
.B --dhcp-host=00:20:e0:3b:13:*,ignore
@@ -1476,7 +1486,7 @@ DUID automatically when it is first needed. When given, this option
provides dnsmasq the data required to create a DUID-EN type DUID. Note
that once set, the DUID is stored in the lease database, so to change between DUID-EN and
automatically created DUIDs or vice-versa, the lease database must be
re-intialised. The enterprise-id is assigned by IANA, and the uid is a
re-initialised. The enterprise-id is assigned by IANA, and the uid is a
string of hex octets unique to a particular device.
.TP
.B \-6 --dhcp-script=<path>
@@ -1569,8 +1579,8 @@ database.
All file descriptors are
closed except stdin, stdout and stderr which are open to /dev/null
(except in debug mode).
closed except stdin, which is open to /dev/null, and stdout and stderr which capture output for logging by dnsmasq.
(In debug mode, stdio, stdout and stderr file are left as those inherited from the invoker of dnsmasq).
The script is not invoked concurrently: at most one instance
of the script is ever running (dnsmasq waits for an instance of script to exit
@@ -1606,7 +1616,7 @@ the arrival of a new entry in the ARP or neighbour table, and "arp-del" indicate
.B --dhcp-luascript=<path>
Specify a script written in Lua, to be run when leases are created,
destroyed or changed. To use this option, dnsmasq must be compiled
with the correct support. The Lua interpreter is intialised once, when
with the correct support. The Lua interpreter is initialised once, when
dnsmasq starts, so that global variables persist between lease
events. The Lua code must define a
.B lease
@@ -1768,7 +1778,7 @@ the relevant link-local address of the machine running dnsmasq is sent
as recursive DNS server. If provided, the DHCPv6 options dns-server and
domain-search are used for the DNS server (RDNSS) and the domain search list (DNSSL).
.TP
.B --ra-param=<interface>,[high|low],[[<ra-interval>],<router lifetime>]
.B --ra-param=<interface>,[mtu:<integer>|<interface>|off,][high,|low,]<ra-interval>[,<router lifetime>]
Set non-default values for router advertisements sent via an
interface. The priority field for the router may be altered from the
default of medium with eg
@@ -1778,9 +1788,19 @@ The interval between router advertisements may be set (in seconds) with
The lifetime of the route may be changed or set to zero, which allows
a router to advertise prefixes but not a route via itself.
.B --ra-parm=eth0,0,0
(A value of zero for the interval means the default value.) All three parameters may be set at once.
.B --ra-param=low,60,1200
(A value of zero for the interval means the default value.) All four parameters may be set at once.
.B --ra-param=eth0,mtu:1280,low,60,1200
The interface field may include a wildcard.
The mtu: parameter may be an arbitrary interface name, in which case the MTU value for that interface is used. This is useful
for (eg) advertising the MTU of a WAN interface on the other interfaces of a router.
.TP
.B --dhcp-reply-delay=[tag:<tag>,]<integer>
Delays sending DHCPOFFER and proxydhcp replies for at least the specified number of seconds.
This can be used as workaround for bugs in PXE boot firmware that does not function properly when
receiving an instant reply.
This option takes into account the time already spent waiting (e.g. performing ping check) if any.
.TP
.B --enable-tftp[=<interface>[,<interface>]]
Enable the TFTP server function. This is deliberately limited to that
@@ -1800,12 +1820,16 @@ directory is only used for TFTP requests via that interface.
.B --tftp-no-fail
Do not abort startup if specified tftp root directories are inaccessible.
.TP
.B --tftp-unique-root
Add the IP address of the TFTP client as a path component on the end
of the TFTP-root (in standard dotted-quad format). Only valid if a
tftp-root is set and the directory exists. For instance, if tftp-root is "/tftp" and client
1.2.3.4 requests file "myfile" then the effective path will be
"/tftp/1.2.3.4/myfile" if /tftp/1.2.3.4 exists or /tftp/myfile otherwise.
.B --tftp-unique-root[=ip|mac]
Add the IP or hardware address of the TFTP client as a path component on the end
of the TFTP-root. Only valid if a tftp-root is set and the directory exists.
Defaults to adding IP address (in standard dotted-quad format).
For instance, if tftp-root is "/tftp" and client 1.2.3.4 requests file "myfile"
then the effective path will be "/tftp/1.2.3.4/myfile" if /tftp/1.2.3.4 exists or /tftp/myfile otherwise.
When "=mac" is specified it will append the MAC address instead, using lowercase zero padded digits
separated by dashes, e.g.: 01-02-03-04-aa-bb
Note that resolving MAC addresses is only possible if the client is in the local network or obtained
a DHCP lease from us.
.TP
.B --tftp-secure
Enable TFTP secure mode: without this, any file which is readable by

View File

@@ -1756,20 +1756,20 @@ dnsmasq est spécifiée comme DNS récursif. Si elles sont fournies, les
options dns-server et domain-search sont utilisées respectivement pour RDNSS et
DNSSL.
.TP
.B --ra-param=<interface>,[high|low],[[<intervalle d'annonce routeur>],<durée de vie route>]
.B --ra-param=<interface>,[mtu:<valeur>|<interface>|off,][high,|low,]<intervalle d'annonce routeur>[,<durée de vie route>]
Configure pour une interface donnée des valeurs pour les annonces routeurs
différentes des valeurs par défaut. La valeur par défaut du champ priorité
pour le routeur peut-être changée de "medium" (moyen) à "high" (haute) ou
"low" (basse). Par exemple :
.B --ra-param=eth0,high.
.B --ra-param=eth0,high,0.
Un intervalle (en secondes) entre les annonces routeur peut-être fourni par :
.B --ra-param=eth0,60.
La durée de vie de la route peut-être changée ou mise à zéro, auquel cas
le routeur peut annoncer les préfixes mais pas de route :
.B --ra-parm=eth0,0,0
(une valeur de zéro pour l'intervalle signifie qu'il garde la valeur par défaut).
Ces trois paramètres peuvent-être configurés en une fois :
.B --ra-param=low,60,1200
Ces quatre paramètres peuvent-être configurés en une fois :
.B --ra-param=eth0,mtu:1280,low,60,1200
La valeur pour l'interface peut inclure un caractère joker.
.TP
.B --enable-tftp[=<interface>[,<interface>]]

View File

@@ -9,10 +9,10 @@
# Simon Kelley <simon@thekelleys.org.uk>, 2005.
msgid ""
msgstr ""
"Project-Id-Version: dnsmasq 2.74\n"
"Project-Id-Version: dnsmasq 2.77\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-06-18 12:24+0100\n"
"PO-Revision-Date: 2015-07-22 23:07+0200\n"
"PO-Revision-Date: 2017-05-11 19:45+0200\n"
"Last-Translator: Conrad Kostecki <ck@conrad-kostecki.de>\n"
"Language-Team: German <de@li.org>\n"
"Language: de\n"
@@ -20,7 +20,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 1.8.3\n"
"X-Generator: Poedit 2.0.1\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: cache.c:513
@@ -387,9 +387,8 @@ msgid "Specify a SRV record."
msgstr "SRV-Eintrag festlegen."
#: option.c:405
#, fuzzy
msgid "Display this message. Use --help dhcp or --help dhcp6 for known DHCP options."
msgstr "Diese Hilfe anzeigen. Benutzen Sie --help dhcp für bekannte DHCP-Optionen."
msgstr "Diese Hilfe anzeigen. Benutzen Sie --help dhcp oder --help dhcp6 für bekannte DHCP-Optionen."
#: option.c:406
#, c-format
@@ -464,7 +463,7 @@ msgstr "Lease-Änderungs-Skript mit den Rechten dieses Nutzers ausführen."
#: option.c:423
msgid "Call dhcp-script with changes to local ARP table."
msgstr ""
msgstr "Rufe dhcp-script mit Änderungen an der lokalen ARP-Tabelle auf."
#: option.c:424
msgid "Read configuration from all the files in this directory."
@@ -522,9 +521,8 @@ msgid "Maximum number of conncurrent TFTP transfers (defaults to %s)."
msgstr "Höchstzahl nebenläufiger TFTP-Übertragungen (%s voreingestellt)."
#: option.c:437
#, fuzzy
msgid "Maximum MTU to use for TFTP transfers."
msgstr "Höchstzahl nebenläufiger TFTP-Übertragungen (%s voreingestellt)."
msgstr "Maximale MTU für TFTP-Übertragungen erreicht."
#: option.c:438
msgid "Disable the TFTP blocksize extension."
@@ -579,9 +577,8 @@ msgid "Specify lowest port available for DNS query transmission."
msgstr "Niedrigsten verfügbaren Port für Übertragung von DNS-Anfragen festlegen."
#: option.c:451
#, fuzzy
msgid "Specify highest port available for DNS query transmission."
msgstr "Niedrigsten verfügbaren Port für Übertragung von DNS-Anfragen festlegen."
msgstr "Höchsten verfügbaren Port für Übertragung von DNS-Anfragen festlegen."
#: option.c:452
msgid "Use only fully qualified domain names for DHCP clients."
@@ -618,17 +615,15 @@ msgstr "Konfigurationssyntax prüfen."
#: option.c:460
msgid "Add requestor's MAC address to forwarded DNS queries."
msgstr "Anfragende MAC-Adresse in die weiterleitende DNS-Anfrage einfügen"
msgstr "Anfragende MAC-Adresse in die weiterleitende DNS-Anfrage einfügen."
#: option.c:461
#, fuzzy
msgid "Add specified IP subnet to forwarded DNS queries."
msgstr "Füge das IP-Subnetz des Anfragenden in die weitergeleiteten DNS-Anfragen hinzu."
msgstr "Füge spezifiziertes IP-Subnetz an weitergeleiteten DNS-Anfragen hinzu."
#: option.c:462
#, fuzzy
msgid "Add client identification to forwarded DNS queries."
msgstr "Füge das IP-Subnetz des Anfragenden in die weitergeleiteten DNS-Anfragen hinzu."
msgstr "Füge Klient Identifikationan weitergeleiteten DNS-Anfragen hinzu."
#: option.c:463
msgid "Proxy DNSSEC validation results from upstream nameservers."
@@ -708,7 +703,7 @@ msgstr "Spezifiziere Vertrauensursprung (Trust Anchor) der Schlüssel-Prüfdaten
#: option.c:482
msgid "Disable upstream checking for DNSSEC debugging."
msgstr "Deaktiviere die Überprüfung vorgelagerter Server für DNSSEC-Debugging"
msgstr "Deaktiviere die Überprüfung vorgelagerter Server für DNSSEC-Debugging."
#: option.c:483
msgid "Ensure answers without DNSSEC are in unsigned zones."
@@ -743,14 +738,12 @@ msgid "Do not log RA."
msgstr "RA nicht protokollieren."
#: option.c:493
#, fuzzy
msgid "Accept queries only from directly-connected networks."
msgstr "Akzeptiere nur Anfragen von direkt verbundenen Netzwerken"
msgstr "Akzeptiere nur Anfragen von direkt verbundenen Netzwerken."
#: option.c:494
#, fuzzy
msgid "Detect and remove DNS forwarding loops."
msgstr "Erkennen und Entfernen von DNS-Weiterleitungsschleifen"
msgstr "Erkennen und Entfernen von DNS-Weiterleitungsschleifen."
#: option.c:495
msgid "Ignore DNS responses containing ipaddr."
@@ -758,7 +751,7 @@ msgstr "Ignoriere DNS-Antworten, welche ipaddr enthalten."
#: option.c:496
msgid "Set TTL in DNS responses with DHCP-derived addresses."
msgstr ""
msgstr "Setzte TTL in DNS-Antworten mit DHCP-abgeleiteten Adressen."
#: option.c:698
#, c-format
@@ -781,7 +774,7 @@ msgstr "Gültige Optionen sind:\n"
#: option.c:749 option.c:843
msgid "bad address"
msgstr "Fehlerhafte Adresse"
msgstr "Fehlerhafte Adresse."
#: option.c:773 option.c:777
msgid "bad port"
@@ -812,9 +805,8 @@ msgid "bad IPv6 address"
msgstr "Fehlerhafte IPv6-Adresse"
#: option.c:1203
#, fuzzy
msgid "bad IPv4 address"
msgstr "Fehlerhafte IPv6-Adresse"
msgstr "Fehlerhafte IPv4-Adresse"
#: option.c:1276 option.c:1370
msgid "bad domain in dhcp-option"
@@ -876,7 +868,7 @@ msgstr "Neuübersetzung mit HAVE_SCRIPT nötig, um Lease-Änderungs-Skripte ausz
#: option.c:1789
msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
msgstr "Um Benutzerdefinierte Lua-Scripte zu ermöglichen, muss mit HAVE_LUASCRIPT neu kompiliert werden"
msgstr "Um Benutzerdefinierte Lua-Skripte zu ermöglichen, muss mit HAVE_LUASCRIPT neu kompiliert werden"
#: option.c:2041 option.c:2086 option.c:2142
msgid "bad prefix"
@@ -973,7 +965,7 @@ msgstr "unzulässiger Alias-Bereich"
#: option.c:3721
msgid "bad TTL"
msgstr ""
msgstr "unzulässige TTL"
#: option.c:3727
msgid "bad CNAME"
@@ -1206,7 +1198,7 @@ msgstr "Schnittstelle %s konnte DHCPv6-Multicast-Gruppe nicht beitreten: %s"
#: network.c:1106
msgid "try increasing /proc/sys/net/core/optmem_max"
msgstr ""
msgstr "Versuche /proc/sys/net/core/optmem_max zu erhöhen"
#: network.c:1302
#, c-format
@@ -1225,7 +1217,7 @@ msgstr "ignoriere Namensserver %s - kann Socket nicht erzeugen/binden: %s"
#: network.c:1520
msgid "(no DNSSEC)"
msgstr ""
msgstr "(kein DNSSEC)"
# FIXME: this isn't translatable - always provide full strings, do not assemble yourself! -- MA
#: network.c:1523
@@ -1255,9 +1247,9 @@ msgid "using standard nameservers for %s %s"
msgstr "Benutze standard Namensserver für %s %s"
#: network.c:1534
#, fuzzy, c-format
#, c-format
msgid "using nameserver %s#%d for %s %s %s"
msgstr "Benutze Namensserver %s#%d für %s %s"
msgstr "Benutze Namensserver %s#%d für %s %s %s"
#: network.c:1538
#, c-format
@@ -1275,18 +1267,17 @@ msgid "using nameserver %s#%d"
msgstr "Benutze Namensserver %s#%d"
#: network.c:1548
#, fuzzy, c-format
#, c-format
msgid "using %d more nameservers"
msgstr "Benutze Namensserver %s#%d"
msgstr "Benutze %d mehr Namensserver"
#: dnsmasq.c:166
msgid "dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"
msgstr "dhcp-hostsdir, dhcp-optsdir und hostsdir sind auf dieser Plattform nicht unterstüzt"
#: dnsmasq.c:181
#, fuzzy
msgid "no root trust anchor provided for DNSSEC"
msgstr "Keine Vertrauensursprünge (Trust Anchor) für DNSSEC verfügbar"
msgstr "Keine Root-Vertrauensursprünge (Root Trust Anchor) für DNSSEC verfügbar"
#: dnsmasq.c:184
msgid "cannot reduce cache size from default when DNSSEC enabled"
@@ -1326,7 +1317,7 @@ msgstr "Loop-Erkennung nicht verfügbar, Aktiviere HAVE_LOOP in src/config.h"
#: dnsmasq.c:227
msgid "max_port cannot be smaller than min_port"
msgstr ""
msgstr "max_port darf nicht kleiner als min_port sein"
#: dnsmasq.c:234
msgid "zone serial must be configured in --auth-soa"
@@ -1618,7 +1609,7 @@ msgstr "APR-Cache Injektion fehlgeschlagen: %s"
#: dhcp.c:460
#, c-format
msgid "Error sending DHCP packet to %s: %s"
msgstr ""
msgstr "Fehler beim Senden des DHCP-Pakets an %s: %s"
#: dhcp.c:521
#, c-format
@@ -2188,9 +2179,9 @@ msgid "%d addresses %s"
msgstr "%d Adressen %s"
#: inotify.c:62
#, fuzzy, c-format
#, c-format
msgid "cannot access path %s: %s"
msgstr "Kann auf %s nicht zugreifen: %s"
msgstr "Kann auf Pfad %s nicht zugreifen: %s"
#: inotify.c:95
#, c-format
@@ -2200,7 +2191,7 @@ msgstr "Kann kein inotify erzeugen: %s"
#: inotify.c:111
#, c-format
msgid "too many symlinks following %s"
msgstr ""
msgstr "Zu viele nachfolgende symbolische Links folgend %s"
#: inotify.c:127
#, c-format

View File

@@ -518,7 +518,8 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
} while ((crecp = cache_find_by_name(crecp, name, now, F_IPV4 | F_IPV6)));
}
if (!found)
/* Only supply CNAME if no record for any type is known. */
if (nxdomain)
{
/* Check for possible wildcard match against *.domain
return length of match, to get longest.

View File

@@ -27,6 +27,7 @@
#define FORWARD_TEST 50 /* try all servers every 50 queries */
#define FORWARD_TIME 20 /* or 20 seconds */
#define SERVERS_LOGGED 30 /* Only log this many servers when logging state */
#define LOCALS_LOGGED 8 /* Only log this many local addresses when logging state */
#define RANDOM_SOCKS 64 /* max simultaneous random ports */
#define LEASE_RETRY 60 /* on error, retry writing leasefile after LEASE_RETRY seconds */
#define CACHESIZ 150 /* default cache size */
@@ -93,10 +94,10 @@ HAVE_DBUS
servers via DBus.
HAVE_IDN
define this if you want international domain name support.
NOTE: for backwards compatibility, IDN support is automatically
included when internationalisation support is built, using the
*-i18n makefile targets, even if HAVE_IDN is not explicitly set.
define this if you want international domain name 2003 support.
HAVE_LIBIDN2
define this if you want international domain name 2008 support.
HAVE_CONNTRACK
define this to include code which propagates conntrack marks from
@@ -131,7 +132,7 @@ NO_SCRIPT
NO_LARGEFILE
NO_AUTH
NO_INOTIFY
these are avilable to explicitly disable compile time options which would
these are available to explicitly disable compile time options which would
otherwise be enabled automatically (HAVE_IPV6, >2Gb file sizes) or
which are enabled by default in the distributed source tree. Building dnsmasq
with something like "make COPTS=-DNO_SCRIPT" will do the trick.
@@ -176,6 +177,7 @@ RESOLVFILE
/* #define HAVE_LUASCRIPT */
/* #define HAVE_DBUS */
/* #define HAVE_IDN */
/* #define HAVE_LIBIDN2 */
/* #define HAVE_CONNTRACK */
/* #define HAVE_DNSSEC */
@@ -395,10 +397,14 @@ static char *compile_opts =
"no-"
#endif
"i18n "
#if !defined(LOCALEDIR) && !defined(HAVE_IDN)
#if defined(HAVE_LIBIDN2)
"IDN2 "
#else
#if !defined(HAVE_IDN)
"no-"
#endif
"IDN "
#endif
"IDN "
#endif
#ifndef HAVE_DHCP
"no-"
#endif
@@ -408,14 +414,14 @@ static char *compile_opts =
"no-"
# endif
"DHCPv6 "
# if !defined(HAVE_SCRIPT)
#endif
#if !defined(HAVE_SCRIPT)
"no-scripts "
# else
# if !defined(HAVE_LUASCRIPT)
"no-"
# endif
"Lua "
#else
# if !defined(HAVE_LUASCRIPT)
"no-"
# endif
"Lua "
#endif
#ifndef HAVE_TFTP
"no-"

View File

@@ -549,17 +549,16 @@ static DBusMessage *dbus_add_lease(DBusMessage* message)
return dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
"Invalid IP address '%s'", ipaddr);
hw_len = parse_hex((char*)hwaddr, dhcp_chaddr, DHCP_CHADDR_MAX, NULL,
&hw_type);
hw_len = parse_hex((char*)hwaddr, dhcp_chaddr, DHCP_CHADDR_MAX, NULL, &hw_type);
if (hw_type == 0 && hw_len != 0)
hw_type = ARPHRD_ETHER;
lease_set_hwaddr(lease, dhcp_chaddr, clid, hw_len, hw_type,
lease_set_hwaddr(lease, dhcp_chaddr, clid, hw_len, hw_type,
clid_len, now, 0);
lease_set_expires(lease, expires, now);
if (hostname_len != 0)
lease_set_hostname(lease, hostname, 0, get_domain(lease->addr), NULL);
lease_update_file(now);
lease_update_dns(0);

View File

@@ -145,12 +145,14 @@ void dhcp_packet(time_t now, int pxe_fd)
struct cmsghdr *cmptr;
struct iovec iov;
ssize_t sz;
int iface_index = 0, unicast_dest = 0, is_inform = 0;
int iface_index = 0, unicast_dest = 0, is_inform = 0, loopback = 0;
int rcvd_iface_index;
struct in_addr iface_addr;
struct iface_param parm;
time_t recvtime = now;
#ifdef HAVE_LINUX_NETWORK
struct arpreq arp_req;
struct timeval tv;
#endif
union {
@@ -177,6 +179,9 @@ void dhcp_packet(time_t now, int pxe_fd)
return;
#if defined (HAVE_LINUX_NETWORK)
if (ioctl(fd, SIOCGSTAMP, &tv) == 0)
recvtime = tv.tv_sec;
if (msg.msg_controllen >= sizeof(struct cmsghdr))
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
@@ -218,9 +223,13 @@ void dhcp_packet(time_t now, int pxe_fd)
}
#endif
if (!indextoname(daemon->dhcpfd, iface_index, ifr.ifr_name))
if (!indextoname(daemon->dhcpfd, iface_index, ifr.ifr_name) ||
ioctl(daemon->dhcpfd, SIOCGIFFLAGS, &ifr) != 0)
return;
mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
loopback = !mess->giaddr.s_addr && (ifr.ifr_flags & IFF_LOOPBACK);
#ifdef HAVE_LINUX_NETWORK
/* ARP fiddling uses original interface even if we pretend to use a different one. */
strncpy(arp_req.arp_dev, ifr.ifr_name, 16);
@@ -326,7 +335,7 @@ void dhcp_packet(time_t now, int pxe_fd)
/* We're relaying this request */
if (parm.relay_local.s_addr != 0 &&
relay_upstream4(parm.relay, (struct dhcp_packet *)daemon->dhcp_packet.iov_base, (size_t)sz, iface_index))
relay_upstream4(parm.relay, mess, (size_t)sz, iface_index))
return;
/* May have configured relay, but not DHCP server */
@@ -335,14 +344,14 @@ void dhcp_packet(time_t now, int pxe_fd)
lease_prune(NULL, now); /* lose any expired leases */
iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t)sz,
now, unicast_dest, &is_inform, pxe_fd, iface_addr);
now, unicast_dest, loopback, &is_inform, pxe_fd, iface_addr, recvtime);
lease_update_file(now);
lease_update_dns(0);
if (iov.iov_len == 0)
return;
}
msg.msg_name = &dest;
msg.msg_namelen = sizeof(dest);
msg.msg_control = NULL;
@@ -496,7 +505,7 @@ static int check_listen_addrs(struct in_addr local, int if_index, char *label,
3) Fills in local (this host) and router (this host or relay) addresses.
4) Links contexts which are valid for hosts directly connected to the arrival interface on ->current.
Note that the current chain may be superceded later for configured hosts or those coming via gateways. */
Note that the current chain may be superseded later for configured hosts or those coming via gateways. */
static int complete_context(struct in_addr local, int if_index, char *label,
struct in_addr netmask, struct in_addr broadcast, void *vparam)
@@ -638,9 +647,69 @@ struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct i
return NULL;
}
/* Check if and address is in use by sending ICMP ping.
This wrapper handles a cache and load-limiting.
Return is NULL is address in use, or a pointer to a cache entry
recording that it isn't. */
struct ping_result *do_icmp_ping(time_t now, struct in_addr addr, unsigned int hash, int loopback)
{
static struct ping_result dummy;
struct ping_result *r, *victim = NULL;
int count, max = (int)(0.6 * (((float)PING_CACHE_TIME)/
((float)PING_WAIT)));
/* check if we failed to ping addr sometime in the last
PING_CACHE_TIME seconds. If so, assume the same situation still exists.
This avoids problems when a stupid client bangs
on us repeatedly. As a final check, if we did more
than 60% of the possible ping checks in the last
PING_CACHE_TIME, we are in high-load mode, so don't do any more. */
for (count = 0, r = daemon->ping_results; r; r = r->next)
if (difftime(now, r->time) > (float)PING_CACHE_TIME)
victim = r; /* old record */
else
{
count++;
if (r->addr.s_addr == addr.s_addr)
return r;
}
/* didn't find cached entry */
if ((count >= max) || option_bool(OPT_NO_PING) || loopback)
{
/* overloaded, or configured not to check, loopback interface, return "not in use" */
dummy.hash = 0;
return &dummy;
}
else if (icmp_ping(addr))
return NULL; /* address in use. */
else
{
/* at this point victim may hold an expired record */
if (!victim)
{
if ((victim = whine_malloc(sizeof(struct ping_result))))
{
victim->next = daemon->ping_results;
daemon->ping_results = victim;
}
}
/* record that this address is OK for 30s
without more ping checks */
if (victim)
{
victim->addr = addr;
victim->time = now;
victim->hash = hash;
}
return victim;
}
}
int address_allocate(struct dhcp_context *context,
struct in_addr *addrp, unsigned char *hwaddr, int hw_len,
struct dhcp_netid *netids, time_t now)
struct dhcp_netid *netids, time_t now, int loopback)
{
/* Find a free address: exclude anything in use and anything allocated to
a particular hwaddr/clientid/hostname in our configuration.
@@ -655,6 +724,10 @@ int address_allocate(struct dhcp_context *context,
dispersal even with similarly-valued "strings". */
for (j = 0, i = 0; i < hw_len; i++)
j = hwaddr[i] + (j << 6) + (j << 16) - j;
/* j == 0 is marker */
if (j == 0)
j = 1;
for (pass = 0; pass <= 1; pass++)
for (c = context; c; c = c->current)
@@ -692,69 +765,27 @@ int address_allocate(struct dhcp_context *context,
(!IN_CLASSC(ntohl(addr.s_addr)) ||
((ntohl(addr.s_addr) & 0xff) != 0xff && ((ntohl(addr.s_addr) & 0xff) != 0x0))))
{
struct ping_result *r, *victim = NULL;
int count, max = (int)(0.6 * (((float)PING_CACHE_TIME)/
((float)PING_WAIT)));
struct ping_result *r;
*addrp = addr;
/* check if we failed to ping addr sometime in the last
PING_CACHE_TIME seconds. If so, assume the same situation still exists.
This avoids problems when a stupid client bangs
on us repeatedly. As a final check, if we did more
than 60% of the possible ping checks in the last
PING_CACHE_TIME, we are in high-load mode, so don't do any more. */
for (count = 0, r = daemon->ping_results; r; r = r->next)
if (difftime(now, r->time) > (float)PING_CACHE_TIME)
victim = r; /* old record */
else
{
count++;
if (r->addr.s_addr == addr.s_addr)
{
/* consec-ip mode: we offered this address for another client
(different hash) recently, don't offer it to this one. */
if (option_bool(OPT_CONSEC_ADDR) && r->hash != j)
break;
return 1;
}
}
if (!r)
{
if ((count < max) && !option_bool(OPT_NO_PING) && icmp_ping(addr))
if ((r = do_icmp_ping(now, addr, j, loopback)))
{
/* consec-ip mode: we offered this address for another client
(different hash) recently, don't offer it to this one. */
if (!option_bool(OPT_CONSEC_ADDR) || r->hash == j)
{
/* address in use: perturb address selection so that we are
less likely to try this address again. */
if (!option_bool(OPT_CONSEC_ADDR))
c->addr_epoch++;
}
else
{
/* at this point victim may hold an expired record */
if (!victim)
{
if ((victim = whine_malloc(sizeof(struct ping_result))))
{
victim->next = daemon->ping_results;
daemon->ping_results = victim;
}
}
/* record that this address is OK for 30s
without more ping checks */
if (victim)
{
victim->addr = addr;
victim->time = now;
victim->hash = j;
}
*addrp = addr;
return 1;
}
}
else
{
/* address in use: perturb address selection so that we are
less likely to try this address again. */
if (!option_bool(OPT_CONSEC_ADDR))
c->addr_epoch++;
}
}
addr.s_addr = htonl(ntohl(addr.s_addr) + 1);
if (addr.s_addr == htonl(ntohl(c->end.s_addr) + 1))

View File

@@ -771,6 +771,8 @@ int main (int argc, char **argv)
if (option_bool(OPT_NOWILD))
warn_bound_listeners();
else if (!option_bool(OPT_CLEVERBIND))
warn_wild_labels();
warn_int_names();
@@ -1300,6 +1302,7 @@ static void async_event(int pipe, time_t now)
daemon->tcp_pids[i] = 0;
break;
#if defined(HAVE_SCRIPT)
case EVENT_KILLED:
my_syslog(LOG_WARNING, _("script process killed by signal %d"), ev.data);
break;
@@ -1313,12 +1316,19 @@ static void async_event(int pipe, time_t now)
daemon->lease_change_command, strerror(ev.data));
break;
case EVENT_SCRIPT_LOG:
my_syslog(MS_SCRIPT | LOG_DEBUG, "%s", msg ? msg : "");
free(msg);
msg = NULL;
break;
/* necessary for fatal errors in helper */
case EVENT_USER_ERR:
case EVENT_DIE:
case EVENT_LUA_ERR:
fatal_event(&ev, msg);
break;
#endif
case EVENT_REOPEN:
/* Note: this may leave TCP-handling processes with the old file still open.
@@ -1365,7 +1375,7 @@ static void async_event(int pipe, time_t now)
/* update timestamp file on TERM if time is considered valid */
if (daemon->back_to_the_future)
{
if (utime(daemon->timestamp_file, NULL) == -1)
if (utimes(daemon->timestamp_file, NULL) == -1)
my_syslog(LOG_ERR, _("failed to update mtime on %s: %s"), daemon->timestamp_file, strerror(errno));
}
#endif
@@ -1745,29 +1755,15 @@ int icmp_ping(struct in_addr addr)
{
/* Try and get an ICMP echo from a machine. */
/* Note that whilst in the three second wait, we check for
(and service) events on the DNS and TFTP sockets, (so doing that
better not use any resources our caller has in use...)
but we remain deaf to signals or further DHCP packets. */
/* There can be a problem using dnsmasq_time() to end the loop, since
it's not monotonic, and can go backwards if the system clock is
tweaked, leading to the code getting stuck in this loop and
ignoring DHCP requests. To fix this, we check to see if select returned
as a result of a timeout rather than a socket becoming available. We
only allow this to happen as many times as it takes to get to the wait time
in quarter-second chunks. This provides a fallback way to end loop. */
int fd, rc;
int fd;
struct sockaddr_in saddr;
struct {
struct ip ip;
struct icmp icmp;
} packet;
unsigned short id = rand16();
unsigned int i, j, timeout_count;
unsigned int i, j;
int gotreply = 0;
time_t start, now;
#if defined(HAVE_LINUX_NETWORK) || defined (HAVE_SOLARIS_NETWORK)
if ((fd = make_icmp_sock()) == -1)
@@ -1797,14 +1793,46 @@ int icmp_ping(struct in_addr addr)
while (retry_send(sendto(fd, (char *)&packet.icmp, sizeof(struct icmp), 0,
(struct sockaddr *)&saddr, sizeof(saddr))));
for (now = start = dnsmasq_time(), timeout_count = 0;
(difftime(now, start) < (float)PING_WAIT) && (timeout_count < PING_WAIT * 4);)
gotreply = delay_dhcp(dnsmasq_time(), PING_WAIT, fd, addr.s_addr, id);
#if defined(HAVE_LINUX_NETWORK) || defined(HAVE_SOLARIS_NETWORK)
while (retry_send(close(fd)));
#else
opt = 1;
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
#endif
return gotreply;
}
int delay_dhcp(time_t start, int sec, int fd, uint32_t addr, unsigned short id)
{
/* Delay processing DHCP packets for "sec" seconds counting from "start".
If "fd" is not -1 it will stop waiting if an ICMP echo reply is received
from "addr" with ICMP ID "id" and return 1 */
/* Note that whilst waiting, we check for
(and service) events on the DNS and TFTP sockets, (so doing that
better not use any resources our caller has in use...)
but we remain deaf to signals or further DHCP packets. */
/* There can be a problem using dnsmasq_time() to end the loop, since
it's not monotonic, and can go backwards if the system clock is
tweaked, leading to the code getting stuck in this loop and
ignoring DHCP requests. To fix this, we check to see if select returned
as a result of a timeout rather than a socket becoming available. We
only allow this to happen as many times as it takes to get to the wait time
in quarter-second chunks. This provides a fallback way to end loop. */
int rc, timeout_count;
time_t now;
for (now = dnsmasq_time(), timeout_count = 0;
(difftime(now, start) <= (float)sec) && (timeout_count < sec * 4);)
{
struct sockaddr_in faddr;
socklen_t len = sizeof(faddr);
poll_reset();
poll_listen(fd, POLLIN);
if (fd != -1)
poll_listen(fd, POLLIN);
set_dns_listeners(now);
set_log_writer();
@@ -1821,10 +1849,10 @@ int icmp_ping(struct in_addr addr)
timeout_count++;
now = dnsmasq_time();
check_log_writer(0);
check_dns_listeners(now);
#ifdef HAVE_DHCP6
if (daemon->doing_ra && poll_check(daemon->icmp6fd, POLLIN))
icmp6_packet(now);
@@ -1834,27 +1862,26 @@ int icmp_ping(struct in_addr addr)
check_tftp_listeners(now);
#endif
if (poll_check(fd, POLLIN) &&
recvfrom(fd, &packet, sizeof(packet), 0,
(struct sockaddr *)&faddr, &len) == sizeof(packet) &&
saddr.sin_addr.s_addr == faddr.sin_addr.s_addr &&
packet.icmp.icmp_type == ICMP_ECHOREPLY &&
packet.icmp.icmp_seq == 0 &&
packet.icmp.icmp_id == id)
{
gotreply = 1;
break;
if (fd != -1)
{
struct {
struct ip ip;
struct icmp icmp;
} packet;
struct sockaddr_in faddr;
socklen_t len = sizeof(faddr);
if (poll_check(fd, POLLIN) &&
recvfrom(fd, &packet, sizeof(packet), 0, (struct sockaddr *)&faddr, &len) == sizeof(packet) &&
addr == faddr.sin_addr.s_addr &&
packet.icmp.icmp_type == ICMP_ECHOREPLY &&
packet.icmp.icmp_seq == 0 &&
packet.icmp.icmp_id == id)
return 1;
}
}
#if defined(HAVE_LINUX_NETWORK) || defined(HAVE_SOLARIS_NETWORK)
while (retry_send(close(fd)));
#else
opt = 1;
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
#endif
return gotreply;
return 0;
}
#endif

View File

@@ -117,7 +117,6 @@ typedef unsigned long long u64;
#include <sys/uio.h>
#include <syslog.h>
#include <dirent.h>
#include <utime.h>
#ifndef HAVE_LINUX_NETWORK
# include <net/if_dl.h>
#endif
@@ -145,30 +144,31 @@ struct event_desc {
int event, data, msg_sz;
};
#define EVENT_RELOAD 1
#define EVENT_DUMP 2
#define EVENT_ALARM 3
#define EVENT_TERM 4
#define EVENT_CHILD 5
#define EVENT_REOPEN 6
#define EVENT_EXITED 7
#define EVENT_KILLED 8
#define EVENT_EXEC_ERR 9
#define EVENT_PIPE_ERR 10
#define EVENT_USER_ERR 11
#define EVENT_CAP_ERR 12
#define EVENT_PIDFILE 13
#define EVENT_HUSER_ERR 14
#define EVENT_GROUP_ERR 15
#define EVENT_DIE 16
#define EVENT_LOG_ERR 17
#define EVENT_FORK_ERR 18
#define EVENT_LUA_ERR 19
#define EVENT_TFTP_ERR 20
#define EVENT_INIT 21
#define EVENT_NEWADDR 22
#define EVENT_NEWROUTE 23
#define EVENT_TIME_ERR 24
#define EVENT_RELOAD 1
#define EVENT_DUMP 2
#define EVENT_ALARM 3
#define EVENT_TERM 4
#define EVENT_CHILD 5
#define EVENT_REOPEN 6
#define EVENT_EXITED 7
#define EVENT_KILLED 8
#define EVENT_EXEC_ERR 9
#define EVENT_PIPE_ERR 10
#define EVENT_USER_ERR 11
#define EVENT_CAP_ERR 12
#define EVENT_PIDFILE 13
#define EVENT_HUSER_ERR 14
#define EVENT_GROUP_ERR 15
#define EVENT_DIE 16
#define EVENT_LOG_ERR 17
#define EVENT_FORK_ERR 18
#define EVENT_LUA_ERR 19
#define EVENT_TFTP_ERR 20
#define EVENT_INIT 21
#define EVENT_NEWADDR 22
#define EVENT_NEWROUTE 23
#define EVENT_TIME_ERR 24
#define EVENT_SCRIPT_LOG 25
/* Exit codes. */
#define EC_GOOD 0
@@ -211,7 +211,7 @@ struct event_desc {
#define OPT_TFTP_SECURE 26
#define OPT_TFTP_NOBLOCK 27
#define OPT_LOG_OPTS 28
#define OPT_TFTP_APREF 29
#define OPT_TFTP_APREF_IP 29
#define OPT_NO_OVERRIDE 30
#define OPT_NO_REBIND 31
#define OPT_ADD_MAC 32
@@ -238,12 +238,14 @@ struct event_desc {
#define OPT_SCRIPT_ARP 53
#define OPT_MAC_B64 54
#define OPT_MAC_HEX 55
#define OPT_LAST 56
#define OPT_TFTP_APREF_MAC 56
#define OPT_LAST 57
/* extra flags for my_syslog, we use a couple of facilities since they are known
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
#define MS_TFTP LOG_USER
#define MS_DHCP LOG_DAEMON
#define MS_TFTP LOG_USER
#define MS_DHCP LOG_DAEMON
#define MS_SCRIPT LOG_MAIL
struct all_addr {
union {
@@ -522,7 +524,7 @@ struct ipsets {
struct irec {
union mysockaddr addr;
struct in_addr netmask; /* only valid for IPv4 */
int tftp_ok, dhcp_ok, mtu, done, warned, dad, dns_auth, index, multicast_done, found;
int tftp_ok, dhcp_ok, mtu, done, warned, dad, dns_auth, index, multicast_done, found, label;
char *name;
struct irec *next;
};
@@ -704,6 +706,12 @@ struct tag_if {
struct tag_if *next;
};
struct delay_config {
int delay;
struct dhcp_netid *netid;
struct delay_config *next;
};
struct hwaddr_config {
int hwaddr_len, hwaddr_type;
unsigned char hwaddr[DHCP_CHADDR_MAX];
@@ -832,7 +840,8 @@ struct prefix_class {
struct ra_interface {
char *name;
int interval, lifetime, prio;
char *mtu_name;
int interval, lifetime, prio, mtu;
struct ra_interface *next;
};
@@ -974,6 +983,7 @@ extern struct daemon {
struct tag_if *tag_if;
struct addr_list *override_relays;
struct dhcp_relay *relay4, *relay6;
struct delay_config *delay_conf;
int override;
int enable_pxe;
int doing_ra, doing_dhcp6;
@@ -1252,6 +1262,7 @@ int enumerate_interfaces(int reset);
void create_wildcard_listeners(void);
void create_bound_listeners(int die);
void warn_bound_listeners(void);
void warn_wild_labels(void);
void warn_int_names(void);
int is_dad_listeners(void);
int iface_check(int family, struct all_addr *addr, char *name, int *auth_dns);
@@ -1280,9 +1291,11 @@ struct dhcp_context *address_available(struct dhcp_context *context,
struct dhcp_context *narrow_context(struct dhcp_context *context,
struct in_addr taddr,
struct dhcp_netid *netids);
struct ping_result *do_icmp_ping(time_t now, struct in_addr addr,
unsigned int hash, int loopback);
int address_allocate(struct dhcp_context *context,
struct in_addr *addrp, unsigned char *hwaddr, int hw_len,
struct dhcp_netid *netids, time_t now);
struct dhcp_netid *netids, time_t now, int loopback);
void dhcp_read_ethers(void);
struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct in_addr addr);
char *host_from_dns(struct in_addr addr);
@@ -1331,7 +1344,8 @@ void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data,
/* rfc2131.c */
#ifdef HAVE_DHCP
size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
size_t sz, time_t now, int unicast_dest, int *is_inform, int pxe_fd, struct in_addr fallback);
size_t sz, time_t now, int unicast_dest, int loopback,
int *is_inform, int pxe_fd, struct in_addr fallback, time_t recvtime);
unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr,
int clid_len, unsigned char *clid, int *len_out);
#endif
@@ -1340,6 +1354,7 @@ unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr,
#ifdef HAVE_DHCP
int make_icmp_sock(void);
int icmp_ping(struct in_addr addr);
int delay_dhcp(time_t start, int sec, int fd, uint32_t addr, unsigned short id);
#endif
void queue_event(int event);
void send_alarm(time_t event, time_t now);

View File

@@ -475,7 +475,7 @@ int setup_timestamp(void)
if (difftime(timestamp_time, time(0)) <= 0)
{
/* time already OK, update timestamp, and do key checking from the start. */
if (utime(daemon->timestamp_file, NULL) == -1)
if (utimes(daemon->timestamp_file, NULL) == -1)
my_syslog(LOG_ERR, _("failed to update mtime on %s: %s"), daemon->timestamp_file, strerror(errno));
daemon->back_to_the_future = 1;
return 0;
@@ -489,12 +489,14 @@ int setup_timestamp(void)
int fd = open(daemon->timestamp_file, O_WRONLY | O_CREAT | O_NONBLOCK | O_EXCL, 0666);
if (fd != -1)
{
struct utimbuf timbuf;
struct timeval tv[2];
close(fd);
timestamp_time = timbuf.actime = timbuf.modtime = 1420070400; /* 1-1-2015 */
if (utime(daemon->timestamp_file, &timbuf) == 0)
timestamp_time = 1420070400; /* 1-1-2015 */
tv[0].tv_sec = tv[1].tv_sec = timestamp_time;
tv[0].tv_usec = tv[1].tv_usec = 0;
if (utimes(daemon->timestamp_file, tv) == 0)
goto check_and_exit;
}
}
@@ -519,7 +521,7 @@ static int check_date_range(u32 date_start, u32 date_end)
{
if (daemon->back_to_the_future == 0 && difftime(timestamp_time, curtime) <= 0)
{
if (utime(daemon->timestamp_file, NULL) != 0)
if (utimes(daemon->timestamp_file, NULL) != 0)
my_syslog(LOG_ERR, _("failed to update mtime on %s: %s"), daemon->timestamp_file, strerror(errno));
my_syslog(LOG_INFO, _("system time considered valid, now checking DNSSEC signature timestamps."));

View File

@@ -304,7 +304,7 @@ static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
/* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
int len;
void *addrp;
void *addrp = NULL;
int sa_family = source->sa.sa_family;
opt->source_netmask = 0;
@@ -344,7 +344,7 @@ static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
len = 0;
if (opt->source_netmask != 0)
if (addrp && opt->source_netmask != 0)
{
len = ((opt->source_netmask - 1) >> 3) + 1;
memcpy(opt->addr, addrp, len);

View File

@@ -120,8 +120,10 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigne
unsigned int flags = 0;
for (serv = daemon->servers; serv; serv=serv->next)
if (qtype == F_DNSSECOK && !(serv->flags & SERV_DO_DNSSEC))
continue;
/* domain matches take priority over NODOTS matches */
if ((serv->flags & SERV_FOR_NODOTS) && *type != SERV_HAS_DOMAIN && !strchr(qdomain, '.') && namelen != 0)
else if ((serv->flags & SERV_FOR_NODOTS) && *type != SERV_HAS_DOMAIN && !strchr(qdomain, '.') && namelen != 0)
{
unsigned int sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
*type = SERV_FOR_NODOTS;
@@ -202,7 +204,7 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigne
}
}
if (flags == 0 && !(qtype & F_QUERY) &&
if (flags == 0 && !(qtype & (F_QUERY | F_DNSSECOK)) &&
option_bool(OPT_NODOTS_LOCAL) && !strchr(qdomain, '.') && namelen != 0)
/* don't forward A or AAAA queries for simple names, except the empty name */
flags = F_NOERR;
@@ -877,10 +879,10 @@ void reply_query(int fd, int family, time_t now)
return;
/* Truncated answer can't be validated.
If this is an answer to a DNSSEC-generated query, we still
need to get the client to retry over TCP, so return
an answer with the TC bit set, even if the actual answer fits.
*/
If this is an answer to a DNSSEC-generated query, we still
need to get the client to retry over TCP, so return
an answer with the TC bit set, even if the actual answer fits.
*/
if (header->hb3 & HB3_TC)
status = STAT_TRUNCATED;
@@ -897,7 +899,7 @@ void reply_query(int fd, int family, time_t now)
status = dnssec_validate_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
else
status = dnssec_validate_reply(now, header, n, daemon->namebuff, daemon->keyname, &forward->class,
option_bool(OPT_DNSSEC_NO_SIGN), NULL, NULL);
option_bool(OPT_DNSSEC_NO_SIGN) && (server->flags & SERV_DO_DNSSEC), NULL, NULL);
}
/* Can't validate, as we're missing key data. Put this
@@ -933,37 +935,35 @@ void reply_query(int fd, int family, time_t now)
/* Find server to forward to. This will normally be the
same as for the original query, but may be another if
servers for domains are involved. */
if (search_servers(now, NULL, F_QUERY, daemon->keyname, &type, &domain, NULL) == 0)
if (search_servers(now, NULL, F_DNSSECOK, daemon->keyname, &type, &domain, NULL) == 0)
{
struct server *start = server, *new_server = NULL;
type &= ~SERV_DO_DNSSEC;
while (1)
{
if (type == (start->flags & SERV_TYPE) &&
(type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
!(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
{
new_server = start;
if (server == start)
{
new_server = NULL;
break;
}
}
if (!(start = start->next))
start = daemon->servers;
if (start == server)
break;
}
if (new_server)
server = new_server;
while (1)
{
if (type == (start->flags & (SERV_TYPE | SERV_DO_DNSSEC)) &&
(type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
!(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
{
new_server = start;
if (server == start)
{
new_server = NULL;
break;
}
}
if (!(start = start->next))
start = daemon->servers;
if (start == server)
break;
}
if (new_server)
server = new_server;
}
new->sentto = server;
new->rfd4 = NULL;
#ifdef HAVE_IPV6
new->rfd6 = NULL;
@@ -1328,7 +1328,7 @@ void receive_query(struct listener *listen, time_t now)
struct irec *iface;
/* get the netmask of the interface which has the address we were sent to.
This is no neccessarily the interface we arrived on. */
This is no necessarily the interface we arrived on. */
for (iface = daemon->interfaces; iface; iface = iface->next)
if (iface->addr.sa.sa_family == AF_INET &&
@@ -1476,7 +1476,8 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
else if (status == STAT_NEED_DS)
new_status = dnssec_validate_ds(now, header, n, name, keyname, class);
else
new_status = dnssec_validate_reply(now, header, n, name, keyname, &class, option_bool(OPT_DNSSEC_NO_SIGN), NULL, NULL);
new_status = dnssec_validate_reply(now, header, n, name, keyname, &class,
option_bool(OPT_DNSSEC_NO_SIGN) && (server->flags & SERV_DO_DNSSEC), NULL, NULL);
if (new_status != STAT_NEED_DS && new_status != STAT_NEED_KEY)
break;
@@ -1505,14 +1506,12 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
/* Find server to forward to. This will normally be the
same as for the original query, but may be another if
servers for domains are involved. */
if (search_servers(now, NULL, F_QUERY, keyname, &type, &domain, NULL) != 0)
if (search_servers(now, NULL, F_DNSSECOK, keyname, &type, &domain, NULL) != 0)
{
new_status = STAT_ABANDONED;
break;
}
type &= ~SERV_DO_DNSSEC;
while (1)
{
if (!firstsendto)
@@ -1529,34 +1528,34 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
}
}
if (type != (server->flags & SERV_TYPE) ||
if (type != (server->flags & (SERV_TYPE | SERV_DO_DNSSEC)) ||
(type == SERV_HAS_DOMAIN && !hostname_isequal(domain, server->domain)) ||
(server->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
continue;
retry:
/* may need to make new connection. */
if (server->tcpfd == -1)
{
if ((server->tcpfd = socket(server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
continue; /* No good, next server */
#ifdef HAVE_CONNTRACK
/* Copy connection mark of incoming query to outgoing connection. */
if (have_mark)
setsockopt(server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
#endif
if (!local_bind(server->tcpfd, &server->source_addr, server->interface, 1) ||
connect(server->tcpfd, &server->addr.sa, sa_len(&server->addr)) == -1)
{
close(server->tcpfd);
server->tcpfd = -1;
retry:
/* may need to make new connection. */
if (server->tcpfd == -1)
{
if ((server->tcpfd = socket(server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
continue; /* No good, next server */
}
server->flags &= ~SERV_GOT_TCP;
}
#ifdef HAVE_CONNTRACK
/* Copy connection mark of incoming query to outgoing connection. */
if (have_mark)
setsockopt(server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
#endif
if (!local_bind(server->tcpfd, &server->source_addr, server->interface, 1) ||
connect(server->tcpfd, &server->addr.sa, sa_len(&server->addr)) == -1)
{
close(server->tcpfd);
server->tcpfd = -1;
continue; /* No good, next server */
}
server->flags &= ~SERV_GOT_TCP;
}
if (!read_write(server->tcpfd, packet, m + sizeof(u16), 0) ||
!read_write(server->tcpfd, &c1, 1, 1) ||
@@ -2079,6 +2078,8 @@ static void free_frec(struct frec *f)
#endif
}
/* if wait==NULL return a free or older than TIMEOUT record.
else return *wait zero if one available, or *wait is delay to
when the oldest in-use record will expire. Impose an absolute
@@ -2125,7 +2126,7 @@ struct frec *get_new_frec(time_t now, int *wait, int force)
/* can't find empty one, use oldest if there is one
and it's older than timeout */
if (oldest && ((int)difftime(now, oldest->time)) >= TIMEOUT)
if (!force && oldest && ((int)difftime(now, oldest->time)) >= TIMEOUT)
{
/* keep stuff for twice timeout if we can by allocating a new
record instead */
@@ -2165,7 +2166,7 @@ struct frec *get_new_frec(time_t now, int *wait, int force)
return f; /* OK if malloc fails and this is NULL */
}
/* crc is all-ones if not known. */
static struct frec *lookup_frec(unsigned short id, void *hash)
{

View File

@@ -14,6 +14,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include "dnsmasq.h"
#ifdef HAVE_SCRIPT
@@ -135,7 +136,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
max_fd != STDIN_FILENO && max_fd != pipefd[0] &&
max_fd != event_fd && max_fd != err_fd)
close(max_fd);
#ifdef HAVE_LUASCRIPT
if (daemon->luascript)
{
@@ -189,6 +190,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
unsigned char *buf = (unsigned char *)daemon->namebuff;
unsigned char *end, *extradata, *alloc_buff = NULL;
int is6, err = 0;
int pipeout[2];
free(alloc_buff);
@@ -472,16 +474,54 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
if (!daemon->lease_change_command)
continue;
/* Pipe to capture stdout and stderr from script */
if (!option_bool(OPT_DEBUG) && pipe(pipeout) == -1)
continue;
/* possible fork errors are all temporary resource problems */
while ((pid = fork()) == -1 && (errno == EAGAIN || errno == ENOMEM))
sleep(2);
if (pid == -1)
continue;
{
if (!option_bool(OPT_DEBUG))
{
close(pipeout[0]);
close(pipeout[1]);
}
continue;
}
/* wait for child to complete */
if (pid != 0)
{
if (!option_bool(OPT_DEBUG))
{
FILE *fp;
close(pipeout[1]);
/* Read lines sent to stdout/err by the script and pass them back to be logged */
if (!(fp = fdopen(pipeout[0], "r")))
close(pipeout[0]);
else
{
while (fgets(daemon->packet, daemon->packet_buff_sz, fp))
{
/* do not include new lines, log will append them */
size_t len = strlen(daemon->packet);
if (len > 0)
{
--len;
if (daemon->packet[len] == '\n')
daemon->packet[len] = 0;
}
send_event(event_fd, EVENT_SCRIPT_LOG, 0, daemon->packet);
}
fclose(fp);
}
}
/* reap our children's children, if necessary */
while (1)
{
@@ -504,6 +544,15 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
continue;
}
if (!option_bool(OPT_DEBUG))
{
/* map stdout/stderr of script to pipeout */
close(pipeout[0]);
dup2(pipeout[1], STDOUT_FILENO);
dup2(pipeout[1], STDERR_FILENO);
close(pipeout[1]);
}
if (data.action != ACTION_TFTP && data.action != ACTION_ARP)
{
@@ -580,7 +629,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
hostname = NULL;
my_setenv("DNSMASQ_LOG_DHCP", option_bool(OPT_LOG_OPTS) ? "1" : NULL, &err);
}
}
/* we need to have the event_fd around if exec fails */
if ((i = fcntl(event_fd, F_GETFD)) != -1)
fcntl(event_fd, F_SETFD, i | FD_CLOEXEC);

View File

@@ -104,7 +104,7 @@ void inotify_dnsmasq_init()
strcpy(path, res->name);
/* Follow symlinks until we reach a non-symlink, or a non-existant file. */
/* Follow symlinks until we reach a non-symlink, or a non-existent file. */
while ((new_path = my_readlink(path)))
{
if (links-- == 0)

View File

@@ -21,21 +21,126 @@
static struct dhcp_lease *leases = NULL, *old_leases = NULL;
static int dns_dirty, file_dirty, leases_left;
void lease_init(time_t now)
static int read_leases(time_t now, FILE *leasestream)
{
unsigned long ei;
struct all_addr addr;
struct dhcp_lease *lease;
int clid_len, hw_len, hw_type;
int items;
char *domain = NULL;
*daemon->dhcp_buff3 = *daemon->dhcp_buff2 = '\0';
/* client-id max length is 255 which is 255*2 digits + 254 colons
borrow DNS packet buffer which is always larger than 1000 bytes
Check various buffers are big enough for the code below */
#if (DHCP_BUFF_SZ < 255) || (MAXDNAME < 64) || (PACKETSZ+MAXDNAME+RRFIXEDSZ < 764)
# error Buffer size breakage in leasefile parsing.
#endif
while ((items=fscanf(leasestream, "%255s %255s", daemon->dhcp_buff3, daemon->dhcp_buff2)) == 2)
{
*daemon->namebuff = *daemon->dhcp_buff = *daemon->packet = '\0';
hw_len = hw_type = clid_len = 0;
#ifdef HAVE_DHCP6
if (strcmp(daemon->dhcp_buff3, "duid") == 0)
{
daemon->duid_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, 130, NULL, NULL);
if (daemon->duid_len < 0)
return 0;
daemon->duid = safe_malloc(daemon->duid_len);
memcpy(daemon->duid, daemon->dhcp_buff2, daemon->duid_len);
continue;
}
#endif
if (fscanf(leasestream, " %64s %255s %764s",
daemon->namebuff, daemon->dhcp_buff, daemon->packet) != 3)
return 0;
if (inet_pton(AF_INET, daemon->namebuff, &addr.addr.addr4))
{
if ((lease = lease4_allocate(addr.addr.addr4)))
domain = get_domain(lease->addr);
hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, DHCP_CHADDR_MAX, NULL, &hw_type);
/* For backwards compatibility, no explicit MAC address type means ether. */
if (hw_type == 0 && hw_len != 0)
hw_type = ARPHRD_ETHER;
}
#ifdef HAVE_DHCP6
else if (inet_pton(AF_INET6, daemon->namebuff, &addr.addr.addr6))
{
char *s = daemon->dhcp_buff2;
int lease_type = LEASE_NA;
if (s[0] == 'T')
{
lease_type = LEASE_TA;
s++;
}
if ((lease = lease6_allocate(&addr.addr.addr6, lease_type)))
{
lease_set_iaid(lease, strtoul(s, NULL, 10));
domain = get_domain6((struct in6_addr *)lease->hwaddr);
}
}
#endif
else
return 0;
if (!lease)
die (_("too many stored leases"), NULL, EC_MISC);
if (strcmp(daemon->packet, "*") != 0)
clid_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL);
lease_set_hwaddr(lease, (unsigned char *)daemon->dhcp_buff2, (unsigned char *)daemon->packet,
hw_len, hw_type, clid_len, now, 0);
if (strcmp(daemon->dhcp_buff, "*") != 0)
lease_set_hostname(lease, daemon->dhcp_buff, 0, domain, NULL);
ei = atol(daemon->dhcp_buff3);
#ifdef HAVE_BROKEN_RTC
if (ei != 0)
lease->expires = (time_t)ei + now;
else
lease->expires = (time_t)0;
lease->length = ei;
#else
/* strictly time_t is opaque, but this hack should work on all sane systems,
even when sizeof(time_t) == 8 */
lease->expires = (time_t)ei;
#endif
/* set these correctly: the "old" events are generated later from
the startup synthesised SIGHUP. */
lease->flags &= ~(LEASE_NEW | LEASE_CHANGED);
*daemon->dhcp_buff3 = *daemon->dhcp_buff2 = '\0';
}
return (items == 0 || items == EOF);
}
void lease_init(time_t now)
{
FILE *leasestream;
leases_left = daemon->dhcp_max;
if (option_bool(OPT_LEASE_RO))
{
/* run "<lease_change_script> init" once to get the
initial state of the database. If leasefile-ro is
set without a script, we just do without any
set without a script, we just do without any
lease database. */
#ifdef HAVE_SCRIPT
if (daemon->lease_change_command)
@@ -56,106 +161,24 @@ void lease_init(time_t now)
{
/* NOTE: need a+ mode to create file if it doesn't exist */
leasestream = daemon->lease_stream = fopen(daemon->lease_file, "a+");
if (!leasestream)
die(_("cannot open or create lease file %s: %s"), daemon->lease_file, EC_FILE);
/* a+ mode leaves pointer at end. */
rewind(leasestream);
}
/* client-id max length is 255 which is 255*2 digits + 254 colons
borrow DNS packet buffer which is always larger than 1000 bytes
Check various buffers are big enough for the code below */
#if (DHCP_BUFF_SZ < 255) || (MAXDNAME < 64) || (PACKETSZ+MAXDNAME+RRFIXEDSZ < 764)
# error Buffer size breakage in leasefile parsing.
#endif
if (leasestream)
while (fscanf(leasestream, "%255s %255s", daemon->dhcp_buff3, daemon->dhcp_buff2) == 2)
{
#ifdef HAVE_DHCP6
if (strcmp(daemon->dhcp_buff3, "duid") == 0)
{
daemon->duid_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, 130, NULL, NULL);
daemon->duid = safe_malloc(daemon->duid_len);
memcpy(daemon->duid, daemon->dhcp_buff2, daemon->duid_len);
continue;
}
#endif
{
if (!read_leases(now, leasestream))
my_syslog(MS_DHCP | LOG_ERR, _("failed to parse lease database, invalid line: %s %s %s %s ..."),
daemon->dhcp_buff3, daemon->dhcp_buff2,
daemon->namebuff, daemon->dhcp_buff);
ei = atol(daemon->dhcp_buff3);
if (fscanf(leasestream, " %64s %255s %764s",
daemon->namebuff, daemon->dhcp_buff, daemon->packet) != 3)
break;
clid_len = 0;
if (strcmp(daemon->packet, "*") != 0)
clid_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL);
if (inet_pton(AF_INET, daemon->namebuff, &addr.addr.addr4) &&
(lease = lease4_allocate(addr.addr.addr4)))
{
hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, DHCP_CHADDR_MAX, NULL, &hw_type);
/* For backwards compatibility, no explicit MAC address type means ether. */
if (hw_type == 0 && hw_len != 0)
hw_type = ARPHRD_ETHER;
lease_set_hwaddr(lease, (unsigned char *)daemon->dhcp_buff2, (unsigned char *)daemon->packet,
hw_len, hw_type, clid_len, now, 0);
if (strcmp(daemon->dhcp_buff, "*") != 0)
lease_set_hostname(lease, daemon->dhcp_buff, 0, get_domain(lease->addr), NULL);
}
#ifdef HAVE_DHCP6
else if (inet_pton(AF_INET6, daemon->namebuff, &addr.addr.addr6))
{
char *s = daemon->dhcp_buff2;
int lease_type = LEASE_NA;
int iaid;
if (s[0] == 'T')
{
lease_type = LEASE_TA;
s++;
}
iaid = strtoul(s, NULL, 10);
if ((lease = lease6_allocate(&addr.addr.addr6, lease_type)))
{
lease_set_hwaddr(lease, NULL, (unsigned char *)daemon->packet, 0, 0, clid_len, now, 0);
lease_set_iaid(lease, iaid);
if (strcmp(daemon->dhcp_buff, "*") != 0)
lease_set_hostname(lease, daemon->dhcp_buff, 0, get_domain6((struct in6_addr *)lease->hwaddr), NULL);
}
}
#endif
else
break;
if (!lease)
die (_("too many stored leases"), NULL, EC_MISC);
#ifdef HAVE_BROKEN_RTC
if (ei != 0)
lease->expires = (time_t)ei + now;
else
lease->expires = (time_t)0;
lease->length = ei;
#else
/* strictly time_t is opaque, but this hack should work on all sane systems,
even when sizeof(time_t) == 8 */
lease->expires = (time_t)ei;
#endif
/* set these correctly: the "old" events are generated later from
the startup synthesised SIGHUP. */
lease->flags &= ~(LEASE_NEW | LEASE_CHANGED);
}
if (ferror(leasestream))
die(_("failed to read lease file %s: %s"), daemon->lease_file, EC_FILE);
}
#ifdef HAVE_SCRIPT
if (!daemon->lease_stream)
@@ -169,6 +192,7 @@ void lease_init(time_t now)
errno = ENOENT;
else if (WEXITSTATUS(rc) == 126)
errno = EACCES;
die(_("cannot run lease-init script %s: %s"), daemon->lease_change_command, EC_FILE);
}

View File

@@ -288,7 +288,9 @@ void my_syslog(int priority, const char *format, ...)
func = "-tftp";
else if ((LOG_FACMASK & priority) == MS_DHCP)
func = "-dhcp";
else if ((LOG_FACMASK & priority) == MS_SCRIPT)
func = "-script";
#ifdef LOG_PRI
priority = LOG_PRI(priority);
#else

View File

@@ -244,6 +244,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
int tftp_ok = !!option_bool(OPT_TFTP);
int dhcp_ok = 1;
int auth_dns = 0;
int is_label = 0;
#if defined(HAVE_DHCP) || defined(HAVE_TFTP)
struct iname *tmp;
#endif
@@ -264,6 +265,8 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
if (!label)
label = ifr.ifr_name;
else
is_label = strcmp(label, ifr.ifr_name);
/* maintain a list of all addresses on all interfaces for --local-service option */
if (option_bool(OPT_LOCAL_SERVICE))
@@ -482,6 +485,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
iface->found = 1;
iface->done = iface->multicast_done = iface->warned = 0;
iface->index = if_index;
iface->label = is_label;
if ((iface->name = whine_malloc(strlen(ifr.ifr_name)+1)))
{
strcpy(iface->name, ifr.ifr_name);
@@ -1034,6 +1038,15 @@ void warn_bound_listeners(void)
my_syslog(LOG_WARNING, _("LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"));
}
void warn_wild_labels(void)
{
struct irec *iface;
for (iface = daemon->interfaces; iface; iface = iface->next)
if (iface->found && iface->name && iface->label)
my_syslog(LOG_WARNING, _("warning: using interface %s instead"), iface->name);
}
void warn_int_names(void)
{
struct interface_name *intname;
@@ -1438,6 +1451,7 @@ void check_servers(void)
struct server *serv;
struct serverfd *sfd, *tmp, **up;
int port = 0, count;
int locals = 0;
/* interface may be new since startup */
if (!option_bool(OPT_NOWILD))
@@ -1541,7 +1555,11 @@ void check_servers(void)
s1 = _("domain"), s2 = serv->domain;
if (serv->flags & SERV_NO_ADDR)
my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
{
count--;
if (++locals <= LOCALS_LOGGED)
my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
}
else if (serv->flags & SERV_USE_RESOLV)
my_syslog(LOG_INFO, _("using standard nameservers for %s %s"), s1, s2);
else
@@ -1558,6 +1576,8 @@ void check_servers(void)
}
}
if (locals > LOCALS_LOGGED)
my_syslog(LOG_INFO, _("using %d more local addresses"), locals - LOCALS_LOGGED);
if (count - 1 > SERVERS_LOGGED)
my_syslog(LOG_INFO, _("using %d more nameservers"), count - SERVERS_LOGGED - 1);

View File

@@ -159,6 +159,7 @@ struct myoption {
#define LOPT_SCRIPT_ARP 347
#define LOPT_DHCPTTL 348
#define LOPT_TFTP_MTU 349
#define LOPT_REPLY_DELAY 350
#ifdef HAVE_GETOPT_LONG
static const struct option opts[] =
@@ -242,7 +243,7 @@ static const struct myoption opts[] =
{ "enable-tftp", 2, 0, LOPT_TFTP },
{ "tftp-secure", 0, 0, LOPT_SECURE },
{ "tftp-no-fail", 0, 0, LOPT_TFTP_NO_FAIL },
{ "tftp-unique-root", 0, 0, LOPT_APREF },
{ "tftp-unique-root", 2, 0, LOPT_APREF },
{ "tftp-root", 1, 0, LOPT_PREFIX },
{ "tftp-max", 1, 0, LOPT_TFTP_MAX },
{ "tftp-mtu", 1, 0, LOPT_TFTP_MTU },
@@ -323,6 +324,7 @@ static const struct myoption opts[] =
{ "dns-loop-detect", 0, 0, LOPT_LOOP_DETECT },
{ "script-arp", 0, 0, LOPT_SCRIPT_ARP },
{ "dhcp-ttl", 1, 0 , LOPT_DHCPTTL },
{ "dhcp-reply-delay", 1, 0, LOPT_REPLY_DELAY },
{ NULL, 0, 0, 0 }
};
@@ -430,7 +432,7 @@ static struct {
{ LOPT_OVERRIDE, OPT_NO_OVERRIDE, NULL, gettext_noop("Do NOT reuse filename and server fields for extra DHCP options."), NULL },
{ LOPT_TFTP, ARG_DUP, "[=<intr>[,<intr>]]", gettext_noop("Enable integrated read-only TFTP server."), NULL },
{ LOPT_PREFIX, ARG_DUP, "<dir>[,<iface>]", gettext_noop("Export files by TFTP only from the specified subtree."), NULL },
{ LOPT_APREF, OPT_TFTP_APREF, NULL, gettext_noop("Add client IP address to tftp-root."), NULL },
{ LOPT_APREF, ARG_DUP, "[=ip|mac]", gettext_noop("Add client IP or hardware address to tftp-root."), NULL },
{ LOPT_SECURE, OPT_TFTP_SECURE, NULL, gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL },
{ LOPT_TFTP_NO_FAIL, OPT_TFTP_NO_FAIL, NULL, gettext_noop("Do not terminate the service if TFTP directories are inaccessible."), NULL },
{ LOPT_TFTP_MAX, ARG_ONE, "<integer>", gettext_noop("Maximum number of concurrent TFTP transfers (defaults to %s)."), "#" },
@@ -486,7 +488,7 @@ static struct {
#ifdef OPTION6_PREFIX_CLASS
{ LOPT_PREF_CLSS, ARG_DUP, "set:tag,<class>", gettext_noop("Specify DHCPv6 prefix class"), NULL },
#endif
{ LOPT_RA_PARAM, ARG_DUP, "<iface>,[<prio>,]<intval>[,<lifetime>]", gettext_noop("Set priority, resend-interval and router-lifetime"), NULL },
{ LOPT_RA_PARAM, ARG_DUP, "<iface>,[mtu:<value>|<interface>|off,][<prio>,]<intval>[,<lifetime>]", gettext_noop("Set MTU, priority, resend-interval and router-lifetime"), NULL },
{ LOPT_QUIET_DHCP, OPT_QUIET_DHCP, NULL, gettext_noop("Do not log routine DHCP."), NULL },
{ LOPT_QUIET_DHCP6, OPT_QUIET_DHCP6, NULL, gettext_noop("Do not log routine DHCPv6."), NULL },
{ LOPT_QUIET_RA, OPT_QUIET_RA, NULL, gettext_noop("Do not log RA."), NULL },
@@ -494,6 +496,7 @@ static struct {
{ LOPT_LOOP_DETECT, OPT_LOOP_DETECT, NULL, gettext_noop("Detect and remove DNS forwarding loops."), NULL },
{ LOPT_IGNORE_ADDR, ARG_DUP, "<ipaddr>", gettext_noop("Ignore DNS responses containing ipaddr."), NULL },
{ LOPT_DHCPTTL, ARG_ONE, "<ttl>", gettext_noop("Set TTL in DNS responses with DHCP-derived addresses."), NULL },
{ LOPT_REPLY_DELAY, ARG_ONE, "<integer>", gettext_noop("Delay DHCP replies for at least number of seconds."), NULL },
{ 0, 0, NULL, NULL, NULL }
};
@@ -757,6 +760,7 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
{
int source_port = 0, serv_port = NAMESERVER_PORT;
char *portno, *source;
char *interface_opt = NULL;
#ifdef HAVE_IPV6
int scope_index = 0;
char *scope_id;
@@ -782,6 +786,19 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
scope_id = split_chr(arg, '%');
#endif
if (source) {
interface_opt = split_chr(source, '@');
if (interface_opt)
{
#if defined(SO_BINDTODEVICE)
strncpy(interface, interface_opt, IF_NAMESIZE - 1);
#else
return _("interface binding not supported");
#endif
}
}
if (inet_pton(AF_INET, arg, &addr->in.sin_addr) > 0)
{
addr->in.sin_port = htons(serv_port);
@@ -800,6 +817,9 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
if (!(inet_pton(AF_INET, source, &source_addr->in.sin_addr) > 0))
{
#if defined(SO_BINDTODEVICE)
if (interface_opt)
return _("interface can only be specified once");
source_addr->in.sin_addr.s_addr = INADDR_ANY;
strncpy(interface, source, IF_NAMESIZE - 1);
#else
@@ -832,7 +852,10 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
if (inet_pton(AF_INET6, source, &source_addr->in6.sin6_addr) == 0)
{
#if defined(SO_BINDTODEVICE)
source_addr->in6.sin6_addr = in6addr_any;
if (interface_opt)
return _("interface can only be specified once");
source_addr->in6.sin6_addr = in6addr_any;
strncpy(interface, source, IF_NAMESIZE - 1);
#else
return _("interface binding not supported");
@@ -850,19 +873,31 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
static struct server *add_rev4(struct in_addr addr, int msize)
{
struct server *serv = opt_malloc(sizeof(struct server));
in_addr_t a = ntohl(addr.s_addr) >> 8;
in_addr_t a = ntohl(addr.s_addr);
char *p;
memset(serv, 0, sizeof(struct server));
p = serv->domain = opt_malloc(25); /* strlen("xxx.yyy.zzz.in-addr.arpa")+1 */
if (msize == 24)
p += sprintf(p, "%d.", a & 0xff);
a = a >> 8;
if (msize != 8)
p += sprintf(p, "%d.", a & 0xff);
a = a >> 8;
p += sprintf(p, "%d.in-addr.arpa", a & 0xff);
p = serv->domain = opt_malloc(29); /* strlen("xxx.yyy.zzz.ttt.in-addr.arpa")+1 */
switch (msize)
{
case 32:
p += sprintf(p, "%d.", a & 0xff);
/* fall through */
case 24:
p += sprintf(p, "%d.", (a >> 8) & 0xff);
/* fall through */
case 16:
p += sprintf(p, "%d.", (a >> 16) & 0xff);
/* fall through */
case 8:
p += sprintf(p, "%d.", (a >> 24) & 0xff);
break;
default:
return NULL;
}
p += sprintf(p, "in-addr.arpa");
serv->flags = SERV_HAS_DOMAIN;
serv->next = daemon->servers;
@@ -2067,6 +2102,9 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
/* generate the equivalent of
local=/xxx.yyy.zzz.in-addr.arpa/ */
struct server *serv = add_rev4(new->start, msize);
if (!serv)
ret_err(_("bad prefix"));
serv->flags |= SERV_NO_ADDR;
/* local=/<domain>/ */
@@ -2438,7 +2476,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
ret_err(gen_err);
if (inet_pton(AF_INET, arg, &addr4))
serv = add_rev4(addr4, size);
{
serv = add_rev4(addr4, size);
if (!serv)
ret_err(_("bad prefix"));
}
#ifdef HAVE_IPV6
else if (inet_pton(AF_INET6, arg, &addr6))
serv = add_rev6(&addr6, size);
@@ -2678,6 +2720,15 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
break;
case LOPT_APREF: /* --tftp-unique-root */
if (!arg || strcasecmp(arg, "ip") == 0)
set_option_bool(OPT_TFTP_APREF_IP);
else if (strcasecmp(arg, "mac") == 0)
set_option_bool(OPT_TFTP_APREF_MAC);
else
ret_err(gen_err);
break;
#endif
case LOPT_BRIDGE: /* --bridge-interface */
@@ -3269,11 +3320,43 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
break;
}
case LOPT_REPLY_DELAY: /* --dhcp-reply-delay */
{
struct dhcp_netid *id = NULL;
while (is_tag_prefix(arg))
{
struct dhcp_netid *newid = opt_malloc(sizeof(struct dhcp_netid));
newid->next = id;
id = newid;
comma = split(arg);
newid->net = opt_string_alloc(arg+4);
arg = comma;
};
if (!arg)
ret_err(gen_err);
else
{
struct delay_config *new;
int delay;
if (!atoi_check(arg, &delay))
ret_err(gen_err);
new = opt_malloc(sizeof(struct delay_config));
new->delay = delay;
new->netid = id;
new->next = daemon->delay_conf;
daemon->delay_conf = new;
}
break;
}
case LOPT_PXE_PROMT: /* --pxe-prompt */
{
struct dhcp_opt *new = opt_malloc(sizeof(struct dhcp_opt));
int timeout;
new->netid = NULL;
new->opt = 10; /* PXE_MENU_PROMPT */
@@ -3623,7 +3706,21 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
struct ra_interface *new = opt_malloc(sizeof(struct ra_interface));
new->lifetime = -1;
new->prio = 0;
new->mtu = 0;
new->mtu_name = NULL;
new->name = opt_string_alloc(arg);
if (strcasestr(comma, "mtu:") == comma)
{
arg = comma + 4;
if (!(comma = split(comma)))
goto err;
if (!strcasecmp(arg, "off"))
new->mtu = -1;
else if (!atoi_check(arg, &new->mtu))
new->mtu_name = opt_string_alloc(arg);
else if (new->mtu < 1280)
goto err;
}
if (strcasestr(comma, "high") == comma || strcasestr(comma, "low") == comma)
{
if (*comma == 'l' || *comma == 'L')
@@ -3635,6 +3732,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
arg = split(comma);
if (!atoi_check(comma, &new->interval) ||
(arg && !atoi_check(arg, &new->lifetime)))
err:
ret_err(_("bad RA-params"));
new->next = daemon->ra_interfaces;
@@ -3750,9 +3848,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
while (arg != last)
{
alias = canonicalise_opt(arg);
if (!alias || !target)
ret_err(_("bad CNAME"));
for (new = daemon->cnames; new; new = new->next)
if (hostname_isequal(new->alias, arg))
if (hostname_isequal(new->alias, alias))
ret_err(_("duplicate CNAME"));
new = opt_malloc(sizeof(struct cname));
new->next = daemon->cnames;
@@ -4089,7 +4190,7 @@ static void read_file(char *file, FILE *f, int hard_opt)
{
int white, i;
volatile int option = (hard_opt == LOPT_REV_SERV) ? 0 : hard_opt;
char *errmess, *p, *arg = NULL, *start;
char *errmess, *p, *arg, *start;
size_t len;
/* Memory allocation failure longjmps here if mem_recover == 1 */
@@ -4100,6 +4201,7 @@ static void read_file(char *file, FILE *f, int hard_opt)
mem_recover = 1;
}
arg = NULL;
lineno++;
errmess = NULL;

View File

@@ -243,7 +243,7 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad
struct dhcp_netid iface_id;
struct dhcp_opt *opt_cfg;
struct ra_interface *ra_param = find_iface_param(iface_name);
int done_dns = 0, old_prefix = 0;
int done_dns = 0, old_prefix = 0, mtu = 0;
unsigned int min_pref_time;
#ifdef HAVE_LINUX_NETWORK
FILE *f;
@@ -399,22 +399,32 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad
put_opt6_long(1000 * calc_interval(find_iface_param(iface_name)));
}
/* Set the MTU from ra_param if any, an MTU of 0 mean automatic for linux, */
/* an MTU of -1 prevents the option from being sent. */
if (ra_param)
mtu = ra_param->mtu;
#ifdef HAVE_LINUX_NETWORK
/* Note that IPv6 MTU is not neccessarily the same as the IPv4 MTU
available from SIOCGIFMTU */
sprintf(daemon->namebuff, "/proc/sys/net/ipv6/conf/%s/mtu", iface_name);
if ((f = fopen(daemon->namebuff, "r")))
if (mtu == 0)
{
if (fgets(daemon->namebuff, MAXDNAME, f))
{
put_opt6_char(ICMP6_OPT_MTU);
put_opt6_char(1);
put_opt6_short(0);
put_opt6_long(atoi(daemon->namebuff));
}
fclose(f);
char *mtu_name = ra_param ? ra_param->mtu_name : NULL;
sprintf(daemon->namebuff, "/proc/sys/net/ipv6/conf/%s/mtu", mtu_name ? : iface_name);
if ((f = fopen(daemon->namebuff, "r")))
{
if (fgets(daemon->namebuff, MAXDNAME, f))
mtu = atoi(daemon->namebuff);
fclose(f);
}
}
#endif
if (mtu > 0)
{
put_opt6_char(ICMP6_OPT_MTU);
put_opt6_char(1);
put_opt6_short(0);
put_opt6_long(mtu);
}
iface_enumerate(AF_LOCAL, &send_iface, add_lla);

View File

@@ -426,6 +426,19 @@ int private_net(struct in_addr addr, int ban_localhost)
((ip_addr & 0xFFFFFFFF) == 0xFFFFFFFF) /* 255.255.255.255/32 (broadcast)*/ ;
}
#ifdef HAVE_IPV6
static int private_net6(struct in6_addr *a)
{
return
IN6_IS_ADDR_UNSPECIFIED(a) || /* RFC 6303 4.3 */
IN6_IS_ADDR_LOOPBACK(a) || /* RFC 6303 4.3 */
IN6_IS_ADDR_LINKLOCAL(a) || /* RFC 6303 4.5 */
((unsigned char *)a)[0] == 0xfd || /* RFC 6303 4.4 */
((u32 *)a)[0] == htonl(0x20010db8); /* RFC 6303 4.6 */
}
#endif
static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header *header, size_t qlen, char *name, int *doctored)
{
int i, qtype, qclass, rdlen;
@@ -1184,7 +1197,7 @@ static unsigned long crec_ttl(struct crec *crecp, time_t now)
if (crecp->flags & F_IMMORTAL)
return crecp->ttd;
/* Return the Max TTL value if it is lower then the actual TTL */
/* Return the Max TTL value if it is lower than the actual TTL */
if (daemon->max_ttl == 0 || ((unsigned)(crecp->ttd - now) < daemon->max_ttl))
return crecp->ttd - now;
else
@@ -1440,20 +1453,48 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
anscount++;
}
}
else if (is_arpa == F_IPV4 &&
option_bool(OPT_BOGUSPRIV) &&
private_net(addr.addr.addr4, 1))
else if (option_bool(OPT_BOGUSPRIV) && (
#ifdef HAVE_IPV6
(is_arpa == F_IPV6 && private_net6(&addr.addr.addr6)) ||
#endif
(is_arpa == F_IPV4 && private_net(addr.addr.addr4, 1))))
{
/* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
ans = 1;
sec_data = 0;
nxdomain = 1;
if (!dryrun)
log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN,
name, &addr, NULL);
struct server *serv;
unsigned int namelen = strlen(name);
char *nameend = name + namelen;
/* see if have rev-server set */
for (serv = daemon->servers; serv; serv = serv->next)
{
unsigned int domainlen;
char *matchstart;
if ((serv->flags & (SERV_HAS_DOMAIN | SERV_NO_ADDR)) != SERV_HAS_DOMAIN)
continue;
domainlen = strlen(serv->domain);
if (domainlen == 0 || domainlen > namelen)
continue;
matchstart = nameend - domainlen;
if (hostname_isequal(matchstart, serv->domain) &&
(namelen == domainlen || *(matchstart-1) == '.' ))
break;
}
/* if no configured server, not in cache, enabled and private IPV4 address, return NXDOMAIN */
if (!serv)
{
ans = 1;
sec_data = 0;
nxdomain = 1;
if (!dryrun)
log_query(F_CONFIG | F_REVERSE | is_arpa | F_NEG | F_NXDOMAIN,
name, &addr, NULL);
}
}
}
for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0)
{
unsigned short type = T_A;
@@ -1520,7 +1561,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
enumerate_interfaces(0);
/* See if a putative address is on the network from which we recieved
/* See if a putative address is on the network from which we received
the query, is so we'll filter other answers. */
if (local_addr.s_addr != 0 && option_bool(OPT_LOCALISE) && type == T_A)
for (intr = daemon->int_names; intr; intr = intr->next)

View File

@@ -64,9 +64,11 @@ static int prune_vendor_opts(struct dhcp_netid *netid);
static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct in_addr local, time_t now);
struct dhcp_boot *find_boot(struct dhcp_netid *netid);
static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid, struct dhcp_packet *mess, struct in_addr local, time_t now, int pxe);
static void apply_delay(u32 xid, time_t recvtime, struct dhcp_netid *netid);
size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
size_t sz, time_t now, int unicast_dest, int *is_inform, int pxe, struct in_addr fallback)
size_t sz, time_t now, int unicast_dest, int loopback,
int *is_inform, int pxe, struct in_addr fallback, time_t recvtime)
{
unsigned char *opt, *clid = NULL;
struct dhcp_lease *ltmp, *lease = NULL;
@@ -381,7 +383,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
{
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))) &&
if ((offset + len + 5 <= (unsigned)(option_len(opt))) &&
(option_uint(opt, offset, 4) == (unsigned int)o->u.encap))
for (o2 = offset + 5; o2 < offset + len + 5; o2 += elen + 1)
{
@@ -486,6 +488,13 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
known_id.next = netid;
netid = &known_id;
}
else if (find_config(daemon->dhcp_conf, NULL, clid, clid_len,
mess->chaddr, mess->hlen, mess->htype, NULL))
{
known_id.net = "known-othernet";
known_id.next = netid;
netid = &known_id;
}
if (mess_type == 0 && !pxe)
{
@@ -567,7 +576,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
lease_prune(lease, now);
lease = NULL;
}
if (!address_allocate(context, &mess->yiaddr, mess->chaddr, mess->hlen, tagif_netid, now))
if (!address_allocate(context, &mess->yiaddr, mess->chaddr, mess->hlen, tagif_netid, now, loopback))
message = _("no address available");
}
else
@@ -825,9 +834,12 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
else
mess->siaddr = context->local;
snprintf((char *)mess->file, sizeof(mess->file),
strchr(service->basename, '.') ? "%s" :"%s.%d",
service->basename, layer);
if (strchr(service->basename, '.'))
snprintf((char *)mess->file, sizeof(mess->file),
"%s", service->basename);
else
snprintf((char *)mess->file, sizeof(mess->file),
"%s.%d", service->basename, layer);
option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(context->local.s_addr));
@@ -918,6 +930,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
log_packet("PXE", NULL, emac, emac_len, iface_name, ignore ? "proxy-ignored" : "proxy", NULL, mess->xid);
log_tags(tagif_netid, ntohl(mess->xid));
if (!ignore)
apply_delay(mess->xid, recvtime, tagif_netid);
return ignore ? 0 : dhcp_packet_size(mess, agent_id, real_end);
}
}
@@ -1026,6 +1040,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
else if (have_config(config, CONFIG_DECLINED) &&
difftime(now, config->decline_time) < (float)DECLINE_BACKOFF)
my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it was previously declined"), addrs);
else if ((!lease || lease->addr.s_addr != config->addr.s_addr) && !do_icmp_ping(now, config->addr, 0, loopback))
my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it is in use by another host"), addrs);
else
conf = config->addr;
}
@@ -1038,11 +1054,11 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
!config_find_by_address(daemon->dhcp_conf, lease->addr))
mess->yiaddr = lease->addr;
else if (opt && address_available(context, addr, tagif_netid) && !lease_find_by_addr(addr) &&
!config_find_by_address(daemon->dhcp_conf, addr))
!config_find_by_address(daemon->dhcp_conf, addr) && do_icmp_ping(now, addr, 0, loopback))
mess->yiaddr = addr;
else if (emac_len == 0)
message = _("no unique-id");
else if (!address_allocate(context, &mess->yiaddr, emac, emac_len, tagif_netid, now))
else if (!address_allocate(context, &mess->yiaddr, emac, emac_len, tagif_netid, now, loopback))
message = _("no address available");
}
@@ -1058,7 +1074,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
}
log_tags(tagif_netid, ntohl(mess->xid));
apply_delay(mess->xid, recvtime, tagif_netid);
log_packet("DHCPOFFER" , &mess->yiaddr, emac, emac_len, iface_name, NULL, NULL, mess->xid);
time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4));
@@ -2615,6 +2631,29 @@ static void do_options(struct dhcp_context *context,
}
}
static void apply_delay(u32 xid, time_t recvtime, struct dhcp_netid *netid)
{
struct delay_config *delay_conf;
/* Decide which delay_config option we're using */
for (delay_conf = daemon->delay_conf; delay_conf; delay_conf = delay_conf->next)
if (match_netid(delay_conf->netid, netid, 0))
break;
if (!delay_conf)
/* No match, look for one without a netid */
for (delay_conf = daemon->delay_conf; delay_conf; delay_conf = delay_conf->next)
if (match_netid(delay_conf->netid, netid, 1))
break;
if (delay_conf)
{
if (!option_bool(OPT_QUIET_DHCP))
my_syslog(MS_DHCP | LOG_INFO, _("%u reply delay: %d"), ntohl(xid), delay_conf->delay);
delay_dhcp(recvtime, delay_conf->delay, -1, 0, 0);
}
}
#endif

View File

@@ -526,7 +526,14 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
if (have_config(config, CONFIG_DISABLE))
ignore = 1;
}
else if (state->clid &&
find_config(daemon->dhcp_conf, NULL, state->clid, state->clid_len, state->mac, state->mac_len, state->mac_type, NULL))
{
known_id.net = "known-othernet";
known_id.next = state->tags;
state->tags = &known_id;
}
#ifdef OPTION6_PREFIX_CLASS
/* OPTION_PREFIX_CLASS in ORO, send addresses in all prefix classes */
if (daemon->prefix_classes && (msg_type == DHCP6SOLICIT || msg_type == DHCP6REQUEST))

View File

@@ -20,9 +20,7 @@
#if defined(HAVE_IPSET) && defined(HAVE_BSD_NETWORK)
#ifndef __FreeBSD__
#include <string.h>
#endif
#include <sys/types.h>
#include <sys/ioctl.h>

View File

@@ -382,7 +382,7 @@ void tftp_request(struct listener *listen, time_t now)
if (prefix[strlen(prefix)-1] != '/')
strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff));
if (option_bool(OPT_TFTP_APREF))
if (option_bool(OPT_TFTP_APREF_IP))
{
size_t oldlen = strlen(daemon->namebuff);
struct stat statbuf;
@@ -394,7 +394,40 @@ void tftp_request(struct listener *listen, time_t now)
if (stat(daemon->namebuff, &statbuf) == -1 || !S_ISDIR(statbuf.st_mode))
daemon->namebuff[oldlen] = 0;
}
if (option_bool(OPT_TFTP_APREF_MAC))
{
unsigned char *macaddr = NULL;
unsigned char macbuf[DHCP_CHADDR_MAX];
#ifdef HAVE_DHCP
if (daemon->dhcp && peer.sa.sa_family == AF_INET)
{
/* Check if the client IP is in our lease database */
struct dhcp_lease *lease = lease_find_by_addr(peer.in.sin_addr);
if (lease && lease->hwaddr_type == ARPHRD_ETHER && lease->hwaddr_len == ETHER_ADDR_LEN)
macaddr = lease->hwaddr;
}
#endif
/* If no luck, try to find in ARP table. This only works if client is in same (V)LAN */
if (!macaddr && find_mac(&peer, macbuf, 1, now) > 0)
macaddr = macbuf;
if (macaddr)
{
size_t oldlen = strlen(daemon->namebuff);
struct stat statbuf;
snprintf(daemon->namebuff + oldlen, (MAXDNAME-1) - oldlen, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x/",
macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]);
/* remove unique-directory if it doesn't exist */
if (stat(daemon->namebuff, &statbuf) == -1 || !S_ISDIR(statbuf.st_mode))
daemon->namebuff[oldlen] = 0;
}
}
/* Absolute pathnames OK if they match prefix */
if (filename[0] == '/')
{
@@ -407,7 +440,7 @@ void tftp_request(struct listener *listen, time_t now)
else if (filename[0] == '/')
daemon->namebuff[0] = 0;
strncat(daemon->namebuff, filename, (MAXDNAME-1) - strlen(daemon->namebuff));
/* check permissions and open file */
if ((transfer->file = check_tftp_fileperm(&len, prefix)))
{

View File

@@ -24,7 +24,9 @@
#include <sys/times.h>
#endif
#if defined(LOCALEDIR) || defined(HAVE_IDN)
#if defined(HAVE_LIBIDN2)
#include <idn2.h>
#elif defined(HAVE_IDN)
#include <idna.h>
#endif
@@ -134,7 +136,7 @@ static int check_name(char *in)
else if (isascii((unsigned char)c) && iscntrl((unsigned char)c))
/* iscntrl only gives expected results for ascii */
return 0;
#if !defined(LOCALEDIR) && !defined(HAVE_IDN)
#if !defined(HAVE_IDN) && !defined(HAVE_LIBIDN2)
else if (!isascii((unsigned char)c))
return 0;
#endif
@@ -184,7 +186,7 @@ int legal_hostname(char *name)
char *canonicalise(char *in, int *nomem)
{
char *ret = NULL;
#if defined(LOCALEDIR) || defined(HAVE_IDN)
#if defined(HAVE_IDN) || defined(HAVE_LIBIDN2)
int rc;
#endif
@@ -194,8 +196,15 @@ char *canonicalise(char *in, int *nomem)
if (!check_name(in))
return NULL;
#if defined(LOCALEDIR) || defined(HAVE_IDN)
if ((rc = idna_to_ascii_lz(in, &ret, 0)) != IDNA_SUCCESS)
#if defined(HAVE_IDN) || defined(HAVE_LIBIDN2)
#ifdef HAVE_LIBIDN2
rc = idn2_to_ascii_lz(in, &ret, IDN2_NONTRANSITIONAL);
if (rc == IDN2_DISALLOWED)
rc = idn2_to_ascii_lz(in, &ret, IDN2_TRANSITIONAL);
#else
rc = idna_to_ascii_lz(in, &ret, 0);
#endif
if (rc != IDNA_SUCCESS)
{
if (ret)
free(ret);
@@ -503,7 +512,8 @@ int parse_hex(char *in, unsigned char *out, int maxlen,
return -1;
out[i] = strtol(&in[j*2], NULL, 16);
mask = mask << 1;
i++;
if (++i == maxlen)
break;
if (j < bytes - 1)
in[(j+1)*2] = sav;
}