Compare commits

..
46 Commits
Author SHA1 Message Date
Simon Kelley c4b9bc63e0 Fix a problem in overload handling.
Sending the same query repeatedly to a dnsmasq instance which
doesn't get replies from upstream will eventually hit the
hard limit on frec_src structures and start gettin REFUSED
replies. This is OK, except that since the queries are no longer
being forwarded, an upstream server coming back doesn't reset the
situation. If there is any other traffic, frec allocation will
eventually delete the timed-out frec and get things moving again,
but that's not guaranteed.

To fix this we explicitly delete the frec once timed out in this case.

Thanks to Filip Jenicek for noticing and characterising this problem.
2022-09-09 12:53:49 +01:00
Simon Kelley 4447d48bb9 Add DHCPv4 option 108 "ipv6-only" to the options table. 2022-09-06 22:40:06 +01:00
Simon Kelley 04cc2ae1a6 Fix logic when a SERVFAIL reply is received after good replt for DNSSEC.
If we get a SERVFAIL or REFUSED answer to a DNSSEC query for which
we already have a good answer, just ignore it.
2022-09-06 18:31:59 +01:00
Simon Kelley 32588c755a Add source address to RA packet dumps. 2022-09-06 18:08:39 +01:00
Simon Kelley 84a6d07cdd Fix DHCPv6 relay to use a more sensble source address.
Tweak things so that packets relayed towards a server
have source address on the server-facing network, not the
client-facing network. Thanks to Luis Thomas for spotting this
and initial patch.
2022-09-06 15:40:42 +01:00
Simon Kelley d6c69f6bdb Free sockets awaiting upstream DNS replies ASAP.
Once we have a good answer, close the socket so that the fd can
be reused during DNSSEC validation and we don't have to read and
discard more replies from other servers.
2022-09-06 15:35:54 +01:00
Simon Kelley ce372917fe Tweak packet dump code to make port numbers more accurate.
Also add query-ids with log-queries=extra.
2022-09-05 18:04:35 +01:00
Simon Kelley 09d741f58a Simplify realloc use in poll.c 2022-08-11 17:04:54 +01:00
Petr Menšík 0666ae3d27 Introduce whine_realloc
Move few patters with whine_malloc, if (successful) copy+free, to a new
whine_realloc. It should do the same thing, but with a help from OS it
can avoid unnecessary copy and free if allocation of more data after
current data is possible.

Added few setting remanining space to 0, because realloc does not use
calloc like whine_malloc does. There is no advantage of zeroing what we
will immediately overwrite. Zero only remaining space.
2022-08-11 16:56:58 +01:00
Simon Kelley ba4c7d906b CHANGELOG typo. 2022-08-08 15:36:47 +01:00
Simon Kelley f4b2813818 Fix bad interaction between --address=/#/<ip> and --server=/some.domain/#
This would return <ip> for queries in some.domain, rather than
forwarding the query via the default server(s) read from /etc/resolv.conf.
2022-08-08 15:27:32 +01:00
Bertie, Taylor 5586934da0 Bound the value of UDP packet size in the EDNS0 header of
forwarded queries to the configured or default value of
edns-packet-max. There's no point letting a client set a larger
value if we're unable to return the answer.
2022-07-31 17:20:21 +01:00
Simon Kelley 6134b94c02 Update man page on DHCP data provided to scripts. Provide requested options for DHCPv6 also. 2022-07-31 12:15:38 +01:00
Simon Kelley 05e6728e98 Fix bit-rotted data handling code for LUA scripts. 2022-07-31 11:33:05 +01:00
Simon Kelley 6578acd668 Tidy last two commits. 2022-07-31 11:04:12 +01:00
Kevin YeichandJasper Wiegratz b5581ed173 Pass MUD URLs (RFC 8520) supplied via DHCPv4 to DHCP scripts
Extract Manufacturer Usage Description (MUD) URL from DHCP Option 161
and make it available to DHCP scripts as DNSMASQ_MUD_URL.

See https://datatracker.ietf.org/doc/html/rfc8520#section-17.3
and https://datatracker.ietf.org/doc/html/rfc8520#section-10

Co-authored-by: Jasper Wiegratz <wiegratz@uni-bremen.de>
2022-07-29 13:01:47 +01:00
Hugo Hakim DamerandJasper Wiegratz 508d6b4885 Pass MUD URLs (RFC 8520) supplied via DHCPv6 to DHCP scripts
Extract Manufacturer Usage Description (MUD) URL from DHCP Option 112
and make it available to DHCP scripts as DNSMASQ_MUD_URL.

This expands on the initial support for Manufacturer Usage Description
URLs that has been added in the previous commit for DHCPv4 by also
supporting MUD URLs supplied using DHCPv6.

See https://datatracker.ietf.org/doc/html/rfc8520#section-17.3
and https://datatracker.ietf.org/doc/html/rfc8520#section-10

Co-authored-by: Jasper Wiegratz <wiegratz@uni-bremen.de>
2022-07-29 12:57:27 +01:00
Simon Kelley ef6efd69ed Merge branch 'master' of ssh://thekelleys.org.uk/var/local/git/dnsmasq 2022-07-19 23:40:50 +01:00
Simon Kelley 151d7dc5ea Fix comment typo. 2022-07-19 23:40:11 +01:00
Simon Kelley 20b4a4ea5b Fix comment typo. 2022-07-07 20:56:07 +01:00
Beniamino Galvani 770bce967c Fix parsing of IPv6 addresses with peer from netlink.
In the most common case, an IPv6 address doesn't have a peer and the
IFA_ADDRESS netlink attribute contains the address itself.

But if the address has a peer (typically for point to point links),
then IFA_ADDRESS contains the peer address and IFA_LOCAL contains the
address [1].

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/ipv6/addrconf.c?h=v5.17#n5030

Fix the parsing of IPv6 addresses with peers, as currently dnsmasq
unsuccessfully tries to bind on the peer address.

A simple reproducer is:

  dnsmasq --conf-file=/dev/null -i dummy1 -d --bind-dynamic &
  sleep 2
  ip link add dummy1 type dummy
  ip link set dummy1 up
  ip addr add dev dummy1 fd01::1/64 peer fd01::2/64
  ip addr add dev dummy1 fd01::42/64
  sleep 2
  ss -lnp | grep dnsmasq | grep fd01

Before the patch:
  dnsmasq: failed to create listening socket for fd01::2: Cannot assign requested address
  dnsmasq: failed to create listening socket for fd01::2: Cannot assign requested address
  udp   UNCONN 0   [fd01::42]:53   [::]:*    users:(("dnsmasq",pid=23947,fd=14))
  tcp   LISTEN 0   [fd01::42]:53   [::]:*    users:(("dnsmasq",pid=23947,fd=15

After:
  udp   UNCONN 0   [fd01::42]:53   [::]:*    users:(("dnsmasq",pid=23973,fd=16))
  udp   UNCONN 0    [fd01::1]:53   [::]:*    users:(("dnsmasq",pid=23973,fd=14))
  tcp   LISTEN 0   [fd01::42]:53   [::]:*    users:(("dnsmasq",pid=23973,fd=17))
  tcp   LISTEN 0    [fd01::1]:53   [::]:*    users:(("dnsmasq",pid=23973,fd=15))
2022-05-27 21:16:18 +01:00
Simon Kelley a267a9e489 Add the ability to specify destination port in DHCP-relay mode.
This change also removes a previous bug
where --dhcp-alternate-port would affect the port used
to relay _to_ as well as the port being listened on.
The new feature allows configuration to provide bug-for-bug
compatibility, if required. Thanks to Damian Kaczkowski
for the feature suggestion.
2022-05-26 16:40:44 +01:00
Simon Kelley f65d210012 Fix outdated comment. 2022-05-26 14:49:10 +01:00
Petr Menšík 858bfcf261 Update GNU GPL file. 2022-05-13 21:22:11 +01:00
Dominik Derigs 9b801c4e72 Also log upstream port for dnssec-retry
Signed-off-by: DL6ER <dl6er@dl6er.de>
2022-04-18 15:28:27 +01:00
袁建鹏 1a98d1a94f Add inode compare while checking resolv file change
Fix a bug found on OpenWrt when IPv4/6 dual stack enabled:

The resolv file is located on tmpfs whose mtime resolution
is 1 second. If the resolv file is updated twice within one
second dnsmasq may can't notice the second update.

netifd updates the resolv file with method: write temp then move,
so adding an inode check fixes this bug.
2022-04-18 15:25:54 +01:00
Simon Kelley 03345ecefe Fix write-after-free error in DHCPv6 code. CVE-2022-0934 refers. 2022-03-31 21:35:20 +01:00
Simon Kelley 191924576c Add DNSMASQ_DATA_MISSING envvar to lease-change script. 2022-03-22 13:47:05 +00:00
Simon Kelley 756a1dcc19 Manpage update for --localise-queries.
Thanks to Leonardo Romor for the suggestion.
2022-03-05 18:13:15 +00:00
Simon Kelley 3ab6dd1c37 Enhance --domain to accept, interface names for the address range.
This allows hosts get a domain which relects the interface they
are attached to in a way which doesn't require hard-coding addresses.

Thanks to Sten Spans for the idea.
2022-03-05 18:07:07 +00:00
Simon Kelley 4458d87289 Merge branch 'master' of ssh://thekelleys.org.uk/var/local/git/dnsmasq 2022-03-05 16:31:17 +00:00
Conrad Kostecki b7f62475d0 Update German translation. 2022-03-02 19:28:26 +00:00
Simon Kelley 4732aa663b Merge branch 'master' of ssh://thekelleys.org.uk/var/local/git/dnsmasq 2022-02-24 23:21:55 +00:00
Simon Kelley c27cfeaa7b Fix memory leak when DBUS connection fails. 2022-02-24 23:18:54 +00:00
Simon Kelley bb6f6bae0b Fix longjump() compiler warnings. 2022-02-24 23:16:04 +00:00
Simon Kelley f4c87b504b Fix missing reverse-records from --dynamic-host.
Thanks to Sten Spans for spotting the bug.
2022-02-18 20:53:56 +00:00
Simon Kelley e426c2d3bc Add --conf-script 2022-02-08 12:10:27 +00:00
Simon Kelley 6279d9eaf3 Merge branch 'master' of ssh://thekelleys.org.uk/var/local/git/dnsmasq 2022-02-04 22:28:53 +00:00
Simon Kelley 12949aa0c0 Ask netlink for new address events unconditionally.
The circumstances under which actions occur depending on
configuration is now controlled only by newaddress() in network.c
2022-02-04 22:24:00 +00:00
Simon Kelley 84f3357dd9 Merge branch 'master' of ssh://thekelleys.org.uk/var/local/git/dnsmasq 2022-02-04 21:00:16 +00:00
Johnny S. Lee via Dnsmasq-discuss 4333d5d93a Fix FTBFS on BSD platforms.
Bug introduced in fc664d114d
2022-02-03 23:42:00 +00:00
Simon Kelley fa580ad3eb Handle changing interface indexes when binding DHCP sockets. 2022-02-03 17:26:28 +00:00
Simon Kelley 292dfa653e Merge branch 'master' of ssh://thekelleys.org.uk/var/local/git/dnsmasq 2022-02-02 18:31:22 +00:00
Simon Kelley bf1fc6c6fd Tidy iface_check(). 2022-01-21 15:47:09 +00:00
Olaf Hering b18e9c8c61 fix dnsmasq typo in man page
Fixes commit 27ce754b3d

Signed-off-by: Olaf Hering <olaf@aepfle.de>
2022-01-21 12:18:08 +00:00
Simon Kelley a3293bb242 Fix indentation in Umbrella option code. 2022-01-21 12:07:42 +00:00
32 changed files with 707 additions and 383 deletions

No files matched your search

+45
View File
@@ -39,6 +39,51 @@ version 2.87
a local NODATA answer. The pre-2.86 behaviour is still available,
by configuring --address=/example.com/1.2.3.4 --local=/example.com/
Fix problem with binding DHCP sockets to an individual interface.
Despite the fact that the system call tales the interface _name_ as
a parameter, it actually, binds the socket to interface _index_.
Deleting the interface and creating a new one with the same name
leaves the socket bound to the old index. (Creating new sockets
always allocates a fresh index, they are not reused). We now
take this behaviour into account and keep up with changing indexes.
Add --conf-script configuration option.
Enhance --domain to accept, for instance,
--domain=net2.thekelleys.org.uk,eth2 so that hosts get a domain
which relects the interface they are attached to in a way which
doesn't require hard-coding addresses. Thanks to Sten Spans for
the idea.
Fix write-after-free error in DHCPv6 server code.
CVE-2022-0934 refers.
Add the ability to specify destination port in
DHCP-relay mode. This change also removes a previous bug
where --dhcp-alternate-port would affect the port used
to relay _to_ as well as the port being listened on.
The new feature allows configuration to provide bug-for-bug
compatibility, if required. Thanks to Damian Kaczkowski
for the feature suggestion.
Bound the value of UDP packet size in the EDNS0 header of
forwarded queries to the configured or default value of
edns-packet-max. There's no point letting a client set a larger
value if we're unable to return the answer. Thanks to Bertie
Taylor for pointing out the problem and supplying the patch.
Fix problem with the configuration
--server=/some.domain/# --address=/#/<ip> --server=<server_ip>
This would return <ip> for queries in some.domain, rather than
forwarding the query via the default server.
Tweak DHCPv6 relay code so that packets relayed towards a server
have source address on the server-facing network, not the
client facing network. Thanks to Luis Thomas for spotting this
and initial patch.
version 2.86
Handle DHCPREBIND requests in the DHCPv6 server code.
+21 -22
View File
@@ -1,12 +1,12 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
@@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
@@ -225,7 +225,7 @@ impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
@@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
@@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
Copyright (C) <year> <name of author>
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
@@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
@@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names:
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
+47 -10
View File
@@ -304,7 +304,8 @@ Return answers to DNS queries from /etc/hosts and \fB--interface-name\fP and \fB
received. If a name has more than one address associated with
it, and at least one of those addresses is on the same subnet as the
interface to which the query was sent, then return only the
address(es) on that subnet. This allows for a server to have multiple
address(es) on that subnet and return all the available addresses otherwise.
This allows for a server to have multiple
addresses in /etc/hosts corresponding to each of its interfaces, and
hosts will get the correct address based on which network they are
attached to. Currently this facility is limited to IPv4.
@@ -777,7 +778,7 @@ will add 1.2.3.0/24 for both IPv4 and IPv6 requestors.
.TP
.B --strip-subnet
Remove any subnet address already present in a downstream query before forwarding it upstream. If --add-subnet is set this also
ensures that any downstream-provided subnet is replaced by the one added by dnsmasq. Otherwise, dnsmaaq will NOT replace an
ensures that any downstream-provided subnet is replaced by the one added by dnsmasq. Otherwise, dnsmasq will NOT replace an
existing subnet in the query.
.TP
.B --umbrella[=[deviceid:<deviceid>][,orgid:<orgid>][,assetid:<id>]]
@@ -1341,7 +1342,7 @@ DHCP options. This make extra space available in the DHCP packet for
options but can, rarely, confuse old or broken clients. This flag
forces "simple and safe" behaviour to avoid problems in such a case.
.TP
.B --dhcp-relay=<local address>[,<server address>][,<interface]
.B --dhcp-relay=<local address>[,<server address>[#<server port>]][,<interface]
Configure dnsmasq to do DHCP relay. The local address is an address
allocated to an interface on the host running dnsmasq. All DHCP
requests arriving on that interface will we relayed to a remote DHCP
@@ -1349,9 +1350,12 @@ 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
configs with the same local address and different server
addresses. A server address must be an IP literal address, not a
domain name. If the server address is ommitted, the request will be
domain name. If the server address is omitted, the request will be
forwarded by broadcast (IPv4) or multicast (IPv6). In this case the interface
must be given and not be wildcard.
must be given and not be wildcard. The server address may specify a non-standard
port to relay to. If this is used then \fB--dhcp-proxy\fP should likely also be set,
otherwise parts of the DHCP conversation which do not pass through the relay
will be delivered to the wrong port.
Access control for DHCP clients has the same rules as for the DHCP
server, see \fB--interface\fP, \fB--except-interface\fP, etc. The optional
@@ -1711,7 +1715,13 @@ If dnsmasq was compiled with HAVE_BROKEN_RTC, then
the length of the lease (in seconds) is stored in
DNSMASQ_LEASE_LENGTH, otherwise the time of lease expiry is stored in
DNSMASQ_LEASE_EXPIRES. The number of seconds until lease expiry is
always stored in DNSMASQ_TIME_REMAINING.
always stored in DNSMASQ_TIME_REMAINING.
DNSMASQ_DATA_MISSING is set to "1" during "old" events for existing
leases generated at startup to indicate that data not stored in the
persistent lease database will not be present. This comprises everything
other than IP address, hostname, MAC address, DUID, IAID and lease length
or expiry time.
If a lease used to have a hostname, which is
removed, an "old" event is generated with the new state of the lease,
@@ -1733,6 +1743,11 @@ DNSMASQ_LOG_DHCP is set if
.B --log-dhcp
is in effect.
DNSMASQ_REQUESTED_OPTIONS a string containing the decimal values in the Parameter Request List option, comma separated, if the parameter request list option is provided by the client.
DNSMASQ_MUD_URL the Manufacturer Usage Description URL if provided by the client. (See RFC8520 for details.)
For IPv4 only:
DNSMASQ_CLIENT_ID if the host provided a client-id.
@@ -1742,8 +1757,6 @@ DHCP relay-agent added any of these options.
If the client provides vendor-class, DNSMASQ_VENDOR_CLASS.
DNSMASQ_REQUESTED_OPTIONS a string containing the decimal values in the Parameter Request List option, comma separated, if the parameter request list option is provided by the client.
For IPv6 only:
If the client provides vendor-class, DNSMASQ_VENDOR_CLASS_ID,
@@ -1935,7 +1948,7 @@ is the address of the relay and the second, as before, specifies an extra subnet
addresses may be allocated from.
.TP
.B \-s, --domain=<domain>[,<address range>[,local]]
.B \-s, --domain=<domain>[[,<address range>[,local]]|<interface>]
Specifies DNS domains for the DHCP server. Domains may be be given
unconditionally (without the IP range) or for limited IP ranges. This has two effects;
firstly it causes the DHCP server to return the domain to any hosts
@@ -1969,6 +1982,11 @@ additional flag "local" may be supplied which has the effect of adding
is identical to
.B --domain=thekelleys.org.uk,192.168.0.0/24
.B --local=/thekelleys.org.uk/ --local=/0.168.192.in-addr.arpa/
The address range can also be given as a network interface name, in which case
all of the subnets currently assigned to the interface are used in matching the
address. This allows hosts on different physical subnets to be given different
domains in a way which updates automatically as the interface addresses change.
.TP
.B --dhcp-fqdn
In the default mode, dnsmasq inserts the unqualified names of
@@ -2141,6 +2159,23 @@ A special case of
which differs in two respects. Firstly, only \fB--server\fP and \fB--rev-server\fP are allowed
in the configuration file included. Secondly, the file is re-read and the configuration
therein is updated when dnsmasq receives SIGHUP.
.TP
.B \--conf-script=<file>[ <arg]
Execute <file>, and treat what it emits to stdout as the contents of a configuration file.
If the script exits with a non-zero exit code, dnsmasq treats this as a fatal error.
The script can be passed arguments, space seperated from the filename and each other so, for instance
.B --conf-dir="/etc/dnsmasq-uncompress-ads /share/ads-domains.gz"
with /etc/dnsmasq-uncompress-ads containing
set -e
zcat ${1} | sed -e "s:^:address=/:" -e "s:$:/:"
exit 0
and /share/ads-domains.gz containing a compressed
list of ad server domains will save disk space with large ad-server blocklists.
.SH CONFIG FILE
At startup, dnsmasq reads
.I /etc/dnsmasq.conf,
@@ -2537,7 +2572,9 @@ file/directory, permissions).
5 - Other miscellaneous problem.
.PP
11 or greater - a non zero return code was received from the
lease-script process "init" call. The exit code from dnsmasq is the
lease-script process "init" call or a
.B \--conf-script
file. The exit code from dnsmasq is the
script's exit code with 10 added.
.SH LIMITS
+52 -58
View File
@@ -2,7 +2,7 @@
#
# This revised version is (C) Copyright by
# Matthias Andree <matthias.andree@gmx.de>, 2010 - 2021.
# Conrad Kostecki <ck@conrad-kostecki.de>, 2014 - 2020.
# Conrad Kostecki <conrad@kostecki.com>, 2014 - 2022.
# It is subject to the GNU General Public License v2,
# or at your option, any later version.
#
@@ -10,17 +10,18 @@
# Simon Kelley <simon@thekelleys.org.uk>, 2005.
msgid ""
msgstr ""
"Project-Id-Version: dnsmasq 2.85rc2\n"
"Project-Id-Version: dnsmasq 2.87test8\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-03-20 00:00+0000\n"
"PO-Revision-Date: 2021-03-27 15:30+0100\n"
"Last-Translator: Matthias Andree <matthias.andree@gmx.de>\n"
"PO-Revision-Date: 2022-02-28 14:49+0100\n"
"Last-Translator: Conrad Kostecki <conrad@kostecki.com>\n"
"Language-Team: German <de@li.org>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 3.0.1\n"
#: cache.c:572
msgid "Internal error in cache."
@@ -243,7 +244,7 @@ msgstr "RFC3993 \"subscriber-id\" auf Marke abbilden."
#: option.c:400
msgid "Specify vendor class to match for PXE requests."
msgstr "Herstellerklasse für Vergleich von PXE-Anforderungen angeben"
msgstr "Herstellerklasse für Vergleich von PXE-Anforderungen angeben."
#: option.c:401
msgid "Don't do DHCP for hosts with tag set."
@@ -726,11 +727,11 @@ msgstr "Spezifiziere IPSets, zu denen passende Domains hinzugefügt werden solle
#: option.c:517
msgid "Enable filtering of DNS queries with connection-track marks."
msgstr ""
msgstr "Aktivieren Sie das Filtern von DNS-Abfragen mit \"connection-track\"-Markierungen."
#: option.c:518
msgid "Set allowed DNS patterns for a connection-track mark."
msgstr ""
msgstr "Legen Sie zulässige DNS-Muster für eine \"connection-track\"-Markierung fest."
#: option.c:519
msgid "Specify a domain and address range for synthesised names"
@@ -819,12 +820,11 @@ msgstr "Rufe dhcp-script auf, wenn der Ablauf des Leases sich ändert."
#: option.c:540
msgid "Send Cisco Umbrella identifiers including remote IP."
msgstr ""
msgstr "Senden Sie Cisco Umbrella-Identifikatoren einschließlich der Remote-IP."
#: option.c:541
#, fuzzy
msgid "Do not log routine TFTP."
msgstr "Protokolliere kein Routine-DHCP."
msgstr "Protokolliere kein Routine-TFTP."
#: option.c:771
#, c-format
@@ -867,11 +867,11 @@ msgstr "Fehlerhafter Schnittestellenname"
#: option.c:1192
msgid "inappropriate vendor:"
msgstr ""
msgstr "Ungeeigneter Anbieter:"
#: option.c:1199
msgid "inappropriate encap:"
msgstr ""
msgstr "Ungeeignete Kapselung:"
#: option.c:1225
msgid "unsupported encapsulation for IPv6 option"
@@ -952,28 +952,24 @@ msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
msgstr "Neuübersetzung mit HAVE_LUASCRIPT nötig, um benutzerdefinierte Lua-Skripte auszuführen"
#: option.c:2291 option.c:2327
#, fuzzy
msgid "bad prefix length"
msgstr "fehlerhaftes Präfix"
msgstr "fehlerhafte Präfixlänge"
#: option.c:2303 option.c:2348 option.c:2398
msgid "bad prefix"
msgstr "fehlerhaftes Präfix"
#: option.c:2418
#, fuzzy
msgid "prefix length too small"
msgstr "Die Präfixlänge muss mindestens 64 sein"
msgstr "Präfixlänge ist zu klein"
#: option.c:2697
#, fuzzy
msgid "Bad address in --address"
msgstr "Adresse in Gebrauch"
msgstr "Fehlerhafte Adresse in --address"
#: option.c:2751
#, fuzzy
msgid "bad IPv4 prefix"
msgstr "fehlerhaftes IPv6-Präfix"
msgstr "fehlerhaftes IPv4-Präfix"
#: option.c:2756 option.c:3569
msgid "bad IPv6 prefix"
@@ -984,9 +980,8 @@ msgid "recompile with HAVE_IPSET defined to enable ipset directives"
msgstr "Neuübersetzung mit HAVE_IPSET nötig, um IPSet-Direktiven zu aktivieren"
#: option.c:2843 option.c:2861
#, fuzzy
msgid "recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"
msgstr "Neuübersetzung mit HAVE_IPSET nötig, um IPSet-Direktiven zu aktivieren"
msgstr "Neukompilierung mit HAVE_CONNTRACK notwendig, um connmark-allowlist-Direktiven zu aktivieren"
#: option.c:3119
msgid "bad port range"
@@ -1131,7 +1126,7 @@ msgstr "unzulässige Wichtung"
#: option.c:4661
msgid "Bad host-record"
msgstr "fehlerhafter \"host-record\""
msgstr "Fehlerhafter \"host-record\""
#: option.c:4700
msgid "Bad name in host-record"
@@ -1314,9 +1309,9 @@ msgid "Maximum number of concurrent DNS queries reached (max: %d)"
msgstr "Höchstzahl an nebenläufiger DNS-Anfragen erreicht (max. %d)"
#: forward.c:2496
#, fuzzy, c-format
#, c-format
msgid "Maximum number of concurrent DNS queries to %s reached (max: %d)"
msgstr "Höchstzahl an nebenläufiger DNS-Anfragen erreicht (max. %d)"
msgstr "Maximale Anzahl gleichzeitiger DNS-Abfragen, die erreicht %s (max. %d)"
#: network.c:670
#, c-format
@@ -1403,9 +1398,9 @@ msgid "domain"
msgstr "Domäne"
#: network.c:1607
#, fuzzy, c-format
#, c-format
msgid "using nameserver %s#%d for %s %s%s %s"
msgstr "Benutze Namensserver %s#%d für %s %s %s"
msgstr "benutze Namensserver %s#%d für %s %s %s %s"
#: network.c:1611
#, c-format
@@ -1423,14 +1418,14 @@ msgid "using nameserver %s#%d"
msgstr "Benutze Namensserver %s#%d"
#: network.c:1630
#, fuzzy, c-format
#, c-format
msgid "using only locally-known addresses for %s"
msgstr "Benutze nur lokal-bekannte Adressen für %s %s"
msgstr "benutze nur lokal-bekannte Adressen für %s"
#: network.c:1633
#, fuzzy, c-format
#, c-format
msgid "using standard nameservers for %s"
msgstr "Benutze standard Namensserver für %s %s"
msgstr "benutze standard Namensserver für %s"
#: network.c:1637
#, c-format
@@ -1534,9 +1529,9 @@ msgid "DBus not available: set HAVE_DBUS in src/config.h"
msgstr "DBus nicht verfügbar: setzen Sie HAVE_DBUS in src/config.h"
#: dnsmasq.c:456 dnsmasq.c:1228
#, fuzzy, c-format
#, c-format
msgid "UBus error: %s"
msgstr "DBus-Fehler: %s"
msgstr "UBus-Fehler: %s"
#: dnsmasq.c:459
msgid "UBus not available: set HAVE_UBUS in src/config.h"
@@ -1696,9 +1691,8 @@ msgid "connected to system DBus"
msgstr "Mit System-DBus verbunden"
#: dnsmasq.c:1225
#, fuzzy
msgid "connected to system UBus"
msgstr "Mit System-UBus verbunden"
msgstr "mit System-UBus verbunden"
#: dnsmasq.c:1391
#, c-format
@@ -2151,7 +2145,7 @@ msgstr "Datei %s nicht gefunden für %s"
#: tftp.c:602
#, c-format
msgid "ignoring packet from %s (TID mismatch)"
msgstr ""
msgstr "Paket von %s wird ignoriert (TID-Nichtübereinstimmung)"
#: tftp.c:646
#, c-format
@@ -2378,95 +2372,95 @@ msgstr "Aktualisierung von ipset %s fehlgeschlagen: %s"
#: pattern.c:29
#, c-format
msgid "[pattern.c:%d] Assertion failure: %s"
msgstr ""
msgstr "[pattern.c:%d] Assertion failure: %s"
#: pattern.c:142
#, c-format
msgid "Invalid DNS name: Invalid character %c."
msgstr ""
msgstr "Ungültiger DNS-Name: Ungültiges Zeichen %c."
#: pattern.c:151
msgid "Invalid DNS name: Empty label."
msgstr ""
msgstr "Ungültiger DNS-Name: Leeres Label."
#: pattern.c:156
msgid "Invalid DNS name: Label starts with hyphen."
msgstr ""
msgstr "Ungültiger DNS-Name: Label beginnt mit Bindestrich."
#: pattern.c:170
msgid "Invalid DNS name: Label ends with hyphen."
msgstr ""
msgstr "Ungültiger DNS-Name: Bezeichnung endet mit Bindestrich."
#: pattern.c:176
#, c-format
msgid "Invalid DNS name: Label is too long (%zu)."
msgstr ""
msgstr "Ungültiger DNS-Name: Label ist zu lang (%zu)."
#: pattern.c:184
#, c-format
msgid "Invalid DNS name: Not enough labels (%zu)."
msgstr ""
msgstr "Ungültiger DNS-Name: Nicht genügend Labels (%zu)."
#: pattern.c:189
msgid "Invalid DNS name: Final label is fully numeric."
msgstr ""
msgstr "Ungültiger DNS-Name: Das endgültige Label ist vollständig numerisch."
#: pattern.c:199
msgid "Invalid DNS name: \"local\" pseudo-TLD."
msgstr ""
msgstr "Ungültiger DNS-Name: \"lokale\" Pseudo-TLD."
#: pattern.c:204
#, c-format
msgid "DNS name has invalid length (%zu)."
msgstr ""
msgstr "Der DNS-Name hat eine ungültige Länge (%zu)."
#: pattern.c:258
#, c-format
msgid "Invalid DNS name pattern: Invalid character %c."
msgstr ""
msgstr "Ungültiges DNS-Namensmuster: Ungültiges Zeichen %c."
#: pattern.c:267
msgid "Invalid DNS name pattern: Empty label."
msgstr ""
msgstr "Ungültiges DNS-Namensmuster: Leeres Label."
#: pattern.c:272
msgid "Invalid DNS name pattern: Label starts with hyphen."
msgstr ""
msgstr "Ungültiges DNS-Namensmuster: Bezeichnung beginnt mit Bindestrich."
#: pattern.c:285
msgid "Invalid DNS name pattern: Wildcard character used more than twice per label."
msgstr ""
msgstr "Ungültiges DNS-Namensmuster: Platzhalterzeichen werden mehr als zweimal pro Label verwendet."
#: pattern.c:295
msgid "Invalid DNS name pattern: Label ends with hyphen."
msgstr ""
msgstr "Ungültiges DNS-Namensmuster: Bezeichnung endet mit Bindestrich."
#: pattern.c:301
#, c-format
msgid "Invalid DNS name pattern: Label is too long (%zu)."
msgstr ""
msgstr "Ungültiges DNS-Namensmuster: Label ist zu lang (%zu)."
#: pattern.c:309
#, c-format
msgid "Invalid DNS name pattern: Not enough labels (%zu)."
msgstr ""
msgstr "Ungültiges DNS-Namensmuster: Nicht genügend Labels (%zu)."
#: pattern.c:314
msgid "Invalid DNS name pattern: Wildcard within final two labels."
msgstr ""
msgstr "Ungültiges DNS-Namensmuster: Platzhalter innerhalb der letzten beiden Labels."
#: pattern.c:319
msgid "Invalid DNS name pattern: Final label is fully numeric."
msgstr ""
msgstr "Ungültiges DNS-Namensmuster: Das endgültige Label ist vollständig numerisch."
#: pattern.c:329
msgid "Invalid DNS name pattern: \"local\" pseudo-TLD."
msgstr ""
msgstr "Ungültiges DNS-Namensmuster: \"lokale\" Pseudo-TLD."
#: pattern.c:334
#, c-format
msgid "DNS name pattern has invalid length after removing wildcards (%zu)."
msgstr ""
msgstr "Das DNS-Namensmuster hat nach dem Entfernen von Platzhaltern (%zu) eine ungültige Länge."
#: dnssec.c:206
msgid "system time considered valid, now checking DNSSEC signature timestamps."
@@ -2600,7 +2594,7 @@ msgstr "Von System-UBus trennen"
#: ubus.c:179 ubus.c:326
#, c-format
msgid "UBus command failed: %d (%s)"
msgstr ""
msgstr "UBus-Befehl fehlgeschlagen: %d (%s)"
#: hash-questions.c:40
msgid "Failed to create SHA-256 hash object"
+1 -3
View File
@@ -1676,10 +1676,8 @@ int cache_make_stat(struct txt_record *t)
{
/* expand buffer if necessary */
newlen = bytes_needed + 1 + bufflen - bytes_avail;
if (!(new = whine_malloc(newlen)))
if (!(new = whine_realloc(buff, newlen)))
return 0;
memcpy(new, buff, bufflen);
free(buff);
p = new + (p - buff);
lenp = p - 1;
buff = new;
+5 -2
View File
@@ -761,8 +761,11 @@ char *dbus_init(void)
dbus_error_init (&dbus_error);
if (!(connection = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_error)))
return NULL;
{
dbus_error_free(&dbus_error);
return NULL;
}
dbus_connection_set_exit_on_disconnect(connection, FALSE);
dbus_connection_set_watch_functions(connection, add_watch, remove_watch,
NULL, NULL, NULL);
+44 -6
View File
@@ -566,12 +566,16 @@ char *whichdevice(void)
}
if (found)
return found->name;
{
char *ret = safe_malloc(strlen(found->name)+1);
strcpy(ret, found->name);
return ret;
}
return NULL;
}
void bindtodevice(char *device, int fd)
static int bindtodevice(char *device, int fd)
{
size_t len = strlen(device)+1;
if (len > IFNAMSIZ)
@@ -579,7 +583,33 @@ void bindtodevice(char *device, int fd)
/* only allowed by root. */
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, device, len) == -1 &&
errno != EPERM)
die(_("failed to set SO_BINDTODEVICE on DHCP socket: %s"), NULL, EC_BADNET);
return 2;
return 1;
}
int bind_dhcp_devices(char *bound_device)
{
int ret = 0;
if (bound_device)
{
if (daemon->dhcp)
{
if (!daemon->relay4)
ret |= bindtodevice(bound_device, daemon->dhcpfd);
if (daemon->enable_pxe && daemon->pxefd != -1)
ret |= bindtodevice(bound_device, daemon->pxefd);
}
#if defined(HAVE_DHCP6)
if (daemon->doing_dhcp6 && !daemon->relay6)
ret |= bindtodevice(bound_device, daemon->dhcp6fd);
#endif
}
return ret;
}
#endif
@@ -655,6 +685,7 @@ static const struct opttab_t {
{ "client-machine-id", 97, 0 },
{ "posix-timezone", 100, OT_NAME }, /* RFC 4833, Sec. 2 */
{ "tzdb-timezone", 101, OT_NAME }, /* RFC 4833, Sec. 2 */
{ "ipv6-only", 108, 4 | OT_DEC }, /* RFC 8925 */
{ "subnet-select", 118, OT_INTERNAL },
{ "domain-search", 119, OT_RFC1035_NAME },
{ "sip-server", 120, 0 },
@@ -987,7 +1018,10 @@ void log_relay(int family, struct dhcp_relay *relay)
{
int broadcast = relay->server.addr4.s_addr == 0;
inet_ntop(family, &relay->local, daemon->addrbuff, ADDRSTRLEN);
inet_ntop(family, &relay->server, daemon->namebuff, ADDRSTRLEN);
inet_ntop(family, &relay->server, daemon->namebuff, ADDRSTRLEN);
if (family == AF_INET && relay->port != DHCP_SERVER_PORT)
sprintf(daemon->namebuff + strlen(daemon->namebuff), "#%u", relay->port);
#ifdef HAVE_DHCP6
struct in6_addr multicast;
@@ -995,7 +1029,11 @@ void log_relay(int family, struct dhcp_relay *relay)
inet_pton(AF_INET6, ALL_SERVERS, &multicast);
if (family == AF_INET6)
broadcast = IN6_ARE_ADDR_EQUAL(&relay->server.addr6, &multicast);
{
broadcast = IN6_ARE_ADDR_EQUAL(&relay->server.addr6, &multicast);
if (relay->port != DHCPV6_SERVER_PORT)
sprintf(daemon->namebuff + strlen(daemon->namebuff), "#%u", relay->port);
}
#endif
+1
View File
@@ -64,6 +64,7 @@
#define OPTION_SIP_SERVER 120
#define OPTION_VENDOR_IDENT 124
#define OPTION_VENDOR_IDENT_OPT 125
#define OPTION_MUD_URL_V4 161
#define OPTION_END 255
#define SUBOPT_CIRCUIT_ID 1
+13 -11
View File
@@ -177,8 +177,7 @@ void dhcp_packet(time_t now, int pxe_fd)
return;
#ifdef HAVE_DUMPFILE
dump_packet(DUMP_DHCP, (void *)daemon->dhcp_packet.iov_base, sz, (union mysockaddr *)&dest, NULL,
pxe_fd ? PXE_PORT : daemon->dhcp_server_port);
dump_packet_udp(DUMP_DHCP, (void *)daemon->dhcp_packet.iov_base, sz, (union mysockaddr *)&dest, NULL, fd);
#endif
#if defined (HAVE_LINUX_NETWORK)
@@ -458,11 +457,14 @@ void dhcp_packet(time_t now, int pxe_fd)
else
{
#ifdef HAVE_DUMPFILE
dest.sin_addr.s_addr = (ntohs(mess->flags) & 0x8000) ? INADDR_BROADCAST : mess->yiaddr;
if (ntohs(mess->flags) & 0x8000)
dest.sin_addr.s_addr = INADDR_BROADCAST;
else
dest.sin_addr = mess->yiaddr;
dest.sin_port = htons(daemon->dhcp_client_port);
dump_packet(DUMP_DHCP, (void *)iov.iov_base, iov.iov_len, NULL,
(union mysockaddr *)&dest, daemon->dhcp_server_port);
dump_packet_udp(DUMP_DHCP, (void *)iov.iov_base, iov.iov_len, NULL,
(union mysockaddr *)&dest, fd);
#endif
send_via_bpf(mess, iov.iov_len, iface_addr, &ifr);
@@ -475,8 +477,8 @@ void dhcp_packet(time_t now, int pxe_fd)
#endif
#ifdef HAVE_DUMPFILE
dump_packet(DUMP_DHCP, (void *)iov.iov_base, iov.iov_len, NULL,
(union mysockaddr *)&dest, daemon->dhcp_server_port);
dump_packet_udp(DUMP_DHCP, (void *)iov.iov_base, iov.iov_len, NULL,
(union mysockaddr *)&dest, fd);
#endif
while(retry_send(sendmsg(fd, &msg, 0)));
@@ -1118,7 +1120,7 @@ static int relay_upstream4(int iface_index, struct dhcp_packet *mess, size_t sz)
to.sa.sa_family = AF_INET;
to.in.sin_addr = relay->server.addr4;
to.in.sin_port = htons(daemon->dhcp_server_port);
to.in.sin_port = htons(relay->port);
/* Broadcasting to server. */
if (relay->server.addr4.s_addr == 0)
@@ -1144,8 +1146,8 @@ static int relay_upstream4(int iface_index, struct dhcp_packet *mess, size_t sz)
fromsock.in.sin_port = htons(daemon->dhcp_server_port);
fromsock.in.sin_addr = from.addr4;
fromsock.sa.sa_family = AF_INET;
dump_packet(DUMP_DHCP, (void *)mess, sz, &fromsock, &to, 0);
dump_packet_udp(DUMP_DHCP, (void *)mess, sz, &fromsock, &to, -1);
}
#endif
+1
View File
@@ -63,6 +63,7 @@
#define OPTION6_FQDN 39
#define OPTION6_NTP_SERVER 56
#define OPTION6_CLIENT_MAC 79
#define OPTION6_MUD_URL 112
#define NTP_SUBOPTION_SRV_ADDR 1
#define NTP_SUBOPTION_MC_ADDR 2
+6 -6
View File
@@ -119,8 +119,8 @@ void dhcp6_packet(time_t now)
return;
#ifdef HAVE_DUMPFILE
dump_packet(DUMP_DHCPV6, (void *)daemon->dhcp_packet.iov_base, sz,
(union mysockaddr *)&from, NULL, DHCPV6_SERVER_PORT);
dump_packet_udp(DUMP_DHCPV6, (void *)daemon->dhcp_packet.iov_base, sz,
(union mysockaddr *)&from, NULL, daemon->dhcp6fd);
#endif
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
@@ -142,8 +142,8 @@ void dhcp6_packet(time_t now)
if (relay_reply6(&from, sz, ifr.ifr_name))
{
#ifdef HAVE_DUMPFILE
dump_packet(DUMP_DHCPV6, (void *)daemon->outpacket.iov_base, save_counter(-1), NULL,
(union mysockaddr *)&from, DHCPV6_SERVER_PORT);
dump_packet_udp(DUMP_DHCPV6, (void *)daemon->outpacket.iov_base, save_counter(-1), NULL,
(union mysockaddr *)&from, daemon->dhcp6fd);
#endif
while (retry_send(sendto(daemon->dhcp6fd, daemon->outpacket.iov_base,
@@ -254,8 +254,8 @@ void dhcp6_packet(time_t now)
from.sin6_port = htons(port);
#ifdef HAVE_DUMPFILE
dump_packet(DUMP_DHCPV6, (void *)daemon->outpacket.iov_base, save_counter(-1),
NULL, (union mysockaddr *)&from, DHCPV6_SERVER_PORT);
dump_packet_udp(DUMP_DHCPV6, (void *)daemon->outpacket.iov_base, save_counter(-1),
NULL, (union mysockaddr *)&from, daemon->dhcp6fd);
#endif
while (retry_send(sendto(daemon->dhcp6fd, daemon->outpacket.iov_base,
+15 -22
View File
@@ -387,28 +387,9 @@ int main (int argc, char **argv)
#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP)
/* after enumerate_interfaces() */
bound_device = whichdevice();
if (daemon->dhcp)
{
if (!daemon->relay4 && bound_device)
{
bindtodevice(bound_device, daemon->dhcpfd);
did_bind = 1;
}
if (daemon->enable_pxe && bound_device && daemon->pxefd != -1)
{
bindtodevice(bound_device, daemon->pxefd);
did_bind = 1;
}
}
#endif
#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP6)
if (daemon->doing_dhcp6 && !daemon->relay6 && bound_device)
{
bindtodevice(bound_device, daemon->dhcp6fd);
did_bind = 1;
}
if ((did_bind = bind_dhcp_devices(bound_device)) & 2)
die(_("failed to set SO_BINDTODEVICE on DHCP socket: %s"), NULL, EC_BADNET);
#endif
}
else
@@ -1100,6 +1081,17 @@ int main (int argc, char **argv)
#endif
#ifdef HAVE_DHCP
# if defined(HAVE_LINUX_NETWORK)
if (bind_dhcp_devices(bound_device) & 2)
{
static int warned = 0;
if (!warned)
{
my_syslog(LOG_ERR, _("error binding DHCP socket to device %s"), bound_device);
warned = 1;
}
}
# endif
if (daemon->dhcp || daemon->relay4)
{
poll_listen(daemon->dhcpfd, POLLIN);
@@ -1673,9 +1665,10 @@ static void poll_resolv(int force, int do_reload, time_t now)
else
{
res->logged = 0;
if (force || (statbuf.st_mtime != res->mtime))
if (force || (statbuf.st_mtime != res->mtime || statbuf.st_ino != res->ino))
{
res->mtime = statbuf.st_mtime;
res->ino = statbuf.st_ino;
if (difftime(statbuf.st_mtime, last_change) > 0.0)
{
last_change = statbuf.st_mtime;
+10 -3
View File
@@ -665,6 +665,7 @@ struct resolvc {
struct resolvc *next;
int is_default, logged;
time_t mtime;
ino_t ino;
char *name;
#ifdef HAVE_INOTIFY
int wd; /* inotify watch descriptor */
@@ -975,6 +976,8 @@ struct dhcp_bridge {
struct cond_domain {
char *domain, *prefix; /* prefix is text-prefix on domain name */
char *interface; /* These two set when domain comes from interface. */
struct addrlist *al;
struct in_addr start, end;
struct in6_addr start6, end6;
int is6, indexed, prefixlen;
@@ -1082,6 +1085,7 @@ struct dhcp_relay {
union all_addr local, server;
char *interface; /* Allowable interface for replies from server, and dest for IPv6 multicast */
int iface_index; /* working - interface in which requests arrived, for return */
int port; /* Port of relay we forward to. */
#ifdef HAVE_SCRIPT
struct snoop_record {
struct in6_addr client, prefix;
@@ -1392,6 +1396,7 @@ void *safe_malloc(size_t size);
void safe_strncpy(char *dest, const char *src, size_t size);
void safe_pipe(int *fd, int read_noblock);
void *whine_malloc(size_t size);
void *whine_realloc(void *ptr, size_t size);
int sa_len(union mysockaddr *addr);
int sockaddr_isequal(const union mysockaddr *s1, const union mysockaddr *s2);
int hostname_order(const char *a, const char *b);
@@ -1715,7 +1720,7 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type);
#ifdef HAVE_LINUX_NETWORK
char *whichdevice(void);
void bindtodevice(char *device, int fd);
int bind_dhcp_devices(char *bound_device);
#endif
# ifdef HAVE_DHCP6
void display_opts6(void);
@@ -1798,8 +1803,10 @@ int do_arp_script_run(void);
/* dump.c */
#ifdef HAVE_DUMPFILE
void dump_init(void);
void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src,
union mysockaddr *dst, int port);
void dump_packet_udp(int mask, void *packet, size_t len, union mysockaddr *src,
union mysockaddr *dst, int fd);
void dump_packet_icmp(int mask, void *packet, size_t len, union mysockaddr *src,
union mysockaddr *dst);
#endif
/* domain-match.c */
+1 -1
View File
@@ -1851,7 +1851,7 @@ static int zone_status(char *name, int class, char *keyname, time_t now)
STAT_NEED_DS need DS to complete validation (name is returned in keyname)
daemon->rr_status points to a char array which corressponds to the RRs in the
answer and auth sections. This is set to 1 for each RR which is validated, and 0 for any which aren't.
answer and auth sections. This is set to >1 for each RR which is validated, and 0 for any which aren't.
When validating replies to DS records, we're only interested in the NSEC{3} RRs in the auth section.
Other RRs in that section missing sigs will not cause am INSECURE reply. We determine this mode
+9 -5
View File
@@ -213,9 +213,13 @@ int lookup_domain(char *domain, int flags, int *lowout, int *highout)
to continue generalising */
{
/* We've matched a setting which says to use servers without a domain.
Continue the search with empty query */
Continue the search with empty query. We set the F_SERVER flag
so that --address=/#/... doesn't match. */
if (daemon->serverarray[nlow]->flags & SERV_USE_RESOLV)
crop_query = qlen;
{
crop_query = qlen;
flags |= F_SERVER;
}
else
break;
}
@@ -299,7 +303,7 @@ int filter_servers(int seed, int flags, int *lowout, int *highout)
for (i = nlow; i < nhigh && (daemon->serverarray[i]->flags & SERV_6ADDR); i++);
if (i != nlow && (flags & F_IPV6))
if (!(flags & F_SERVER) && i != nlow && (flags & F_IPV6))
nhigh = i;
else
{
@@ -307,7 +311,7 @@ int filter_servers(int seed, int flags, int *lowout, int *highout)
for (i = nlow; i < nhigh && (daemon->serverarray[i]->flags & SERV_4ADDR); i++);
if (i != nlow && (flags & F_IPV4))
if (!(flags & F_SERVER) && i != nlow && (flags & F_IPV4))
nhigh = i;
else
{
@@ -315,7 +319,7 @@ int filter_servers(int seed, int flags, int *lowout, int *highout)
for (i = nlow; i < nhigh && (daemon->serverarray[i]->flags & SERV_ALL_ZEROS); i++);
if (i != nlow && (flags & (F_IPV4 | F_IPV6)))
if (!(flags & F_SERVER) && i != nlow && (flags & (F_IPV4 | F_IPV6)))
nhigh = i;
else
{
+24 -7
View File
@@ -230,9 +230,17 @@ int is_rev_synth(int flag, union all_addr *addr, char *name)
static int match_domain(struct in_addr addr, struct cond_domain *c)
{
if (!c->is6 &&
ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
if (c->interface)
{
struct addrlist *al;
for (al = c->al; al; al = al->next)
if (!(al->flags & ADDRLIST_IPV6) &&
is_same_net_prefix(addr, al->addr.addr4, al->prefixlen))
return 1;
}
else if (!c->is6 &&
ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
return 1;
return 0;
@@ -259,12 +267,21 @@ char *get_domain(struct in_addr addr)
static int match_domain6(struct in6_addr *addr, struct cond_domain *c)
{
u64 addrpart = addr6part(addr);
if (c->is6)
/* subnet from interface address. */
if (c->interface)
{
struct addrlist *al;
for (al = c->al; al; al = al->next)
if (al->flags & ADDRLIST_IPV6 &&
is_same_net6(addr, &al->addr.addr6, al->prefixlen))
return 1;
}
else if (c->is6)
{
if (c->prefixlen >= 64)
{
u64 addrpart = addr6part(addr);
if (is_same_net6(addr, &c->start6, 64) &&
addrpart >= addr6part(&c->start6) &&
addrpart <= addr6part(&c->end6))
@@ -273,7 +290,7 @@ static int match_domain6(struct in6_addr *addr, struct cond_domain *c)
else if (is_same_net6(addr, &c->start6, c->prefixlen))
return 1;
}
return 0;
}
+80 -45
View File
@@ -21,6 +21,8 @@
#include <netinet/icmp6.h>
static u32 packet_count;
static void do_dump_packet(int mask, void *packet, size_t len,
union mysockaddr *src, union mysockaddr *dst, int port, int proto);
/* https://wiki.wireshark.org/Development/LibpcapFileFormat */
struct pcap_hdr_s {
@@ -81,9 +83,45 @@ void dump_init(void)
}
}
/* port == -1 ->ICMPv6 */
void dump_packet(int mask, void *packet, size_t len,
union mysockaddr *src, union mysockaddr *dst, int port)
void dump_packet_udp(int mask, void *packet, size_t len,
union mysockaddr *src, union mysockaddr *dst, int fd)
{
union mysockaddr fd_addr;
socklen_t addr_len = sizeof(fd_addr);
if (daemon->dumpfd != -1 && (mask & daemon->dump_mask))
{
/* if fd is negative it carries a port number (negated)
which we use as a source or destination when not otherwise
specified so wireshark can ID the packet.
If both src and dst are specified, set this to -1 to avoid
a spurious getsockname() call. */
int port = (fd < 0) ? -fd : -1;
/* fd >= 0 is a file descriptor and the address of that file descriptor is used
in place of a NULL src or dst. */
if (fd >= 0 && getsockname(fd, (struct sockaddr *)&fd_addr, &addr_len) != -1)
{
if (!src)
src = &fd_addr;
if (!dst)
dst = &fd_addr;
}
do_dump_packet(mask, packet, len, src, dst, port, IPPROTO_UDP);
}
}
void dump_packet_icmp(int mask, void *packet, size_t len,
union mysockaddr *src, union mysockaddr *dst)
{
if (daemon->dumpfd != -1 && (mask & daemon->dump_mask))
do_dump_packet(mask, packet, len, src, dst, -1, IPPROTO_ICMP);
}
static void do_dump_packet(int mask, void *packet, size_t len,
union mysockaddr *src, union mysockaddr *dst, int port, int proto)
{
struct ip ip;
struct ip6_hdr ip6;
@@ -100,13 +138,14 @@ void dump_packet(int mask, void *packet, size_t len,
void *iphdr;
size_t ipsz;
int rc;
/* if port != -1 it carries a port number
which we use as a source or destination when not otherwise
specified so wireshark can ID the packet.
If both src and dst are specified, set this to -1 to avoid
a spurious getsockname() call. */
udp.uh_sport = udp.uh_dport = htons(port < 0 ? 0 : port);
if (daemon->dumpfd == -1 || !(mask & daemon->dump_mask))
return;
/* So wireshark can Id the packet. */
udp.uh_sport = udp.uh_dport = htons(port);
if (src)
family = src->sa.sa_family;
else
@@ -121,15 +160,12 @@ void dump_packet(int mask, void *packet, size_t len,
ip6.ip6_vfc = 6 << 4;
ip6.ip6_hops = 64;
if (port == -1)
{
ip6.ip6_plen = htons(len);
ip6.ip6_nxt = IPPROTO_ICMPV6;
}
if ((ip6.ip6_nxt = proto) == IPPROTO_UDP)
ip6.ip6_plen = htons(sizeof(struct udphdr) + len);
else
{
ip6.ip6_plen = htons(sizeof(struct udphdr) + len);
ip6.ip6_nxt = IPPROTO_UDP;
proto = ip6.ip6_nxt = IPPROTO_ICMPV6;
ip6.ip6_plen = htons(len);
}
if (src)
@@ -161,15 +197,12 @@ void dump_packet(int mask, void *packet, size_t len,
ip.ip_hl = sizeof(struct ip) / 4;
ip.ip_ttl = IPDEFTTL;
if (port == -1)
{
ip.ip_len = htons(sizeof(struct ip) + len);
ip.ip_p = IPPROTO_ICMP;
}
if ((ip.ip_p = proto) == IPPROTO_UDP)
ip.ip_len = htons(sizeof(struct ip) + sizeof(struct udphdr) + len);
else
{
ip.ip_len = htons(sizeof(struct ip) + sizeof(struct udphdr) + len);
ip.ip_p = IPPROTO_UDP;
ip.ip_len = htons(sizeof(struct ip) + len);
proto = ip.ip_p = IPPROTO_ICMP;
}
if (src)
@@ -191,7 +224,7 @@ void dump_packet(int mask, void *packet, size_t len,
sum = (sum & 0xffff) + (sum >> 16);
ip.ip_sum = (sum == 0xffff) ? sum : ~sum;
/* start UDP checksum */
/* start UDP/ICMP checksum */
sum = ip.ip_src.s_addr & 0xffff;
sum += (ip.ip_src.s_addr >> 16) & 0xffff;
sum += ip.ip_dst.s_addr & 0xffff;
@@ -201,25 +234,7 @@ void dump_packet(int mask, void *packet, size_t len,
if (len & 1)
((unsigned char *)packet)[len] = 0; /* for checksum, in case length is odd. */
if (port == -1)
{
/* ICMP - ICMPv6 packet is a superset of ICMP */
struct icmp6_hdr *icmp = packet;
/* See comment in UDP code below. */
sum += htons((family == AF_INET6) ? IPPROTO_ICMPV6 : IPPROTO_ICMP);
sum += htons(len);
icmp->icmp6_cksum = 0;
for (i = 0; i < (len + 1) / 2; i++)
sum += ((u16 *)packet)[i];
while (sum >> 16)
sum = (sum & 0xffff) + (sum >> 16);
icmp->icmp6_cksum = (sum == 0xffff) ? sum : ~sum;
pcap_header.incl_len = pcap_header.orig_len = ipsz + len;
}
else
if (proto == IPPROTO_UDP)
{
/* Add Remaining part of the pseudoheader. Note that though the
IPv6 pseudoheader is very different to the IPv4 one, the
@@ -241,7 +256,25 @@ void dump_packet(int mask, void *packet, size_t len,
pcap_header.incl_len = pcap_header.orig_len = ipsz + sizeof(udp) + len;
}
else
{
/* ICMP - ICMPv6 packet is a superset of ICMP */
struct icmp6_hdr *icmp = packet;
/* See comment in UDP code above. */
sum += htons(proto);
sum += htons(len);
icmp->icmp6_cksum = 0;
for (i = 0; i < (len + 1) / 2; i++)
sum += ((u16 *)packet)[i];
while (sum >> 16)
sum = (sum & 0xffff) + (sum >> 16);
icmp->icmp6_cksum = (sum == 0xffff) ? sum : ~sum;
pcap_header.incl_len = pcap_header.orig_len = ipsz + len;
}
rc = gettimeofday(&time, NULL);
pcap_header.ts_sec = time.tv_sec;
pcap_header.ts_usec = time.tv_usec;
@@ -249,9 +282,11 @@ void dump_packet(int mask, void *packet, size_t len,
if (rc == -1 ||
!read_write(daemon->dumpfd, (void *)&pcap_header, sizeof(pcap_header), 0) ||
!read_write(daemon->dumpfd, iphdr, ipsz, 0) ||
(port != -1 && !read_write(daemon->dumpfd, (void *)&udp, sizeof(udp), 0)) ||
(proto == IPPROTO_UDP && !read_write(daemon->dumpfd, (void *)&udp, sizeof(udp), 0)) ||
!read_write(daemon->dumpfd, (void *)packet, len, 0))
my_syslog(LOG_ERR, _("failed to write packet dump"));
else if (option_bool(OPT_EXTRALOG))
my_syslog(LOG_INFO, _("%u dumping packet %u mask 0x%04x"), daemon->log_display_id, ++packet_count, mask);
else
my_syslog(LOG_INFO, _("dumping packet %u mask 0x%04x"), ++packet_count, mask);
+45 -23
View File
@@ -244,6 +244,14 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
if (!daemon->free_frec_src)
{
query_full(now, NULL);
/* This is tricky; if we're blasted with the same query
over and over, we'll end up taking this path each time
and never resetting until the frec gets deleted by
aging followed by the receipt of a different query. This
is a bit of a DoS vuln. Avoid by explicitly deleting the
frec once it expires. */
if (difftime(now, forward->time) >= TIMEOUT)
free_frec(forward);
goto reply;
}
@@ -510,7 +518,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
if (errno == 0)
{
#ifdef HAVE_DUMPFILE
dump_packet(DUMP_UP_QUERY, (void *)header, plen, NULL, &srv->addr, daemon->port);
dump_packet_udp(DUMP_UP_QUERY, (void *)header, plen, NULL, &srv->addr, fd);
#endif
/* Keep info in case we want to re-send this packet */
@@ -527,8 +535,8 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
}
#ifdef HAVE_DNSSEC
else
log_query_mysockaddr(F_NOEXTRA | F_DNSSEC, daemon->namebuff, &srv->addr,
"dnssec-retry", (forward->flags & FREC_DNSKEY_QUERY) ? T_DNSKEY : T_DS);
log_query_mysockaddr(F_NOEXTRA | F_DNSSEC | F_SERVER, daemon->namebuff, &srv->addr,
(forward->flags & FREC_DNSKEY_QUERY) ? "dnssec-retry[DNSKEY]" : "dnssec-retry[DS]", 0);
#endif
srv->queries++;
@@ -839,8 +847,8 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,
NULL, NULL, NULL);
#ifdef HAVE_DUMPFILE
if (STAT_ISEQUAL(status, STAT_BOGUS))
dump_packet((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_BOGUS : DUMP_BOGUS,
header, (size_t)plen, &forward->sentto->addr, NULL, daemon->port);
dump_packet_udp((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_BOGUS : DUMP_BOGUS,
header, (size_t)plen, &forward->sentto->addr, NULL, -daemon->port);
#endif
}
@@ -950,13 +958,13 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,
set_outgoing_mark(orig, fd);
#endif
server_send(server, fd, header, nn, 0);
server->queries++;
#ifdef HAVE_DUMPFILE
dump_packet(DUMP_SEC_QUERY, (void *)header, (size_t)nn, NULL, &server->addr, daemon->port);
dump_packet_udp(DUMP_SEC_QUERY, (void *)header, (size_t)nn, NULL, &server->addr, fd);
#endif
log_query_mysockaddr(F_NOEXTRA | F_DNSSEC | F_SERVER, daemon->keyname, &server->addr,
STAT_ISEQUAL(status, STAT_NEED_KEY) ? "dnssec-query[DNSKEY]" : "dnssec-query[DS]", 0);
server_send(server, fd, header, nn, 0);
server->queries++;
return;
}
@@ -1045,16 +1053,16 @@ void reply_query(int fd, time_t now)
if (difftime(now, server->pktsz_reduced) > UDP_TEST_TIME)
server->edns_pktsz = daemon->edns_pktsz;
#ifdef HAVE_DUMPFILE
dump_packet((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_REPLY : DUMP_UP_REPLY,
(void *)header, n, &serveraddr, NULL, daemon->port);
#endif
/* log_query gets called indirectly all over the place, so
pass these in global variables - sorry. */
daemon->log_display_id = forward->frec_src.log_id;
daemon->log_source_addr = &forward->frec_src.source;
#ifdef HAVE_DUMPFILE
dump_packet_udp((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_REPLY : DUMP_UP_REPLY,
(void *)header, n, &serveraddr, NULL, fd);
#endif
if (daemon->ignore_addr && RCODE(header) == NOERROR &&
check_for_ignored_address(header, n))
return;
@@ -1073,12 +1081,15 @@ void reply_query(int fd, time_t now)
size_t nn = 0;
#ifdef HAVE_DNSSEC
/* DNSSEC queries have a copy of the original query stashed.
The query MAY have got a good answer, and be awaiting
/* The query MAY have got a good answer, and be awaiting
the results of further queries, in which case
The Stash contains something else and we don't need to retry anyway. */
if ((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) && !forward->blocking_query)
if (forward->blocking_query)
return;
if (forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY))
{
/* DNSSEC queries have a copy of the original query stashed. */
blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
nn = forward->stash_len;
udp_size = daemon->edns_pktsz;
@@ -1144,6 +1155,13 @@ void reply_query(int fd, time_t now)
}
forward->sentto = server;
/* We have a good answer, and will now validate it or return it.
It may be some time before this the validation completes, but we don't need
any more answers, so close the socket(s) on which we were expecting
answers, to conserve file descriptors, and to save work reading and
discarding answers for other upstreams. */
free_rfds(&forward->rfds);
#ifdef HAVE_DNSSEC
if ((forward->sentto->flags & SERV_DO_DNSSEC) &&
@@ -1251,7 +1269,7 @@ static void return_reply(time_t now, struct frec *forward, struct dns_header *he
header->id = htons(src->orig_id);
#ifdef HAVE_DUMPFILE
dump_packet(DUMP_REPLY, daemon->packet, (size_t)nn, NULL, &src->source, daemon->port);
dump_packet_udp(DUMP_REPLY, daemon->packet, (size_t)nn, NULL, &src->source, src->fd);
#endif
#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
@@ -1566,7 +1584,7 @@ void receive_query(struct listener *listen, time_t now)
daemon->log_source_addr = &source_addr;
#ifdef HAVE_DUMPFILE
dump_packet(DUMP_QUERY, daemon->packet, (size_t)n, &source_addr, NULL, daemon->port);
dump_packet_udp(DUMP_QUERY, daemon->packet, (size_t)n, &source_addr, NULL, listen->fd);
#endif
#ifdef HAVE_CONNTRACK
@@ -1619,13 +1637,17 @@ void receive_query(struct listener *listen, time_t now)
/* If the client provides an EDNS0 UDP size, use that to limit our reply.
(bounded by the maximum configured). If no EDNS0, then it
defaults to 512 */
defaults to 512. We write this value into the query packet too, so that
if it's forwarded, we don't specify a maximum size greater than we can handle. */
if (udp_size > daemon->edns_pktsz)
udp_size = daemon->edns_pktsz;
else if (udp_size < PACKETSZ)
udp_size = PACKETSZ; /* Sanity check - can't reduce below default. RFC 6891 6.2.3 */
}
pheader -= 6; /* ext_class */
PUTSHORT(udp_size, pheader); /* Bounding forwarded queries to maximum configured */
}
#ifdef HAVE_CONNTRACK
#ifdef HAVE_AUTH
if (!auth_dns || local_auth)
@@ -1649,7 +1671,7 @@ void receive_query(struct listener *listen, time_t now)
if (m >= 1)
{
#ifdef HAVE_DUMPFILE
dump_packet(DUMP_REPLY, daemon->packet, m, NULL, &source_addr, daemon->port);
dump_packet_udp(DUMP_REPLY, daemon->packet, m, NULL, &source_addr, listen->fd);
#endif
send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
(char *)header, m, &source_addr, &dst_addr, if_index);
@@ -1665,7 +1687,7 @@ void receive_query(struct listener *listen, time_t now)
if (m >= 1)
{
#ifdef HAVE_DUMPFILE
dump_packet(DUMP_REPLY, daemon->packet, m, NULL, &source_addr, daemon->port);
dump_packet_udp(DUMP_REPLY, daemon->packet, m, NULL, &source_addr, listen->fd);
#endif
#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
if (local_auth)
@@ -1691,7 +1713,7 @@ void receive_query(struct listener *listen, time_t now)
if (m >= 1)
{
#ifdef HAVE_DUMPFILE
dump_packet(DUMP_REPLY, daemon->packet, m, NULL, &source_addr, daemon->port);
dump_packet_udp(DUMP_REPLY, daemon->packet, m, NULL, &source_addr, listen->fd);
#endif
#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
if (option_bool(OPT_CMARK_ALST_EN) && have_mark && ((u32)mark & daemon->allowlist_mask))
+1 -1
View File
@@ -23,7 +23,7 @@
The hash used is SHA-256. If we're building with DNSSEC support,
we use the Nettle cypto library. If not, we prefer not to
add a dependency on Nettle, and use a stand-alone implementaion.
add a dependency on Nettle, and use a stand-alone implementation.
*/
#include "dnsmasq.h"
+12 -3
View File
@@ -421,6 +421,9 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
end = extradata + data.ed_len;
buf = extradata;
lua_pushnumber(lua, data.ed_len == 0 ? 1 : 0);
lua_setfield(lua, -2, "data_missing");
if (!is6)
buf = grab_extradata_lua(buf, end, "vendor_class");
@@ -448,7 +451,9 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
buf = grab_extradata_lua(buf, end, "subscriber_id");
buf = grab_extradata_lua(buf, end, "remote_id");
}
buf = grab_extradata_lua(buf, end, "requested_options");
buf = grab_extradata_lua(buf, end, "mud_url");
buf = grab_extradata_lua(buf, end, "tags");
if (is6)
@@ -599,6 +604,9 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
end = extradata + data.ed_len;
buf = extradata;
if (data.ed_len == 0)
my_setenv("DNSMASQ_DATA_MISSING", "1", &err);
if (!is6)
buf = grab_extradata(buf, end, "DNSMASQ_VENDOR_CLASS", &err);
@@ -627,11 +635,12 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
buf = grab_extradata(buf, end, "DNSMASQ_CIRCUIT_ID", &err);
buf = grab_extradata(buf, end, "DNSMASQ_SUBSCRIBER_ID", &err);
buf = grab_extradata(buf, end, "DNSMASQ_REMOTE_ID", &err);
buf = grab_extradata(buf, end, "DNSMASQ_REQUESTED_OPTIONS", &err);
}
buf = grab_extradata(buf, end, "DNSMASQ_REQUESTED_OPTIONS", &err);
buf = grab_extradata(buf, end, "DNSMASQ_MUD_URL", &err);
buf = grab_extradata(buf, end, "DNSMASQ_TAGS", &err);
if (is6)
buf = grab_extradata(buf, end, "DNSMASQ_RELAY_ADDRESS", &err);
else
+1 -7
View File
@@ -1180,17 +1180,11 @@ void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data, unsigned
if ((lease->extradata_size - lease->extradata_len) < (len + 1))
{
size_t newsz = lease->extradata_len + len + 100;
unsigned char *new = whine_malloc(newsz);
unsigned char *new = whine_realloc(lease->extradata, newsz);
if (!new)
return;
if (lease->extradata)
{
memcpy(new, lease->extradata, lease->extradata_len);
free(lease->extradata);
}
lease->extradata = new;
lease->extradata_size = newsz;
}
+12 -10
View File
@@ -66,17 +66,10 @@ char *netlink_init(void)
addr.nl_pad = 0;
addr.nl_pid = 0; /* autobind */
addr.nl_groups = RTMGRP_IPV4_ROUTE;
if (option_bool(OPT_CLEVERBIND))
addr.nl_groups |= RTMGRP_IPV4_IFADDR;
addr.nl_groups |= RTMGRP_IPV4_IFADDR;
addr.nl_groups |= RTMGRP_IPV6_ROUTE;
if (option_bool(OPT_CLEVERBIND))
addr.nl_groups |= RTMGRP_IPV6_IFADDR;
addr.nl_groups |= RTMGRP_IPV6_IFADDR;
#ifdef HAVE_DHCP6
if (daemon->doing_ra || daemon->doing_dhcp6)
addr.nl_groups |= RTMGRP_IPV6_IFADDR;
#endif
/* May not be able to have permission to set multicast groups don't die in that case */
if ((daemon->netlinkfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) != -1)
{
@@ -265,7 +258,16 @@ int iface_enumerate(int family, void *parm, int (*callback)())
while (RTA_OK(rta, len1))
{
if (rta->rta_type == IFA_ADDRESS)
/*
* Important comment: (from if_addr.h)
* IFA_ADDRESS is prefix address, rather than local interface address.
* It makes no difference for normally configured broadcast interfaces,
* but for point-to-point IFA_ADDRESS is DESTINATION address,
* local address is supplied in IFA_LOCAL attribute.
*/
if (rta->rta_type == IFA_LOCAL)
addrp = ((struct in6_addr *)(rta+1));
else if (rta->rta_type == IFA_ADDRESS && !addrp)
addrp = ((struct in6_addr *)(rta+1));
else if (rta->rta_type == IFA_CACHEINFO)
{
+70 -26
View File
@@ -114,13 +114,8 @@ int iface_check(int family, union all_addr *addr, char *name, int *auth)
struct iname *tmp;
int ret = 1, match_addr = 0;
/* Note: have to check all and not bail out early, so that we set the
"used" flags.
May be called with family == AF_LOCALto check interface by name only. */
if (auth)
*auth = 0;
/* Note: have to check all and not bail out early, so that we set the "used" flags.
May be called with family == AF_LOCAL to check interface by name only. */
if (daemon->if_names || daemon->if_addrs)
{
@@ -149,25 +144,29 @@ int iface_check(int family, union all_addr *addr, char *name, int *auth)
if (tmp->name && wildcard_match(tmp->name, name))
ret = 0;
for (tmp = daemon->authinterface; tmp; tmp = tmp->next)
if (tmp->name)
{
if (strcmp(tmp->name, name) == 0 &&
(tmp->addr.sa.sa_family == 0 || tmp->addr.sa.sa_family == family))
break;
}
else if (addr && tmp->addr.sa.sa_family == AF_INET && family == AF_INET &&
tmp->addr.in.sin_addr.s_addr == addr->addr4.s_addr)
break;
else if (addr && tmp->addr.sa.sa_family == AF_INET6 && family == AF_INET6 &&
IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, &addr->addr6))
break;
if (tmp && auth)
if (auth)
{
*auth = 1;
ret = 1;
*auth = 0;
for (tmp = daemon->authinterface; tmp; tmp = tmp->next)
if (tmp->name)
{
if (strcmp(tmp->name, name) == 0 &&
(tmp->addr.sa.sa_family == 0 || tmp->addr.sa.sa_family == family))
break;
}
else if (addr && tmp->addr.sa.sa_family == AF_INET && family == AF_INET &&
tmp->addr.in.sin_addr.s_addr == addr->addr4.s_addr)
break;
else if (addr && tmp->addr.sa.sa_family == AF_INET6 && family == AF_INET6 &&
IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, &addr->addr6))
break;
if (tmp)
{
*auth = 1;
ret = 1;
}
}
return ret;
@@ -232,6 +231,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
union mysockaddr *addr, struct in_addr netmask, int prefixlen, int iface_flags)
{
struct irec *iface;
struct cond_domain *cond;
int loopback;
struct ifreq ifr;
int tftp_ok = !!option_bool(OPT_TFTP);
@@ -454,7 +454,37 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
}
}
}
/* Update addresses for domain=<domain>,<interface> */
for (cond = daemon->cond_domain; cond; cond = cond->next)
if (cond->interface && strncmp(label, cond->interface, IF_NAMESIZE) == 0)
{
struct addrlist *al;
if (param->spare)
{
al = param->spare;
param->spare = al->next;
}
else
al = whine_malloc(sizeof(struct addrlist));
if (addr->sa.sa_family == AF_INET)
{
al->addr.addr4 = addr->in.sin_addr;
al->flags = 0;
}
else
{
al->addr.addr6 = addr->in6.sin6_addr;
al->flags = ADDRLIST_IPV6;
}
al->prefixlen = prefixlen;
al->next = cond->al;
cond->al = al;
}
/* check whether the interface IP has been added already
we call this routine multiple times. */
for (iface = daemon->interfaces; iface; iface = iface->next)
@@ -692,6 +722,7 @@ int enumerate_interfaces(int reset)
int errsave, ret = 1;
struct addrlist *addr, *tmp;
struct interface_name *intname;
struct cond_domain *cond;
struct irec *iface;
#ifdef HAVE_AUTH
struct auth_zone *zone;
@@ -751,6 +782,19 @@ again:
intname->addr = NULL;
}
/* remove addresses stored against cond-domains. */
for (cond = daemon->cond_domain; cond; cond = cond->next)
{
for (addr = cond->al; addr; addr = tmp)
{
tmp = addr->next;
addr->next = spare;
spare = addr;
}
cond->al = NULL;
}
/* Remove list of addresses of local interfaces */
for (addr = daemon->interface_addrs; addr; addr = tmp)
{
+87 -25
View File
@@ -179,6 +179,8 @@ struct myoption {
#define LOPT_FILTER_AAAA 370
#define LOPT_STRIP_SBNET 371
#define LOPT_STRIP_MAC 372
#define LOPT_CONF_OPT 373
#define LOPT_CONF_SCRIPT 374
#ifdef HAVE_GETOPT_LONG
static const struct option opts[] =
@@ -225,6 +227,7 @@ static const struct myoption opts[] =
{ "local", 1, 0, LOPT_LOCAL },
{ "address", 1, 0, 'A' },
{ "conf-file", 2, 0, 'C' },
{ "conf-script", 1, 0, LOPT_CONF_SCRIPT },
{ "no-resolv", 0, 0, 'R' },
{ "expand-hosts", 0, 0, 'E' },
{ "localmx", 0, 0, 'L' },
@@ -467,6 +470,7 @@ static struct {
{ LOPT_SCRIPTUSR, ARG_ONE, "<username>", gettext_noop("Run lease-change scripts as this user."), NULL },
{ LOPT_SCRIPT_ARP, OPT_SCRIPT_ARP, NULL, gettext_noop("Call dhcp-script with changes to local ARP table."), NULL },
{ '7', ARG_DUP, "<path>", gettext_noop("Read configuration from all the files in this directory."), NULL },
{ LOPT_CONF_SCRIPT, ARG_DUP, "<path>", gettext_noop("Execute file and read configuration from stdin."), NULL },
{ '8', ARG_ONE, "<facility>|<file>", gettext_noop("Log to this syslog facility or file. (defaults to DAEMON)"), NULL },
{ '9', OPT_LEASE_RO, NULL, gettext_noop("Do not use leasefile."), NULL },
{ '0', ARG_ONE, "<integer>", gettext_noop("Maximum number of concurrent DNS queries. (defaults to %s)"), "!" },
@@ -1810,6 +1814,17 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
break;
}
case LOPT_CONF_SCRIPT: /* --conf-script */
{
char *file = opt_string_alloc(arg);
if (file)
{
one_file(file, LOPT_CONF_SCRIPT);
free(file);
}
break;
}
case '7': /* --conf-dir */
{
DIR *dir_stream;
@@ -2477,9 +2492,15 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
else if (!inet_pton(AF_INET6, arg, &new->end6))
ret_err_free(gen_err, new);
}
else
else if (option == 's')
{
/* subnet from interface. */
new->interface = opt_string_alloc(comma);
new->al = NULL;
}
else
ret_err_free(gen_err, new);
if (option != 's' && prefstr)
{
if (!(new->prefix = canonicalise_opt(prefstr)) ||
@@ -2537,13 +2558,13 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
arg += 9;
if (strlen(arg) != 16)
ret_err(gen_err);
for (p = arg; *p; p++)
if (!isxdigit((int)*p))
ret_err(gen_err);
set_option_bool(OPT_UMBRELLA_DEVID);
for (i = 0; i < (int)sizeof(daemon->umbrella_device); i++, arg+=2)
{
memcpy(word, &(arg[0]), 2);
@@ -2555,13 +2576,13 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
if (!strtoul_check(arg+6, &daemon->umbrella_org))
ret_err(gen_err);
}
else if (strstr(arg, "assetid:"))
{
if (!strtoul_check(arg+8, &daemon->umbrella_asset))
ret_err(gen_err);
}
else
ret_err(gen_err);
else if (strstr(arg, "assetid:"))
{
if (!strtoul_check(arg+8, &daemon->umbrella_asset))
ret_err(gen_err);
}
else
ret_err(gen_err);
arg = comma;
}
@@ -4312,6 +4333,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
{
if (inet_pton(AF_INET, arg, &new->local))
{
char *hash = split_chr(two, '#');
if (!hash || !atoi_check16(hash, &new->port))
new->port = DHCP_SERVER_PORT;
if (!inet_pton(AF_INET, two, &new->server))
{
new->server.addr4.s_addr = 0;
@@ -4330,6 +4356,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
#ifdef HAVE_DHCP6
else if (inet_pton(AF_INET6, arg, &new->local))
{
char *hash = split_chr(two, '#');
if (!hash || !atoi_check16(hash, &new->port))
new->port = DHCPV6_SERVER_PORT;
if (!inet_pton(AF_INET6, two, &new->server))
{
inet_pton(AF_INET6, ALL_SERVERS, &new->server.addr6);
@@ -4959,7 +4990,7 @@ err:
return 1;
}
static void read_file(char *file, FILE *f, int hard_opt)
static void read_file(char *file, FILE *f, int hard_opt, int from_script)
{
volatile int lineno = 0;
char *buff = daemon->namebuff;
@@ -4967,10 +4998,12 @@ static void read_file(char *file, FILE *f, int hard_opt)
while (fgets(buff, MAXDNAME, f))
{
int white, i;
volatile int option = (hard_opt == LOPT_REV_SERV) ? 0 : hard_opt;
volatile int option;
char *errmess, *p, *arg, *start;
size_t len;
option = (hard_opt == LOPT_REV_SERV) ? 0 : hard_opt;
/* Memory allocation failure longjmps here if mem_recover == 1 */
if (option != 0 || hard_opt == LOPT_REV_SERV)
{
@@ -4978,7 +5011,7 @@ static void read_file(char *file, FILE *f, int hard_opt)
continue;
mem_recover = 1;
}
arg = NULL;
lineno++;
errmess = NULL;
@@ -5084,7 +5117,11 @@ static void read_file(char *file, FILE *f, int hard_opt)
if (errmess || !one_opt(option, arg, daemon->namebuff, _("error"), 0, hard_opt == LOPT_REV_SERV))
{
sprintf(daemon->namebuff + strlen(daemon->namebuff), _(" at line %d of %s"), lineno, file);
if (from_script)
sprintf(daemon->namebuff + strlen(daemon->namebuff), _(" in output from %s"), file);
else
sprintf(daemon->namebuff + strlen(daemon->namebuff), _(" at line %d of %s"), lineno, file);
if (hard_opt != 0)
my_syslog(LOG_ERR, "%s", daemon->namebuff);
else
@@ -5093,7 +5130,6 @@ static void read_file(char *file, FILE *f, int hard_opt)
}
mem_recover = 0;
fclose(f);
}
#if defined(HAVE_DHCP) && defined(HAVE_INOTIFY)
@@ -5113,7 +5149,7 @@ int option_read_dynfile(char *file, int flags)
static int one_file(char *file, int hard_opt)
{
FILE *f;
int nofile_ok = 0;
int nofile_ok = 0, do_popen = 0;
static int read_stdin = 0;
static struct fileread {
dev_t dev;
@@ -5121,14 +5157,20 @@ static int one_file(char *file, int hard_opt)
struct fileread *next;
} *filesread = NULL;
if (hard_opt == '7')
if (hard_opt == LOPT_CONF_OPT)
{
/* default conf-file reading */
hard_opt = 0;
nofile_ok = 1;
}
if (hard_opt == 0 && strcmp(file, "-") == 0)
if (hard_opt == LOPT_CONF_SCRIPT)
{
hard_opt = 0;
do_popen = 1;
}
if (hard_opt == 0 && !do_popen && strcmp(file, "-") == 0)
{
if (read_stdin == 1)
return 1;
@@ -5155,8 +5197,13 @@ static int one_file(char *file, int hard_opt)
r->dev = statbuf.st_dev;
r->ino = statbuf.st_ino;
}
if (!(f = fopen(file, "r")))
if (do_popen)
{
if (!(f = popen(file, "r")))
die(_("cannot execute %s: %s"), file, EC_FILE);
}
else if (!(f = fopen(file, "r")))
{
if (errno == ENOENT && nofile_ok)
return 1; /* No conffile, all done. */
@@ -5174,7 +5221,21 @@ static int one_file(char *file, int hard_opt)
}
}
read_file(file, f, hard_opt);
read_file(file, f, hard_opt, do_popen);
if (do_popen)
{
int rc;
if ((rc = pclose(f)) == -1)
die(_("error executing %s: %s"), file, EC_MISC);
if (rc != 0)
die(_("%s returns non-zero error code"), file, rc+10);
}
else
fclose(f);
return 1;
}
@@ -5314,7 +5375,8 @@ void read_servers_file(void)
}
mark_servers(SERV_FROM_FILE);
read_file(daemon->servers_file, f, LOPT_REV_SERV);
read_file(daemon->servers_file, f, LOPT_REV_SERV, 0);
fclose(f);
cleanup_servers();
check_servers(0);
}
@@ -5540,7 +5602,7 @@ void read_opts(int argc, char **argv, char *compile_opts)
free(conffile);
}
else
one_file(CONFFILE, '7');
one_file(CONFFILE, LOPT_CONF_OPT);
/* port might not be known when the address is parsed - fill in here */
if (daemon->servers)
+5 -12
View File
@@ -96,28 +96,21 @@ void poll_listen(int fd, short event)
pollfds[i].events |= event;
else
{
if (arrsize != nfds)
memmove(&pollfds[i+1], &pollfds[i], (nfds - i) * sizeof(struct pollfd));
else
if (arrsize == nfds)
{
/* Array too small, extend. */
struct pollfd *new;
arrsize = (arrsize == 0) ? 64 : arrsize * 2;
if (!(new = whine_malloc(arrsize * sizeof(struct pollfd))))
if (!(new = whine_realloc(pollfds, arrsize * sizeof(struct pollfd))))
return;
if (pollfds)
{
memcpy(new, pollfds, i * sizeof(struct pollfd));
memcpy(&new[i+1], &pollfds[i], (nfds - i) * sizeof(struct pollfd));
free(pollfds);
}
pollfds = new;
}
memmove(&pollfds[i+1], &pollfds[i], (nfds - i) * sizeof(struct pollfd));
pollfds[i].fd = fd;
pollfds[i].events = event;
nfds++;
+8 -2
View File
@@ -203,7 +203,7 @@ void icmp6_packet(time_t now)
int opt_sz;
#ifdef HAVE_DUMPFILE
dump_packet(DUMP_RA, (void *)packet, sz, (union mysockaddr *)&from, NULL, -1);
dump_packet_icmp(DUMP_RA, (void *)packet, sz, (union mysockaddr *)&from, NULL);
#endif
/* look for link-layer address option for logging */
@@ -560,7 +560,13 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad
}
#ifdef HAVE_DUMPFILE
dump_packet(DUMP_RA, (void *)daemon->outpacket.iov_base, save_counter(-1), NULL, (union mysockaddr *)&addr, -1);
{
struct sockaddr_in6 src;
src.sin6_family = AF_INET6;
src.sin6_addr = parm.link_local;
dump_packet_icmp(DUMP_RA, (void *)daemon->outpacket.iov_base, save_counter(-1), (union mysockaddr *)&src, (union mysockaddr *)&addr);
}
#endif
while (retry_send(sendto(daemon->icmp6fd, daemon->outpacket.iov_base,
+2 -2
View File
@@ -1597,7 +1597,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
if (addrlist)
break;
else
else if (!(intr->flags & INP4))
while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
intr = intr->next;
}
@@ -1612,7 +1612,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
if (addrlist)
break;
else
else if (!(intr->flags & INP6))
while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
intr = intr->next;
}
+8 -11
View File
@@ -1420,21 +1420,18 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
/* DNSMASQ_REQUESTED_OPTIONS */
if ((opt = option_find(mess, sz, OPTION_REQUESTED_OPTIONS, 1)))
{
int len = option_len(opt);
int i, len = option_len(opt);
unsigned char *rop = option_ptr(opt, 0);
char *q = daemon->namebuff;
int i;
for (i = 0; i < len; i++)
{
q += snprintf(q, MAXDNAME - (q - daemon->namebuff), "%d%s", rop[i], i + 1 == len ? "" : ",");
}
lease_add_extradata(lease, (unsigned char *)daemon->namebuff, (q - daemon->namebuff), 0);
lease_add_extradata(lease, (unsigned char *)daemon->namebuff,
sprintf(daemon->namebuff, "%u", rop[i]), (i + 1) == len ? 0 : ',');
}
else
{
add_extradata_opt(lease, NULL);
}
lease_add_extradata(lease, NULL, 0, 0);
add_extradata_opt(lease, option_find(mess, sz, OPTION_MUD_URL_V4, 1));
/* space-concat tag set */
if (!tagif_netid)
add_extradata_opt(lease, NULL);
+61 -46
View File
@@ -33,9 +33,9 @@ struct state {
unsigned int mac_len, mac_type;
};
static int dhcp6_maybe_relay(struct state *state, void *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);
static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_t sz, int is_unicast, time_t now);
static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbuff, size_t sz, int is_unicast, time_t now);
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_quiet(struct state *state, char *type, struct in6_addr *addr, char *string);
@@ -104,12 +104,12 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *if
}
/* This cost me blood to write, it will probably cost you blood to understand - srk. */
static int dhcp6_maybe_relay(struct state *state, void *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)
{
void *end = inbuff + sz;
void *opts = inbuff + 34;
int msg_type = *((unsigned char *)inbuff);
int msg_type = *inbuff;
unsigned char *outmsgtypep;
void *opt;
struct dhcp_vendor *vendor;
@@ -259,15 +259,15 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
return 1;
}
static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_t sz, int is_unicast, time_t now)
static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbuff, size_t sz, int is_unicast, time_t now)
{
void *opt;
int i, o, o1, start_opts;
int i, o, o1, start_opts, start_msg;
struct dhcp_opt *opt_cfg;
struct dhcp_netid *tagif;
struct dhcp_config *config = NULL;
struct dhcp_netid known_id, iface_id, v6_id;
unsigned char *outmsgtypep;
unsigned char outmsgtype;
struct dhcp_vendor *vendor;
struct dhcp_context *context_tmp;
struct dhcp_mac *mac_opt;
@@ -296,12 +296,13 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
v6_id.next = state->tags;
state->tags = &v6_id;
/* copy over transaction-id, and save pointer to message type */
if (!(outmsgtypep = put_opt6(inbuff, 4)))
start_msg = save_counter(-1);
/* copy over transaction-id */
if (!put_opt6(inbuff, 4))
return 0;
start_opts = save_counter(-1);
state->xid = outmsgtypep[3] | outmsgtypep[2] << 8 | outmsgtypep[1] << 16;
state->xid = inbuff[3] | inbuff[2] << 8 | inbuff[1] << 16;
/* We're going to be linking tags from all context we use.
mark them as unused so we don't link one twice and break the list */
for (context_tmp = state->context; context_tmp; context_tmp = context_tmp->current)
@@ -347,7 +348,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
(msg_type == DHCP6REQUEST || msg_type == DHCP6RENEW || msg_type == DHCP6RELEASE || msg_type == DHCP6DECLINE))
{
*outmsgtypep = DHCP6REPLY;
outmsgtype = DHCP6REPLY;
o1 = new_opt6(OPTION6_STATUS_CODE);
put_opt6_short(DHCP6USEMULTI);
put_opt6_string("Use multicast");
@@ -619,11 +620,11 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
struct dhcp_netid *solicit_tags;
struct dhcp_context *c;
*outmsgtypep = DHCP6ADVERTISE;
outmsgtype = DHCP6ADVERTISE;
if (opt6_find(state->packet_options, state->end, OPTION6_RAPID_COMMIT, 0))
{
*outmsgtypep = DHCP6REPLY;
outmsgtype = DHCP6REPLY;
state->lease_allocate = 1;
o = new_opt6(OPTION6_RAPID_COMMIT);
end_opt6(o);
@@ -809,7 +810,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
int start = save_counter(-1);
/* set reply message type */
*outmsgtypep = DHCP6REPLY;
outmsgtype = DHCP6REPLY;
state->lease_allocate = 1;
log6_quiet(state, "DHCPREQUEST", NULL, ignore ? _("ignored") : NULL);
@@ -924,7 +925,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
int address_assigned = 0;
/* set reply message type */
*outmsgtypep = DHCP6REPLY;
outmsgtype = DHCP6REPLY;
log6_quiet(state, msg_type == DHCP6RENEW ? "DHCPRENEW" : "DHCPREBIND", NULL, NULL);
@@ -1057,7 +1058,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
int good_addr = 0;
/* set reply message type */
*outmsgtypep = DHCP6REPLY;
outmsgtype = DHCP6REPLY;
log6_quiet(state, "DHCPCONFIRM", NULL, NULL);
@@ -1121,7 +1122,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
log6_quiet(state, "DHCPINFORMATION-REQUEST", NULL, ignore ? _("ignored") : state->hostname);
if (ignore)
return 0;
*outmsgtypep = DHCP6REPLY;
outmsgtype = DHCP6REPLY;
tagif = add_options(state, 1);
break;
}
@@ -1130,7 +1131,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
case DHCP6RELEASE:
{
/* set reply message type */
*outmsgtypep = DHCP6REPLY;
outmsgtype = DHCP6REPLY;
log6_quiet(state, "DHCPRELEASE", NULL, NULL);
@@ -1195,7 +1196,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
case DHCP6DECLINE:
{
/* set reply message type */
*outmsgtypep = DHCP6REPLY;
outmsgtype = DHCP6REPLY;
log6_quiet(state, "DHCPDECLINE", NULL, NULL);
@@ -1275,7 +1276,12 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
}
}
/* Fill in the message type. Note that we store the offset,
not a direct pointer, since the packet memory may have been
reallocated. */
((unsigned char *)(daemon->outpacket.iov_base))[start_msg] = outmsgtype;
log_tags(tagif, state->xid);
log6_opts(0, state->xid, daemon->outpacket.iov_base + start_opts, daemon->outpacket.iov_base + save_counter(-1));
@@ -1873,23 +1879,24 @@ static void update_leases(struct state *state, struct dhcp_context *context, str
#ifdef HAVE_SCRIPT
if (daemon->lease_change_command)
{
void *class_opt;
void *opt;
lease->flags |= LEASE_CHANGED;
free(lease->extradata);
lease->extradata = NULL;
lease->extradata_size = lease->extradata_len = 0;
lease->vendorclass_count = 0;
if ((class_opt = opt6_find(state->packet_options, state->end, OPTION6_VENDOR_CLASS, 4)))
if ((opt = opt6_find(state->packet_options, state->end, OPTION6_VENDOR_CLASS, 4)))
{
void *enc_opt, *enc_end = opt6_ptr(class_opt, opt6_len(class_opt));
void *enc_opt, *enc_end = opt6_ptr(opt, opt6_len(opt));
lease->vendorclass_count++;
/* send enterprise number first */
sprintf(daemon->dhcp_buff2, "%u", opt6_uint(class_opt, 0, 4));
sprintf(daemon->dhcp_buff2, "%u", opt6_uint(opt, 0, 4));
lease_add_extradata(lease, (unsigned char *)daemon->dhcp_buff2, strlen(daemon->dhcp_buff2), 0);
if (opt6_len(class_opt) >= 6)
for (enc_opt = opt6_ptr(class_opt, 4); enc_opt; enc_opt = opt6_next(enc_opt, enc_end))
if (opt6_len(opt) >= 6)
for (enc_opt = opt6_ptr(opt, 4); enc_opt; enc_opt = opt6_next(enc_opt, enc_end))
{
lease->vendorclass_count++;
lease_add_extradata(lease, opt6_ptr(enc_opt, 0), opt6_len(enc_opt), 0);
@@ -1899,6 +1906,24 @@ static void update_leases(struct state *state, struct dhcp_context *context, str
lease_add_extradata(lease, (unsigned char *)state->client_hostname,
state->client_hostname ? strlen(state->client_hostname) : 0, 0);
/* DNSMASQ_REQUESTED_OPTIONS */
if ((opt = opt6_find(state->packet_options, state->end, OPTION6_ORO, 2)))
{
int i, len = opt6_len(opt)/2;
u16 *rop = opt6_ptr(opt, 0);
for (i = 0; i < len; i++)
lease_add_extradata(lease, (unsigned char *)daemon->namebuff,
sprintf(daemon->namebuff, "%u", ntohs(rop[i])), (i + 1) == len ? 0 : ',');
}
else
lease_add_extradata(lease, NULL, 0, 0);
if ((opt = opt6_find(state->packet_options, state->end, OPTION6_MUD_URL, 1)))
lease_add_extradata(lease, opt6_ptr(opt, 0), opt6_len(opt), 0);
else
lease_add_extradata(lease, NULL, 0, 0);
/* space-concat tag set */
if (!tagif && !context->netid.net)
lease_add_extradata(lease, NULL, 0, 0);
@@ -1928,10 +1953,10 @@ static void update_leases(struct state *state, struct dhcp_context *context, str
lease_add_extradata(lease, (unsigned char *)daemon->addrbuff, state->link_address ? strlen(daemon->addrbuff) : 0, 0);
if ((class_opt = opt6_find(state->packet_options, state->end, OPTION6_USER_CLASS, 2)))
if ((opt = opt6_find(state->packet_options, state->end, OPTION6_USER_CLASS, 2)))
{
void *enc_opt, *enc_end = opt6_ptr(class_opt, opt6_len(class_opt));
for (enc_opt = opt6_ptr(class_opt, 0); enc_opt; enc_opt = opt6_next(enc_opt, enc_end))
void *enc_opt, *enc_end = opt6_ptr(opt, opt6_len(opt));
for (enc_opt = opt6_ptr(opt, 0); enc_opt; enc_opt = opt6_next(enc_opt, enc_end))
lease_add_extradata(lease, opt6_ptr(enc_opt, 0), opt6_len(enc_opt), 0);
}
}
@@ -2156,15 +2181,12 @@ int relay_upstream6(int iface_index, ssize_t sz,
if (relay->iface_index != 0 && relay->iface_index == iface_index)
{
union mysockaddr to;
union all_addr from;
/* source address == relay address */
from.addr6 = relay->local.addr6;
memcpy(&header[2], &relay->local.addr6, IN6ADDRSZ);
to.sa.sa_family = AF_INET6;
to.in6.sin6_addr = relay->server.addr6;
to.in6.sin6_port = htons(DHCPV6_SERVER_PORT);
to.in6.sin6_port = htons(relay->port);
to.in6.sin6_flowinfo = 0;
to.in6.sin6_scope_id = 0;
@@ -2181,18 +2203,11 @@ int relay_upstream6(int iface_index, ssize_t sz,
}
#ifdef HAVE_DUMPFILE
{
union mysockaddr fromsock;
fromsock.in6.sin6_port = htons(DHCPV6_SERVER_PORT);
fromsock.in6.sin6_addr = from.addr6;
fromsock.sa.sa_family = AF_INET6;
fromsock.in6.sin6_flowinfo = 0;
fromsock.in6.sin6_scope_id = 0;
dump_packet(DUMP_DHCPV6, (void *)daemon->outpacket.iov_base, save_counter(-1), &fromsock, &to, 0);
}
dump_packet_udp(DUMP_DHCPV6, (void *)daemon->outpacket.iov_base, save_counter(-1), NULL, &to, daemon->dhcp6fd);
#endif
send_from(daemon->dhcp6fd, 0, daemon->outpacket.iov_base, save_counter(-1), &to, &from, 0);
while (retry_send(sendto(daemon->dhcp6fd, (void *)daemon->outpacket.iov_base, save_counter(-1),
0, (struct sockaddr *)&to, sa_len(&to))));
if (option_bool(OPT_LOG_OPTS))
{
+6 -10
View File
@@ -159,7 +159,7 @@ static int check_rrs(unsigned char *p, struct dns_header *header, size_t plen, i
/* mode may be remove EDNS0 or DNSSEC RRs or remove A or AAAA from answer section. */
size_t rrfilter(struct dns_header *header, size_t plen, int mode)
{
static unsigned char **rrs;
static unsigned char **rrs = NULL;
static int rr_sz = 0;
unsigned char *p = (unsigned char *)(header+1);
@@ -339,15 +339,11 @@ int expand_workspace(unsigned char ***wkspc, int *szp, int new)
return 0;
new += 5;
if (!(p = whine_malloc(new * sizeof(unsigned char *))))
return 0;
if (old != 0 && *wkspc)
{
memcpy(p, *wkspc, old * sizeof(unsigned char *));
free(*wkspc);
}
if (!(p = whine_realloc(*wkspc, new * sizeof(unsigned char *))))
return 0;
memset(p+old, 0, new-old);
*wkspc = p;
*szp = new;
+4 -4
View File
@@ -97,7 +97,7 @@ void tftp_request(struct listener *listen, time_t now)
return;
#ifdef HAVE_DUMPFILE
dump_packet(DUMP_TFTP, (void *)packet, len, (union mysockaddr *)&peer, NULL, TFTP_PORT);
dump_packet_udp(DUMP_TFTP, (void *)packet, len, (union mysockaddr *)&peer, NULL, listen->tftpfd);
#endif
/* Can always get recvd interface for IPv6 */
@@ -488,7 +488,7 @@ void tftp_request(struct listener *listen, time_t now)
send_from(transfer->sockfd, !option_bool(OPT_SINGLE_PORT), packet, len, &peer, &addra, if_index);
#ifdef HAVE_DUMPFILE
dump_packet(DUMP_TFTP, (void *)packet, len, NULL, (union mysockaddr *)&peer, TFTP_PORT);
dump_packet_udp(DUMP_TFTP, (void *)packet, len, NULL, (union mysockaddr *)&peer, transfer->sockfd);
#endif
if (is_err)
@@ -610,7 +610,7 @@ void check_tftp_listeners(time_t now)
while(retry_send(sendto(transfer->sockfd, daemon->packet, len, 0, &peer.sa, sa_len(&peer))));
#ifdef HAVE_DUMPFILE
dump_packet(DUMP_TFTP, (void *)daemon->packet, len, NULL, (union mysockaddr *)&peer, TFTP_PORT);
dump_packet_udp(DUMP_TFTP, (void *)daemon->packet, len, NULL, (union mysockaddr *)&peer, transfer->sockfd);
#endif
}
}
@@ -650,7 +650,7 @@ void check_tftp_listeners(time_t now)
send_from(transfer->sockfd, !option_bool(OPT_SINGLE_PORT), daemon->packet, len,
&transfer->peer, &transfer->source, transfer->if_index);
#ifdef HAVE_DUMPFILE
dump_packet(DUMP_TFTP, (void *)daemon->packet, len, NULL, (union mysockaddr *)&transfer->peer, TFTP_PORT);
dump_packet_udp(DUMP_TFTP, (void *)daemon->packet, len, NULL, (union mysockaddr *)&transfer->peer, transfer->sockfd);
#endif
}
+10
View File
@@ -336,6 +336,16 @@ void *whine_malloc(size_t size)
return ret;
}
void *whine_realloc(void *ptr, size_t size)
{
void *ret = realloc(ptr, size);
if (!ret)
my_syslog(LOG_ERR, _("failed to reallocate %d bytes"), (int) size);
return ret;
}
int sockaddr_isequal(const union mysockaddr *s1, const union mysockaddr *s2)
{
if (s1->sa.sa_family == s2->sa.sa_family)