mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-06 15:51:41 +00:00
Compare commits
62
Commits
v2.91test1
...
v2.91rc2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
368ceff6e0 | ||
|
|
77c4e95d4a | ||
|
|
e44165c0f7 | ||
|
|
a1a214c393 | ||
|
|
94b7144a1b | ||
|
|
e72910dec8 | ||
|
|
0b6144583b | ||
|
|
f31667317d | ||
|
|
5226b712a3 | ||
|
|
1f84cde024 | ||
|
|
046bfa2af0 | ||
|
|
0762732647 | ||
|
|
efb8f10450 | ||
|
|
6dbdf16fd1 | ||
|
|
6e6a45a7d9 | ||
|
|
a4569c22cc | ||
|
|
199e65c4d9 | ||
|
|
bb8811d472 | ||
|
|
995a16ca0c | ||
|
|
65f9c1aca1 | ||
|
|
b72ecb3a59 | ||
|
|
c221030f89 | ||
|
|
5bbea085d0 | ||
|
|
622cf03ab9 | ||
|
|
8ce27433f8 | ||
|
|
5d894620b4 | ||
|
|
71766c0c35 | ||
|
|
da58455508 | ||
|
|
b915c9a661 | ||
|
|
424aaa0f9d | ||
|
|
c72c895869 | ||
|
|
b7156116c2 | ||
|
|
7d915a0bb9 | ||
|
|
509afcd1d2 | ||
|
|
51343bd9a2 | ||
|
|
b58276a73c | ||
|
|
f162d344c0 | ||
|
|
0003db15cb | ||
|
|
275f4a4475 | ||
|
|
12e4565fef | ||
|
|
7af26eed32 | ||
|
|
63dc6eb316 | ||
|
|
6656790f24 | ||
|
|
c8de423038 | ||
|
|
c52653f97c | ||
|
|
e24c341068 | ||
|
|
5ef6c8c24f | ||
|
|
7c348a0b73 | ||
|
|
d578da0665 | ||
|
|
8949ef44b4 | ||
|
|
3ac11cdd98 | ||
|
|
5d49fa112d | ||
|
|
d29d19e654 | ||
|
|
49ea7db74e | ||
|
|
fcb40ee73d | ||
|
|
0f437b3b5e | ||
|
|
8a5fe8ce6b | ||
|
|
2a664c03db | ||
|
|
4902807879 | ||
|
|
742af6e4b9 | ||
|
|
3eb008c36d | ||
|
|
32248ebd5b |
No files matched your search
@@ -1,3 +1,6 @@
|
|||||||
[submodule "debian"]
|
[submodule "debian"]
|
||||||
path = debian
|
path = debian
|
||||||
url = git://thekelleys.org.uk/dnsmasq-debian.git
|
url = git://thekelleys.org.uk/dnsmasq-debian.git
|
||||||
|
[submodule "submodules/dnsmasq-debian"]
|
||||||
|
path = submodules/dnsmasq-debian
|
||||||
|
url = https://thekelleys.org.uk/git/dnsmasq-debian
|
||||||
@@ -7,9 +7,9 @@ version 2.91
|
|||||||
Literal address records are smaller and don't have
|
Literal address records are smaller and don't have
|
||||||
this field and don't need to be ordered on it.
|
this field and don't need to be ordered on it.
|
||||||
To actually provoke this bug seems to need the same server-literal
|
To actually provoke this bug seems to need the same server-literal
|
||||||
to be repeated twice, eg --address=/a/1.1.1.1 --address-/a/1.1.1.1
|
to be repeated twice, e.g., --address=/a/1.1.1.1 --address-/a/1.1.1.1
|
||||||
which is clearly rare in the wild, but if it did exist it could
|
which is clearly rare in the wild, but if it did exist it could
|
||||||
provoke a SIGSEV. Thanks to Daniel Rhea for fuzzing this one.
|
provoke a SIGSEGV. Thanks to Daniel Rhea for fuzzing this one.
|
||||||
|
|
||||||
Fix buffer overflow when configured lease-change script name
|
Fix buffer overflow when configured lease-change script name
|
||||||
is too long.
|
is too long.
|
||||||
@@ -17,7 +17,7 @@ version 2.91
|
|||||||
|
|
||||||
Improve behaviour in the face of non-responsive upstream TCP DNS
|
Improve behaviour in the face of non-responsive upstream TCP DNS
|
||||||
servers. Without shorter timeouts, clients are blocked for too long
|
servers. Without shorter timeouts, clients are blocked for too long
|
||||||
and fail wuth their own timeouts.
|
and fail with their own timeouts.
|
||||||
|
|
||||||
Set --fast-dns-retries by default when doing DNSSEC. A single
|
Set --fast-dns-retries by default when doing DNSSEC. A single
|
||||||
downstream query can trigger many upstream queries. On an
|
downstream query can trigger many upstream queries. On an
|
||||||
@@ -36,7 +36,7 @@ version 2.91
|
|||||||
empty answer.
|
empty answer.
|
||||||
|
|
||||||
Fix handling of EDNS0 UDP packet sizes.
|
Fix handling of EDNS0 UDP packet sizes.
|
||||||
When talking upstream we always add a pseudoheader, and set the
|
When talking upstream we always add a pseudo header, and set the
|
||||||
UDP packet size to --edns-packet-max. Answering queries from
|
UDP packet size to --edns-packet-max. Answering queries from
|
||||||
downstream, we get the answer (either from upstream or local
|
downstream, we get the answer (either from upstream or local
|
||||||
data) If local data won't fit the advertised size (or 512 if
|
data) If local data won't fit the advertised size (or 512 if
|
||||||
@@ -75,7 +75,56 @@ version 2.91
|
|||||||
Fix erroneous "DNSSEC validated" state with non-DNSSEC
|
Fix erroneous "DNSSEC validated" state with non-DNSSEC
|
||||||
upstream servers. Thanks to Dominik Derigs for the bug report.
|
upstream servers. Thanks to Dominik Derigs for the bug report.
|
||||||
|
|
||||||
|
Handle queries with EDNS client subnet fields better. If dnsmasq
|
||||||
|
is configured to add an EDNS client subnet to a query, it is careful
|
||||||
|
to suppress use of the cache, since a cached answer may not be valid
|
||||||
|
for a query with a different client subnet. Extend this behaviour
|
||||||
|
to queries which arrive a dnsmasq already carrying an EDNS client
|
||||||
|
subnet.
|
||||||
|
|
||||||
|
Handle DS queries to auth zones. When dnsmasq is configured to
|
||||||
|
act as an authoritative server and has an authoritative zone
|
||||||
|
configured, and receives a query for that zone _as_forwarder_
|
||||||
|
it answers the query directly rather than forwarding it. This
|
||||||
|
doesn't affect the answer, but it saves dnsmasq forwarding the
|
||||||
|
query to the recursor upstream, which then bounces it back to dnsmasq
|
||||||
|
in auth mode. The exception should be when the query is for the root
|
||||||
|
of zone, for a DS RR. The answer to that has to come from the parent,
|
||||||
|
via the recursor, and will typically be a proof-of-non-existence
|
||||||
|
since dnsmasq doesn't support signed zones. This patch suppresses
|
||||||
|
local answers and forces forwarding to the upstream recursor for such
|
||||||
|
queries. It stops breakage when a DNSSEC validating client makes
|
||||||
|
queries to dnsmasq acting as forwarder for a zone for which it is
|
||||||
|
authoritative.
|
||||||
|
|
||||||
|
Implement "DNS-0x20 encoding", for extra protection against
|
||||||
|
reply-spoof attacks. Since DNS queries are case-insensitive,
|
||||||
|
it's possible to randomly flip the case of letters in a query
|
||||||
|
and still get the correct answer back.
|
||||||
|
This adds an extra dimension for a cache-poisoning attacker
|
||||||
|
to guess when sending replies in-the-blind since it's expected
|
||||||
|
that the legitimate answer will have the same pattern of upper
|
||||||
|
and lower case as the query, so any replies which don't can be
|
||||||
|
ignored as malicious. The amount of extra entropy clearly depends
|
||||||
|
on the number of a-z and A-Z characters in the query, and this
|
||||||
|
implementation puts a hard limit of 32 bits to make resource
|
||||||
|
allocation easy. This about doubles entropy over the standard
|
||||||
|
random ID and random port combination. This technique can interact
|
||||||
|
badly with rare broken DNS servers which don't preserve the case
|
||||||
|
of the query in their reply. The first time a reply is returned
|
||||||
|
which matches the query in all respects except case, a warning
|
||||||
|
will be logged. If this coincides with DNS not functioning, it
|
||||||
|
is necessary to disable bit 0x20 encoding with --no-0x20-encode.
|
||||||
|
|
||||||
|
Fix a long-standing problem when two queries which are identical
|
||||||
|
in every repect _except_ case, get combined by dnsmasq. If
|
||||||
|
dnsmasq gets eg, two queries for example.com and Example.com
|
||||||
|
in quick succession it will get the answer for example.com from
|
||||||
|
upstream and send that answer to both requestors. This means that
|
||||||
|
the query for Example.com will get an answer for example.com, and
|
||||||
|
in the modern DNS, that answer may not be accepted.
|
||||||
|
|
||||||
|
|
||||||
version 2.90
|
version 2.90
|
||||||
Fix reversion in --rev-server introduced in 2.88 which
|
Fix reversion in --rev-server introduced in 2.88 which
|
||||||
caused breakage if the prefix length is not exactly divisible
|
caused breakage if the prefix length is not exactly divisible
|
||||||
@@ -1944,7 +1993,7 @@ version 2.61
|
|||||||
|
|
||||||
Set the environment variable DNSMASQ_LOG_DHCP when running
|
Set the environment variable DNSMASQ_LOG_DHCP when running
|
||||||
the script id --log-dhcp is in effect, so that script can
|
the script id --log-dhcp is in effect, so that script can
|
||||||
taylor their logging verbosity. Suggestion from Malte
|
tailor their logging verbosity. Suggestion from Malte
|
||||||
Forkel.
|
Forkel.
|
||||||
|
|
||||||
Arrange that addresses specified with --listen-address
|
Arrange that addresses specified with --listen-address
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
# dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -71,8 +71,8 @@ nft_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_NFTSET $(PKG_CONFIG
|
|||||||
nft_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_NFTSET $(PKG_CONFIG) --libs libnftables`
|
nft_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_NFTSET $(PKG_CONFIG) --libs libnftables`
|
||||||
version = -DVERSION='\"`$(top)/bld/get-version $(top)`\"'
|
version = -DVERSION='\"`$(top)/bld/get-version $(top)`\"'
|
||||||
|
|
||||||
sum?=$(shell $(CC) -DDNSMASQ_COMPILE_OPTS $(COPTS) -E $(top)/$(SRC)/dnsmasq.h | ( md5sum 2>/dev/null || md5 ) | cut -f 1 -d ' ')
|
sum?=$(shell echo $(CC) -DDNSMASQ_COMPILE_FLAGS="$(CFLAGS)" -DDNSMASQ_COMPILE_OPTS $(COPTS) -E $(top)/$(SRC)/dnsmasq.h | ( md5sum 2>/dev/null || md5 ) | cut -f 1 -d ' ')
|
||||||
sum!=$(CC) -DDNSMASQ_COMPILE_OPTS $(COPTS) -E $(top)/$(SRC)/dnsmasq.h | ( md5sum 2>/dev/null || md5 ) | cut -f 1 -d ' '
|
sum!=echo $(CC) -DDNSMASQ_COMPILE_FLAGS="$(CFLAGS)" -DDNSMASQ_COMPILE_OPTS $(COPTS) -E $(top)/$(SRC)/dnsmasq.h | ( md5sum 2>/dev/null || md5 ) | cut -f 1 -d ' '
|
||||||
copts_conf = .copts_$(sum)
|
copts_conf = .copts_$(sum)
|
||||||
|
|
||||||
objs = cache.o rfc1035.o util.o option.o forward.o network.o \
|
objs = cache.o rfc1035.o util.o option.o forward.o network.o \
|
||||||
@@ -102,9 +102,7 @@ clean : mostly_clean
|
|||||||
rm -f core */core
|
rm -f core */core
|
||||||
rm -f *~ contrib/*/*~ */*~
|
rm -f *~ contrib/*/*~ */*~
|
||||||
|
|
||||||
install : all install-common
|
install : all
|
||||||
|
|
||||||
install-common :
|
|
||||||
$(INSTALL) -d $(DESTDIR)$(BINDIR)
|
$(INSTALL) -d $(DESTDIR)$(BINDIR)
|
||||||
$(INSTALL) -d $(DESTDIR)$(MANDIR)/man8
|
$(INSTALL) -d $(DESTDIR)$(MANDIR)/man8
|
||||||
$(INSTALL) -m 644 $(MAN)/dnsmasq.8 $(DESTDIR)$(MANDIR)/man8
|
$(INSTALL) -m 644 $(MAN)/dnsmasq.8 $(DESTDIR)$(MANDIR)/man8
|
||||||
@@ -121,7 +119,11 @@ all-i18n : $(BUILDDIR)
|
|||||||
cd $(top) && cd $(BUILDDIR) && $(MAKE) top="$(top)" -f $(top)/Makefile $${f%.po}.mo; \
|
cd $(top) && cd $(BUILDDIR) && $(MAKE) top="$(top)" -f $(top)/Makefile $${f%.po}.mo; \
|
||||||
done
|
done
|
||||||
|
|
||||||
install-i18n : all-i18n install-common
|
install-i18n : all-i18n
|
||||||
|
$(INSTALL) -d $(DESTDIR)$(BINDIR)
|
||||||
|
$(INSTALL) -d $(DESTDIR)$(MANDIR)/man8
|
||||||
|
$(INSTALL) -m 644 $(MAN)/dnsmasq.8 $(DESTDIR)$(MANDIR)/man8
|
||||||
|
$(INSTALL) -m 755 $(BUILDDIR)/dnsmasq $(DESTDIR)$(BINDIR)
|
||||||
cd $(BUILDDIR); $(top)/bld/install-mo $(DESTDIR)$(LOCALEDIR) $(INSTALL)
|
cd $(BUILDDIR); $(top)/bld/install-mo $(DESTDIR)$(LOCALEDIR) $(INSTALL)
|
||||||
cd $(MAN); ../bld/install-man $(DESTDIR)$(MANDIR) $(INSTALL)
|
cd $(MAN); ../bld/install-man $(DESTDIR)$(MANDIR) $(INSTALL)
|
||||||
|
|
||||||
|
|||||||
-1
Submodule debian deleted from 83e05da879.
+123
-99
@@ -1,4 +1,4 @@
|
|||||||
.TH DNSMASQ 8 2021-08-16
|
.TH DNSMASQ 8 2025-02-05
|
||||||
.SH NAME
|
.SH NAME
|
||||||
dnsmasq \- A lightweight DHCP and caching DNS server.
|
dnsmasq \- A lightweight DHCP and caching DNS server.
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -852,6 +852,14 @@ name on successive queries, for load-balancing. This turns off that
|
|||||||
behaviour, so that the records are always returned in the order
|
behaviour, so that the records are always returned in the order
|
||||||
that they are received from upstream.
|
that they are received from upstream.
|
||||||
.TP
|
.TP
|
||||||
|
.B --no-0x20-encode
|
||||||
|
By default, dnsmasq scrambles the case of letters in DNS queries it sends upstream as a security feature.
|
||||||
|
This technique can interact badly with rare broken DNS servers which don't preserve the case
|
||||||
|
of the query in their reply. The first time a reply is returned
|
||||||
|
which matches the query in all respects except case, a warning
|
||||||
|
will be logged. If this coincides with DNS not functioning, it
|
||||||
|
is necessary to disable this scrambling with --no-0x20-encode.
|
||||||
|
.TP
|
||||||
.B --use-stale-cache[=<max TTL excess in s>]
|
.B --use-stale-cache[=<max TTL excess in s>]
|
||||||
When set, if a DNS name exists in the cache, but its time-to-live has expired, dnsmasq will return the data anyway. (It attempts to refresh the
|
When set, if a DNS name exists in the cache, but its time-to-live has expired, dnsmasq will return the data anyway. (It attempts to refresh the
|
||||||
data with an upstream query after returning the stale data.) This can improve speed and reliability. It comes at the expense
|
data with an upstream query after returning the stale data.) This can improve speed and reliability. It comes at the expense
|
||||||
@@ -882,7 +890,7 @@ ie capable of returning DNSSEC records with data. If they are not,
|
|||||||
then dnsmasq will not be able to determine the trusted status of
|
then dnsmasq will not be able to determine the trusted status of
|
||||||
answers and this means that DNS service will be entirely broken.
|
answers and this means that DNS service will be entirely broken.
|
||||||
.TP
|
.TP
|
||||||
.B --trust-anchor=[<class>],<domain>,<key-tag>,<algorithm>,<digest-type>,<digest>
|
.B --trust-anchor=<domain>,[<class>,]<key-tag>,<algorithm>,<digest-type>,<digest>
|
||||||
Provide DS records to act a trust anchors for DNSSEC
|
Provide DS records to act a trust anchors for DNSSEC
|
||||||
validation. Typically these will be the DS record(s) for Key Signing
|
validation. Typically these will be the DS record(s) for Key Signing
|
||||||
key(s) (KSK) of the root zone,
|
key(s) (KSK) of the root zone,
|
||||||
@@ -1188,7 +1196,7 @@ available, though it normally is for direct-connected clients, or
|
|||||||
clients using DHCP relays which support RFC 6939.
|
clients using DHCP relays which support RFC 6939.
|
||||||
|
|
||||||
|
|
||||||
For DHCPv4, the special option id:* means "ignore any client-id
|
For DHCPv4, the special option \fBid:*\fP means "ignore any client-id
|
||||||
and use MAC addresses only." This is useful when a client presents a client-id sometimes
|
and use MAC addresses only." This is useful when a client presents a client-id sometimes
|
||||||
but not others.
|
but not others.
|
||||||
|
|
||||||
@@ -1216,36 +1224,34 @@ the result is undefined. A corollary to this is that the name associated with a
|
|||||||
does not appear in the DNS until the host obtains a DHCP lease.
|
does not appear in the DNS until the host obtains a DHCP lease.
|
||||||
|
|
||||||
|
|
||||||
The special keyword "ignore"
|
The special keyword \fBignore\fP tells dnsmasq never to offer a DHCP lease
|
||||||
tells dnsmasq to never offer a DHCP lease to a machine. The machine
|
to a machine. The machine
|
||||||
can be specified by hardware address, client ID or hostname, for
|
can be specified by hardware address, client ID or hostname. For
|
||||||
instance
|
example: \fB--dhcp-host=00:20:e0:3b:13:af,ignore\fP.
|
||||||
.B --dhcp-host=00:20:e0:3b:13:af,ignore
|
This can be useful when there is another DHCP server on the network which should
|
||||||
This is
|
|
||||||
useful when there is another DHCP server on the network which should
|
|
||||||
be used by some machines.
|
be used by some machines.
|
||||||
|
|
||||||
The set:<tag> construct sets the tag
|
The \fBset:<tag>\fP construct sets the tag
|
||||||
whenever this \fB--dhcp-host\fP directive is in use. This can be used to
|
whenever this \fB--dhcp-host\fP directive is in use. This can be used to
|
||||||
selectively send DHCP options just for this host. More than one tag
|
selectively send DHCP options just for this host. More than one tag
|
||||||
can be set in a \fB--dhcp-host\fP directive (but not in other places where
|
can be set in a \fB--dhcp-host\fP directive (but not in other places where
|
||||||
"set:<tag>" is allowed). When a host matches any
|
\fBset:<tag>\fP is allowed). When a host matches any
|
||||||
\fB--dhcp-host\fP directive (or one implied by /etc/ethers) then the special
|
\fB--dhcp-host\fP directive (or one implied by /etc/ethers) then the special
|
||||||
tag "known" is set. This allows dnsmasq to be configured to
|
tag \fBknown\fP is set. This allows dnsmasq to be configured to
|
||||||
ignore requests from unknown machines using
|
ignore requests from unknown machines using
|
||||||
.B --dhcp-ignore=tag:!known
|
\fB--dhcp-ignore=tag:!known\fP.
|
||||||
If the host matches only a \fB--dhcp-host\fP directive which cannot
|
If the host matches only a \fB--dhcp-host\fP directive which cannot
|
||||||
be used because it specifies an address on different subnet, the tag "known-othernet" is set.
|
be used because it specifies an address on a different subnet, the tag \fBknown-othernet\fP is set.
|
||||||
|
|
||||||
The tag:<tag> construct filters which dhcp-host directives are used; more than
|
The \fBtag:<tag>\fP construct filters which dhcp-host directives are used. More than
|
||||||
one can be provided, in this case the request must match all of them. Tagged
|
one tag can be provided. In this case, the request must match all tags. Tagged
|
||||||
directives are used in preference to untagged ones. Note that one of <hwaddr>,
|
directives are used in preference to untagged ones. Note that one of <hwaddr>,
|
||||||
<client_id> or <hostname> still needs to be specified (can be a wildcard).
|
<client_id> or <hostname> still must be specified (can be a wildcard).
|
||||||
|
|
||||||
Ethernet addresses (but not client-ids) may have
|
Ethernet addresses (but not client-ids) may have
|
||||||
wildcard bytes, so for example
|
wildcard bytes, so for example
|
||||||
.B --dhcp-host=00:20:e0:3b:13:*,ignore
|
.B --dhcp-host=00:20:e0:3b:13:*,ignore
|
||||||
will cause dnsmasq to ignore a range of hardware addresses. Note that
|
will cause dnsmasq to ignore the given range of hardware addresses. Note that
|
||||||
the "*" will need to be escaped or quoted on a command line, but not
|
the "*" will need to be escaped or quoted on a command line, but not
|
||||||
in the configuration file.
|
in the configuration file.
|
||||||
|
|
||||||
@@ -1259,11 +1265,11 @@ is 6.
|
|||||||
|
|
||||||
As a special case, in DHCPv4, it is possible to include more than one
|
As a special case, in DHCPv4, it is possible to include more than one
|
||||||
hardware address. eg:
|
hardware address. eg:
|
||||||
.B --dhcp-host=11:22:33:44:55:66,12:34:56:78:90:12,192.168.0.2
|
\fB--dhcp-host=11:22:33:44:55:66,12:34:56:78:90:12,192.168.0.2\fP.
|
||||||
This allows an IP address to be associated with
|
This allows an IP address to be associated with
|
||||||
multiple hardware addresses, and gives dnsmasq permission to abandon a
|
multiple hardware addresses, and gives dnsmasq permission to abandon a
|
||||||
DHCP lease to one of the hardware addresses when another one asks for
|
DHCP lease to one of the hardware addresses when another one asks for
|
||||||
a lease. Beware that this is a dangerous thing to do, it will only
|
a lease. Beware that this is a dangerous thing to do: it will only
|
||||||
work reliably if only one of the hardware addresses is active at any
|
work reliably if only one of the hardware addresses is active at any
|
||||||
time and there is no way for dnsmasq to enforce this. It is, for instance,
|
time and there is no way for dnsmasq to enforce this. It is, for instance,
|
||||||
useful to allocate a stable IP address to a laptop which
|
useful to allocate a stable IP address to a laptop which
|
||||||
@@ -1310,27 +1316,25 @@ options containing the same information. /etc/ethers is re-read when
|
|||||||
dnsmasq receives SIGHUP. IPv6 addresses are NOT read from /etc/ethers.
|
dnsmasq receives SIGHUP. IPv6 addresses are NOT read from /etc/ethers.
|
||||||
.TP
|
.TP
|
||||||
.B \-O, --dhcp-option=[tag:<tag>,[tag:<tag>,]][encap:<opt>,][vi-encap:<enterprise>,][vendor:[<vendor-class>],][<opt>|option:<opt-name>|option6:<opt>|option6:<opt-name>],[<value>[,<value>]]
|
.B \-O, --dhcp-option=[tag:<tag>,[tag:<tag>,]][encap:<opt>,][vi-encap:<enterprise>,][vendor:[<vendor-class>],][<opt>|option:<opt-name>|option6:<opt>|option6:<opt-name>],[<value>[,<value>]]
|
||||||
Specify different or extra options to DHCP clients. By default,
|
Send various extra options to DHCP clients. By default,
|
||||||
dnsmasq sends some standard options to DHCP clients, the netmask and
|
dnsmasq sends some standard options to DHCP clients, the netmask and
|
||||||
broadcast address are set to the same as the host running dnsmasq, and
|
broadcast address are set to the same as the host running dnsmasq, and
|
||||||
the DNS server and default route are set to the address of the machine
|
the DNS server and default route are set to the address of the machine
|
||||||
running dnsmasq. (Equivalent rules apply for IPv6.) If the domain name option has been set, that is sent.
|
running dnsmasq. (Equivalent rules apply for IPv6.) If the domain name option has been set, that is sent.
|
||||||
This configuration allows these defaults to be overridden,
|
This configuration allows these defaults to be overridden,
|
||||||
or other options specified. The option, to be sent may be given as a
|
or other options specified. The option to be sent may be given as a
|
||||||
decimal number or as "option:<option-name>" The option numbers are
|
decimal number or as \fBoption:<option-name>\fP.
|
||||||
|
|
||||||
|
Option numbers are
|
||||||
specified in RFC2132 and subsequent RFCs. The set of option-names
|
specified in RFC2132 and subsequent RFCs. The set of option-names
|
||||||
known by dnsmasq can be discovered by running "dnsmasq --help dhcp".
|
known by dnsmasq can be discovered by running \fBdnsmasq --help dhcp\fP.
|
||||||
For example, to set the default route option to
|
For example, to set the default route option to 192.168.4.4, use
|
||||||
192.168.4.4, do
|
\fB--dhcp-option=3,192.168.4.4\fP or
|
||||||
.B --dhcp-option=3,192.168.4.4
|
\fB--dhcp-option=option:router,192.168.4.4\fP
|
||||||
or
|
and to set the time-server address to 192.168.0.4, use
|
||||||
.B --dhcp-option = option:router, 192.168.4.4
|
\fB--dhcp-option=42,192.168.0.4\fP or
|
||||||
and to set the time-server address to 192.168.0.4, do
|
\fB--dhcp-option=option:ntp-server,192.168.0.4\fP.
|
||||||
.B --dhcp-option = 42,192.168.0.4
|
The special address 0.0.0.0 means "the address of the system running dnsmasq".
|
||||||
or
|
|
||||||
.B --dhcp-option = option:ntp-server, 192.168.0.4
|
|
||||||
The special address 0.0.0.0 is taken to mean "the address of the
|
|
||||||
machine running dnsmasq".
|
|
||||||
|
|
||||||
An option without data is valid, and includes just the option without data.
|
An option without data is valid, and includes just the option without data.
|
||||||
(There is only one option with a zero length data field currently defined for DHCPv4, 80:rapid commit, so this feature is not very useful in practice). Options for which dnsmasq normally
|
(There is only one option with a zero length data field currently defined for DHCPv4, 80:rapid commit, so this feature is not very useful in practice). Options for which dnsmasq normally
|
||||||
@@ -1351,30 +1355,29 @@ to option 120 are handled as per RFC 3361. Dotted-quad IP addresses
|
|||||||
which are followed by a slash and then a netmask size are encoded as
|
which are followed by a slash and then a netmask size are encoded as
|
||||||
described in RFC 3442.
|
described in RFC 3442.
|
||||||
|
|
||||||
IPv6 options are specified using the
|
IPv6 options are specified using the \fBoption6:\fP
|
||||||
.B option6:
|
|
||||||
keyword, followed by the option number or option name. The IPv6 option
|
keyword, followed by the option number or option name. The IPv6 option
|
||||||
name space is disjoint from the IPv4 option name space. IPv6 addresses
|
name space is disjoint from the IPv4 option name space. IPv6 addresses
|
||||||
in options must be bracketed with square brackets, eg.
|
in options must be bracketed with square brackets, eg.
|
||||||
.B --dhcp-option=option6:ntp-server,[1234::56]
|
\fB --dhcp-option=option6:ntp-server,[1234::56]\fP.
|
||||||
For IPv6, [::] means "the global address of
|
For IPv6, [::] means "the global address of
|
||||||
the machine running dnsmasq", whilst [fd00::] is replaced with the
|
the machine running dnsmasq", whilst [fd00::] is replaced with the
|
||||||
ULA, if it exists, and [fe80::] with the link-local address.
|
ULA, if it exists, and [fe80::] with the link-local address.
|
||||||
|
|
||||||
Be careful: no checking is done that the correct type of data for the
|
Be careful: data-type suitability for the option number sent is not checked.
|
||||||
option number is sent, it is quite possible to
|
It is quite possible to persuade dnsmasq to generate illegal DHCP packets with
|
||||||
persuade dnsmasq to generate illegal DHCP packets with injudicious use
|
injudicious use of this flag.
|
||||||
of this flag. When the value is a decimal number, dnsmasq must determine how
|
When the value is a decimal number, dnsmasq must determine how
|
||||||
large the data item is. It does this by examining the option number and/or the
|
large the data item is. It does this by examining the option number and/or the
|
||||||
value, but can be overridden by appending a single letter flag as follows:
|
value, but can be overridden by appending a single letter flag as follows:
|
||||||
b = one byte, s = two bytes, i = four bytes. This is mainly useful with
|
b = one byte, s = two bytes, i = four bytes. This is mainly useful with
|
||||||
encapsulated vendor class options (see below) where dnsmasq cannot
|
encapsulated vendor class options (see below) where dnsmasq cannot
|
||||||
determine data size from the option number. Option data which
|
determine data size from the option number. Option data which
|
||||||
consists solely of periods and digits will be interpreted by dnsmasq
|
consists solely of periods and digits will be interpreted by dnsmasq
|
||||||
as an IP address, and inserted into an option as such. To force a
|
as an IP address, and inserted into an option as such. To force a
|
||||||
literal string, use quotes. For instance when using option 66 to send
|
literal string, use quotes. For instance when using option 66 to send
|
||||||
a literal IP address as TFTP server name, it is necessary to do
|
a literal IP address as TFTP server name, it is necessary to do
|
||||||
.B --dhcp-option=66,"1.2.3.4"
|
\fB--dhcp-option=66,"1.2.3.4"\fP.
|
||||||
|
|
||||||
Encapsulated Vendor-class options may also be specified (IPv4 only) using
|
Encapsulated Vendor-class options may also be specified (IPv4 only) using
|
||||||
\fB--dhcp-option\fP: for instance
|
\fB--dhcp-option\fP: for instance
|
||||||
@@ -1403,7 +1406,7 @@ Vendor Options" as specified by RFC3925. These are denoted like this:
|
|||||||
The number in the vi-encap: section is the IANA enterprise number
|
The number in the vi-encap: section is the IANA enterprise number
|
||||||
used to identify this option. This form of encapsulation is supported
|
used to identify this option. This form of encapsulation is supported
|
||||||
in IPv6.
|
in IPv6.
|
||||||
|
|
||||||
The address 0.0.0.0 is not treated specially in
|
The address 0.0.0.0 is not treated specially in
|
||||||
encapsulated options.
|
encapsulated options.
|
||||||
.TP
|
.TP
|
||||||
@@ -1429,7 +1432,7 @@ forces "simple and safe" behaviour to avoid problems in such a case.
|
|||||||
.B --dhcp-relay=<local address>[,<server address>[#<server port>]][,<interface]
|
.B --dhcp-relay=<local address>[,<server address>[#<server port>]][,<interface]
|
||||||
Configure dnsmasq to do DHCP relay. The local address is an address
|
Configure dnsmasq to do DHCP relay. The local address is an address
|
||||||
allocated to an interface on the host running dnsmasq. All DHCP
|
allocated to an interface on the host running dnsmasq. All DHCP
|
||||||
requests arriving on that interface will we relayed to a remote DHCP
|
requests arriving on that interface will be relayed to a remote DHCP
|
||||||
server at the server address. It is possible to relay from a single local
|
server at the server address. It is possible to relay from a single local
|
||||||
address to multiple remote servers by using multiple \fB--dhcp-relay\fP
|
address to multiple remote servers by using multiple \fB--dhcp-relay\fP
|
||||||
configs with the same local address and different server
|
configs with the same local address and different server
|
||||||
@@ -1529,45 +1532,47 @@ via relays. If a list of IP addresses is given, only interactions via
|
|||||||
relays at those addresses are affected.
|
relays at those addresses are affected.
|
||||||
.TP
|
.TP
|
||||||
.B --dhcp-match=set:<tag>,<option number>|option:<option name>|vi-encap:<enterprise>[,<value>]
|
.B --dhcp-match=set:<tag>,<option number>|option:<option name>|vi-encap:<enterprise>[,<value>]
|
||||||
Without a value, set the tag if the client sends a DHCP
|
Without \fB<value>\fP, set \fB<tag>\fP if the client sends a DHCP
|
||||||
option of the given number or name. When a value is given, set the tag only if
|
\fBoption\fP of the given number or name. With \fB<value>\fP, set \fB<tag>\fP only if
|
||||||
the option is sent and matches the value. The value may be of the form
|
the client sends the \fBoption\fP matching or containing \fB<value>\fP.
|
||||||
|
|
||||||
|
The value may be of the form
|
||||||
"01:ff:*:02" in which case the value must match (apart from wildcards)
|
"01:ff:*:02" in which case the value must match (apart from wildcards)
|
||||||
but the option sent may have unmatched data past the end of the
|
but the option sent may have unmatched data past the end of the
|
||||||
value. The value may also be of the same form as in
|
value. The value may also be of the same form as in
|
||||||
.B --dhcp-option
|
.B --dhcp-option
|
||||||
in which case the option sent is treated as an array, and one element
|
in which case the option sent is treated as an array, and one element
|
||||||
must match, so
|
must match.
|
||||||
.B --dhcp-match=set:efi-ia32,option:client-arch,6
|
.B --dhcp-match=set:efi-ia32,option:client-arch,6
|
||||||
will set the tag "efi-ia32" if the the number 6 appears in the list of
|
sets the tag \fBefi-ia32\fP if the number \fB6\fP appears in the list of
|
||||||
architectures sent by the client in option 93. (See RFC 4578 for
|
architectures sent by the client in option 93. (See RFC 4578 for
|
||||||
details.) If the value is a string, substring matching is used.
|
details.) If the value is a string, substring matching is used.
|
||||||
|
|
||||||
The special form with vi-encap:<enterprise number> matches against
|
The special form with vi-encap:<enterprise number> matches against
|
||||||
vendor-identifying vendor classes for the specified enterprise. Please
|
vendor-identifying vendor classes for the specified enterprise. Please
|
||||||
see RFC 3925 for more details of these rare and interesting beasts.
|
see RFC 3925 for more details of these rare and interesting beasts.
|
||||||
.TP
|
.TP
|
||||||
.B --dhcp-name-match=set:<tag>,<name>[*]
|
.B --dhcp-name-match=set:<tag>,<name>[*]
|
||||||
Set the tag if the given name is supplied by a DHCP client. There may be a single trailing wildcard *, which has the usual meaning. Combined with dhcp-ignore or dhcp-ignore-names this gives the ability to ignore certain clients by name, or disallow certain hostnames from being claimed by a client.
|
Set a \fB<tag>\fP if the given \fB<name>\fP is supplied by a DHCP client. There may be a single trailing wildcard *, with a glob meaning. Combined with \fBdhcp-ignore\fP or \fBdhcp-ignore-names\fP this gives the ability to ignore certain clients by name, or disallow certain hostnames from being claimed by a client.
|
||||||
.TP
|
.TP
|
||||||
.B --tag-if=set:<tag>[,set:<tag>[,tag:<tag>[,tag:<tag>]]]
|
.B --tag-if=set:<tag>[,set:<tag>[,tag:<tag>[,tag:<tag>]]]
|
||||||
Perform boolean operations on tags. Any tag appearing as set:<tag> is set if
|
Perform boolean operations on tags. All \fBset:<tag>\fP tags are set if
|
||||||
all the tags which appear as tag:<tag> are set, (or unset when tag:!<tag> is used)
|
all \fBtag:<tag>\fP are already set, (or unset when \fBtag:!<tag>\fP is used).
|
||||||
If no tag:<tag> appears set:<tag> tags are set unconditionally.
|
If no \fBtag:<tag>\fP appears, \fBset:<tag>\fP tags are set unconditionally.
|
||||||
Any number of set: and tag: forms may appear, in any order.
|
Any number of \fBset:\fP and \fBtag:\fP forms may appear, in any order.
|
||||||
\fB--tag-if\fP lines are executed in order, so if the tag in tag:<tag> is a
|
\fB--tag-if\fP lines are executed in order, so if the tag in \fBtag:<tag>\fP is a
|
||||||
tag set by another
|
tag set by another
|
||||||
.B --tag-if,
|
.B --tag-if,
|
||||||
the line which sets the tag must precede the one which tests it.
|
the line which sets the tag must precede the line which tests it.
|
||||||
|
|
||||||
As an extension, the tag:<tag> clauses support limited wildcard matching,
|
As an extension, the \fBtag:<tag>\fP clauses support limited wildcard matching,
|
||||||
similar to the matching in the \fB--interface\fP directive. This allows, for
|
similar to the matching in the \fB--interface\fP directive. This allows the
|
||||||
example, using \fB--tag-if=set:ppp,tag:ppp*\fP to set the tag 'ppp' for all requests
|
example \fB--tag-if=set:ppp,tag:ppp*\fP to set the tag 'ppp' for all requests
|
||||||
received on any matching interface (ppp0, ppp1, etc). This can be used in conjunction
|
received on any matching interface (ppp0, ppp1, etc). This can be used in conjunction
|
||||||
with the tag:!<tag> format meaning that no tag matching the wildcard may be set.
|
with the \fBtag:!<tag>\fP format meaning that no tag matching the wildcard may be set.
|
||||||
.TP
|
.TP
|
||||||
.B \-J, --dhcp-ignore=tag:<tag>[,tag:<tag>]
|
.B \-J, --dhcp-ignore=tag:<tag>[,tag:<tag>]
|
||||||
When all the given tags appear in the tag set ignore the host and do
|
When all the given tags appear in the tag set, ignore the host and do
|
||||||
not allocate it a DHCP lease.
|
not allocate it a DHCP lease.
|
||||||
.TP
|
.TP
|
||||||
.B --dhcp-ignore-names[=tag:<tag>[,tag:<tag>]]
|
.B --dhcp-ignore-names[=tag:<tag>[,tag:<tag>]]
|
||||||
@@ -2416,48 +2421,67 @@ the CNAME. To work around this, add the CNAME to /etc/hosts so that
|
|||||||
the CNAME is shadowed too.
|
the CNAME is shadowed too.
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
The tag system works as follows: For each DHCP request, dnsmasq
|
The tag system works as follows: dnsmasq tags each DHCP request
|
||||||
collects a set of valid tags from active configuration lines which
|
with tags from applicable configuration lines containing \fBset:<tag>\fP i.e.
|
||||||
include set:<tag>, including one from the
|
|
||||||
.B --dhcp-range
|
|
||||||
used to allocate the address, one from any matching
|
|
||||||
.B --dhcp-host
|
|
||||||
(and "known" or "known-othernet" if a \fB--dhcp-host\fP matches)
|
|
||||||
The tag "bootp" is set for BOOTP requests, and a tag whose name is the
|
|
||||||
name of the interface on which the request arrived is also set.
|
|
||||||
|
|
||||||
Any configuration lines which include one or more tag:<tag> constructs
|
\fBset:<tag>\fP from the \fB--dhcp-range\fP used to allocate the address;
|
||||||
will only be valid if all that tags are matched in the set derived
|
|
||||||
above. Typically this is \fB--dhcp-option\fP.
|
\fBset:<tag>\fP from any matching \fB--dhcp-host\fP (plus the tag \fBknown\fP or
|
||||||
.B --dhcp-option
|
\fBknown-othernet\fP).
|
||||||
which has tags will be used in preference to an untagged
|
|
||||||
.B --dhcp-option,
|
BOOTP requests are tagged \fBbootp\fP. Each request is also tagged with the name of
|
||||||
provided that _all_ the tags match somewhere in the
|
the interface on which the request arrived.
|
||||||
set collected as described above. The prefix '!' on a tag means 'not'
|
|
||||||
so \fB--dhcp-option=tag:!purple,3,1.2.3.4\fP sends the option when the
|
Each configuration line containing one or more \fBtag:<tag>\fP constructs
|
||||||
tag purple is not in the set of valid tags. (If using this in a
|
applies when all its tags exist on the request. That is:
|
||||||
command line rather than a configuration file, be sure to escape !,
|
|
||||||
which is a shell metacharacter)
|
Configuration tag:A applies to a request set:tagged A.
|
||||||
|
|
||||||
|
Configuration tag:B applies to a request set:tagged B.
|
||||||
|
|
||||||
|
Configuration tag:A+B doesn't apply to a request set:tagged A.
|
||||||
|
|
||||||
|
Configuration tag:A+B doesn't apply to a request set:tagged B.
|
||||||
|
|
||||||
|
Configurations tag:A+B, tag:A, tag:B apply to a request set:tagged A+B.
|
||||||
|
|
||||||
|
\fBset:<tag>\fP constructs in \fB--dhcp-range\fP and \fB--dhcp-host\fP tag requests.
|
||||||
|
|
||||||
|
Use \fBtag:<tag>\fPs in \fB--dhcp-option\fPs to match \fBset:<tag>\fP and apply configurations.
|
||||||
|
|
||||||
|
A \fB--dhcp-option\fP with \fBtag:<tag>\fP is preferred over an untagged
|
||||||
|
\fB--dhcp-option\fP, provided that \fBall\fP its tags match somewhere in the
|
||||||
|
set gathered above.
|
||||||
|
|
||||||
|
The tag prefix '!' means 'not'.
|
||||||
|
\fB--dhcp-option=tag:!purple,3,1.2.3.4\fP sends the option when the request
|
||||||
|
is not tagged with purple. (The shell metacharacter '!' must be escaped on the
|
||||||
|
command line but not in a configuration file).
|
||||||
|
|
||||||
|
When selecting \fB--dhcp-option\fPs, a \fB--dhcp-range\fP tag is second class
|
||||||
|
to other tags, to make it easy to override options for
|
||||||
|
individual hosts, so:
|
||||||
|
|
||||||
When selecting \fB--dhcp-options\fP, a tag from \fB--dhcp-range\fP is second class
|
|
||||||
relative to other tags, to make it easy to override options for
|
|
||||||
individual hosts, so
|
|
||||||
.B --dhcp-range=set:interface1,......
|
.B --dhcp-range=set:interface1,......
|
||||||
|
|
||||||
.B --dhcp-host=set:myhost,.....
|
.B --dhcp-host=set:myhost,.....
|
||||||
|
|
||||||
.B --dhcp-option=tag:interface1,option:nis-domain,"domain1"
|
.B --dhcp-option=tag:interface1,option:nis-domain,"domain1"
|
||||||
|
|
||||||
.B --dhcp-option=tag:myhost,option:nis-domain,"domain2"
|
.B --dhcp-option=tag:myhost,option:nis-domain,"domain2"
|
||||||
will set the NIS-domain to domain1 for hosts in the range, but
|
|
||||||
override that to domain2 for a particular host.
|
sets the NIS-domain to domain1 for hosts in the range, but
|
||||||
|
to domain2 for a particular host that may or may not fall in the range.
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
Note that for
|
Note that for \fB--dhcp-range\fP both
|
||||||
.B --dhcp-range
|
\fBtag:<tag>\fP and
|
||||||
both tag:<tag> and set:<tag> are allowed, to both select the range in
|
\fBset:<tag>\fP are possible, in order to both select the range in
|
||||||
use based on (eg) \fB--dhcp-host\fP, and to affect the options sent, based on
|
use based on (eg) \fB--dhcp-host\fP, and to affect the options sent, based on
|
||||||
the range selected.
|
the range selected.
|
||||||
|
|
||||||
This system evolved from an earlier, more limited one and for backward
|
The tag system evolved from an earlier, more limited system. For backward
|
||||||
compatibility "net:" may be used instead of "tag:" and "set:" may be
|
compatibility, "net:" may be used instead of "tag:" and "set:" may be
|
||||||
omitted. (Except in
|
omitted. (Except in
|
||||||
.B --dhcp-host,
|
.B --dhcp-host,
|
||||||
where "net:" may be used instead of "set:".) For the same reason, '#'
|
where "net:" may be used instead of "set:".) For the same reason, '#'
|
||||||
@@ -2475,7 +2499,7 @@ configuration option is present to activate the DHCP server
|
|||||||
on a particular network. (Setting \fB--bootp-dynamic\fP removes the need for
|
on a particular network. (Setting \fB--bootp-dynamic\fP removes the need for
|
||||||
static address mappings.) The filename
|
static address mappings.) The filename
|
||||||
parameter in a BOOTP request is used as a tag,
|
parameter in a BOOTP request is used as a tag,
|
||||||
as is the tag "bootp", allowing some control over the options returned to
|
as is the tag \fBbootp\fP, allowing some control over the options returned to
|
||||||
different classes of hosts.
|
different classes of hosts.
|
||||||
|
|
||||||
.SH AUTHORITATIVE CONFIGURATION
|
.SH AUTHORITATIVE CONFIGURATION
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#
|
#
|
||||||
# This revised version is (C) Copyright by
|
# This revised version is (C) Copyright by
|
||||||
# Matthias Andree <matthias.andree@gmx.de>, 2010 - 2021.
|
# Matthias Andree <matthias.andree@gmx.de>, 2010 - 2021.
|
||||||
# Conrad Kostecki <conrad@kostecki.com>, 2014 - 2022.
|
# Conrad Kostecki <conrad@kostecki.com>, 2014 - 2024.
|
||||||
# It is subject to the GNU General Public License v2,
|
# It is subject to the GNU General Public License v2,
|
||||||
# or at your option, any later version.
|
# or at your option, any later version.
|
||||||
#
|
#
|
||||||
@@ -10,10 +10,10 @@
|
|||||||
# Simon Kelley <simon@thekelleys.org.uk>, 2005.
|
# Simon Kelley <simon@thekelleys.org.uk>, 2005.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: dnsmasq 2.88\n"
|
"Project-Id-Version: dnsmasq 2.91\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-03-20 00:00+0000\n"
|
"POT-Creation-Date: 2021-03-20 00:00+0000\n"
|
||||||
"PO-Revision-Date: 2022-11-17 20:08+0100\n"
|
"PO-Revision-Date: 2024-12-23 22:36+0100\n"
|
||||||
"Last-Translator: Conrad Kostecki <conrad@kostecki.com>\n"
|
"Last-Translator: Conrad Kostecki <conrad@kostecki.com>\n"
|
||||||
"Language-Team: German <de@li.org>\n"
|
"Language-Team: German <de@li.org>\n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
@@ -21,7 +21,7 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
"X-Generator: Poedit 3.2\n"
|
"X-Generator: Poedit 3.5\n"
|
||||||
|
|
||||||
#: cache.c:652
|
#: cache.c:652
|
||||||
msgid "Internal error in cache."
|
msgid "Internal error in cache."
|
||||||
@@ -43,9 +43,9 @@ msgid "bad name at %s line %d"
|
|||||||
msgstr "Fehlerhafter Name in %s Zeile %d"
|
msgstr "Fehlerhafter Name in %s Zeile %d"
|
||||||
|
|
||||||
#: cache.c:1265
|
#: cache.c:1265
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "read %s - %d names"
|
msgid "read %s - %d names"
|
||||||
msgstr "%s gelesen - %d Adressen"
|
msgstr "%s gelesen - %d Namen"
|
||||||
|
|
||||||
#: cache.c:1381
|
#: cache.c:1381
|
||||||
msgid "cleared cache"
|
msgid "cleared cache"
|
||||||
@@ -84,7 +84,7 @@ msgstr "weitergeleitete Anfragen %u, lokal beantwortete Anfragen %u"
|
|||||||
#: cache.c:1766
|
#: cache.c:1766
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "queries answered from stale cache %u"
|
msgid "queries answered from stale cache %u"
|
||||||
msgstr ""
|
msgstr "Anfragen beantwortet vom veralteten Cache %u"
|
||||||
|
|
||||||
#: cache.c:1768
|
#: cache.c:1768
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -92,9 +92,9 @@ msgid "queries for authoritative zones %u"
|
|||||||
msgstr "Anfragen nach autoritativen Zonen %u"
|
msgstr "Anfragen nach autoritativen Zonen %u"
|
||||||
|
|
||||||
#: cache.c:1796
|
#: cache.c:1796
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "server %s#%d: queries sent %u, retried %u, failed %u, nxdomain replies %u, avg. latency %ums"
|
msgid "server %s#%d: queries sent %u, retried %u, failed %u, nxdomain replies %u, avg. latency %ums"
|
||||||
msgstr "Server %s#%d: Anfragen gesendet %u, erneut versucht oder fehlgeschlagen %u"
|
msgstr "Server %s#%d: Anfragen gesendet %u, erneut versucht %u, fehlgeschlagen %u, nxdomain-Antworten %u, durchschnittliche Latenz %ums"
|
||||||
|
|
||||||
#: util.c:51
|
#: util.c:51
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -120,14 +120,14 @@ msgid "failed to allocate %d bytes"
|
|||||||
msgstr "Konnte %d Bytes nicht belegen"
|
msgstr "Konnte %d Bytes nicht belegen"
|
||||||
|
|
||||||
#: util.c:344
|
#: util.c:344
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "failed to reallocate %d bytes"
|
msgid "failed to reallocate %d bytes"
|
||||||
msgstr "Konnte %d Bytes nicht belegen"
|
msgstr "Konnte %d Bytes nicht allozieren"
|
||||||
|
|
||||||
#: util.c:465
|
#: util.c:465
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "cannot read monotonic clock: %s"
|
msgid "cannot read monotonic clock: %s"
|
||||||
msgstr "kann Netlink-Socket nicht erzeugen: %s"
|
msgstr "monotone Uhr kann nicht gelesen werden: %s"
|
||||||
|
|
||||||
# @Simon: not perfect but I cannot get nearer right now.
|
# @Simon: not perfect but I cannot get nearer right now.
|
||||||
#: util.c:579
|
#: util.c:579
|
||||||
@@ -188,11 +188,11 @@ msgstr "Unberechtigte DNS-Anfragen von Windows-Rechnern nicht weiterleiten."
|
|||||||
|
|
||||||
#: option.c:404
|
#: option.c:404
|
||||||
msgid "Don't include IPv4 addresses in DNS answers."
|
msgid "Don't include IPv4 addresses in DNS answers."
|
||||||
msgstr ""
|
msgstr "Keine IPv4-Adressen in DNS-Antworten inkludieren."
|
||||||
|
|
||||||
#: option.c:405
|
#: option.c:405
|
||||||
msgid "Don't include IPv6 addresses in DNS answers."
|
msgid "Don't include IPv6 addresses in DNS answers."
|
||||||
msgstr ""
|
msgstr "Keine IPv6-Adressen in DNS-Antworten inkludieren."
|
||||||
|
|
||||||
#: option.c:406
|
#: option.c:406
|
||||||
msgid "Enable DHCP in the range given with lease duration."
|
msgid "Enable DHCP in the range given with lease duration."
|
||||||
@@ -313,7 +313,7 @@ msgstr "Fehlerhafte Suchergebnisse NICHT zwischenspeichern."
|
|||||||
|
|
||||||
#: option.c:434
|
#: option.c:434
|
||||||
msgid "Use expired cache data for faster reply."
|
msgid "Use expired cache data for faster reply."
|
||||||
msgstr ""
|
msgstr "Verwende abgelaufene Cachedaten für schnellere Antwort."
|
||||||
|
|
||||||
#: option.c:435
|
#: option.c:435
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -347,7 +347,7 @@ msgstr "Ausgehenden Port für DNS-Anfragen an vorgelagerte Server erzwingen."
|
|||||||
|
|
||||||
#: option.c:442
|
#: option.c:442
|
||||||
msgid "Set maximum number of random originating ports for a query."
|
msgid "Set maximum number of random originating ports for a query."
|
||||||
msgstr ""
|
msgstr "Setze die maximale Anzahl zufälliger Ursprungsports für eine Abfrage."
|
||||||
|
|
||||||
#: option.c:443
|
#: option.c:443
|
||||||
msgid "Do NOT read resolv.conf."
|
msgid "Do NOT read resolv.conf."
|
||||||
@@ -404,7 +404,7 @@ msgstr "Spezifiziere untere Gültigkeitsdauergrenze für Zwischenspeicher."
|
|||||||
|
|
||||||
#: option.c:456
|
#: option.c:456
|
||||||
msgid "Retry DNS queries after this many milliseconds."
|
msgid "Retry DNS queries after this many milliseconds."
|
||||||
msgstr ""
|
msgstr "DNS-Abfragen nach so vielen Millisekunden wiederholen."
|
||||||
|
|
||||||
#: option.c:457
|
#: option.c:457
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -520,7 +520,7 @@ msgstr "Konfiguration aus allen Dateien in diesem Verzeichnis lesen."
|
|||||||
|
|
||||||
#: option.c:484
|
#: option.c:484
|
||||||
msgid "Execute file and read configuration from stdin."
|
msgid "Execute file and read configuration from stdin."
|
||||||
msgstr ""
|
msgstr "Führe Datei aus und lese die Konfiguration aus stdin."
|
||||||
|
|
||||||
#: option.c:485
|
#: option.c:485
|
||||||
msgid "Log to this syslog facility or file. (defaults to DAEMON)"
|
msgid "Log to this syslog facility or file. (defaults to DAEMON)"
|
||||||
@@ -680,7 +680,7 @@ msgstr "Anfragende MAC-Adresse in die weiterleitende DNS-Anfrage einfügen."
|
|||||||
|
|
||||||
#: option.c:523
|
#: option.c:523
|
||||||
msgid "Strip MAC information from queries."
|
msgid "Strip MAC information from queries."
|
||||||
msgstr ""
|
msgstr "Entferne die MAC-Information von Abfragen."
|
||||||
|
|
||||||
#: option.c:524
|
#: option.c:524
|
||||||
msgid "Add specified IP subnet to forwarded DNS queries."
|
msgid "Add specified IP subnet to forwarded DNS queries."
|
||||||
@@ -688,7 +688,7 @@ msgstr "Füge spezifiziertes IP-Subnetz an weitergeleiteten DNS-Anfragen hinzu."
|
|||||||
|
|
||||||
#: option.c:525
|
#: option.c:525
|
||||||
msgid "Strip ECS information from queries."
|
msgid "Strip ECS information from queries."
|
||||||
msgstr ""
|
msgstr "Entferne die ECS-Information von Abfragen."
|
||||||
|
|
||||||
#: option.c:526
|
#: option.c:526
|
||||||
msgid "Add client identification to forwarded DNS queries."
|
msgid "Add client identification to forwarded DNS queries."
|
||||||
@@ -773,9 +773,8 @@ msgid "Specify ipsets to which matching domains should be added"
|
|||||||
msgstr "Spezifiziere IPSets, zu denen passende Domains hinzugefügt werden sollen"
|
msgstr "Spezifiziere IPSets, zu denen passende Domains hinzugefügt werden sollen"
|
||||||
|
|
||||||
#: option.c:546
|
#: option.c:546
|
||||||
#, fuzzy
|
|
||||||
msgid "Specify nftables sets to which matching domains should be added"
|
msgid "Specify nftables sets to which matching domains should be added"
|
||||||
msgstr "Spezifiziere IPSets, zu denen passende Domains hinzugefügt werden sollen"
|
msgstr "Geben Sie nftables sets an, zu denen passende Domänen hinzugefügt werden sollen"
|
||||||
|
|
||||||
#: option.c:547
|
#: option.c:547
|
||||||
msgid "Enable filtering of DNS queries with connection-track marks."
|
msgid "Enable filtering of DNS queries with connection-track marks."
|
||||||
@@ -880,7 +879,7 @@ msgstr "Protokolliere kein Routine-TFTP."
|
|||||||
|
|
||||||
#: option.c:572
|
#: option.c:572
|
||||||
msgid "Suppress round-robin ordering of DNS records."
|
msgid "Suppress round-robin ordering of DNS records."
|
||||||
msgstr ""
|
msgstr "Unterdrückt die Round-Robin-Sortierung von DNS-Einträgen."
|
||||||
|
|
||||||
#: option.c:802
|
#: option.c:802
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -915,11 +914,11 @@ msgstr "Schnittstellenbindung nicht unterstützt"
|
|||||||
|
|
||||||
#: option.c:955
|
#: option.c:955
|
||||||
msgid "Cannot resolve server name"
|
msgid "Cannot resolve server name"
|
||||||
msgstr ""
|
msgstr "Servername kann nicht aufgelöst werden"
|
||||||
|
|
||||||
#: option.c:991
|
#: option.c:991
|
||||||
msgid "cannot use IPv4 server address with IPv6 source address"
|
msgid "cannot use IPv4 server address with IPv6 source address"
|
||||||
msgstr ""
|
msgstr "IPv4-Serveradresse kann nicht mit IPv6-Quelladresse verwendet werden"
|
||||||
|
|
||||||
#: option.c:997 option.c:1043
|
#: option.c:997 option.c:1043
|
||||||
msgid "interface can only be specified once"
|
msgid "interface can only be specified once"
|
||||||
@@ -931,21 +930,19 @@ msgstr "Fehlerhafter Schnittestellenname"
|
|||||||
|
|
||||||
#: option.c:1037
|
#: option.c:1037
|
||||||
msgid "cannot use IPv6 server address with IPv4 source address"
|
msgid "cannot use IPv6 server address with IPv4 source address"
|
||||||
msgstr ""
|
msgstr "IPv6-Serveradresse kann nicht mit IPv4-Quelladresse verwendet werden"
|
||||||
|
|
||||||
#: option.c:1124
|
#: option.c:1124
|
||||||
#, fuzzy
|
|
||||||
msgid "bad IPv4 prefix length"
|
msgid "bad IPv4 prefix length"
|
||||||
msgstr "fehlerhafte Präfixlänge"
|
msgstr "ungültige IPv4-Präfixlänge"
|
||||||
|
|
||||||
#: option.c:1155 option.c:1165 option.c:1240 option.c:1250 option.c:5360
|
#: option.c:1155 option.c:1165 option.c:1240 option.c:1250 option.c:5360
|
||||||
msgid "error"
|
msgid "error"
|
||||||
msgstr "Fehler"
|
msgstr "Fehler"
|
||||||
|
|
||||||
#: option.c:1207
|
#: option.c:1207
|
||||||
#, fuzzy
|
|
||||||
msgid "bad IPv6 prefix length"
|
msgid "bad IPv6 prefix length"
|
||||||
msgstr "fehlerhafte Präfixlänge"
|
msgstr "ungültige IPv6-Präfixlänge"
|
||||||
|
|
||||||
#: option.c:1467
|
#: option.c:1467
|
||||||
msgid "inappropriate vendor:"
|
msgid "inappropriate vendor:"
|
||||||
@@ -1034,7 +1031,6 @@ msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
|
|||||||
msgstr "Neuübersetzung mit HAVE_LUASCRIPT nötig, um benutzerdefinierte Lua-Skripte auszuführen"
|
msgstr "Neuübersetzung mit HAVE_LUASCRIPT nötig, um benutzerdefinierte Lua-Skripte auszuführen"
|
||||||
|
|
||||||
#: option.c:2447
|
#: option.c:2447
|
||||||
#, fuzzy
|
|
||||||
msgid "invalid auth-zone"
|
msgid "invalid auth-zone"
|
||||||
msgstr "unzulässiger Alias-Bereich"
|
msgstr "unzulässiger Alias-Bereich"
|
||||||
|
|
||||||
@@ -1059,9 +1055,8 @@ msgid "recompile with HAVE_IPSET defined to enable ipset directives"
|
|||||||
msgstr "Neuübersetzung mit HAVE_IPSET nötig, um IPSet-Direktiven zu aktivieren"
|
msgstr "Neuübersetzung mit HAVE_IPSET nötig, um IPSet-Direktiven zu aktivieren"
|
||||||
|
|
||||||
#: option.c:3117
|
#: option.c:3117
|
||||||
#, fuzzy
|
|
||||||
msgid "recompile with HAVE_NFTSET defined to enable nftset directives"
|
msgid "recompile with HAVE_NFTSET defined to enable nftset directives"
|
||||||
msgstr "Neuübersetzung mit HAVE_IPSET nötig, um IPSet-Direktiven zu aktivieren"
|
msgstr "Neukompilieren mit definiertem HAVE_NFTSET, um NFTSET-Direktiven zu aktivieren"
|
||||||
|
|
||||||
#: option.c:3192 option.c:3210
|
#: option.c:3192 option.c:3210
|
||||||
msgid "recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"
|
msgid "recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"
|
||||||
@@ -1259,7 +1254,7 @@ msgstr "unzulässige Option"
|
|||||||
#: option.c:5363
|
#: option.c:5363
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid " in output from %s"
|
msgid " in output from %s"
|
||||||
msgstr ""
|
msgstr " in der Ausgabe von %s"
|
||||||
|
|
||||||
#: option.c:5365
|
#: option.c:5365
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -1272,9 +1267,9 @@ msgid "read %s"
|
|||||||
msgstr "%s gelesen"
|
msgstr "%s gelesen"
|
||||||
|
|
||||||
#: option.c:5446
|
#: option.c:5446
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "cannot execute %s: %s"
|
msgid "cannot execute %s: %s"
|
||||||
msgstr "kann %s nicht erstellen: %s"
|
msgstr "kann %s nicht ausführen: %s"
|
||||||
|
|
||||||
#: option.c:5454 option.c:5615 tftp.c:790
|
#: option.c:5454 option.c:5615 tftp.c:790
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -1282,14 +1277,14 @@ msgid "cannot read %s: %s"
|
|||||||
msgstr "kann %s nicht lesen: %s"
|
msgstr "kann %s nicht lesen: %s"
|
||||||
|
|
||||||
#: option.c:5473
|
#: option.c:5473
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "error executing %s: %s"
|
msgid "error executing %s: %s"
|
||||||
msgstr "konnte %s nicht ausführen: %s"
|
msgstr "Fehler bei der Ausführung von %s: %s"
|
||||||
|
|
||||||
#: option.c:5476
|
#: option.c:5476
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s returns non-zero error code"
|
msgid "%s returns non-zero error code"
|
||||||
msgstr ""
|
msgstr "%s gibt einen Fehlercode ungleich Null zurück"
|
||||||
|
|
||||||
#: option.c:5775
|
#: option.c:5775
|
||||||
msgid "junk found in command line"
|
msgid "junk found in command line"
|
||||||
@@ -1399,14 +1394,14 @@ msgid "reducing DNS packet size for nameserver %s to %d"
|
|||||||
msgstr "Reduziere die DNS-Paketgröße für Nameserver %s auf %d"
|
msgstr "Reduziere die DNS-Paketgröße für Nameserver %s auf %d"
|
||||||
|
|
||||||
#: forward.c:1565
|
#: forward.c:1565
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "ignoring query from non-local network %s (logged only once)"
|
msgid "ignoring query from non-local network %s (logged only once)"
|
||||||
msgstr "Ignoriere Anfrage von auswärtigem Netzwerk"
|
msgstr "Ignoriere Abfrage von nicht-lokalen Netzwerk %s (Nur einmal protokolliert)"
|
||||||
|
|
||||||
#: forward.c:2139
|
#: forward.c:2139
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "ignoring query from non-local network %s"
|
msgid "ignoring query from non-local network %s"
|
||||||
msgstr "Ignoriere Anfrage von auswärtigem Netzwerk"
|
msgstr "Ignoriere Abfrage von nicht-lokalen Netzwerk %s"
|
||||||
|
|
||||||
#: forward.c:2501
|
#: forward.c:2501
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -1488,7 +1483,7 @@ msgstr "ignoriere Namensserver %s - kann Socket nicht erzeugen/binden: %s"
|
|||||||
|
|
||||||
#: network.c:1643
|
#: network.c:1643
|
||||||
msgid "more servers are defined but not logged"
|
msgid "more servers are defined but not logged"
|
||||||
msgstr ""
|
msgstr "mehr Server sind definiert aber nicht protokolliert"
|
||||||
|
|
||||||
#: network.c:1654
|
#: network.c:1654
|
||||||
msgid "(no DNSSEC)"
|
msgid "(no DNSSEC)"
|
||||||
@@ -1605,7 +1600,7 @@ msgstr "max_port darf nicht kleiner als min_port sein"
|
|||||||
|
|
||||||
#: dnsmasq.c:271
|
#: dnsmasq.c:271
|
||||||
msgid "port_limit must not be larger than available port range"
|
msgid "port_limit must not be larger than available port range"
|
||||||
msgstr ""
|
msgstr "port_limit darf nicht größer als der verfügbare Portbereich sein"
|
||||||
|
|
||||||
#: dnsmasq.c:278
|
#: dnsmasq.c:278
|
||||||
msgid "--auth-server required when an auth zone is defined."
|
msgid "--auth-server required when an auth zone is defined."
|
||||||
@@ -1810,9 +1805,9 @@ msgid "restricting maximum simultaneous TFTP transfers to %d"
|
|||||||
msgstr "Begrenze gleichzeitige TFTP-Übertragungen auf maximal %d"
|
msgstr "Begrenze gleichzeitige TFTP-Übertragungen auf maximal %d"
|
||||||
|
|
||||||
#: dnsmasq.c:1095
|
#: dnsmasq.c:1095
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "error binding DHCP socket to device %s"
|
msgid "error binding DHCP socket to device %s"
|
||||||
msgstr "Fehler beim Senden des DHCP-Pakets an %s: %s"
|
msgstr "Fehler beim Binden des DHCP-Sockets an Gerät %s"
|
||||||
|
|
||||||
#: dnsmasq.c:1229
|
#: dnsmasq.c:1229
|
||||||
msgid "connected to system DBus"
|
msgid "connected to system DBus"
|
||||||
@@ -1981,19 +1976,19 @@ msgid "read %s - %d addresses"
|
|||||||
msgstr "%s gelesen - %d Adressen"
|
msgstr "%s gelesen - %d Adressen"
|
||||||
|
|
||||||
#: dhcp.c:1136
|
#: dhcp.c:1136
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "Cannot broadcast DHCP relay via interface %s"
|
msgid "Cannot broadcast DHCP relay via interface %s"
|
||||||
msgstr "Kann nicht zum DHCPv6 Server multicasten ohne korrekte Schnittstelle"
|
msgstr "DHCP-Relay kann nicht über die Schnittstelle %s gesendet werden"
|
||||||
|
|
||||||
#: dhcp.c:1160
|
#: dhcp.c:1160
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "broadcast via %s"
|
msgid "broadcast via %s"
|
||||||
msgstr ""
|
msgstr "broadcast via %s"
|
||||||
|
|
||||||
#: dhcp.c:1163 rfc3315.c:2219
|
#: dhcp.c:1163 rfc3315.c:2219
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "DHCP relay at %s -> %s"
|
msgid "DHCP relay at %s -> %s"
|
||||||
msgstr "DHCP Relais %s -> %s"
|
msgstr "DHCP-Relay bei %s -> %s"
|
||||||
|
|
||||||
#: lease.c:64
|
#: lease.c:64
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -2405,14 +2400,14 @@ msgid "release received"
|
|||||||
msgstr "Freigabe empfangen"
|
msgstr "Freigabe empfangen"
|
||||||
|
|
||||||
#: rfc3315.c:2200
|
#: rfc3315.c:2200
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "Cannot multicast DHCP relay via interface %s"
|
msgid "Cannot multicast DHCP relay via interface %s"
|
||||||
msgstr "Kann nicht zum DHCPv6 Server multicasten ohne korrekte Schnittstelle"
|
msgstr "Multicast-DHCP-Relay über Schnittstelle %s nicht möglich"
|
||||||
|
|
||||||
#: rfc3315.c:2216
|
#: rfc3315.c:2216
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "multicast via %s"
|
msgid "multicast via %s"
|
||||||
msgstr ""
|
msgstr "multicast via %s"
|
||||||
|
|
||||||
#: dhcp-common.c:187
|
#: dhcp-common.c:187
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -2484,9 +2479,9 @@ msgid "router advertisement on %s%s"
|
|||||||
msgstr "Router-Advertisment auf %s%s"
|
msgstr "Router-Advertisment auf %s%s"
|
||||||
|
|
||||||
#: dhcp-common.c:1043
|
#: dhcp-common.c:1043
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "DHCP relay from %s via %s"
|
msgid "DHCP relay from %s via %s"
|
||||||
msgstr "DHCP Weiterleitung von %s nach %s"
|
msgstr "DHCP-Relay von %s über %s"
|
||||||
|
|
||||||
#: dhcp-common.c:1045
|
#: dhcp-common.c:1045
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -2621,9 +2616,9 @@ msgid "Insecure DS reply received for %s, check domain configuration and upstrea
|
|||||||
msgstr "Unsichere DS-Antwort für %s, bitte Domainkonfiguration und Upstream DNS-Server für DNSSEC-Unterstützung überprüfen"
|
msgstr "Unsichere DS-Antwort für %s, bitte Domainkonfiguration und Upstream DNS-Server für DNSSEC-Unterstützung überprüfen"
|
||||||
|
|
||||||
#: blockdata.c:55
|
#: blockdata.c:55
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "pool memory in use %zu, max %zu, allocated %zu"
|
msgid "pool memory in use %zu, max %zu, allocated %zu"
|
||||||
msgstr "Speicherpool in Benutzung %u, Max %u, zugewiesen %u"
|
msgstr "Speicherpool in Benutzung %zu, Max %zu, zugewiesen %zu"
|
||||||
|
|
||||||
#: tables.c:61
|
#: tables.c:61
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -2695,24 +2690,23 @@ msgid "bad dynamic directory %s: %s"
|
|||||||
msgstr "fehlerhaftes dynamisches Verzeichnis %s: %s"
|
msgstr "fehlerhaftes dynamisches Verzeichnis %s: %s"
|
||||||
|
|
||||||
#: inotify.c:186
|
#: inotify.c:186
|
||||||
#, fuzzy
|
|
||||||
msgid "not a directory"
|
msgid "not a directory"
|
||||||
msgstr "Kann auf Verzeichnis %s nicht zugreifen: %s"
|
msgstr "ist kein Verzeichnis"
|
||||||
|
|
||||||
#: inotify.c:299
|
#: inotify.c:299
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "inotify: %s removed"
|
msgid "inotify: %s removed"
|
||||||
msgstr ""
|
msgstr "inotify: %s entfernt"
|
||||||
|
|
||||||
#: inotify.c:301
|
#: inotify.c:301
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "inotify: %s new or modified"
|
msgid "inotify: %s new or modified"
|
||||||
msgstr "inotify, neue oder geänderte Datei %s"
|
msgstr "inotify: %s neu oder modifiziert"
|
||||||
|
|
||||||
#: inotify.c:309
|
#: inotify.c:309
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "inotify: flushed %u names read from %s"
|
msgid "inotify: flushed %u names read from %s"
|
||||||
msgstr ""
|
msgstr "inotify: %u Namen gelöscht, aus %s gelesen"
|
||||||
|
|
||||||
#: dump.c:68
|
#: dump.c:68
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -2729,14 +2723,14 @@ msgid "failed to write packet dump"
|
|||||||
msgstr "schreiben des Paketmitschnitts fehlgeschlagen"
|
msgstr "schreiben des Paketmitschnitts fehlgeschlagen"
|
||||||
|
|
||||||
#: dump.c:289
|
#: dump.c:289
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "%u dumping packet %u mask 0x%04x"
|
msgid "%u dumping packet %u mask 0x%04x"
|
||||||
msgstr "Lade UDP Paket %u Maske 0x%04x ab"
|
msgstr "%u dumpe Paket %u Maske 0x%04x"
|
||||||
|
|
||||||
#: dump.c:291
|
#: dump.c:291
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "dumping packet %u mask 0x%04x"
|
msgid "dumping packet %u mask 0x%04x"
|
||||||
msgstr "Lade UDP Paket %u Maske 0x%04x ab"
|
msgstr "Dumpe Packet %u Make 0x%04x"
|
||||||
|
|
||||||
#: ubus.c:79
|
#: ubus.c:79
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -2770,9 +2764,8 @@ msgid "Failed to create SHA-256 hash object"
|
|||||||
msgstr "Kann SHA-256-Hash-Objekt nicht erstellen"
|
msgstr "Kann SHA-256-Hash-Objekt nicht erstellen"
|
||||||
|
|
||||||
#: nftset.c:35
|
#: nftset.c:35
|
||||||
#, fuzzy
|
|
||||||
msgid "failed to create nftset context"
|
msgid "failed to create nftset context"
|
||||||
msgstr "konnte IPset-Kontroll-Socket nicht erzeugen: %s"
|
msgstr "Fehler beim Erstellen des NFTSET-Kontexts"
|
||||||
|
|
||||||
#~ msgid "bad IPv4 prefix"
|
#~ msgid "bad IPv4 prefix"
|
||||||
#~ msgstr "fehlerhaftes IPv4-Präfix"
|
#~ msgstr "fehlerhaftes IPv4-Präfix"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -35,7 +35,7 @@ struct arp_record {
|
|||||||
static struct arp_record *arps = NULL, *old = NULL, *freelist = NULL;
|
static struct arp_record *arps = NULL, *old = NULL, *freelist = NULL;
|
||||||
static time_t last = 0;
|
static time_t last = 0;
|
||||||
|
|
||||||
static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *parmv)
|
static int filter_mac(int family, void *addrp, char *mac, size_t maclen, void *parmv)
|
||||||
{
|
{
|
||||||
struct arp_record *arp;
|
struct arp_record *arp;
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -137,7 +137,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
nameoffset = p - (unsigned char *)header;
|
nameoffset = p - (unsigned char *)header;
|
||||||
|
|
||||||
/* now extract name as .-concatenated string into name */
|
/* now extract name as .-concatenated string into name */
|
||||||
if (!extract_name(header, qlen, &p, name, 1, 4))
|
if (!extract_name(header, qlen, &p, name, EXTR_NAME_EXTRACT, 4))
|
||||||
return 0; /* bad packet */
|
return 0; /* bad packet */
|
||||||
|
|
||||||
GETSHORT(qtype, p);
|
GETSHORT(qtype, p);
|
||||||
@@ -513,7 +513,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
nxdomain = 0;
|
nxdomain = 0;
|
||||||
if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr))))
|
if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr))))
|
||||||
{
|
{
|
||||||
log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid), 0);
|
log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr, record_source(crecp->uid), 0);
|
||||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||||
daemon->auth_ttl, NULL, qtype, C_IN,
|
daemon->auth_ttl, NULL, qtype, C_IN,
|
||||||
qtype == T_A ? "4" : "6", &crecp->addr))
|
qtype == T_A ? "4" : "6", &crecp->addr))
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -193,7 +193,7 @@ void *blockdata_retrieve(struct blockdata *block, size_t len, void *data)
|
|||||||
{
|
{
|
||||||
size_t blen;
|
size_t blen;
|
||||||
struct blockdata *b;
|
struct blockdata *b;
|
||||||
void *new, *d;
|
uint8_t *new, *d;
|
||||||
|
|
||||||
static unsigned int buff_len = 0;
|
static unsigned int buff_len = 0;
|
||||||
static unsigned char *buff = NULL;
|
static unsigned char *buff = NULL;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -100,14 +100,14 @@ int arp_enumerate(void *parm, callback_t callback)
|
|||||||
#endif /* defined(HAVE_BSD_NETWORK) && !defined(__APPLE__) */
|
#endif /* defined(HAVE_BSD_NETWORK) && !defined(__APPLE__) */
|
||||||
|
|
||||||
|
|
||||||
int iface_enumerate(int family, void *parm, int (*callback)())
|
int iface_enumerate(int family, void *parm, callback_t callback)
|
||||||
{
|
{
|
||||||
struct ifaddrs *head, *addrs;
|
struct ifaddrs *head, *addrs;
|
||||||
int errsave, fd = -1, ret = 0;
|
int errsave, fd = -1, ret = 0;
|
||||||
|
|
||||||
if (family == AF_UNSPEC)
|
if (family == AF_UNSPEC)
|
||||||
#if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
|
#if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
|
||||||
return arp_enumerate(parm, callback.af_unspec);
|
return arp_enumerate(parm, callback);
|
||||||
#else
|
#else
|
||||||
return 0; /* need code for Solaris and MacOS*/
|
return 0; /* need code for Solaris and MacOS*/
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+29
-8
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -101,6 +101,7 @@ static const struct {
|
|||||||
{ 63, "ZONEMD" }, /* Message Digest Over Zone Data [RFC8976] ZONEMD/zonemd-completed-template 2018-12-12*/
|
{ 63, "ZONEMD" }, /* Message Digest Over Zone Data [RFC8976] ZONEMD/zonemd-completed-template 2018-12-12*/
|
||||||
{ 64, "SVCB" }, /* Service Binding [draft-ietf-dnsop-svcb-https-00] SVCB/svcb-completed-template 2020-06-30*/
|
{ 64, "SVCB" }, /* Service Binding [draft-ietf-dnsop-svcb-https-00] SVCB/svcb-completed-template 2020-06-30*/
|
||||||
{ 65, "HTTPS" }, /* HTTPS Binding [draft-ietf-dnsop-svcb-https-00] HTTPS/https-completed-template 2020-06-30*/
|
{ 65, "HTTPS" }, /* HTTPS Binding [draft-ietf-dnsop-svcb-https-00] HTTPS/https-completed-template 2020-06-30*/
|
||||||
|
{ 66, "DSYNC" }, /* Endpoint discovery for delegation synchronization [draft-ietf-dnsop-generalized-notify-03] DSYNC/dsync-completed-template 2024-12-10 */
|
||||||
{ 99, "SPF" }, /* [RFC7208] */
|
{ 99, "SPF" }, /* [RFC7208] */
|
||||||
{ 100, "UINFO" }, /* [IANA-Reserved] */
|
{ 100, "UINFO" }, /* [IANA-Reserved] */
|
||||||
{ 101, "UID" }, /* [IANA-Reserved] */
|
{ 101, "UID" }, /* [IANA-Reserved] */
|
||||||
@@ -112,6 +113,7 @@ static const struct {
|
|||||||
{ 107, "LP" }, /* [RFC6742] ILNP/lp-completed-template */
|
{ 107, "LP" }, /* [RFC6742] ILNP/lp-completed-template */
|
||||||
{ 108, "EUI48" }, /* an EUI-48 address [RFC7043] EUI48/eui48-completed-template 2013-03-27*/
|
{ 108, "EUI48" }, /* an EUI-48 address [RFC7043] EUI48/eui48-completed-template 2013-03-27*/
|
||||||
{ 109, "EUI64" }, /* an EUI-64 address [RFC7043] EUI64/eui64-completed-template 2013-03-27*/
|
{ 109, "EUI64" }, /* an EUI-64 address [RFC7043] EUI64/eui64-completed-template 2013-03-27*/
|
||||||
|
{ 128, "NXNAME" }, /* NXDOMAIN indicator for Compact Denial of Existence https://www.iana.org/go/draft-ietf-dnsop-compact-denial-of-existence-04 */
|
||||||
{ 249, "TKEY" }, /* Transaction Key [RFC2930] */
|
{ 249, "TKEY" }, /* Transaction Key [RFC2930] */
|
||||||
{ 250, "TSIG" }, /* Transaction Signature [RFC8945] */
|
{ 250, "TSIG" }, /* Transaction Signature [RFC8945] */
|
||||||
{ 251, "IXFR" }, /* incremental transfer [RFC1995] */
|
{ 251, "IXFR" }, /* incremental transfer [RFC1995] */
|
||||||
@@ -125,6 +127,9 @@ static const struct {
|
|||||||
{ 259, "DOA" }, /* Digital Object Architecture [draft-durand-doa-over-dns] DOA/doa-completed-template 2017-08-30*/
|
{ 259, "DOA" }, /* Digital Object Architecture [draft-durand-doa-over-dns] DOA/doa-completed-template 2017-08-30*/
|
||||||
{ 260, "AMTRELAY" }, /* Automatic Multicast Tunneling Relay [RFC8777] AMTRELAY/amtrelay-completed-template 2019-02-06*/
|
{ 260, "AMTRELAY" }, /* Automatic Multicast Tunneling Relay [RFC8777] AMTRELAY/amtrelay-completed-template 2019-02-06*/
|
||||||
{ 261, "RESINFO" }, /* Resolver Information as Key/Value Pairs https://datatracker.ietf.org/doc/draft-ietf-add-resolver-info/06/ */
|
{ 261, "RESINFO" }, /* Resolver Information as Key/Value Pairs https://datatracker.ietf.org/doc/draft-ietf-add-resolver-info/06/ */
|
||||||
|
{ 262, "WALLET" }, /* Public wallet address https://www.iana.org/assignments/dns-parameters/WALLET/wallet-completed-template */
|
||||||
|
{ 263, "CLA" }, /* BP Convergence Layer Adapter https://www.iana.org/go/draft-johnson-dns-ipn-cla-07 */
|
||||||
|
{ 264, "IPN" }, /* BP Node Number https://www.iana.org/go/draft-johnson-dns-ipn-cla-07 */
|
||||||
{ 32768, "TA" }, /* DNSSEC Trust Authorities [Sam_Weiler][http://cameo.library.cmu.edu/][ Deploying DNSSEC Without a Signed Root. Technical Report 1999-19, Information Networking Institute, Carnegie Mellon University, April 2004.] 2005-12-13*/
|
{ 32768, "TA" }, /* DNSSEC Trust Authorities [Sam_Weiler][http://cameo.library.cmu.edu/][ Deploying DNSSEC Without a Signed Root. Technical Report 1999-19, Information Networking Institute, Carnegie Mellon University, April 2004.] 2005-12-13*/
|
||||||
{ 32769, "DLV" }, /* DNSSEC Lookaside Validation (OBSOLETE) [RFC8749][RFC4431] */
|
{ 32769, "DLV" }, /* DNSSEC Lookaside Validation (OBSOLETE) [RFC8749][RFC4431] */
|
||||||
};
|
};
|
||||||
@@ -474,7 +479,7 @@ static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned s
|
|||||||
if ((crecp->flags & F_FORWARD) && hostname_isequal(cache_get_name(crecp), name))
|
if ((crecp->flags & F_FORWARD) && hostname_isequal(cache_get_name(crecp), name))
|
||||||
{
|
{
|
||||||
int rrmatch = 0;
|
int rrmatch = 0;
|
||||||
if (crecp->flags & flags & F_RR)
|
if (addr && (crecp->flags & flags & F_RR))
|
||||||
{
|
{
|
||||||
unsigned short rrc = (crecp->flags & F_KEYTAG) ? crecp->addr.rrblock.rrtype : crecp->addr.rrdata.rrtype;
|
unsigned short rrc = (crecp->flags & F_KEYTAG) ? crecp->addr.rrblock.rrtype : crecp->addr.rrdata.rrtype;
|
||||||
unsigned short rra = (flags & F_KEYTAG) ? addr->rrblock.rrtype : addr->rrdata.rrtype;
|
unsigned short rra = (flags & F_KEYTAG) ? addr->rrblock.rrtype : addr->rrdata.rrtype;
|
||||||
@@ -1847,15 +1852,31 @@ int cache_make_stat(struct txt_record *t)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* There can be names in the cache containing control chars, don't
|
/* There can be names in the cache containing control chars, don't
|
||||||
mess up logging or open security holes. */
|
mess up logging or open security holes. Also convert to all-LC
|
||||||
|
so that 0x20-encoding doesn't make logs look like ransom notes
|
||||||
|
made out of letters cut from a newspaper.
|
||||||
|
Overwrites daemon->workspacename */
|
||||||
static char *sanitise(char *name)
|
static char *sanitise(char *name)
|
||||||
{
|
{
|
||||||
unsigned char *r;
|
unsigned char *r = (unsigned char *)name;
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
for (r = (unsigned char *)name; *r; r++)
|
{
|
||||||
if (!isprint((int)*r))
|
char *d = name = daemon->workspacename;
|
||||||
return "<name unprintable>";
|
|
||||||
|
for (; *r; r++, d++)
|
||||||
|
if (!isprint((int)*r))
|
||||||
|
return "<name unprintable>";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned char c = *r;
|
||||||
|
|
||||||
|
*d = (char)((c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : c);
|
||||||
|
}
|
||||||
|
|
||||||
|
*d = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -362,6 +362,11 @@ HAVE_SOCKADDR_SA_LEN
|
|||||||
#define HAVE_INOTIFY
|
#define HAVE_INOTIFY
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* This never compiles code, it's only used by the makefile to fingerprint builds. */
|
||||||
|
#ifdef DNSMASQ_COMPILE_FLAGS
|
||||||
|
static char *compile_flags = DNSMASQ_COMPILE_FLAGS;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Define a string indicating which options are in use.
|
/* Define a string indicating which options are in use.
|
||||||
DNSMASQ_COMPILE_OPTS is only defined in dnsmasq.c */
|
DNSMASQ_COMPILE_OPTS is only defined in dnsmasq.c */
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+294
-228
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -32,6 +32,7 @@ static volatile int pipewrite;
|
|||||||
static void set_dns_listeners(void);
|
static void set_dns_listeners(void);
|
||||||
static void set_tftp_listeners(void);
|
static void set_tftp_listeners(void);
|
||||||
static void check_dns_listeners(time_t now);
|
static void check_dns_listeners(time_t now);
|
||||||
|
static void do_tcp_connection(struct listener *listener, time_t now, int slot);
|
||||||
static void sig_handler(int sig);
|
static void sig_handler(int sig);
|
||||||
static void async_event(int pipe, time_t now);
|
static void async_event(int pipe, time_t now);
|
||||||
static void fatal_event(struct event_desc *ev, char *msg);
|
static void fatal_event(struct event_desc *ev, char *msg);
|
||||||
@@ -61,6 +62,7 @@ int main (int argc, char **argv)
|
|||||||
int need_cap_net_admin = 0;
|
int need_cap_net_admin = 0;
|
||||||
int need_cap_net_raw = 0;
|
int need_cap_net_raw = 0;
|
||||||
int need_cap_net_bind_service = 0;
|
int need_cap_net_bind_service = 0;
|
||||||
|
int have_cap_chown = 0;
|
||||||
char *bound_device = NULL;
|
char *bound_device = NULL;
|
||||||
int did_bind = 0;
|
int did_bind = 0;
|
||||||
struct server *serv;
|
struct server *serv;
|
||||||
@@ -556,6 +558,8 @@ int main (int argc, char **argv)
|
|||||||
data = safe_malloc(sizeof(*data) * capsize);
|
data = safe_malloc(sizeof(*data) * capsize);
|
||||||
capget(hdr, data); /* Get current values, for verification */
|
capget(hdr, data); /* Get current values, for verification */
|
||||||
|
|
||||||
|
have_cap_chown = data->permitted & (1 << CAP_CHOWN);
|
||||||
|
|
||||||
if (need_cap_net_admin && !(data->permitted & (1 << CAP_NET_ADMIN)))
|
if (need_cap_net_admin && !(data->permitted & (1 << CAP_NET_ADMIN)))
|
||||||
fail = "NET_ADMIN";
|
fail = "NET_ADMIN";
|
||||||
else if (need_cap_net_raw && !(data->permitted & (1 << CAP_NET_RAW)))
|
else if (need_cap_net_raw && !(data->permitted & (1 << CAP_NET_RAW)))
|
||||||
@@ -869,7 +873,14 @@ int main (int argc, char **argv)
|
|||||||
my_syslog(LOG_INFO, _("compile time options: %s"), compile_opts);
|
my_syslog(LOG_INFO, _("compile time options: %s"), compile_opts);
|
||||||
|
|
||||||
if (chown_warn != 0)
|
if (chown_warn != 0)
|
||||||
my_syslog(LOG_WARNING, "chown of PID file %s failed: %s", daemon->runfile, strerror(chown_warn));
|
{
|
||||||
|
#if defined(HAVE_LINUX_NETWORK)
|
||||||
|
if (chown_warn == EPERM && !have_cap_chown)
|
||||||
|
my_syslog(LOG_INFO, "chown of PID file %s failed: please add capability CAP_CHOWN", daemon->runfile);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
my_syslog(LOG_WARNING, "chown of PID file %s failed: %s", daemon->runfile, strerror(chown_warn));
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DBUS
|
#ifdef HAVE_DBUS
|
||||||
if (option_bool(OPT_DBUS))
|
if (option_bool(OPT_DBUS))
|
||||||
@@ -951,7 +962,14 @@ int main (int argc, char **argv)
|
|||||||
my_syslog(LOG_WARNING, _("warning: ignoring resolv-file flag because no-resolv is set"));
|
my_syslog(LOG_WARNING, _("warning: ignoring resolv-file flag because no-resolv is set"));
|
||||||
daemon->resolv_files = NULL;
|
daemon->resolv_files = NULL;
|
||||||
if (!daemon->servers)
|
if (!daemon->servers)
|
||||||
my_syslog(LOG_WARNING, _("warning: no upstream servers configured"));
|
{
|
||||||
|
#ifdef HAVE_DBUS
|
||||||
|
if (option_bool(OPT_DBUS))
|
||||||
|
my_syslog(LOG_INFO, _("no upstream servers configured - please set them from DBus"));
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
my_syslog(LOG_WARNING, _("warning: no upstream servers configured"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (daemon->max_logs != 0)
|
if (daemon->max_logs != 0)
|
||||||
@@ -1466,7 +1484,7 @@ static void async_event(int pipe, time_t now)
|
|||||||
{
|
{
|
||||||
pid_t p;
|
pid_t p;
|
||||||
struct event_desc ev;
|
struct event_desc ev;
|
||||||
int i, check = 0;
|
int wstatus, i, check = 0;
|
||||||
char *msg;
|
char *msg;
|
||||||
|
|
||||||
/* NOTE: the memory used to return msg is leaked: use msgs in events only
|
/* NOTE: the memory used to return msg is leaked: use msgs in events only
|
||||||
@@ -1529,7 +1547,7 @@ static void async_event(int pipe, time_t now)
|
|||||||
|
|
||||||
case EVENT_CHILD:
|
case EVENT_CHILD:
|
||||||
/* See Stevens 5.10 */
|
/* See Stevens 5.10 */
|
||||||
while ((p = waitpid(-1, NULL, WNOHANG)) != 0)
|
while ((p = waitpid(-1, &wstatus, WNOHANG)) != 0)
|
||||||
if (p == -1)
|
if (p == -1)
|
||||||
{
|
{
|
||||||
if (errno != EINTR)
|
if (errno != EINTR)
|
||||||
@@ -1540,6 +1558,20 @@ static void async_event(int pipe, time_t now)
|
|||||||
if (daemon->tcp_pids[i] == p)
|
if (daemon->tcp_pids[i] == p)
|
||||||
{
|
{
|
||||||
daemon->tcp_pids[i] = 0;
|
daemon->tcp_pids[i] = 0;
|
||||||
|
|
||||||
|
if (!WIFEXITED(wstatus))
|
||||||
|
{
|
||||||
|
/* If a helper process dies, (eg with SIGSEV)
|
||||||
|
log that and attempt to patch things up so that the
|
||||||
|
parent can continue to function. */
|
||||||
|
my_syslog(LOG_WARNING, _("TCP helper process %u died unexpectedly"), (unsigned int)p);
|
||||||
|
if (daemon->tcp_pipes[i] != -1)
|
||||||
|
{
|
||||||
|
close(daemon->tcp_pipes[i]);
|
||||||
|
daemon->tcp_pipes[i] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* tcp_pipes == -1 && tcp_pids == 0 required to free slot */
|
/* tcp_pipes == -1 && tcp_pids == 0 required to free slot */
|
||||||
if (daemon->tcp_pipes[i] == -1)
|
if (daemon->tcp_pipes[i] == -1)
|
||||||
daemon->metrics[METRIC_TCP_CONNECTIONS]--;
|
daemon->metrics[METRIC_TCP_CONNECTIONS]--;
|
||||||
@@ -1822,247 +1854,281 @@ static void check_dns_listeners(time_t now)
|
|||||||
struct listener *listener;
|
struct listener *listener;
|
||||||
struct randfd_list *rfl;
|
struct randfd_list *rfl;
|
||||||
int i;
|
int i;
|
||||||
int pipefd[2];
|
|
||||||
|
|
||||||
|
/* Note that handling events here can create or destroy fds and
|
||||||
|
render the result of the last poll() call invalid. Once
|
||||||
|
we find an fd that needs service, do it, then return to go around the
|
||||||
|
poll() loop again. This avoid really, really, wierd bugs. */
|
||||||
|
|
||||||
|
if (!option_bool(OPT_DEBUG))
|
||||||
|
for (i = 0; i < daemon->max_procs; i++)
|
||||||
|
if (daemon->tcp_pipes[i] != -1 &&
|
||||||
|
poll_check(daemon->tcp_pipes[i], POLLIN | POLLHUP))
|
||||||
|
{
|
||||||
|
/* Races. The child process can die before we read all of the data from the
|
||||||
|
pipe, or vice versa. Therefore send tcp_pids to zero when we wait() the
|
||||||
|
process, and tcp_pipes to -1 and close the FD when we read the last
|
||||||
|
of the data - indicated by cache_recv_insert returning zero.
|
||||||
|
The order of these events is indeterminate, and both are needed
|
||||||
|
to free the process slot. Once the child process has gone, poll()
|
||||||
|
returns POLLHUP, not POLLIN, so have to check for both here. */
|
||||||
|
if (!cache_recv_insert(now, daemon->tcp_pipes[i]))
|
||||||
|
{
|
||||||
|
close(daemon->tcp_pipes[i]);
|
||||||
|
daemon->tcp_pipes[i] = -1;
|
||||||
|
/* tcp_pipes == -1 && tcp_pids == 0 required to free slot */
|
||||||
|
if (daemon->tcp_pids[i] == 0)
|
||||||
|
daemon->metrics[METRIC_TCP_CONNECTIONS]--;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
|
for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
|
||||||
if (poll_check(serverfdp->fd, POLLIN))
|
if (poll_check(serverfdp->fd, POLLIN))
|
||||||
reply_query(serverfdp->fd, now);
|
{
|
||||||
|
reply_query(serverfdp->fd, now);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < daemon->numrrand; i++)
|
for (i = 0; i < daemon->numrrand; i++)
|
||||||
if (daemon->randomsocks[i].refcount != 0 &&
|
if (daemon->randomsocks[i].refcount != 0 &&
|
||||||
poll_check(daemon->randomsocks[i].fd, POLLIN))
|
poll_check(daemon->randomsocks[i].fd, POLLIN))
|
||||||
reply_query(daemon->randomsocks[i].fd, now);
|
{
|
||||||
|
reply_query(daemon->randomsocks[i].fd, now);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check overflow random sockets too. */
|
/* Check overflow random sockets too. */
|
||||||
for (rfl = daemon->rfl_poll; rfl; rfl = rfl->next)
|
for (rfl = daemon->rfl_poll; rfl; rfl = rfl->next)
|
||||||
if (poll_check(rfl->rfd->fd, POLLIN))
|
if (poll_check(rfl->rfd->fd, POLLIN))
|
||||||
reply_query(rfl->rfd->fd, now);
|
{
|
||||||
|
reply_query(rfl->rfd->fd, now);
|
||||||
/* Races. The child process can die before we read all of the data from the
|
return;
|
||||||
pipe, or vice versa. Therefore send tcp_pids to zero when we wait() the
|
}
|
||||||
process, and tcp_pipes to -1 and close the FD when we read the last
|
|
||||||
of the data - indicated by cache_recv_insert returning zero.
|
|
||||||
The order of these events is indeterminate, and both are needed
|
|
||||||
to free the process slot. Once the child process has gone, poll()
|
|
||||||
returns POLLHUP, not POLLIN, so have to check for both here. */
|
|
||||||
if (!option_bool(OPT_DEBUG))
|
|
||||||
for (i = 0; i < daemon->max_procs; i++)
|
|
||||||
if (daemon->tcp_pipes[i] != -1 &&
|
|
||||||
poll_check(daemon->tcp_pipes[i], POLLIN | POLLHUP) &&
|
|
||||||
!cache_recv_insert(now, daemon->tcp_pipes[i]))
|
|
||||||
{
|
|
||||||
close(daemon->tcp_pipes[i]);
|
|
||||||
daemon->tcp_pipes[i] = -1;
|
|
||||||
/* tcp_pipes == -1 && tcp_pids == 0 required to free slot */
|
|
||||||
if (daemon->tcp_pids[i] == 0)
|
|
||||||
daemon->metrics[METRIC_TCP_CONNECTIONS]--;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (listener = daemon->listeners; listener; listener = listener->next)
|
for (listener = daemon->listeners; listener; listener = listener->next)
|
||||||
{
|
if (listener->fd != -1 && poll_check(listener->fd, POLLIN))
|
||||||
if (listener->fd != -1 && poll_check(listener->fd, POLLIN))
|
{
|
||||||
receive_query(listener, now);
|
receive_query(listener, now);
|
||||||
|
return;
|
||||||
/* check to see if we have a free tcp process slot.
|
}
|
||||||
Note that we can't assume that because we had
|
|
||||||
at least one a poll() time, that we still do.
|
/* check to see if we have a free tcp process slot.
|
||||||
There may be more waiting connections after
|
Note that we can't assume that because we had
|
||||||
poll() returns then free process slots. */
|
at least one a poll() time, that we still do.
|
||||||
for (i = daemon->max_procs - 1; i >= 0; i--)
|
There may be more waiting connections after
|
||||||
if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
|
poll() returns then free process slots. */
|
||||||
break;
|
for (i = daemon->max_procs - 1; i >= 0; i--)
|
||||||
|
if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
if (listener->tcpfd != -1 && i >= 0 && poll_check(listener->tcpfd, POLLIN))
|
if (i >= 0)
|
||||||
|
for (listener = daemon->listeners; listener; listener = listener->next)
|
||||||
|
if (listener->tcpfd != -1 && poll_check(listener->tcpfd, POLLIN))
|
||||||
{
|
{
|
||||||
int confd, client_ok = 1;
|
do_tcp_connection(listener, now, i);
|
||||||
struct irec *iface = NULL;
|
return;
|
||||||
pid_t p;
|
}
|
||||||
union mysockaddr tcp_addr;
|
}
|
||||||
socklen_t tcp_len = sizeof(union mysockaddr);
|
|
||||||
|
|
||||||
while ((confd = accept(listener->tcpfd, NULL, NULL)) == -1 && errno == EINTR);
|
static void do_tcp_connection(struct listener *listener, time_t now, int slot)
|
||||||
|
{
|
||||||
if (confd == -1)
|
int confd, client_ok = 1;
|
||||||
continue;
|
struct irec *iface = NULL;
|
||||||
|
pid_t p;
|
||||||
if (getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) == -1)
|
union mysockaddr tcp_addr;
|
||||||
{
|
socklen_t tcp_len = sizeof(union mysockaddr);
|
||||||
close(confd);
|
unsigned char a = 0, *buff;
|
||||||
continue;
|
struct server *s;
|
||||||
}
|
int flags, auth_dns;
|
||||||
|
struct in_addr netmask;
|
||||||
/* Make sure that the interface list is up-to-date.
|
int pipefd[2];
|
||||||
|
|
||||||
We do this here as we may need the results below, and
|
|
||||||
the DNS code needs them for --interface-name stuff.
|
|
||||||
|
|
||||||
Multiple calls to enumerate_interfaces() per select loop are
|
while ((confd = accept(listener->tcpfd, NULL, NULL)) == -1 && errno == EINTR);
|
||||||
inhibited, so calls to it in the child process (which doesn't select())
|
|
||||||
have no effect. This avoids two processes reading from the same
|
if (confd == -1)
|
||||||
netlink fd and screwing the pooch entirely.
|
return;
|
||||||
*/
|
|
||||||
|
if (getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) == -1)
|
||||||
enumerate_interfaces(0);
|
{
|
||||||
|
closeconandreturn:
|
||||||
|
shutdown(confd, SHUT_RDWR);
|
||||||
|
close(confd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure that the interface list is up-to-date.
|
||||||
|
|
||||||
|
We do this here as we may need the results below, and
|
||||||
|
the DNS code needs them for --interface-name stuff.
|
||||||
|
|
||||||
|
Multiple calls to enumerate_interfaces() per select loop are
|
||||||
|
inhibited, so calls to it in the child process (which doesn't select())
|
||||||
|
have no effect. This avoids two processes reading from the same
|
||||||
|
netlink fd and screwing the pooch entirely.
|
||||||
|
*/
|
||||||
|
|
||||||
|
enumerate_interfaces(0);
|
||||||
|
|
||||||
|
if (option_bool(OPT_NOWILD))
|
||||||
|
iface = listener->iface; /* May be NULL */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int if_index;
|
||||||
|
char intr_name[IF_NAMESIZE];
|
||||||
|
|
||||||
|
/* if we can find the arrival interface, check it's one that's allowed */
|
||||||
|
if ((if_index = tcp_interface(confd, tcp_addr.sa.sa_family)) != 0 &&
|
||||||
|
indextoname(listener->tcpfd, if_index, intr_name))
|
||||||
|
{
|
||||||
|
union all_addr addr;
|
||||||
|
|
||||||
if (option_bool(OPT_NOWILD))
|
if (tcp_addr.sa.sa_family == AF_INET6)
|
||||||
iface = listener->iface; /* May be NULL */
|
addr.addr6 = tcp_addr.in6.sin6_addr;
|
||||||
else
|
|
||||||
{
|
|
||||||
int if_index;
|
|
||||||
char intr_name[IF_NAMESIZE];
|
|
||||||
|
|
||||||
/* if we can find the arrival interface, check it's one that's allowed */
|
|
||||||
if ((if_index = tcp_interface(confd, tcp_addr.sa.sa_family)) != 0 &&
|
|
||||||
indextoname(listener->tcpfd, if_index, intr_name))
|
|
||||||
{
|
|
||||||
union all_addr addr;
|
|
||||||
|
|
||||||
if (tcp_addr.sa.sa_family == AF_INET6)
|
|
||||||
addr.addr6 = tcp_addr.in6.sin6_addr;
|
|
||||||
else
|
|
||||||
addr.addr4 = tcp_addr.in.sin_addr;
|
|
||||||
|
|
||||||
for (iface = daemon->interfaces; iface; iface = iface->next)
|
|
||||||
if (iface->index == if_index &&
|
|
||||||
iface->addr.sa.sa_family == tcp_addr.sa.sa_family)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!iface && !loopback_exception(listener->tcpfd, tcp_addr.sa.sa_family, &addr, intr_name))
|
|
||||||
client_ok = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (option_bool(OPT_CLEVERBIND))
|
|
||||||
iface = listener->iface; /* May be NULL */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Check for allowed interfaces when binding the wildcard address:
|
|
||||||
we do this by looking for an interface with the same address as
|
|
||||||
the local address of the TCP connection, then looking to see if that's
|
|
||||||
an allowed interface. As a side effect, we get the netmask of the
|
|
||||||
interface too, for localisation. */
|
|
||||||
|
|
||||||
for (iface = daemon->interfaces; iface; iface = iface->next)
|
|
||||||
if (sockaddr_isequal(&iface->addr, &tcp_addr))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!iface)
|
|
||||||
client_ok = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!client_ok)
|
|
||||||
{
|
|
||||||
shutdown(confd, SHUT_RDWR);
|
|
||||||
close(confd);
|
|
||||||
}
|
|
||||||
else if (!option_bool(OPT_DEBUG) && pipe(pipefd) == 0 && (p = fork()) != 0)
|
|
||||||
{
|
|
||||||
close(pipefd[1]); /* parent needs read pipe end. */
|
|
||||||
if (p == -1)
|
|
||||||
close(pipefd[0]);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef HAVE_LINUX_NETWORK
|
|
||||||
/* The child process inherits the netlink socket,
|
|
||||||
which it never uses, but when the parent (us)
|
|
||||||
uses it in the future, the answer may go to the
|
|
||||||
child, resulting in the parent blocking
|
|
||||||
forever awaiting the result. To avoid this
|
|
||||||
the child closes the netlink socket, but there's
|
|
||||||
a nasty race, since the parent may use netlink
|
|
||||||
before the child has done the close.
|
|
||||||
|
|
||||||
To avoid this, the parent blocks here until a
|
|
||||||
single byte comes back up the pipe, which
|
|
||||||
is sent by the child after it has closed the
|
|
||||||
netlink socket. */
|
|
||||||
|
|
||||||
unsigned char a;
|
|
||||||
read_write(pipefd[0], &a, 1, RW_READ);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* i holds index of free slot */
|
|
||||||
daemon->tcp_pids[i] = p;
|
|
||||||
daemon->tcp_pipes[i] = pipefd[0];
|
|
||||||
daemon->metrics[METRIC_TCP_CONNECTIONS]++;
|
|
||||||
if (daemon->metrics[METRIC_TCP_CONNECTIONS] > daemon->max_procs_used)
|
|
||||||
daemon->max_procs_used = daemon->metrics[METRIC_TCP_CONNECTIONS];
|
|
||||||
}
|
|
||||||
close(confd);
|
|
||||||
|
|
||||||
/* The child can use up to TCP_MAX_QUERIES ids, so skip that many. */
|
|
||||||
daemon->log_id += TCP_MAX_QUERIES;
|
|
||||||
#ifdef HAVE_DNSSEC
|
|
||||||
/* It can do more if making DNSSEC queries too. */
|
|
||||||
if (option_bool(OPT_DNSSEC_VALID))
|
|
||||||
daemon->log_id += daemon->limit[LIMIT_WORK];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
addr.addr4 = tcp_addr.in.sin_addr;
|
||||||
unsigned char *buff;
|
|
||||||
struct server *s;
|
for (iface = daemon->interfaces; iface; iface = iface->next)
|
||||||
int flags;
|
if (iface->index == if_index &&
|
||||||
struct in_addr netmask;
|
iface->addr.sa.sa_family == tcp_addr.sa.sa_family)
|
||||||
int auth_dns;
|
break;
|
||||||
|
|
||||||
if (iface)
|
if (!iface && !loopback_exception(listener->tcpfd, tcp_addr.sa.sa_family, &addr, intr_name))
|
||||||
{
|
client_ok = 0;
|
||||||
netmask = iface->netmask;
|
}
|
||||||
auth_dns = iface->dns_auth;
|
|
||||||
}
|
if (option_bool(OPT_CLEVERBIND))
|
||||||
else
|
iface = listener->iface; /* May be NULL */
|
||||||
{
|
else
|
||||||
netmask.s_addr = 0;
|
{
|
||||||
auth_dns = 0;
|
/* Check for allowed interfaces when binding the wildcard address:
|
||||||
}
|
we do this by looking for an interface with the same address as
|
||||||
|
the local address of the TCP connection, then looking to see if that's
|
||||||
/* Arrange for SIGALRM after CHILD_LIFETIME seconds to
|
an allowed interface. As a side effect, we get the netmask of the
|
||||||
terminate the process. */
|
interface too, for localisation. */
|
||||||
if (!option_bool(OPT_DEBUG))
|
|
||||||
{
|
for (iface = daemon->interfaces; iface; iface = iface->next)
|
||||||
#ifdef HAVE_LINUX_NETWORK
|
if (sockaddr_isequal(&iface->addr, &tcp_addr))
|
||||||
/* See comment above re: netlink socket. */
|
break;
|
||||||
unsigned char a = 0;
|
|
||||||
|
if (!iface)
|
||||||
close(daemon->netlinkfd);
|
client_ok = 0;
|
||||||
read_write(pipefd[1], &a, 1, RW_WRITE);
|
|
||||||
#endif
|
|
||||||
alarm(CHILD_LIFETIME);
|
|
||||||
close(pipefd[0]); /* close read end in child. */
|
|
||||||
daemon->pipe_to_parent = pipefd[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The connected socket inherits non-blocking
|
|
||||||
attribute from the listening socket.
|
|
||||||
Reset that here. */
|
|
||||||
if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
|
|
||||||
while(retry_send(fcntl(confd, F_SETFL, flags & ~O_NONBLOCK)));
|
|
||||||
|
|
||||||
buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);
|
|
||||||
|
|
||||||
if (buff)
|
|
||||||
free(buff);
|
|
||||||
|
|
||||||
for (s = daemon->servers; s; s = s->next)
|
|
||||||
if (s->tcpfd != -1)
|
|
||||||
{
|
|
||||||
shutdown(s->tcpfd, SHUT_RDWR);
|
|
||||||
close(s->tcpfd);
|
|
||||||
s->tcpfd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!option_bool(OPT_DEBUG))
|
|
||||||
{
|
|
||||||
close(daemon->pipe_to_parent);
|
|
||||||
flush_log();
|
|
||||||
_exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!client_ok)
|
||||||
|
goto closeconandreturn;
|
||||||
|
|
||||||
|
if (!option_bool(OPT_DEBUG))
|
||||||
|
{
|
||||||
|
if (pipe(pipefd) == -1)
|
||||||
|
goto closeconandreturn; /* pipe failed */
|
||||||
|
|
||||||
|
if ((p = fork()) == -1)
|
||||||
|
{
|
||||||
|
/* fork failed */
|
||||||
|
close(pipefd[0]);
|
||||||
|
close(pipefd[1]);
|
||||||
|
goto closeconandreturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p != 0)
|
||||||
|
{
|
||||||
|
/* fork() done: parent side */
|
||||||
|
close(pipefd[1]); /* parent needs read pipe end. */
|
||||||
|
|
||||||
|
#ifdef HAVE_LINUX_NETWORK
|
||||||
|
/* The child process inherits the netlink socket,
|
||||||
|
which it never uses, but when the parent (us)
|
||||||
|
uses it in the future, the answer may go to the
|
||||||
|
child, resulting in the parent blocking
|
||||||
|
forever awaiting the result. To avoid this
|
||||||
|
the child closes the netlink socket, but there's
|
||||||
|
a nasty race, since the parent may use netlink
|
||||||
|
before the child has done the close.
|
||||||
|
|
||||||
|
To avoid this, the parent blocks here until a
|
||||||
|
single byte comes back up the pipe, which
|
||||||
|
is sent by the child after it has closed the
|
||||||
|
netlink socket. */
|
||||||
|
|
||||||
|
read_write(pipefd[0], &a, 1, RW_READ);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
daemon->tcp_pids[slot] = p;
|
||||||
|
daemon->tcp_pipes[slot] = pipefd[0];
|
||||||
|
daemon->metrics[METRIC_TCP_CONNECTIONS]++;
|
||||||
|
if (daemon->metrics[METRIC_TCP_CONNECTIONS] > daemon->max_procs_used)
|
||||||
|
daemon->max_procs_used = daemon->metrics[METRIC_TCP_CONNECTIONS];
|
||||||
|
|
||||||
|
close(confd);
|
||||||
|
|
||||||
|
/* The child can use up to TCP_MAX_QUERIES ids, so skip that many. */
|
||||||
|
daemon->log_id += TCP_MAX_QUERIES;
|
||||||
|
#ifdef HAVE_DNSSEC
|
||||||
|
/* It can do more if making DNSSEC queries too. */
|
||||||
|
if (option_bool(OPT_DNSSEC_VALID))
|
||||||
|
daemon->log_id += daemon->limit[LIMIT_WORK];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iface)
|
||||||
|
{
|
||||||
|
netmask = iface->netmask;
|
||||||
|
auth_dns = iface->dns_auth;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
netmask.s_addr = 0;
|
||||||
|
auth_dns = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Arrange for SIGALRM after CHILD_LIFETIME seconds to
|
||||||
|
terminate the process. */
|
||||||
|
if (!option_bool(OPT_DEBUG))
|
||||||
|
{
|
||||||
|
#ifdef HAVE_LINUX_NETWORK
|
||||||
|
/* See comment above re: netlink socket. */
|
||||||
|
close(daemon->netlinkfd);
|
||||||
|
read_write(pipefd[1], &a, 1, RW_WRITE);
|
||||||
|
#endif
|
||||||
|
alarm(CHILD_LIFETIME);
|
||||||
|
close(pipefd[0]); /* close read end in child. */
|
||||||
|
daemon->pipe_to_parent = pipefd[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The connected socket inherits non-blocking
|
||||||
|
attribute from the listening socket.
|
||||||
|
Reset that here. */
|
||||||
|
if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
|
||||||
|
while(retry_send(fcntl(confd, F_SETFL, flags & ~O_NONBLOCK)));
|
||||||
|
|
||||||
|
buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);
|
||||||
|
|
||||||
|
if (buff)
|
||||||
|
free(buff);
|
||||||
|
|
||||||
|
for (s = daemon->servers; s; s = s->next)
|
||||||
|
if (s->tcpfd != -1)
|
||||||
|
{
|
||||||
|
shutdown(s->tcpfd, SHUT_RDWR);
|
||||||
|
close(s->tcpfd);
|
||||||
|
s->tcpfd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!option_bool(OPT_DEBUG))
|
||||||
|
{
|
||||||
|
close(daemon->pipe_to_parent);
|
||||||
|
flush_log();
|
||||||
|
_exit(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_DNSSEC
|
#ifdef HAVE_DNSSEC
|
||||||
/* If a DNSSEC query over UDP returns a truncated answer,
|
/* If a DNSSEC query over UDP returns a truncated answer,
|
||||||
we swap to the TCP path. This routine is responsible for forking
|
we swap to the TCP path. This routine is responsible for forking
|
||||||
@@ -2091,11 +2157,11 @@ int swap_to_tcp(struct frec *forward, time_t now, int status, struct dns_header
|
|||||||
if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
|
if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* No slots */
|
/* No slots or no pipe */
|
||||||
if (i < 0)
|
if (i < 0 || pipe(pipefd) != 0)
|
||||||
return STAT_ABANDONED;
|
return STAT_ABANDONED;
|
||||||
|
|
||||||
if (pipe(pipefd) == 0 && (p = fork()) != 0)
|
if ((p = fork()) != 0)
|
||||||
{
|
{
|
||||||
close(pipefd[1]); /* parent needs read pipe end. */
|
close(pipefd[1]); /* parent needs read pipe end. */
|
||||||
if (p == -1)
|
if (p == -1)
|
||||||
|
|||||||
+21
-12
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define COPYRIGHT "Copyright (c) 2000-2024 Simon Kelley"
|
#define COPYRIGHT "Copyright (c) 2000-2025 Simon Kelley"
|
||||||
|
|
||||||
/* We do defines that influence behavior of stdio.h, so complain
|
/* We do defines that influence behavior of stdio.h, so complain
|
||||||
if included too early. */
|
if included too early. */
|
||||||
@@ -279,7 +279,8 @@ struct event_desc {
|
|||||||
#define OPT_CACHE_RR 71
|
#define OPT_CACHE_RR 71
|
||||||
#define OPT_LOCALHOST_SERVICE 72
|
#define OPT_LOCALHOST_SERVICE 72
|
||||||
#define OPT_LOG_PROTO 73
|
#define OPT_LOG_PROTO 73
|
||||||
#define OPT_LAST 74
|
#define OPT_NO_0x20 74
|
||||||
|
#define OPT_LAST 75
|
||||||
|
|
||||||
#define OPTION_BITS (sizeof(unsigned int)*8)
|
#define OPTION_BITS (sizeof(unsigned int)*8)
|
||||||
#define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) )
|
#define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) )
|
||||||
@@ -339,7 +340,7 @@ union all_addr {
|
|||||||
struct datablock {
|
struct datablock {
|
||||||
unsigned short rrtype;
|
unsigned short rrtype;
|
||||||
unsigned char datalen; /* also length of SOA in negative records. */
|
unsigned char datalen; /* also length of SOA in negative records. */
|
||||||
char data[];
|
char data[1];
|
||||||
} rrdata;
|
} rrdata;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -772,15 +773,15 @@ struct dyndir {
|
|||||||
#define FREC_DS_QUERY 16
|
#define FREC_DS_QUERY 16
|
||||||
#define FREC_AD_QUESTION 32
|
#define FREC_AD_QUESTION 32
|
||||||
#define FREC_DO_QUESTION 64
|
#define FREC_DO_QUESTION 64
|
||||||
#define FREC_ADDED_PHEADER 128
|
#define FREC_HAS_PHEADER 128
|
||||||
#define FREC_HAS_PHEADER 256
|
#define FREC_GONE_TO_TCP 256
|
||||||
#define FREC_GONE_TO_TCP 512
|
#define FREC_ANSWER 512
|
||||||
|
|
||||||
struct frec {
|
struct frec {
|
||||||
struct frec_src {
|
struct frec_src {
|
||||||
union mysockaddr source;
|
union mysockaddr source;
|
||||||
union all_addr dest;
|
union all_addr dest;
|
||||||
unsigned int iface, log_id;
|
unsigned int iface, log_id, encode_bitmap, *encode_bigmap;
|
||||||
int fd;
|
int fd;
|
||||||
unsigned short orig_id, udp_pkt_size;
|
unsigned short orig_id, udp_pkt_size;
|
||||||
struct frec_src *next;
|
struct frec_src *next;
|
||||||
@@ -1125,7 +1126,10 @@ struct tftp_prefix {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct dhcp_relay {
|
struct dhcp_relay {
|
||||||
union all_addr local, server;
|
union {
|
||||||
|
struct in_addr addr4;
|
||||||
|
struct in6_addr addr6;
|
||||||
|
} local, server;
|
||||||
char *interface; /* Allowable interface for replies from server, and dest for IPv6 multicast */
|
char *interface; /* Allowable interface for replies from server, and dest for IPv6 multicast */
|
||||||
int iface_index; /* working - interface in which requests arrived, for return */
|
int iface_index; /* working - interface in which requests arrived, for return */
|
||||||
int port; /* Port of relay we forward to. */
|
int port; /* Port of relay we forward to. */
|
||||||
@@ -1384,7 +1388,7 @@ int is_rev_synth(int flag, union all_addr *addr, char *name);
|
|||||||
/* rfc1035.c */
|
/* rfc1035.c */
|
||||||
int do_doctor(struct dns_header *header, size_t qlen, char *namebuff);
|
int do_doctor(struct dns_header *header, size_t qlen, char *namebuff);
|
||||||
int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
|
int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
|
||||||
char *name, int isExtract, int extrabytes);
|
char *name, int func, unsigned int parm);
|
||||||
unsigned char *skip_name(unsigned char *ansp, struct dns_header *header, size_t plen, int extrabytes);
|
unsigned char *skip_name(unsigned char *ansp, struct dns_header *header, size_t plen, int extrabytes);
|
||||||
unsigned char *skip_questions(struct dns_header *header, size_t plen);
|
unsigned char *skip_questions(struct dns_header *header, size_t plen);
|
||||||
unsigned char *skip_section(unsigned char *ansp, int count, struct dns_header *header, size_t plen);
|
unsigned char *skip_section(unsigned char *ansp, int count, struct dns_header *header, size_t plen);
|
||||||
@@ -1399,7 +1403,7 @@ void report_addresses(struct dns_header *header, size_t len, u32 mark);
|
|||||||
#endif
|
#endif
|
||||||
size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||||
struct in_addr local_addr, struct in_addr local_netmask,
|
struct in_addr local_addr, struct in_addr local_netmask,
|
||||||
time_t now, int ad_reqd, int do_bit, int *stale, int *filtered);
|
time_t now, int ad_reqd, int do_bit, int no_cache, int *stale, int *filtered);
|
||||||
int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
|
int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
|
||||||
time_t now);
|
time_t now);
|
||||||
int check_for_ignored_address(struct dns_header *header, size_t qlen);
|
int check_for_ignored_address(struct dns_header *header, size_t qlen);
|
||||||
@@ -1411,6 +1415,11 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp,
|
|||||||
int *offset, unsigned short type, unsigned short class, char *format, ...);
|
int *offset, unsigned short type, unsigned short class, char *format, ...);
|
||||||
int in_arpa_name_2_addr(char *namein, union all_addr *addrp);
|
int in_arpa_name_2_addr(char *namein, union all_addr *addrp);
|
||||||
int private_net(struct in_addr addr, int ban_localhost);
|
int private_net(struct in_addr addr, int ban_localhost);
|
||||||
|
/* extract_name ops */
|
||||||
|
#define EXTR_NAME_EXTRACT 1
|
||||||
|
#define EXTR_NAME_COMPARE 2
|
||||||
|
#define EXTR_NAME_NOCASE 3
|
||||||
|
#define EXTR_NAME_FLIP 4
|
||||||
|
|
||||||
/* auth.c */
|
/* auth.c */
|
||||||
#ifdef HAVE_AUTH
|
#ifdef HAVE_AUTH
|
||||||
@@ -1664,7 +1673,7 @@ void route_sock(void);
|
|||||||
|
|
||||||
/* bpf.c or netlink.c */
|
/* bpf.c or netlink.c */
|
||||||
typedef union {
|
typedef union {
|
||||||
int (*af_unspec)(int family, char *addrp, char *mac, size_t maclen, void *parmv);
|
int (*af_unspec)(int family, void *addrp, char *mac, size_t maclen, void *parmv);
|
||||||
int (*af_inet)(struct in_addr local, int if_index, char *label, struct in_addr netmask, struct in_addr broadcast, void *vparam);
|
int (*af_inet)(struct in_addr local, int if_index, char *label, struct in_addr netmask, struct in_addr broadcast, void *vparam);
|
||||||
int (*af_inet6)(struct in6_addr *local, int prefix, int scope, int if_index, int flags, unsigned int preferred, unsigned int valid, void *vparam);
|
int (*af_inet6)(struct in6_addr *local, int prefix, int scope, int if_index, int flags, unsigned int preferred, unsigned int valid, void *vparam);
|
||||||
int (*af_local)(int index, unsigned int type, char *mac, size_t maclen, void *parm);
|
int (*af_local)(int index, unsigned int type, char *mac, size_t maclen, void *parm);
|
||||||
|
|||||||
+24
-24
@@ -1,5 +1,5 @@
|
|||||||
/* dnssec.c is Copyright (c) 2012 Giovanni Bajo <rasky@develer.com>
|
/* dnssec.c is Copyright (c) 2012 Giovanni Bajo <rasky@develer.com>
|
||||||
and Copyright (c) 2012-2023 Simon Kelley
|
and Copyright (c) 2012-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -191,7 +191,7 @@ static int get_rdata(struct dns_header *header, size_t plen, struct rdata_state
|
|||||||
/* domain-name, canonicalise */
|
/* domain-name, canonicalise */
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (!extract_name(header, plen, &state->ip, state->buff, 1, 0) ||
|
if (!extract_name(header, plen, &state->ip, state->buff, EXTR_NAME_EXTRACT, 0) ||
|
||||||
(len = to_wire(state->buff)) == 0)
|
(len = to_wire(state->buff)) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -339,7 +339,7 @@ static int explore_rrset(struct dns_header *header, size_t plen, int class, int
|
|||||||
|
|
||||||
pstart = p;
|
pstart = p;
|
||||||
|
|
||||||
if (!(res = extract_name(header, plen, &p, name, 0, 10)))
|
if (!(res = extract_name(header, plen, &p, name, EXTR_NAME_COMPARE, 10)))
|
||||||
return 0; /* bad packet */
|
return 0; /* bad packet */
|
||||||
|
|
||||||
GETSHORT(stype, p);
|
GETSHORT(stype, p);
|
||||||
@@ -374,14 +374,14 @@ static int explore_rrset(struct dns_header *header, size_t plen, int class, int
|
|||||||
if (gotkey)
|
if (gotkey)
|
||||||
{
|
{
|
||||||
/* If there's more than one SIG, ensure they all have same keyname */
|
/* If there's more than one SIG, ensure they all have same keyname */
|
||||||
if (extract_name(header, plen, &p, keyname, 0, 0) != 1)
|
if (extract_name(header, plen, &p, keyname, EXTR_NAME_COMPARE, 0) != 1)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gotkey = 1;
|
gotkey = 1;
|
||||||
|
|
||||||
if (!extract_name(header, plen, &p, keyname, 1, 0))
|
if (!extract_name(header, plen, &p, keyname, EXTR_NAME_EXTRACT, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* RFC 4035 5.3.1 says that the Signer's Name field MUST equal
|
/* RFC 4035 5.3.1 says that the Signer's Name field MUST equal
|
||||||
@@ -503,7 +503,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
|||||||
GETLONG(sig_inception, p);
|
GETLONG(sig_inception, p);
|
||||||
GETSHORT(key_tag, p);
|
GETSHORT(key_tag, p);
|
||||||
|
|
||||||
if (!extract_name(header, plen, &p, keyname, 1, 0))
|
if (!extract_name(header, plen, &p, keyname, EXTR_NAME_EXTRACT, 0))
|
||||||
return STAT_BOGUS;
|
return STAT_BOGUS;
|
||||||
|
|
||||||
if (!time_check)
|
if (!time_check)
|
||||||
@@ -568,7 +568,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
|||||||
|
|
||||||
p = rrset[i];
|
p = rrset[i];
|
||||||
|
|
||||||
if (!extract_name(header, plen, &p, name, 1, 10))
|
if (!extract_name(header, plen, &p, name, EXTR_NAME_EXTRACT, 10))
|
||||||
return STAT_BOGUS;
|
return STAT_BOGUS;
|
||||||
|
|
||||||
name_start = name;
|
name_start = name;
|
||||||
@@ -661,7 +661,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
|||||||
|
|
||||||
/* namebuff used for workspace above, restore to leave unchanged on exit */
|
/* namebuff used for workspace above, restore to leave unchanged on exit */
|
||||||
p = (unsigned char*)(rrset[0]);
|
p = (unsigned char*)(rrset[0]);
|
||||||
if (!extract_name(header, plen, &p, name, 1, 0))
|
if (!extract_name(header, plen, &p, name, EXTR_NAME_EXTRACT, 0))
|
||||||
return STAT_BOGUS;
|
return STAT_BOGUS;
|
||||||
|
|
||||||
if (key)
|
if (key)
|
||||||
@@ -727,7 +727,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
|
|||||||
static unsigned char **cached_digest;
|
static unsigned char **cached_digest;
|
||||||
static size_t cached_digest_size = 0;
|
static size_t cached_digest_size = 0;
|
||||||
|
|
||||||
if (ntohs(header->qdcount) != 1 || RCODE(header) != NOERROR || !extract_name(header, plen, &p, name, 1, 4))
|
if (ntohs(header->qdcount) != 1 || RCODE(header) != NOERROR || !extract_name(header, plen, &p, name, EXTR_NAME_EXTRACT, 4))
|
||||||
return STAT_BOGUS | DNSSEC_FAIL_NOKEY;
|
return STAT_BOGUS | DNSSEC_FAIL_NOKEY;
|
||||||
|
|
||||||
GETSHORT(qtype, p);
|
GETSHORT(qtype, p);
|
||||||
@@ -752,7 +752,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
|
|||||||
for (j = ntohs(header->ancount); j != 0; j--)
|
for (j = ntohs(header->ancount); j != 0; j--)
|
||||||
{
|
{
|
||||||
/* Ensure we have type, class TTL and length */
|
/* Ensure we have type, class TTL and length */
|
||||||
if (!(rc = extract_name(header, plen, &p, name, 0, 10)))
|
if (!(rc = extract_name(header, plen, &p, name, EXTR_NAME_COMPARE, 10)))
|
||||||
return STAT_BOGUS; /* bad packet */
|
return STAT_BOGUS; /* bad packet */
|
||||||
|
|
||||||
GETSHORT(qtype, p);
|
GETSHORT(qtype, p);
|
||||||
@@ -904,7 +904,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
|
|||||||
for (j = ntohs(header->ancount); j != 0; j--)
|
for (j = ntohs(header->ancount); j != 0; j--)
|
||||||
{
|
{
|
||||||
/* Ensure we have type, class TTL and length */
|
/* Ensure we have type, class TTL and length */
|
||||||
if (!(rc = extract_name(header, plen, &p, name, 0, 10)))
|
if (!(rc = extract_name(header, plen, &p, name, EXTR_NAME_COMPARE, 10)))
|
||||||
return STAT_BOGUS; /* bad packet */
|
return STAT_BOGUS; /* bad packet */
|
||||||
|
|
||||||
GETSHORT(qtype, p);
|
GETSHORT(qtype, p);
|
||||||
@@ -1024,7 +1024,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
|
|||||||
}
|
}
|
||||||
|
|
||||||
p = (unsigned char *)(header+1);
|
p = (unsigned char *)(header+1);
|
||||||
if (!extract_name(header, plen, &p, name, 1, 4))
|
if (!extract_name(header, plen, &p, name, EXTR_NAME_EXTRACT, 4))
|
||||||
return STAT_BOGUS;
|
return STAT_BOGUS;
|
||||||
|
|
||||||
p += 4; /* qtype, qclass */
|
p += 4; /* qtype, qclass */
|
||||||
@@ -1050,7 +1050,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
|
|||||||
{
|
{
|
||||||
unsigned char *psave;
|
unsigned char *psave;
|
||||||
|
|
||||||
if (!(rc = extract_name(header, plen, &p, name, 0, 10)))
|
if (!(rc = extract_name(header, plen, &p, name, EXTR_NAME_COMPARE, 10)))
|
||||||
return STAT_BOGUS; /* bad packet */
|
return STAT_BOGUS; /* bad packet */
|
||||||
|
|
||||||
GETSHORT(atype, p);
|
GETSHORT(atype, p);
|
||||||
@@ -1231,12 +1231,12 @@ static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsi
|
|||||||
int sig_labels, name_labels;
|
int sig_labels, name_labels;
|
||||||
|
|
||||||
p = nsecs[i];
|
p = nsecs[i];
|
||||||
if (!extract_name(header, plen, &p, workspace1, 1, 10))
|
if (!extract_name(header, plen, &p, workspace1, EXTR_NAME_EXTRACT, 10))
|
||||||
return DNSSEC_FAIL_BADPACKET;
|
return DNSSEC_FAIL_BADPACKET;
|
||||||
p += 8; /* class, type, TTL */
|
p += 8; /* class, type, TTL */
|
||||||
GETSHORT(rdlen, p);
|
GETSHORT(rdlen, p);
|
||||||
psave = p;
|
psave = p;
|
||||||
if (!extract_name(header, plen, &p, workspace2, 1, 0))
|
if (!extract_name(header, plen, &p, workspace2, EXTR_NAME_EXTRACT, 0))
|
||||||
return DNSSEC_FAIL_BADPACKET;
|
return DNSSEC_FAIL_BADPACKET;
|
||||||
|
|
||||||
/* If NSEC comes from wildcard expansion, use original wildcard
|
/* If NSEC comes from wildcard expansion, use original wildcard
|
||||||
@@ -1400,7 +1400,7 @@ static int check_nsec3_coverage(struct dns_header *header, size_t plen, int dige
|
|||||||
for (i = 0; i < nsec_count; i++)
|
for (i = 0; i < nsec_count; i++)
|
||||||
if ((p = nsecs[i]))
|
if ((p = nsecs[i]))
|
||||||
{
|
{
|
||||||
if (!extract_name(header, plen, &p, workspace1, 1, 10) ||
|
if (!extract_name(header, plen, &p, workspace1, EXTR_NAME_EXTRACT, 10) ||
|
||||||
!(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
|
!(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -1609,7 +1609,7 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
|||||||
for (i = 0; i < nsec_count; i++)
|
for (i = 0; i < nsec_count; i++)
|
||||||
if ((p = nsecs[i]))
|
if ((p = nsecs[i]))
|
||||||
{
|
{
|
||||||
if (!extract_name(header, plen, &p, workspace1, 1, 0))
|
if (!extract_name(header, plen, &p, workspace1, EXTR_NAME_EXTRACT, 0))
|
||||||
return DNSSEC_FAIL_BADPACKET;
|
return DNSSEC_FAIL_BADPACKET;
|
||||||
|
|
||||||
if (!(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
|
if (!(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
|
||||||
@@ -1684,7 +1684,7 @@ static int prove_non_existence(struct dns_header *header, size_t plen, char *key
|
|||||||
{
|
{
|
||||||
unsigned char *pstart = p;
|
unsigned char *pstart = p;
|
||||||
|
|
||||||
if (!extract_name(header, plen, &p, daemon->workspacename, 1, 10))
|
if (!extract_name(header, plen, &p, daemon->workspacename, EXTR_NAME_EXTRACT, 10))
|
||||||
return DNSSEC_FAIL_BADPACKET;
|
return DNSSEC_FAIL_BADPACKET;
|
||||||
|
|
||||||
GETSHORT(type, p);
|
GETSHORT(type, p);
|
||||||
@@ -1735,7 +1735,7 @@ static int prove_non_existence(struct dns_header *header, size_t plen, char *key
|
|||||||
{
|
{
|
||||||
unsigned char *psav;
|
unsigned char *psav;
|
||||||
|
|
||||||
if (!(res = extract_name(header, plen, &p1, daemon->workspacename, 0, 10)))
|
if (!(res = extract_name(header, plen, &p1, daemon->workspacename, EXTR_NAME_COMPARE, 10)))
|
||||||
return DNSSEC_FAIL_BADPACKET;
|
return DNSSEC_FAIL_BADPACKET;
|
||||||
|
|
||||||
GETSHORT(type1, p1);
|
GETSHORT(type1, p1);
|
||||||
@@ -1965,7 +1965,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
|||||||
targets[0] = p1;
|
targets[0] = p1;
|
||||||
targetidx = 1;
|
targetidx = 1;
|
||||||
|
|
||||||
if (!extract_name(header, plen, &p1, name, 1, 4))
|
if (!extract_name(header, plen, &p1, name, EXTR_NAME_EXTRACT, 4))
|
||||||
return STAT_BOGUS;
|
return STAT_BOGUS;
|
||||||
|
|
||||||
GETSHORT(qtype, p1);
|
GETSHORT(qtype, p1);
|
||||||
@@ -2003,7 +2003,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
|||||||
if (i != 0 && !ADD_RDLEN(header, p1, plen, rdlen1))
|
if (i != 0 && !ADD_RDLEN(header, p1, plen, rdlen1))
|
||||||
return STAT_BOGUS;
|
return STAT_BOGUS;
|
||||||
|
|
||||||
if (!extract_name(header, plen, &p1, name, 1, 10))
|
if (!extract_name(header, plen, &p1, name, EXTR_NAME_EXTRACT, 10))
|
||||||
return STAT_BOGUS; /* bad packet */
|
return STAT_BOGUS; /* bad packet */
|
||||||
|
|
||||||
GETSHORT(type1, p1);
|
GETSHORT(type1, p1);
|
||||||
@@ -2018,7 +2018,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
|||||||
/* Check if we've done this RRset already */
|
/* Check if we've done this RRset already */
|
||||||
for (p2 = ans_start, j = 0; j < i; j++)
|
for (p2 = ans_start, j = 0; j < i; j++)
|
||||||
{
|
{
|
||||||
if (!(rc = extract_name(header, plen, &p2, name, 0, 10)))
|
if (!(rc = extract_name(header, plen, &p2, name, EXTR_NAME_COMPARE, 10)))
|
||||||
return STAT_BOGUS; /* bad packet */
|
return STAT_BOGUS; /* bad packet */
|
||||||
|
|
||||||
GETSHORT(type2, p2);
|
GETSHORT(type2, p2);
|
||||||
@@ -2115,7 +2115,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
|||||||
if ((p2 = targets[j]))
|
if ((p2 = targets[j]))
|
||||||
{
|
{
|
||||||
int rc1;
|
int rc1;
|
||||||
if (!(rc1 = extract_name(header, plen, &p2, name, 0, 10)))
|
if (!(rc1 = extract_name(header, plen, &p2, name, EXTR_NAME_COMPARE, 10)))
|
||||||
return STAT_BOGUS; /* bad packet */
|
return STAT_BOGUS; /* bad packet */
|
||||||
|
|
||||||
if (class1 == qclass && rc1 == 1 && (type1 == T_CNAME || type1 == qtype || qtype == T_ANY ))
|
if (class1 == qclass && rc1 == 1 && (type1 == T_CNAME || type1 == qtype || qtype == T_ANY ))
|
||||||
@@ -2149,7 +2149,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
|||||||
if (neganswer)
|
if (neganswer)
|
||||||
*neganswer = 1;
|
*neganswer = 1;
|
||||||
|
|
||||||
if (!extract_name(header, plen, &p2, name, 1, 10))
|
if (!extract_name(header, plen, &p2, name, EXTR_NAME_EXTRACT, 10))
|
||||||
return STAT_BOGUS; /* bad packet */
|
return STAT_BOGUS; /* bad packet */
|
||||||
|
|
||||||
/* NXDOMAIN or NODATA reply, unanswered question is (name, qclass, qtype) */
|
/* NXDOMAIN or NODATA reply, unanswered question is (name, qclass, qtype) */
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+31
-13
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -417,21 +417,34 @@ static size_t add_source_addr(struct dns_header *header, size_t plen, unsigned c
|
|||||||
else if (option_bool(OPT_STRIP_ECS))
|
else if (option_bool(OPT_STRIP_ECS))
|
||||||
replace = 2;
|
replace = 2;
|
||||||
else
|
else
|
||||||
return plen;
|
{
|
||||||
|
unsigned char *pheader;
|
||||||
|
/* If we still think the data is cacheable, and we're not
|
||||||
|
messing with EDNS client subnet ourselves, see if the client
|
||||||
|
sent a client subnet. If so, mark the data as uncacheable */
|
||||||
|
if (*cacheable &&
|
||||||
|
(pheader = find_pseudoheader(header, plen, NULL, NULL, NULL, NULL)) &&
|
||||||
|
!check_source(header, plen, pheader, NULL))
|
||||||
|
*cacheable = 0;
|
||||||
|
|
||||||
|
return plen;
|
||||||
|
}
|
||||||
|
|
||||||
return add_pseudoheader(header, plen, (unsigned char *)limit, EDNS0_OPTION_CLIENT_SUBNET, (unsigned char *)&opt, len, 0, replace);
|
return add_pseudoheader(header, plen, (unsigned char *)limit, EDNS0_OPTION_CLIENT_SUBNET, (unsigned char *)&opt, len, 0, replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer)
|
int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer)
|
||||||
{
|
{
|
||||||
/* Section 9.2, Check that subnet option in reply matches. */
|
/* Section 9.2, Check that subnet option (if any) in reply matches.
|
||||||
|
if peer == NULL, this degrades to a check for the existence of and EDNS0 client-subnet option. */
|
||||||
|
|
||||||
int len, calc_len;
|
int len, calc_len;
|
||||||
struct subnet_opt opt;
|
struct subnet_opt opt;
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
int code, i, rdlen;
|
int code, i, rdlen;
|
||||||
|
|
||||||
calc_len = calc_subnet_opt(&opt, peer, NULL);
|
if (peer)
|
||||||
|
calc_len = calc_subnet_opt(&opt, peer, NULL);
|
||||||
|
|
||||||
if (!(p = skip_name(pseudoheader, header, plen, 10)))
|
if (!(p = skip_name(pseudoheader, header, plen, 10)))
|
||||||
return 1;
|
return 1;
|
||||||
@@ -443,21 +456,26 @@ int check_source(struct dns_header *header, size_t plen, unsigned char *pseudohe
|
|||||||
return 1; /* bad packet */
|
return 1; /* bad packet */
|
||||||
|
|
||||||
/* check if option there */
|
/* check if option there */
|
||||||
for (i = 0; i + 4 < rdlen; i += len + 4)
|
for (i = 0; i + 4 < rdlen; i += len + 4)
|
||||||
{
|
{
|
||||||
GETSHORT(code, p);
|
GETSHORT(code, p);
|
||||||
GETSHORT(len, p);
|
GETSHORT(len, p);
|
||||||
if (code == EDNS0_OPTION_CLIENT_SUBNET)
|
if (code == EDNS0_OPTION_CLIENT_SUBNET)
|
||||||
{
|
{
|
||||||
/* make sure this doesn't mismatch. */
|
if (peer)
|
||||||
opt.scope_netmask = p[3];
|
{
|
||||||
if (len != calc_len || memcmp(p, &opt, len) != 0)
|
/* make sure this doesn't mismatch. */
|
||||||
|
opt.scope_netmask = p[3];
|
||||||
|
if (len != calc_len || memcmp(p, &opt, len) != 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (((struct subnet_opt *)p)->source_netmask != 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
p += len;
|
p += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See https://docs.umbrella.com/umbrella-api/docs/identifying-dns-traffic for
|
/* See https://docs.umbrella.com/umbrella-api/docs/identifying-dns-traffic for
|
||||||
@@ -491,7 +509,7 @@ static size_t add_umbrella_opt(struct dns_header *header, size_t plen, unsigned
|
|||||||
{
|
{
|
||||||
*cacheable = 0;
|
*cacheable = 0;
|
||||||
|
|
||||||
struct umbrella_opt opt = {{"ODNS"}, UMBRELLA_VERSION, 0, {}};
|
struct umbrella_opt opt = {{"ODNS"}, UMBRELLA_VERSION, 0, {0}};
|
||||||
u8 *u = &opt.fields[0];
|
u8 *u = &opt.fields[0];
|
||||||
int family = source->sa.sa_family;
|
int family = source->sa.sa_family;
|
||||||
int size = family == AF_INET ? INADDRSZ : IN6ADDRSZ;
|
int size = family == AF_INET ? INADDRSZ : IN6ADDRSZ;
|
||||||
@@ -541,6 +559,6 @@ size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *l
|
|||||||
plen = add_umbrella_opt(header, plen, limit, source, cacheable);
|
plen = add_umbrella_opt(header, plen, limit, source, cacheable);
|
||||||
|
|
||||||
plen = add_source_addr(header, plen, limit, source, cacheable);
|
plen = add_source_addr(header, plen, limit, source, cacheable);
|
||||||
|
|
||||||
return plen;
|
return plen;
|
||||||
}
|
}
|
||||||
+560
-420
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+4
-4
@@ -75,11 +75,11 @@ static char *buffer;
|
|||||||
|
|
||||||
static inline void add_attr(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data)
|
static inline void add_attr(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data)
|
||||||
{
|
{
|
||||||
struct my_nlattr *attr = (void *)nlh + NL_ALIGN(nlh->nlmsg_len);
|
struct my_nlattr *attr = (struct my_nlattr *)((u8 *)nlh + NL_ALIGN(nlh->nlmsg_len));
|
||||||
uint16_t payload_len = NL_ALIGN(sizeof(struct my_nlattr)) + len;
|
uint16_t payload_len = NL_ALIGN(sizeof(struct my_nlattr)) + len;
|
||||||
attr->nla_type = type;
|
attr->nla_type = type;
|
||||||
attr->nla_len = payload_len;
|
attr->nla_len = payload_len;
|
||||||
memcpy((void *)attr + NL_ALIGN(sizeof(struct my_nlattr)), data, len);
|
memcpy((u8 *)attr + NL_ALIGN(sizeof(struct my_nlattr)), data, len);
|
||||||
nlh->nlmsg_len += NL_ALIGN(payload_len);
|
nlh->nlmsg_len += NL_ALIGN(payload_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,8 +138,8 @@ static int new_add_to_ipset(const char *setname, const union all_addr *ipaddr, i
|
|||||||
add_attr(nlh,
|
add_attr(nlh,
|
||||||
(af == AF_INET ? IPSET_ATTR_IPADDR_IPV4 : IPSET_ATTR_IPADDR_IPV6) | NLA_F_NET_BYTEORDER,
|
(af == AF_INET ? IPSET_ATTR_IPADDR_IPV4 : IPSET_ATTR_IPADDR_IPV6) | NLA_F_NET_BYTEORDER,
|
||||||
addrsz, ipaddr);
|
addrsz, ipaddr);
|
||||||
nested[1]->nla_len = (void *)buffer + NL_ALIGN(nlh->nlmsg_len) - (void *)nested[1];
|
nested[1]->nla_len = (u8 *)buffer + NL_ALIGN(nlh->nlmsg_len) - (u8 *)nested[1];
|
||||||
nested[0]->nla_len = (void *)buffer + NL_ALIGN(nlh->nlmsg_len) - (void *)nested[0];
|
nested[0]->nla_len = (u8 *)buffer + NL_ALIGN(nlh->nlmsg_len) - (u8 *)nested[0];
|
||||||
|
|
||||||
while (retry_send(sendto(ipset_sock, buffer, nlh->nlmsg_len, 0,
|
while (retry_send(sendto(ipset_sock, buffer, nlh->nlmsg_len, 0,
|
||||||
(struct sockaddr *)&snl, sizeof(snl))));
|
(struct sockaddr *)&snl, sizeof(snl))));
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
#ifdef HAVE_LOOP
|
#ifdef HAVE_LOOP
|
||||||
static ssize_t loop_make_probe(u32 uid);
|
static ssize_t loop_make_probe(u32 uid);
|
||||||
|
|
||||||
void loop_send_probes()
|
void loop_send_probes(void)
|
||||||
{
|
{
|
||||||
struct server *serv;
|
struct server *serv;
|
||||||
struct randfd_list *rfds = NULL;
|
struct randfd_list *rfds = NULL;
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -647,7 +647,7 @@ static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
|
|||||||
/*
|
/*
|
||||||
* Clean old interfaces no longer found.
|
* Clean old interfaces no longer found.
|
||||||
*/
|
*/
|
||||||
static void clean_interfaces()
|
static void clean_interfaces(void)
|
||||||
{
|
{
|
||||||
struct irec *iface;
|
struct irec *iface;
|
||||||
struct irec **up = &daemon->interfaces;
|
struct irec **up = &daemon->interfaces;
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+9
-6
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -193,6 +193,7 @@ struct myoption {
|
|||||||
#define LOPT_MAX_PROCS 384
|
#define LOPT_MAX_PROCS 384
|
||||||
#define LOPT_DNSSEC_LIMITS 385
|
#define LOPT_DNSSEC_LIMITS 385
|
||||||
#define LOPT_PXE_OPT 386
|
#define LOPT_PXE_OPT 386
|
||||||
|
#define LOPT_NO_ENCODE 387
|
||||||
|
|
||||||
#ifdef HAVE_GETOPT_LONG
|
#ifdef HAVE_GETOPT_LONG
|
||||||
static const struct option opts[] =
|
static const struct option opts[] =
|
||||||
@@ -247,6 +248,7 @@ static const struct myoption opts[] =
|
|||||||
{ "local-ttl", 1, 0, 'T' },
|
{ "local-ttl", 1, 0, 'T' },
|
||||||
{ "no-negcache", 0, 0, 'N' },
|
{ "no-negcache", 0, 0, 'N' },
|
||||||
{ "no-round-robin", 0, 0, LOPT_NORR },
|
{ "no-round-robin", 0, 0, LOPT_NORR },
|
||||||
|
{ "no-0x20-encode", 0, 0, LOPT_NO_ENCODE },
|
||||||
{ "cache-rr", 1, 0, LOPT_CACHE_RR },
|
{ "cache-rr", 1, 0, LOPT_CACHE_RR },
|
||||||
{ "addn-hosts", 1, 0, 'H' },
|
{ "addn-hosts", 1, 0, 'H' },
|
||||||
{ "hostsdir", 1, 0, LOPT_HOST_INOTIFY },
|
{ "hostsdir", 1, 0, LOPT_HOST_INOTIFY },
|
||||||
@@ -568,7 +570,7 @@ static struct {
|
|||||||
{ LOPT_CMARK_ALST, ARG_DUP, "<connmark>[/<mask>][,<pattern>[/<pattern>...]]", gettext_noop("Set allowed DNS patterns for a connection-track mark."), NULL },
|
{ LOPT_CMARK_ALST, ARG_DUP, "<connmark>[/<mask>][,<pattern>[/<pattern>...]]", gettext_noop("Set allowed DNS patterns for a connection-track mark."), NULL },
|
||||||
{ LOPT_SYNTH, ARG_DUP, "<domain>,<range>,[<prefix>]", gettext_noop("Specify a domain and address range for synthesised names"), NULL },
|
{ LOPT_SYNTH, ARG_DUP, "<domain>,<range>,[<prefix>]", gettext_noop("Specify a domain and address range for synthesised names"), NULL },
|
||||||
{ LOPT_SEC_VALID, OPT_DNSSEC_VALID, NULL, gettext_noop("Activate DNSSEC validation"), NULL },
|
{ LOPT_SEC_VALID, OPT_DNSSEC_VALID, NULL, gettext_noop("Activate DNSSEC validation"), NULL },
|
||||||
{ LOPT_TRUST_ANCHOR, ARG_DUP, "<domain>,[<class>],...", gettext_noop("Specify trust anchor key digest."), NULL },
|
{ LOPT_TRUST_ANCHOR, ARG_DUP, "<domain>,[<class>,]...", gettext_noop("Specify trust anchor key digest."), NULL },
|
||||||
{ LOPT_DNSSEC_DEBUG, OPT_DNSSEC_DEBUG, NULL, gettext_noop("Disable upstream checking for DNSSEC debugging."), NULL },
|
{ LOPT_DNSSEC_DEBUG, OPT_DNSSEC_DEBUG, NULL, gettext_noop("Disable upstream checking for DNSSEC debugging."), NULL },
|
||||||
{ LOPT_DNSSEC_CHECK, ARG_DUP, NULL, gettext_noop("Ensure answers without DNSSEC are in unsigned zones."), NULL },
|
{ LOPT_DNSSEC_CHECK, ARG_DUP, NULL, gettext_noop("Ensure answers without DNSSEC are in unsigned zones."), NULL },
|
||||||
{ LOPT_DNSSEC_TIME, OPT_DNSSEC_TIME, NULL, gettext_noop("Don't check DNSSEC signature timestamps until first cache-reload"), NULL },
|
{ LOPT_DNSSEC_TIME, OPT_DNSSEC_TIME, NULL, gettext_noop("Don't check DNSSEC signature timestamps until first cache-reload"), NULL },
|
||||||
@@ -591,6 +593,7 @@ static struct {
|
|||||||
{ LOPT_UMBRELLA, ARG_ONE, "[=<optspec>]", gettext_noop("Send Cisco Umbrella identifiers including remote IP."), NULL },
|
{ LOPT_UMBRELLA, ARG_ONE, "[=<optspec>]", gettext_noop("Send Cisco Umbrella identifiers including remote IP."), NULL },
|
||||||
{ LOPT_QUIET_TFTP, OPT_QUIET_TFTP, NULL, gettext_noop("Do not log routine TFTP."), NULL },
|
{ LOPT_QUIET_TFTP, OPT_QUIET_TFTP, NULL, gettext_noop("Do not log routine TFTP."), NULL },
|
||||||
{ LOPT_NORR, OPT_NORR, NULL, gettext_noop("Suppress round-robin ordering of DNS records."), NULL },
|
{ LOPT_NORR, OPT_NORR, NULL, gettext_noop("Suppress round-robin ordering of DNS records."), NULL },
|
||||||
|
{ LOPT_NO_ENCODE, OPT_NO_0x20, NULL, gettext_noop("Suppress DNS bit 0x20 encoding."), NULL },
|
||||||
{ LOPT_NO_IDENT, OPT_NO_IDENT, NULL, gettext_noop("Do not add CHAOS TXT records."), NULL },
|
{ LOPT_NO_IDENT, OPT_NO_IDENT, NULL, gettext_noop("Do not add CHAOS TXT records."), NULL },
|
||||||
{ LOPT_CACHE_RR, ARG_DUP, "<RR-type>", gettext_noop("Cache this DNS resource record type."), NULL },
|
{ LOPT_CACHE_RR, ARG_DUP, "<RR-type>", gettext_noop("Cache this DNS resource record type."), NULL },
|
||||||
{ LOPT_MAX_PROCS, ARG_ONE, "<integer>", gettext_noop("Maximum number of concurrent tcp connections."), NULL },
|
{ LOPT_MAX_PROCS, ARG_ONE, "<integer>", gettext_noop("Maximum number of concurrent tcp connections."), NULL },
|
||||||
@@ -4043,10 +4046,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
}
|
}
|
||||||
|
|
||||||
new_addr = opt_malloc(sizeof(struct addrlist));
|
new_addr = opt_malloc(sizeof(struct addrlist));
|
||||||
new_addr->next = new->addr6;
|
|
||||||
new_addr->flags = 0;
|
new_addr->flags = 0;
|
||||||
new_addr->addr.addr6 = in6;
|
new_addr->addr.addr6 = in6;
|
||||||
new->addr6 = new_addr;
|
|
||||||
|
|
||||||
if (pref)
|
if (pref)
|
||||||
{
|
{
|
||||||
@@ -4057,7 +4058,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
((((u64)1<<(128-new_addr->prefixlen))-1) & addrpart) != 0)
|
((((u64)1<<(128-new_addr->prefixlen))-1) & addrpart) != 0)
|
||||||
{
|
{
|
||||||
dhcp_config_free(new);
|
dhcp_config_free(new);
|
||||||
ret_err(_("bad IPv6 prefix"));
|
ret_err_free(_("bad IPv6 prefix"), new_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
new_addr->flags |= ADDRLIST_PREFIX;
|
new_addr->flags |= ADDRLIST_PREFIX;
|
||||||
@@ -4071,6 +4072,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
if (i == 8)
|
if (i == 8)
|
||||||
new_addr->flags |= ADDRLIST_WILDCARD;
|
new_addr->flags |= ADDRLIST_WILDCARD;
|
||||||
|
|
||||||
|
new_addr->next = new->addr6;
|
||||||
|
new->addr6 = new_addr;
|
||||||
new->flags |= CONFIG_ADDR6;
|
new->flags |= CONFIG_ADDR6;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -4161,7 +4164,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
}
|
}
|
||||||
else if (strcmp(arg, "ignore") == 0)
|
else if (strcmp(arg, "ignore") == 0)
|
||||||
new->flags |= CONFIG_DISABLE;
|
new->flags |= CONFIG_DISABLE;
|
||||||
if (new->hostname)
|
else if (new->hostname)
|
||||||
{
|
{
|
||||||
dhcp_config_free(new);
|
dhcp_config_free(new);
|
||||||
ret_err(_("DHCP host has multiple names"));
|
ret_err(_("DHCP host has multiple names"));
|
||||||
|
|||||||
+7
-7
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -23,7 +23,7 @@ static size_t outpacket_counter;
|
|||||||
|
|
||||||
void end_opt6(int container)
|
void end_opt6(int container)
|
||||||
{
|
{
|
||||||
void *p = daemon->outpacket.iov_base + container + 2;
|
uint8_t *p = (uint8_t *)daemon->outpacket.iov_base + container + 2;
|
||||||
u16 len = outpacket_counter - container - 4 ;
|
u16 len = outpacket_counter - container - 4 ;
|
||||||
|
|
||||||
PUTSHORT(len, p);
|
PUTSHORT(len, p);
|
||||||
@@ -50,11 +50,11 @@ int save_counter(int newval)
|
|||||||
|
|
||||||
void *expand(size_t headroom)
|
void *expand(size_t headroom)
|
||||||
{
|
{
|
||||||
void *ret;
|
uint8_t *ret;
|
||||||
|
|
||||||
if (expand_buf(&daemon->outpacket, outpacket_counter + headroom))
|
if (expand_buf(&daemon->outpacket, outpacket_counter + headroom))
|
||||||
{
|
{
|
||||||
ret = daemon->outpacket.iov_base + outpacket_counter;
|
ret = (uint8_t *)daemon->outpacket.iov_base + outpacket_counter;
|
||||||
outpacket_counter += headroom;
|
outpacket_counter += headroom;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ void *expand(size_t headroom)
|
|||||||
int new_opt6(int opt)
|
int new_opt6(int opt)
|
||||||
{
|
{
|
||||||
int ret = outpacket_counter;
|
int ret = outpacket_counter;
|
||||||
void *p;
|
unsigned char *p;
|
||||||
|
|
||||||
if ((p = expand(4)))
|
if ((p = expand(4)))
|
||||||
{
|
{
|
||||||
@@ -88,7 +88,7 @@ void *put_opt6(void *data, size_t len)
|
|||||||
|
|
||||||
void put_opt6_long(unsigned int val)
|
void put_opt6_long(unsigned int val)
|
||||||
{
|
{
|
||||||
void *p;
|
unsigned char *p;
|
||||||
|
|
||||||
if ((p = expand(4)))
|
if ((p = expand(4)))
|
||||||
PUTLONG(val, p);
|
PUTLONG(val, p);
|
||||||
@@ -96,7 +96,7 @@ void put_opt6_long(unsigned int val)
|
|||||||
|
|
||||||
void put_opt6_short(unsigned int val)
|
void put_opt6_short(unsigned int val)
|
||||||
{
|
{
|
||||||
void *p;
|
uint8_t *p;
|
||||||
|
|
||||||
if ((p = expand(2)))
|
if ((p = expand(2)))
|
||||||
PUTSHORT(val, p);
|
PUTSHORT(val, p);
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+102
-42
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -16,16 +16,41 @@
|
|||||||
|
|
||||||
#include "dnsmasq.h"
|
#include "dnsmasq.h"
|
||||||
|
|
||||||
|
/* EXTR_NAME_EXTRACT -> extract name
|
||||||
|
EXTR_NAME_COMPARE -> compare name, case insensitive
|
||||||
|
EXTR_NAME_NOCASE -> compare name, case sensitive
|
||||||
|
EXTR_NAME_FLIP -> flip 0x20 bits in packet.
|
||||||
|
|
||||||
|
For flip, name is an array of ints, whose size
|
||||||
|
is given in parm, which forms the bitmap. Bits beyond the size
|
||||||
|
are assumed to be zero.
|
||||||
|
|
||||||
|
return = 0 -> error
|
||||||
|
return = 1 -> extract OK, compare OK, flip OK
|
||||||
|
return = 2 -> extract OK, compare failed.
|
||||||
|
return = 3 -> extract OK, compare failed but only on case.
|
||||||
|
*/
|
||||||
int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
|
int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
|
||||||
char *name, int isExtract, int extrabytes)
|
char *name, int func, unsigned int parm)
|
||||||
{
|
{
|
||||||
unsigned char *cp = (unsigned char *)name, *p = *pp, *p1 = NULL;
|
unsigned char *cp = (unsigned char *)name, *p = *pp, *p1 = NULL;
|
||||||
unsigned int j, l, namelen = 0, hops = 0;
|
unsigned int j, l, namelen = 0, hops = 0;
|
||||||
int retvalue = 1;
|
unsigned int bigmap_counter = 0, bigmap_posn = 0, bigmap_size, bitmap;
|
||||||
|
int retvalue = 1, case_insens = 1, isExtract = 0, flip = 0, extrabytes = (int)parm;
|
||||||
if (isExtract)
|
unsigned int *bigmap;
|
||||||
*cp = 0;
|
|
||||||
|
|
||||||
|
if (func == EXTR_NAME_EXTRACT)
|
||||||
|
isExtract = 1, *cp = 0;
|
||||||
|
else if (func == EXTR_NAME_NOCASE)
|
||||||
|
case_insens = 0;
|
||||||
|
else if (func == EXTR_NAME_FLIP)
|
||||||
|
{
|
||||||
|
flip = 1, extrabytes = 0;
|
||||||
|
bigmap = (unsigned int *)name;
|
||||||
|
name = NULL;
|
||||||
|
bigmap_size = parm;
|
||||||
|
}
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
unsigned int label_type;
|
unsigned int label_type;
|
||||||
@@ -46,7 +71,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
|
|||||||
cp--;
|
cp--;
|
||||||
*cp = 0; /* terminate: lose final period */
|
*cp = 0; /* terminate: lose final period */
|
||||||
}
|
}
|
||||||
else if (*cp != 0)
|
else if (!flip && *cp != 0)
|
||||||
retvalue = 2;
|
retvalue = 2;
|
||||||
|
|
||||||
if (p1) /* we jumped via compression */
|
if (p1) /* we jumped via compression */
|
||||||
@@ -85,7 +110,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
|
|||||||
if (!CHECK_LEN(header, p, plen, l))
|
if (!CHECK_LEN(header, p, plen, l))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for(j=0; j<l; j++, p++)
|
for (j=0; j<l; j++, p++)
|
||||||
if (isExtract)
|
if (isExtract)
|
||||||
{
|
{
|
||||||
unsigned char c = *p;
|
unsigned char c = *p;
|
||||||
@@ -98,6 +123,24 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
|
|||||||
else
|
else
|
||||||
*cp++ = c;
|
*cp++ = c;
|
||||||
}
|
}
|
||||||
|
else if (flip)
|
||||||
|
{
|
||||||
|
unsigned char c = *p;
|
||||||
|
|
||||||
|
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
|
||||||
|
{
|
||||||
|
/* Get the next int of the bitmap */
|
||||||
|
if (bigmap_posn < bigmap_size && bigmap_counter-- == 0)
|
||||||
|
{
|
||||||
|
bitmap = bigmap[bigmap_posn++];
|
||||||
|
bigmap_counter = (sizeof(unsigned int) * 8) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bitmap & 1)
|
||||||
|
*p ^= 0x20;
|
||||||
|
bitmap >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned char c1 = *cp, c2 = *p;
|
unsigned char c1 = *cp, c2 = *p;
|
||||||
@@ -107,23 +150,35 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
cp++;
|
cp++;
|
||||||
if (c1 >= 'A' && c1 <= 'Z')
|
|
||||||
c1 += 'a' - 'A';
|
|
||||||
|
|
||||||
if (c1 == NAME_ESCAPE)
|
if (c1 == NAME_ESCAPE)
|
||||||
c1 = (*cp++)-1;
|
c1 = (*cp++)-1;
|
||||||
|
else if (case_insens && c1 >= 'A' && c1 <= 'Z')
|
||||||
|
c1 += 'a' - 'A';
|
||||||
|
|
||||||
if (c2 >= 'A' && c2 <= 'Z')
|
if (case_insens && c2 >= 'A' && c2 <= 'Z')
|
||||||
c2 += 'a' - 'A';
|
c2 += 'a' - 'A';
|
||||||
|
|
||||||
|
if (!case_insens && retvalue != 2 && c1 != c2)
|
||||||
|
{
|
||||||
|
if (c1 >= 'A' && c1 <= 'Z')
|
||||||
|
c1 += 'a' - 'A';
|
||||||
|
|
||||||
|
if (c2 >= 'A' && c2 <= 'Z')
|
||||||
|
c2 += 'a' - 'A';
|
||||||
|
|
||||||
|
if (c1 == c2)
|
||||||
|
retvalue = 3;
|
||||||
|
}
|
||||||
|
|
||||||
if (c1 != c2)
|
if (c1 != c2)
|
||||||
retvalue = 2;
|
retvalue = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isExtract)
|
if (isExtract)
|
||||||
*cp++ = '.';
|
*cp++ = '.';
|
||||||
else if (*cp != 0 && *cp++ != '.')
|
else if (!flip && *cp != 0 && *cp++ != '.')
|
||||||
retvalue = 2;
|
retvalue = 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -399,7 +454,7 @@ int do_doctor(struct dns_header *header, size_t qlen, char *namebuff)
|
|||||||
if (i == ntohs(header->ancount) && !(p = skip_section(p, ntohs(header->nscount), header, qlen)))
|
if (i == ntohs(header->ancount) && !(p = skip_section(p, ntohs(header->nscount), header, qlen)))
|
||||||
return done;
|
return done;
|
||||||
|
|
||||||
if (!extract_name(header, qlen, &p, namebuff, 1, 10))
|
if (!extract_name(header, qlen, &p, namebuff, EXTR_NAME_EXTRACT, 10))
|
||||||
return done; /* bad packet */
|
return done; /* bad packet */
|
||||||
|
|
||||||
GETSHORT(qtype, p);
|
GETSHORT(qtype, p);
|
||||||
@@ -480,7 +535,7 @@ static int find_soa(struct dns_header *header, size_t qlen, char *name, int *sub
|
|||||||
|
|
||||||
for (i = 0; i < ntohs(header->nscount); i++)
|
for (i = 0; i < ntohs(header->nscount); i++)
|
||||||
{
|
{
|
||||||
if (!extract_name(header, qlen, &p, daemon->workspacename, 1, 0))
|
if (!extract_name(header, qlen, &p, daemon->workspacename, EXTR_NAME_EXTRACT, 0))
|
||||||
return 0; /* bad packet */
|
return 0; /* bad packet */
|
||||||
|
|
||||||
GETSHORT(qtype, p);
|
GETSHORT(qtype, p);
|
||||||
@@ -509,7 +564,7 @@ static int find_soa(struct dns_header *header, size_t qlen, char *name, int *sub
|
|||||||
|
|
||||||
for (j = 0; j < 2; j++) /* MNAME, RNAME */
|
for (j = 0; j < 2; j++) /* MNAME, RNAME */
|
||||||
{
|
{
|
||||||
if (!extract_name(header, qlen, &p, daemon->workspacename, 1, 0))
|
if (!extract_name(header, qlen, &p, daemon->workspacename, EXTR_NAME_EXTRACT, 0))
|
||||||
{
|
{
|
||||||
if (!no_cache)
|
if (!no_cache)
|
||||||
blockdata_free(addr.rrblock.rrdata);
|
blockdata_free(addr.rrblock.rrdata);
|
||||||
@@ -660,7 +715,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
|
|||||||
|
|
||||||
namep = p = (unsigned char *)(header+1);
|
namep = p = (unsigned char *)(header+1);
|
||||||
|
|
||||||
if (ntohs(header->qdcount) != 1 || !extract_name(header, qlen, &p, name, 1, 4))
|
if (ntohs(header->qdcount) != 1 || !extract_name(header, qlen, &p, name, EXTR_NAME_EXTRACT, 4))
|
||||||
return 2; /* bad packet */
|
return 2; /* bad packet */
|
||||||
|
|
||||||
GETSHORT(qtype, p);
|
GETSHORT(qtype, p);
|
||||||
@@ -684,7 +739,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
|
|||||||
for (j = 0; j < ntohs(header->ancount); j++)
|
for (j = 0; j < ntohs(header->ancount); j++)
|
||||||
{
|
{
|
||||||
int secflag = 0;
|
int secflag = 0;
|
||||||
if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
|
if (!(res = extract_name(header, qlen, &p1, name, EXTR_NAME_COMPARE, 10)))
|
||||||
return 2; /* bad packet */
|
return 2; /* bad packet */
|
||||||
|
|
||||||
GETSHORT(aqtype, p1);
|
GETSHORT(aqtype, p1);
|
||||||
@@ -722,7 +777,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
|
|||||||
if (aqtype == T_CNAME)
|
if (aqtype == T_CNAME)
|
||||||
log_query(secflag | F_CNAME | F_FORWARD | F_UPSTREAM, name, NULL, NULL, 0);
|
log_query(secflag | F_CNAME | F_FORWARD | F_UPSTREAM, name, NULL, NULL, 0);
|
||||||
|
|
||||||
if (!extract_name(header, qlen, &p1, name, 1, 0))
|
if (!extract_name(header, qlen, &p1, name, EXTR_NAME_EXTRACT, 0))
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
if (aqtype == T_CNAME)
|
if (aqtype == T_CNAME)
|
||||||
@@ -800,7 +855,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
|
|||||||
{
|
{
|
||||||
int secflag = 0;
|
int secflag = 0;
|
||||||
|
|
||||||
if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
|
if (!(res = extract_name(header, qlen, &p1, name, EXTR_NAME_COMPARE, 10)))
|
||||||
return 2; /* bad packet */
|
return 2; /* bad packet */
|
||||||
|
|
||||||
GETSHORT(aqtype, p1);
|
GETSHORT(aqtype, p1);
|
||||||
@@ -862,7 +917,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
namep = p1;
|
namep = p1;
|
||||||
if (!extract_name(header, qlen, &p1, name, 1, 0))
|
if (!extract_name(header, qlen, &p1, name, EXTR_NAME_EXTRACT, 0))
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
if (qtype != T_CNAME)
|
if (qtype != T_CNAME)
|
||||||
@@ -932,7 +987,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
|
|||||||
/* Name, extract it then re-encode. */
|
/* Name, extract it then re-encode. */
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (!extract_name(header, qlen, &p1, name, 1, 0))
|
if (!extract_name(header, qlen, &p1, name, EXTR_NAME_EXTRACT, 0))
|
||||||
{
|
{
|
||||||
blockdata_free(addr.rrblock.rrdata);
|
blockdata_free(addr.rrblock.rrdata);
|
||||||
return 2;
|
return 2;
|
||||||
@@ -965,7 +1020,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
|
|||||||
} while (desc != -1);
|
} while (desc != -1);
|
||||||
|
|
||||||
/* we overwrote the original name, so get it back here. */
|
/* we overwrote the original name, so get it back here. */
|
||||||
if (!extract_name(header, qlen, &tmp, name, 1, 0))
|
if (!extract_name(header, qlen, &tmp, name, EXTR_NAME_EXTRACT, 0))
|
||||||
{
|
{
|
||||||
blockdata_free(addr.rrblock.rrdata);
|
blockdata_free(addr.rrblock.rrdata);
|
||||||
return 2;
|
return 2;
|
||||||
@@ -1127,7 +1182,7 @@ void report_addresses(struct dns_header *header, size_t len, u32 mark)
|
|||||||
{
|
{
|
||||||
int aqtype, aqclass, ardlen;
|
int aqtype, aqclass, ardlen;
|
||||||
|
|
||||||
if (!extract_name(header, len, &p, daemon->namebuff, 1, 10))
|
if (!extract_name(header, len, &p, daemon->namebuff, EXTR_NAME_EXTRACT, 10))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!CHECK_LEN(header, p, len, 10))
|
if (!CHECK_LEN(header, p, len, 10))
|
||||||
@@ -1145,7 +1200,7 @@ void report_addresses(struct dns_header *header, size_t len, u32 mark)
|
|||||||
{
|
{
|
||||||
if (aqtype == T_CNAME)
|
if (aqtype == T_CNAME)
|
||||||
{
|
{
|
||||||
if (!extract_name(header, len, &p, daemon->workspacename, 1, 0))
|
if (!extract_name(header, len, &p, daemon->workspacename, EXTR_NAME_EXTRACT, 0))
|
||||||
return;
|
return;
|
||||||
if (safe_name(daemon->namebuff) && safe_name(daemon->workspacename))
|
if (safe_name(daemon->namebuff) && safe_name(daemon->workspacename))
|
||||||
ubus_event_bcast_connmark_allowlist_resolved(mark, daemon->namebuff, daemon->workspacename, attl);
|
ubus_event_bcast_connmark_allowlist_resolved(mark, daemon->namebuff, daemon->workspacename, attl);
|
||||||
@@ -1191,11 +1246,11 @@ unsigned int extract_request(struct dns_header *header, size_t qlen, char *name,
|
|||||||
|
|
||||||
if (ntohs(header->qdcount) != 1 || OPCODE(header) != QUERY)
|
if (ntohs(header->qdcount) != 1 || OPCODE(header) != QUERY)
|
||||||
return 0; /* must be exactly one query. */
|
return 0; /* must be exactly one query. */
|
||||||
|
|
||||||
if (!(header->hb3 & HB3_QR) && (ntohs(header->ancount) != 0 || ntohs(header->nscount) != 0))
|
if (!(header->hb3 & HB3_QR) && (ntohs(header->ancount) != 0 || ntohs(header->nscount) != 0))
|
||||||
return 0; /* non-standard query. */
|
return 0; /* non-standard query. */
|
||||||
|
|
||||||
if (!extract_name(header, qlen, &p, name, 1, 4))
|
if (!extract_name(header, qlen, &p, name, EXTR_NAME_EXTRACT, 4))
|
||||||
return 0; /* bad packet */
|
return 0; /* bad packet */
|
||||||
|
|
||||||
GETSHORT(qtype, p);
|
GETSHORT(qtype, p);
|
||||||
@@ -1309,7 +1364,7 @@ static int check_bad_address(struct dns_header *header, size_t qlen, struct bogu
|
|||||||
|
|
||||||
for (i = ntohs(header->ancount); i != 0; i--)
|
for (i = ntohs(header->ancount); i != 0; i--)
|
||||||
{
|
{
|
||||||
if (name && !extract_name(header, qlen, &p, name, 1, 10))
|
if (name && !extract_name(header, qlen, &p, name, EXTR_NAME_EXTRACT, 10))
|
||||||
return 0; /* bad packet */
|
return 0; /* bad packet */
|
||||||
|
|
||||||
if (!name && !(p = skip_name(p, header, qlen, 10)))
|
if (!name && !(p = skip_name(p, header, qlen, 10)))
|
||||||
@@ -1559,7 +1614,7 @@ static unsigned long crec_ttl(struct crec *crecp, time_t now)
|
|||||||
return daemon->max_ttl;
|
return daemon->max_ttl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cache_validated(const struct crec *crecp)
|
static int cache_not_validated(const struct crec *crecp)
|
||||||
{
|
{
|
||||||
return (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK));
|
return (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK));
|
||||||
}
|
}
|
||||||
@@ -1567,7 +1622,7 @@ static int cache_validated(const struct crec *crecp)
|
|||||||
/* return zero if we can't answer from cache, or packet size if we can */
|
/* return zero if we can't answer from cache, or packet size if we can */
|
||||||
size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||||
struct in_addr local_addr, struct in_addr local_netmask,
|
struct in_addr local_addr, struct in_addr local_netmask,
|
||||||
time_t now, int ad_reqd, int do_bit, int *stale, int *filtered)
|
time_t now, int ad_reqd, int do_bit, int no_cache, int *stale, int *filtered)
|
||||||
{
|
{
|
||||||
char *name = daemon->namebuff;
|
char *name = daemon->namebuff;
|
||||||
unsigned char *p, *ansp;
|
unsigned char *p, *ansp;
|
||||||
@@ -1582,6 +1637,10 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
size_t len;
|
size_t len;
|
||||||
int rd_bit = (header->hb3 & HB3_RD);
|
int rd_bit = (header->hb3 & HB3_RD);
|
||||||
int count = 255; /* catch loops */
|
int count = 255; /* catch loops */
|
||||||
|
|
||||||
|
/* Suppress cached answers of no_cache set. */
|
||||||
|
if (no_cache)
|
||||||
|
rd_bit = 0;
|
||||||
|
|
||||||
if (stale)
|
if (stale)
|
||||||
*stale = 0;
|
*stale = 0;
|
||||||
@@ -1615,7 +1674,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
nameoffset = p - (unsigned char *)header;
|
nameoffset = p - (unsigned char *)header;
|
||||||
|
|
||||||
/* now extract name as .-concatenated string into name */
|
/* now extract name as .-concatenated string into name */
|
||||||
if (!extract_name(header, qlen, &p, name, 1, 4))
|
if (!extract_name(header, qlen, &p, name, EXTR_NAME_EXTRACT, 4))
|
||||||
return 0; /* bad packet */
|
return 0; /* bad packet */
|
||||||
|
|
||||||
GETSHORT(qtype, p);
|
GETSHORT(qtype, p);
|
||||||
@@ -1656,7 +1715,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
|
|
||||||
/* If the client asked for DNSSEC don't use cached data. */
|
/* If the client asked for DNSSEC don't use cached data. */
|
||||||
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
|
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
|
||||||
(rd_bit && (!do_bit || cache_validated(crecp))))
|
(rd_bit && (!do_bit || cache_not_validated(crecp))))
|
||||||
{
|
{
|
||||||
if (crecp->flags & F_CONFIG || qtype == T_CNAME)
|
if (crecp->flags & F_CONFIG || qtype == T_CNAME)
|
||||||
ans = 1;
|
ans = 1;
|
||||||
@@ -1815,7 +1874,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
the zone is unsigned, which implies that we're doing
|
the zone is unsigned, which implies that we're doing
|
||||||
validation. */
|
validation. */
|
||||||
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
|
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
|
||||||
(rd_bit && (!do_bit || cache_validated(crecp)) ))
|
(rd_bit && (!do_bit || cache_not_validated(crecp)) ))
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -1971,7 +2030,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
|
|
||||||
/* If the client asked for DNSSEC don't use cached data. */
|
/* If the client asked for DNSSEC don't use cached data. */
|
||||||
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
|
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
|
||||||
(rd_bit && (!do_bit || cache_validated(crecp)) ))
|
(rd_bit && (!do_bit || cache_not_validated(crecp)) ))
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int stale_flag = 0;
|
int stale_flag = 0;
|
||||||
@@ -2153,19 +2212,19 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
|
|
||||||
if (!ans)
|
if (!ans)
|
||||||
{
|
{
|
||||||
if ((crecp = cache_find_by_name(NULL, name, now, F_RR | F_NXDOMAIN)) &&
|
if ((crecp = cache_find_by_name(NULL, name, now, F_RR | F_NXDOMAIN)) && rd_bit)
|
||||||
rd_bit && (!do_bit || cache_validated(crecp)))
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int flags = crecp->flags;
|
int flags = crecp->flags;
|
||||||
unsigned short rrtype;
|
unsigned short rrtype;
|
||||||
|
|
||||||
if (flags & F_KEYTAG)
|
if (flags & F_KEYTAG)
|
||||||
rrtype = crecp->addr.rrblock.rrtype;
|
rrtype = crecp->addr.rrblock.rrtype;
|
||||||
else
|
else
|
||||||
rrtype = crecp->addr.rrdata.rrtype;
|
rrtype = crecp->addr.rrdata.rrtype;
|
||||||
|
|
||||||
if ((flags & F_NXDOMAIN) || rrtype == qtype)
|
if (((flags & F_NXDOMAIN) || rrtype == qtype) &&
|
||||||
|
(!do_bit || cache_not_validated(crecp)))
|
||||||
{
|
{
|
||||||
char *rrdata = NULL;
|
char *rrdata = NULL;
|
||||||
unsigned short rrlen = 0;
|
unsigned short rrlen = 0;
|
||||||
@@ -2228,14 +2287,15 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (qtype != T_ANY && !ans && rr_on_list(daemon->filter_rr, qtype))
|
if (qtype != T_ANY && !ans && rr_on_list(daemon->filter_rr, qtype) && !do_bit)
|
||||||
{
|
{
|
||||||
/* We don't have a cached answer and when we get an answer from upstream we're going to
|
/* We don't have a cached answer and when we get an answer from upstream we're going to
|
||||||
filter it anyway. If we have a cached answer for the domain for another RRtype then
|
filter it anyway. If we have a cached answer for the domain for another RRtype then
|
||||||
that may be enough to tell us if the answer should be NODATA and save the round trip.
|
that may be enough to tell us if the answer should be NODATA and save the round trip.
|
||||||
Cached NXDOMAIN has already been handled, so here we look for any record for the domain,
|
Cached NXDOMAIN has already been handled, so here we look for any record for the domain,
|
||||||
since its existence allows us to return a NODATA answer. Note that we never set the AD flag,
|
since its existence allows us to return a NODATA answer. Note that we never set the AD flag,
|
||||||
since we didn't authenticate the record. */
|
since we didn't authenticate the record; this doesn't work if we want auth data, so
|
||||||
|
don't use this shortcut in that case. */
|
||||||
|
|
||||||
if (cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_RR | F_CNAME))
|
if (cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_RR | F_CNAME))
|
||||||
{
|
{
|
||||||
@@ -2334,7 +2394,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
if (!(ansp = skip_questions(header, qlen)))
|
if (!(ansp = skip_questions(header, qlen)))
|
||||||
return 0; /* bad packet */
|
return 0; /* bad packet */
|
||||||
anscount = nscount = addncount = 0;
|
anscount = nscount = addncount = 0;
|
||||||
log_query(F_CONFIG, "reply", NULL, "truncated", 0);
|
log_query(0, "reply", NULL, "truncated", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nxdomain)
|
if (nxdomain)
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+13
-13
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -39,8 +39,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu
|
|||||||
static void log6_opts(int nest, unsigned int xid, void *start_opts, void *end_opts);
|
static void log6_opts(int nest, unsigned int xid, void *start_opts, void *end_opts);
|
||||||
static void log6_packet(struct state *state, char *type, struct in6_addr *addr, char *string);
|
static void log6_packet(struct state *state, char *type, struct in6_addr *addr, char *string);
|
||||||
static void log6_quiet(struct state *state, char *type, struct in6_addr *addr, char *string);
|
static void log6_quiet(struct state *state, char *type, struct in6_addr *addr, char *string);
|
||||||
static void *opt6_find (void *opts, void *end, unsigned int search, unsigned int minsize);
|
static void *opt6_find (uint8_t *opts, uint8_t *end, unsigned int search, unsigned int minsize);
|
||||||
static void *opt6_next(void *opts, void *end);
|
static void *opt6_next(uint8_t *opts, uint8_t *end);
|
||||||
static unsigned int opt6_uint(unsigned char *opt, int offset, int size);
|
static unsigned int opt6_uint(unsigned char *opt, int offset, int size);
|
||||||
static void get_context_tag(struct state *state, struct dhcp_context *context);
|
static void get_context_tag(struct state *state, struct dhcp_context *context);
|
||||||
static int check_ia(struct state *state, void *opt, void **endp, void **ia_option);
|
static int check_ia(struct state *state, void *opt, void **endp, void **ia_option);
|
||||||
@@ -61,11 +61,11 @@ static void calculate_times(struct dhcp_context *context, unsigned int *min_time
|
|||||||
|
|
||||||
#define opt6_len(opt) ((int)(opt6_uint(opt, -2, 2)))
|
#define opt6_len(opt) ((int)(opt6_uint(opt, -2, 2)))
|
||||||
#define opt6_type(opt) (opt6_uint(opt, -4, 2))
|
#define opt6_type(opt) (opt6_uint(opt, -4, 2))
|
||||||
#define opt6_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[4+(i)]))
|
#define opt6_ptr(opt, i) ((void *)&(((uint8_t *)(opt))[4+(i)]))
|
||||||
|
|
||||||
#define opt6_user_vendor_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[2+(i)]))
|
#define opt6_user_vendor_ptr(opt, i) ((void *)&(((uint8_t *)(opt))[2+(i)]))
|
||||||
#define opt6_user_vendor_len(opt) ((int)(opt6_uint(opt, -4, 2)))
|
#define opt6_user_vendor_len(opt) ((int)(opt6_uint(opt, -4, 2)))
|
||||||
#define opt6_user_vendor_next(opt, end) (opt6_next(((void *) opt) - 2, end))
|
#define opt6_user_vendor_next(opt, end) (opt6_next(((uint8_t *) opt) - 2, end))
|
||||||
|
|
||||||
|
|
||||||
unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name,
|
unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name,
|
||||||
@@ -107,11 +107,11 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *if
|
|||||||
static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t sz,
|
static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t sz,
|
||||||
struct in6_addr *client_addr, int is_unicast, time_t now)
|
struct in6_addr *client_addr, int is_unicast, time_t now)
|
||||||
{
|
{
|
||||||
void *end = inbuff + sz;
|
uint8_t *end = inbuff + sz;
|
||||||
void *opts = inbuff + 34;
|
uint8_t *opts = inbuff + 34;
|
||||||
int msg_type = *inbuff;
|
int msg_type = *inbuff;
|
||||||
unsigned char *outmsgtypep;
|
unsigned char *outmsgtypep;
|
||||||
void *opt;
|
uint8_t *opt;
|
||||||
struct dhcp_vendor *vendor;
|
struct dhcp_vendor *vendor;
|
||||||
|
|
||||||
/* if not an encapsulated relayed message, just do the stuff */
|
/* if not an encapsulated relayed message, just do the stuff */
|
||||||
@@ -232,7 +232,7 @@ static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t
|
|||||||
|
|
||||||
for (opt = opts; opt; opt = opt6_next(opt, end))
|
for (opt = opts; opt; opt = opt6_next(opt, end))
|
||||||
{
|
{
|
||||||
if (opt6_ptr(opt, 0) + opt6_len(opt) > end)
|
if ((uint8_t *)opt6_ptr(opt, 0) + opt6_len(opt) > end)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Don't copy MAC address into reply. */
|
/* Don't copy MAC address into reply. */
|
||||||
@@ -1307,7 +1307,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu
|
|||||||
reallocated. */
|
reallocated. */
|
||||||
((unsigned char *)(daemon->outpacket.iov_base))[start_msg] = outmsgtype;
|
((unsigned char *)(daemon->outpacket.iov_base))[start_msg] = outmsgtype;
|
||||||
|
|
||||||
log6_opts(0, state->xid, daemon->outpacket.iov_base + start_opts, daemon->outpacket.iov_base + save_counter(-1));
|
log6_opts(0, state->xid, (uint8_t *)daemon->outpacket.iov_base + start_opts, (uint8_t *)daemon->outpacket.iov_base + save_counter(-1));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@@ -2093,7 +2093,7 @@ static void log6_packet(struct state *state, char *type, struct in6_addr *addr,
|
|||||||
string ? string : "");
|
string ? string : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *opt6_find (void *opts, void *end, unsigned int search, unsigned int minsize)
|
static void *opt6_find (uint8_t *opts, uint8_t *end, unsigned int search, unsigned int minsize)
|
||||||
{
|
{
|
||||||
u16 opt, opt_len;
|
u16 opt, opt_len;
|
||||||
void *start;
|
void *start;
|
||||||
@@ -2120,7 +2120,7 @@ static void *opt6_find (void *opts, void *end, unsigned int search, unsigned int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *opt6_next(void *opts, void *end)
|
static void *opt6_next(uint8_t *opts, uint8_t *end)
|
||||||
{
|
{
|
||||||
u16 opt_len;
|
u16 opt_len;
|
||||||
|
|
||||||
|
|||||||
+1
-4
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -345,9 +345,6 @@ int expand_workspace(unsigned char ***wkspc, int *szp, int new)
|
|||||||
if (old >= new+1)
|
if (old >= new+1)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (new >= 100)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
new += 5;
|
new += 5;
|
||||||
|
|
||||||
if (!(p = whine_realloc(*wkspc, new * sizeof(unsigned char *))))
|
if (!(p = whine_realloc(*wkspc, new * sizeof(unsigned char *))))
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -360,7 +360,7 @@ void tftp_request(struct listener *listen, time_t now)
|
|||||||
}
|
}
|
||||||
|
|
||||||
p = packet + 2;
|
p = packet + 2;
|
||||||
end = packet + len;
|
end = packet + 2 + len;
|
||||||
|
|
||||||
if (ntohs(*((unsigned short *)packet)) != OP_RRQ ||
|
if (ntohs(*((unsigned short *)packet)) != OP_RRQ ||
|
||||||
!(filename = next(&p, end)) ||
|
!(filename = next(&p, end)) ||
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+47
-28
@@ -1,4 +1,4 @@
|
|||||||
/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley
|
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -41,7 +41,7 @@ static u32 in[12];
|
|||||||
static u32 out[8];
|
static u32 out[8];
|
||||||
static int outleft = 0;
|
static int outleft = 0;
|
||||||
|
|
||||||
void rand_init()
|
void rand_init(void)
|
||||||
{
|
{
|
||||||
int fd = open(RANDFILE, O_RDONLY);
|
int fd = open(RANDFILE, O_RDONLY);
|
||||||
|
|
||||||
@@ -767,10 +767,10 @@ int retry_send(ssize_t rc)
|
|||||||
|
|
||||||
/* rw = 0 -> write
|
/* rw = 0 -> write
|
||||||
rw = 1 -> read
|
rw = 1 -> read
|
||||||
rw = 2 -> read once
|
rw = 2 -> write once
|
||||||
rw = 3 -> write once
|
rw = 3 -> read once
|
||||||
|
|
||||||
"once" fail if all the data doesn't arrive/go in a single read/write.
|
"once" fails on EAGAIN, as this a timeout.
|
||||||
This indicates a timeout of a TCP socket.
|
This indicates a timeout of a TCP socket.
|
||||||
*/
|
*/
|
||||||
int read_write(int fd, unsigned char *packet, int size, int rw)
|
int read_write(int fd, unsigned char *packet, int size, int rw)
|
||||||
@@ -779,29 +779,34 @@ int read_write(int fd, unsigned char *packet, int size, int rw)
|
|||||||
|
|
||||||
for (done = 0; done < size; done += n)
|
for (done = 0; done < size; done += n)
|
||||||
{
|
{
|
||||||
do {
|
if (rw & 1)
|
||||||
if (rw & 1)
|
n = read(fd, &packet[done], (size_t)(size - done));
|
||||||
n = read(fd, &packet[done], (size_t)(size - done));
|
else
|
||||||
else
|
n = write(fd, &packet[done], (size_t)(size - done));
|
||||||
n = write(fd, &packet[done], (size_t)(size - done));
|
|
||||||
|
|
||||||
if (n == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (n == -1 && errno == EINTR)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* "once" variant */
|
|
||||||
if ((rw & 2) && n != size)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
} while (n == -1 && (errno == EINTR || errno == ENOMEM || errno == ENOBUFS ||
|
|
||||||
errno == EAGAIN || errno == EWOULDBLOCK));
|
|
||||||
|
|
||||||
if (n == -1)
|
if (n == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (n == -1)
|
||||||
|
{
|
||||||
|
n = 0; /* don't mess with counter when we loop. */
|
||||||
|
|
||||||
|
if (errno == EINTR || errno == ENOMEM || errno == ENOBUFS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||||
|
{
|
||||||
|
/* "once" variant */
|
||||||
|
if (rw & 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -810,11 +815,25 @@ void close_fds(long max_fd, int spare1, int spare2, int spare3)
|
|||||||
{
|
{
|
||||||
/* On Linux, use the /proc/ filesystem to find which files
|
/* On Linux, use the /proc/ filesystem to find which files
|
||||||
are actually open, rather than iterate over the whole space,
|
are actually open, rather than iterate over the whole space,
|
||||||
for efficiency reasons. If this fails we drop back to the dumb code. */
|
for efficiency reasons.
|
||||||
#ifdef HAVE_LINUX_NETWORK
|
|
||||||
|
On *BSD, the same facility is found at /dev/fd.
|
||||||
|
|
||||||
|
If this fails we drop back to the dumb code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_LINUX_NETWORK
|
||||||
|
#define FDESCFS "/proc/self/fd"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_BSD_NETWORK
|
||||||
|
#define FDESCFS "/dev/fd"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FDESCFS
|
||||||
DIR *d;
|
DIR *d;
|
||||||
|
|
||||||
if ((d = opendir("/proc/self/fd")))
|
if ((d = opendir(FDESCFS)))
|
||||||
{
|
{
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
|
|
||||||
|
|||||||
Submodule
+1
Submodule submodules/dnsmasq-debian added at 9fe6b08a52.
Reference in new issue
Block a user