Compare commits

..
47 Commits
Author SHA1 Message Date
Dominik DL6ER e0ce3c12f2 Add all current RR types to the table of type names used for query logging.
This patch also changes the method of calling querystr() such that
it is only called when logging is enabled, to eliminate any
possible performance problems from searching the larger table.
2021-09-10 23:13:53 +01:00
Gustaf Ullberg 93cf516bf1 check_name() determines if IDN processing is needed.
Optimization that only runs IDN processing if it would alter the domain
name (non-ascii or uppercase characters).

This patch has conributions from Petr Menšík.
2021-09-10 00:13:39 +01:00
Simon Kelley 6f4de018af Revert "Skip ascii-only names IDN processing"
This reverts commit 9cb7f8a655.
2021-09-10 00:02:11 +01:00
Simon Kelley 6e91cf3172 Bump version in Debian changelog. 2021-09-08 23:19:08 +01:00
Petr Menšík 9cb7f8a655 Skip ascii-only names IDN processing
Calls to libidn on names without with only a-z A-Z - _ 0-9
have no effect, but are slow. This change elides those calls.

Patch inspire by analysis and an earlier patch from
Gustaf Ullberg <gustaf.ullberg@gmail.com>
2021-09-08 23:08:21 +01:00
Simon Kelley 5d8d1ad14b Merge branch 'nxdomain' 2021-09-08 23:05:35 +01:00
Simon Kelley cac9ca38f6 Treat ANY queries the same as CNAME queries WRT to DNSSEC on CNAME targets. 2021-09-08 21:21:22 +01:00
Simon Kelley c4523639d5 Treat ANY queries the same as CNAME queries WRT to DNSSEC on CNAME targets. 2021-09-08 21:19:15 +01:00
Simon Kelley 1ce1c6beae Caching cleanup. Use cached NXDOMAIN to answer queries of any type. 2021-09-05 18:47:45 +01:00
DL6ER 51d56df7a3 Add RFC 4833 DHCP options "posix-timezone" and "tzdb-timezone".
Signed-off-by: DL6ER <dl6er@dl6er.de>
2021-09-04 22:24:14 +01:00
Simon Kelley 860a9a57d6 Get logging of DNSSEC status right when Checking Disabled bit set. 2021-09-02 10:07:08 +01:00
Dominik DL6ER c83e33d608 Final logging tweaks. 2021-09-01 21:19:47 +01:00
Simon Kelley 7b80c75d9d Rationalise query-reply logging.
Try and log exactly what was returned, rather than just what
got cached. Also give validation status of RRsets if extra logging specified.

This commit also fixes a long-standing bug in caching of CNAME chains
leading to a PTR record.

Based on and inspired by a patch from Dominik DL6ER <dl6er@dl6er.de>
2021-08-31 18:23:03 +01:00
Geoff Back 79337f99ae Support limited wildcards in the input tags for --tag-if. 2021-08-29 13:27:27 +01:00
Geert Stappers via Dnsmasq-discuss a42ee397f3 Man page BNF error fix.
Move dhcp-range bracket indicating option.

There should already be an end-address or mode  when adding a netmask.

Also the date bumped.

Signed-off-by: Geert Stappers <stappers@stappers.nl>
2021-08-25 14:32:43 +01:00
Simon Kelley e58f8bb8c1 Merge message changes into I18N files. 2021-08-25 14:11:42 +01:00
Dominik DL6ER 58cf958e41 Fix empty domain in server option parsing when more than one domain is given
Signed-off-by: DL6ER <dl6er@dl6er.de>
2021-08-25 14:09:40 +01:00
Etan Kissling 06d01f7ae4 Make comment style consistent.
Majority of code base does not use C90-style // end of line comments.
This formats the few existing exceptions using /* */ for consistency.
2021-08-12 17:02:45 +01:00
Etan Kissling 1a33eec0ba Adjust logging levels for connmark patterns.
This brings the log levels emitted by connmark pattern code in line with
the rest of the code base. LOG_DEBUG is used for diagnostics that may be
verbose depending on the request patterns. LOG_ERR is used for problems
with the implementation itself.

Signed-off-by: Etan Kissling <etan.kissling@gmail.com>
2021-08-12 17:02:24 +01:00
Etan Kissling 82de7a1e96 Re-order UBus teardown logic.
When destroying the UBus context, private fields of our ubus_object were
being reset to 0 while UBus was still owning those objects. While this
seems to work out fine, it seems cleaner to first release the object so
that UBus no longer owns it, before proceding to reset those fields.

Signed-off-by: Etan Kissling <etan.kissling@gmail.com>
2021-08-12 17:02:07 +01:00
Etan Kissling 8e9bde57c5 Eliminate redundant UBus notify variable.
There was a `notify` variable to keep track whether a subscriber is
observing our UBus object. However, it was not properly cleaned up in
`ubus_destroy`, potentially becoming stale over UBus reconnections.
The variable was removed and the current state is examined when sending
notifications, similarly as is done in other existing OpenWrt code.

Signed-off-by: Etan Kissling <etan.kissling@gmail.com>
2021-08-12 17:01:17 +01:00
Etan Kissling 1bb70e08be Handle UBus serialization errors.
The various blob / blobmsg commands can fail, e.g., when memory is low.
Previously, those errors were silently discarded. This patch adds checks
for the error conditions, logging them and exiting from the functions.

Signed-off-by: Etan Kissling <etan.kissling@gmail.com>
2021-08-12 17:00:18 +01:00
Simon Kelley 9afcb7ae61 Revert "There was a notify variable to keep track whether a subscriber is"
This reverts commit ea43234c86.
2021-08-12 17:00:10 +01:00
Simon Kelley 545c4955e6 Revert "Re-order UBus teardown logic."
This reverts commit d387f8f06c.
2021-08-12 16:58:30 +01:00
Simon Kelley 2f2d59b35c Define order of reading files when --addn-hosts given a directory.
Also applies to --dhcp-hostsfile and --dhcp-optsfile though it is
less useful there.
2021-08-12 16:48:54 +01:00
Simon Kelley a1729deed3 Fiz sizeof() confusion in 527c3c7d0d 2021-08-11 09:10:39 +01:00
Simon Kelley fc64b97cd5 dhcp_buff2 not availble in log_packet, use daemon->addrbuff 2021-08-10 23:54:13 +01:00
Simon Kelley daddc8cb80 Merge branch 'master' of ssh://thekelleys.org.uk/var/local/git/dnsmasq 2021-08-10 23:15:46 +01:00
Petr Menšík 527c3c7d0d Remove remaining uses of deprecated inet_ntoa() 2021-08-10 22:50:33 +01:00
Petr Menšík fcb4dcaf7c Remove remaining uses of deprecated inet_addr() function. 2021-08-10 22:21:01 +01:00
Matthias Andree 3ca4995d34 CHANGELOG: spell-check 2021-08-10 21:40:06 +01:00
Etan Kissling d387f8f06c Re-order UBus teardown logic.
When destroying the UBus context, private fields of our ubus_object were
being reset to 0 while UBus was still owning those objects. While this
seems to work out fine, it seems cleaner to first release the object so
that UBus no longer owns it, before proceding to reset those fields.

Signed-off-by: Etan Kissling <etan.kissling@gmail.com>
2021-08-10 21:16:03 +01:00
Etan Kissling ea43234c86 There was a notify variable to keep track whether a subscriber is
observing our UBus object. However, it was not properly cleaned up in
`ubus_destroy`, potentially becoming stale over UBus reconnections.
The variable was removed and the current state is examined when sending
notifications, similarly as is done in other existing OpenWrt code.

Signed-off-by: Etan Kissling <etan.kissling@gmail.com>
2021-08-10 21:15:09 +01:00
Simon Kelley 867e56a45e Fix NOERR/NXDOMAIN in answers configured by --domain-needed. 2021-08-10 13:00:23 +01:00
Simon Kelley a163c63787 CONNTRACK needs CAP_NET_ADMIN. 2021-08-05 23:40:04 +01:00
Simon Kelley 8389b943d3 Better fix than f2266d9678 2021-07-21 21:27:14 +01:00
Simon Kelley f2266d9678 Add UINT32_MAX if not defined by system. 2021-07-21 00:23:28 +01:00
Simon Kelley 56bd806978 Typo in new EDE code. 2021-07-21 00:15:58 +01:00
Simon Kelley ac7eeea44d Handle empty hostmaster in --auth-soa
Spotted by Max Julian Hofmann and the Advanced Research Team at CrowdStrike
2021-07-21 00:15:15 +01:00
Simon Kelley b741059549 Detect malformed --dhcp-relay option.
Spotted by Max Julian Hofmann and the Advanced Research Team at CrowdStrike
2021-07-20 23:49:38 +01:00
Simon Kelley cbd984287f Fix argument checking for --dhcp-match.
Spotted by Max Julian Hofmann and the Advanced Research Team at CrowdStrike
2021-07-20 23:45:36 +01:00
Simon Kelley 32e15c3f45 canonicalise_opt must always return heap memory.
Thanks to Max Julian Hofmann for spotting this.
2021-07-20 23:22:37 +01:00
Simon Kelley f0dc324e35 Checks on prefix-length in --domain --synth-domain and --rev-server. 2021-07-20 23:15:28 +01:00
Simon Kelley f83c6cf51a Return REFUSED in auth mode when we are not authoritative for the query. 2021-07-20 17:15:36 +01:00
Simon Kelley c068b3ae2f --synth-domain now works in auth mode. 2021-07-19 09:38:48 +01:00
Simon Kelley adf9dec1e6 Allow shorter IPv6 prefix lengths in (some) --synth-domain options. 2021-07-18 18:18:56 +01:00
Kevin Darbyshire-Bryant 767d9cbd96 Add --quiet-tftp. 2021-07-09 22:48:49 +01:00
35 changed files with 8150 additions and 6165 deletions

No files matched your search

+21 -2
View File
@@ -1,6 +1,6 @@
version 2.86
Handle DHCPREBIND requests in the DHCPv6 server code.
Thanks to Aichun Li for spotting this ommision, and the initial
Thanks to Aichun Li for spotting this omission, and the initial
patch.
Fix bug which caused dnsmasq to lose track of processes forked
@@ -33,7 +33,7 @@ version 2.86
address=/example.com/1.2.3.4
address=/example.com/5.6.7.8
It also handles multiple upstream servers for a domain better; using
the same try/retry alogrithms as non domain-specific servers. This
the same try/retry algorithms as non domain-specific servers. This
also applies to DNSSEC-generated queries.
Finally, some of the oldest and gnarliest code in dnsmasq has had
a significant clean-up. It's far from perfect, but it _is_ better.
@@ -76,6 +76,22 @@ version 2.86
Disallowed queries are not forwarded; they are rejected
with a REFUSED error code.
Allow smaller than 64 prefix lengths in synth-domain, with caveats.
--synth-domain=1234:4567::/56,example.com is now valid.
Make domains generated by --synth-domain appear in replies
when in authoritative mode.
Ensure CAP_NET_ADMIN capability is available when
conntrack is configured. Thanks to Yick Xie for spotting
the lack of this.
When --dhcp-hostsfile --dhcp-optsfile and --addn-hosts are
given a directory as argument, define the order in which
files within that directory are read (alphabetical order
of filename). Thanks to Ed Wildgoose for the initial patch
and motivation for this.
version 2.85
Fix problem with DNS retries in 2.83/2.84.
@@ -147,6 +163,9 @@ version 2.85
Tweak TFTP code to check sender of all received packets, as
specified in RFC 1350 para 4.
Support some wildcard matching of input tags to --tag-if.
Thanks to Geoff Back for the idea and the patch.
version 2.84
Fix a problem, introduced in 2.83, which could see DNS replies
+7 -3
View File
@@ -153,7 +153,11 @@ int main(int argc, char **argv)
exit(1);
}
lease.s_addr = inet_addr(argv[1]);
if (inet_pton(AF_INET, argv[1], &lease) < 1)
{
fprintf(stderr, "invalid address: %s\n", argv[1]);
exit(1);
}
memset(&packet, 0, sizeof(packet));
@@ -176,8 +180,8 @@ int main(int argc, char **argv)
*(p++) = OPTION_END;
dest.sin_family = AF_INET;
dest.sin_addr.s_addr = inet_addr("127.0.0.1");
dest.sin_family = AF_INET;
(void)inet_pton(AF_INET, "127.0.0.1", &dest.sin_addr);
dest.sin_port = ntohs(DHCP_SERVER_PORT);
if (sendto(fd, &packet, sizeof(packet), 0,
+1 -2
View File
@@ -288,13 +288,12 @@ int main(int argc, char **argv)
exit(1);
}
if (inet_addr(argv[2]) == INADDR_NONE)
if (inet_pton(AF_INET, argv[2], &lease.s_addr) < 1)
{
perror("invalid ip address");
exit(1);
}
lease.s_addr = inet_addr(argv[2]);
server = find_interface(lease, nl, if_nametoindex(argv[1]), fd, &ifr);
memset(&packet, 0, sizeof(packet));
+6
View File
@@ -1,3 +1,9 @@
dnsmasq (2.87-1) unstable; urgency=low
* New upstream.
-- Simon Kelley <simon@thekelleys.org.uk> Wed, 08 Sep 2021 23:11:25 +0000
dnsmasq (2.86-1) unstable; urgency=low
* Fix debian/changelog format error. (closes: #986626)
+24 -10
View File
@@ -1,4 +1,4 @@
.TH DNSMASQ 8 2020-04-05
.TH DNSMASQ 8 2021-08-16
.SH NAME
dnsmasq \- A lightweight DHCP and caching DNS server.
.SH SYNOPSIS
@@ -55,7 +55,8 @@ Don't read the hostnames in /etc/hosts.
.B \-H, --addn-hosts=<file>
Additional hosts file. Read the specified file as well as /etc/hosts. If \fB--no-hosts\fP is given, read
only the specified file. This option may be repeated for more than one
additional hosts file. If a directory is given, then read all the files contained in that directory.
additional hosts file. If a directory is given, then read all the files contained in that directory
in alphabetical order.
.TP
.B --hostsdir=<path>
Read all the hosts files contained in the directory. New or changed files
@@ -705,7 +706,8 @@ configured a zero is added in front of the label. ::1 becomes 0--1.
V4 mapped IPv6 addresses, which have a representation like ::ffff:1.2.3.4 are handled specially, and become like 0--ffff-1-2-3-4
The address range can be of the form
<ip address>,<ip address> or <ip address>/<netmask> in both forms of the option.
<start address>,<end address> or <ip address>/<prefix-length> in both forms of the option. For IPv6 the start and end addresses
must fall in the same /64 network, or prefix-length must be greater than or equal to 64 except that shorter prefix lengths than 64 are allowed only if non-sequential names are in use.
.TP
.B --dumpfile=<path/to/file>
Specify the location of a pcap-format file which dnsmasq uses to dump copies of network packets for debugging purposes. If the file exists when dnsmasq starts, it is not deleted; new packets are added to the end.
@@ -904,7 +906,7 @@ compiled in and the kernel must have conntrack support
included and configured. This option cannot be combined with
.B --query-port.
.TP
.B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-addr>[,<end-addr>|<mode>][,<netmask>[,<broadcast>]][,<lease time>]
.B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-addr>[,<end-addr>|<mode>[,<netmask>[,<broadcast>]]][,<lease time>]
.TP
.B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-IPv6addr>[,<end-IPv6addr>|constructor:<interface>][,<mode>][,<prefix-len>][,<lease time>]
@@ -1164,7 +1166,7 @@ has both wired and wireless interfaces.
.TP
.B --dhcp-hostsfile=<path>
Read DHCP host information from the specified file. If a directory
is given, then read all the files contained in that directory. The file contains
is given, then read all the files contained in that directory in alphabetical order. The file contains
information about one host per line. The format of a line is the same
as text to the right of '=' in \fB--dhcp-host\fP. The advantage of storing DHCP host information
in this file is that it can be changed without re-starting dnsmasq:
@@ -1172,7 +1174,7 @@ the file will be re-read when dnsmasq receives SIGHUP.
.TP
.B --dhcp-optsfile=<path>
Read DHCP option information from the specified file. If a directory
is given, then read all the files contained in that directory. The advantage of
is given, then read all the files contained in that directory in alphabetical order. The advantage of
using this option is the same as for \fB--dhcp-hostsfile\fP: the
\fB--dhcp-optsfile\fP will be re-read when dnsmasq receives SIGHUP. Note that
it is possible to encode the information in a
@@ -1187,7 +1189,8 @@ directory, and not an individual file. Changed or new files within
the directory are read automatically, without the need to send SIGHUP.
If a file is deleted or changed after it has been read by dnsmasq, then the
host record it contained will remain until dnsmasq receives a SIGHUP, or
is restarted; ie host records are only added dynamically.
is restarted; ie host records are only added dynamically. The order in which the
files in a directory are read is not defined.
.TP
.B --dhcp-optsdir=<path>
This is equivalent to \fB--dhcp-optsfile\fP, with the differences noted for \fB--dhcp-hostsdir\fP.
@@ -1432,6 +1435,12 @@ Any number of set: and tag: forms may appear, in any order.
tag set by another
.B --tag-if,
the line which sets the tag must precede the one which tests it.
As an extension, the tag:<tag> clauses support limited wildcard matching,
similar to the matching in the \fB--interface\fP directive. This allows, for
example, using \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
with the tag:!<tag> format meaning that no tag matching the wildcard may be set.
.TP
.B \-J, --dhcp-ignore=tag:<tag>[,tag:<tag>]
When all the given tags appear in the tag set ignore the host and do
@@ -1612,10 +1621,11 @@ tried. This flag disables this check. Use with caution.
Extra logging for DHCP: log all the options sent to DHCP clients and
the tags used to determine them.
.TP
.B --quiet-dhcp, --quiet-dhcp6, --quiet-ra
.B --quiet-dhcp, --quiet-dhcp6, --quiet-ra, --quiet-tftp
Suppress logging of the routine operation of these protocols. Errors and
problems will still be logged. \fB--quiet-dhcp\fP and quiet-dhcp6 are
over-ridden by \fB--log-dhcp\fP.
problems will still be logged. \fB--quiet-tftp\fP does not consider file not
found to be an error. \fB--quiet-dhcp\fP and quiet-dhcp6 are over-ridden by
\fB--log-dhcp\fP.
.TP
.B \-l, --dhcp-leasefile=<path>
Use the specified file to store DHCP lease information.
@@ -2417,6 +2427,10 @@ following data is used to populate the authoritative zone.
.B --mx-host, --srv-host, --dns-rr, --txt-record, --naptr-record, --caa-record,
as long as the record names are in the authoritative domain.
.PP
.B --synth-domain
as long as the domain is in the authoritative zone and, for
reverse (PTR) queries, the address is in the relevant subnet.
.PP
.B --cname
as long as the record name is in the authoritative domain. If the
target of the CNAME is unqualified, then it is qualified with the
+671 -512
View File
File diff suppressed because it is too large. Load diff
+689 -524
View File
File diff suppressed because it is too large. Load diff
+731 -579
View File
File diff suppressed because it is too large. Load diff
+690 -525
View File
File diff suppressed because it is too large. Load diff
+698 -530
View File
File diff suppressed because it is too large. Load diff
+731 -579
View File
File diff suppressed because it is too large. Load diff
+717 -554
View File
File diff suppressed because it is too large. Load diff
+690 -524
View File
File diff suppressed because it is too large. Load diff
+731 -579
View File
File diff suppressed because it is too large. Load diff
+717 -554
View File
File diff suppressed because it is too large. Load diff
+55 -18
View File
@@ -105,7 +105,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
int nameoffset, axfroffset = 0;
int q, anscount = 0, authcount = 0;
struct crec *crecp;
int auth = !local_query, trunc = 0, nxdomain = 1, soa = 0, ns = 0, axfr = 0;
int auth = !local_query, trunc = 0, nxdomain = 1, soa = 0, ns = 0, axfr = 0, out_of_zone = 0;
struct auth_zone *zone = NULL;
struct addrlist *subnet = NULL;
char *cut;
@@ -146,6 +146,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if (qclass != C_IN)
{
auth = 0;
out_of_zone = 1;
continue;
}
@@ -159,6 +160,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if (!zone)
{
out_of_zone = 1;
auth = 0;
continue;
}
@@ -208,7 +210,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if (local_query || in_zone(zone, intr->name, NULL))
{
found = 1;
log_query(flag | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
log_query(flag | F_REVERSE | F_CONFIG, intr->name, &addr, NULL, 0);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL,
T_PTR, C_IN, "d", intr->name))
@@ -232,7 +234,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
strcat(name, ".");
strcat(name, zone->domain);
}
log_query(flag | F_DHCP | F_REVERSE, name, &addr, record_source(crecp->uid));
log_query(flag | F_DHCP | F_REVERSE, name, &addr, record_source(crecp->uid), 0);
found = 1;
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL,
@@ -241,7 +243,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
}
else if (crecp->flags & (F_DHCP | F_HOSTS) && (local_query || in_zone(zone, name, NULL)))
{
log_query(crecp->flags & ~F_FORWARD, name, &addr, record_source(crecp->uid));
log_query(crecp->flags & ~F_FORWARD, name, &addr, record_source(crecp->uid), 0);
found = 1;
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL,
@@ -253,10 +255,21 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
} while ((crecp = cache_find_by_addr(crecp, &addr, now, flag)));
if (!found && is_rev_synth(flag, &addr, name) && (local_query || in_zone(zone, name, NULL)))
{
log_query(F_CONFIG | F_REVERSE | flag, name, &addr, NULL, 0);
found = 1;
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL,
T_PTR, C_IN, "d", name))
anscount++;
}
if (found)
nxdomain = 0;
else
log_query(flag | F_NEG | F_NXDOMAIN | F_REVERSE | (auth ? F_AUTH : 0), NULL, &addr, NULL);
log_query(flag | F_NEG | F_NXDOMAIN | F_REVERSE | (auth ? F_AUTH : 0), NULL, &addr, NULL, 0);
continue;
}
@@ -273,6 +286,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if (!zone)
{
out_of_zone = 1;
auth = 0;
continue;
}
@@ -286,7 +300,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if (rc == 2 && qtype == T_MX)
{
found = 1;
log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>", 0);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
NULL, T_MX, C_IN, "sd", rec->weight, rec->target))
anscount++;
@@ -301,7 +315,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if (rc == 2 && qtype == T_SRV)
{
found = 1;
log_query(F_CONFIG | F_RRNAME, name, NULL, "<SRV>");
log_query(F_CONFIG | F_RRNAME, name, NULL, "<SRV>", 0);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
NULL, T_SRV, C_IN, "sssd",
rec->priority, rec->weight, rec->srvport, rec->target))
@@ -335,7 +349,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if (rc == 2 && txt->class == qtype)
{
found = 1;
log_query(F_CONFIG | F_RRNAME, name, NULL, querystr(NULL, txt->class));
log_query(F_CONFIG | F_RRNAME, name, NULL, NULL, txt->class);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
NULL, txt->class, C_IN, "t", txt->len, txt->txt))
anscount++;
@@ -349,7 +363,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if (rc == 2 && qtype == T_TXT)
{
found = 1;
log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>");
log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>", 0);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
NULL, T_TXT, C_IN, "t", txt->len, txt->txt))
anscount++;
@@ -363,7 +377,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if (rc == 2 && qtype == T_NAPTR)
{
found = 1;
log_query(F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>");
log_query(F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>", 0);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
NULL, T_NAPTR, C_IN, "sszzzd",
na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
@@ -393,13 +407,24 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
continue;
found = 1;
log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL, 0);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN,
qtype == T_A ? "4" : "6", &addrlist->addr))
anscount++;
}
}
if (!found && is_name_synthetic(flag, name, &addr) )
{
found = 1;
nxdomain = 0;
log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL, 0);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN, qtype == T_A ? "4" : "6", &addr))
anscount++;
}
if (!cut)
{
@@ -409,7 +434,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
{
auth = soa = 1; /* inhibits auth section */
found = 1;
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>");
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>", 0);
}
else if (qtype == T_AXFR)
{
@@ -446,14 +471,14 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
axfr = 1;
found = 1;
axfroffset = nameoffset;
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<AXFR>");
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<AXFR>", 0);
}
else if (qtype == T_NS)
{
auth = 1;
ns = 1; /* inhibits auth section */
found = 1;
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>");
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>", 0);
}
}
@@ -471,7 +496,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
(local_query || filter_zone(zone, flag, &(crecp->addr))))
{
*cut = '.'; /* restore domain part */
log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid));
log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid), 0);
*cut = 0; /* remove domain part */
found = 1;
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
@@ -493,7 +518,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
nxdomain = 0;
if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr))))
{
log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid));
log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid), 0);
found = 1;
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN,
@@ -541,7 +566,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if (candidate)
{
log_query(F_CONFIG | F_CNAME, name, NULL, NULL);
log_query(F_CONFIG | F_CNAME, name, NULL, NULL, 0);
strcpy(name, candidate->target);
if (!strchr(name, '.'))
{
@@ -559,7 +584,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
else if (cache_find_non_terminal(name, now))
nxdomain = 0;
log_query(flag | F_NEG | (nxdomain ? F_NXDOMAIN : 0) | F_FORWARD | F_AUTH, name, NULL, NULL);
log_query(flag | F_NEG | (nxdomain ? F_NXDOMAIN : 0) | F_FORWARD | F_AUTH, name, NULL, NULL, 0);
}
}
@@ -855,10 +880,22 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
SET_RCODE(header, NXDOMAIN);
else
SET_RCODE(header, NOERROR); /* no error */
header->ancount = htons(anscount);
header->nscount = htons(authcount);
header->arcount = htons(0);
if (!local_query && out_of_zone)
{
SET_RCODE(header, REFUSED);
header->ancount = htons(0);
header->nscount = htons(0);
addr.log.rcode = REFUSED;
addr.log.ede = EDE_NOT_AUTH;
log_query(F_UPSTREAM | F_RCODE, "error", &addr, NULL, 0);
return resize_packet(header, ansp - (unsigned char *)header, NULL, 0);
}
/* Advertise our packet size limit in our reply */
if (have_pseudoheader)
return add_pseudoheader(header, ansp - (unsigned char *)header, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
+110 -52
View File
@@ -30,50 +30,100 @@ static struct crec *really_insert(char *name, union all_addr *addr, unsigned sho
time_t now, unsigned long ttl, unsigned int flags);
/* type->string mapping: this is also used by the name-hash function as a mixing table. */
/* taken from https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml */
static const struct {
unsigned int type;
const char * const name;
} typestr[] = {
{ 1, "A" },
{ 2, "NS" },
{ 5, "CNAME" },
{ 6, "SOA" },
{ 10, "NULL" },
{ 11, "WKS" },
{ 12, "PTR" },
{ 13, "HINFO" },
{ 15, "MX" },
{ 16, "TXT" },
{ 22, "NSAP" },
{ 23, "NSAP_PTR" },
{ 24, "SIG" },
{ 25, "KEY" },
{ 28, "AAAA" },
{ 29, "LOC" },
{ 33, "SRV" },
{ 35, "NAPTR" },
{ 36, "KX" },
{ 37, "CERT" },
{ 38, "A6" },
{ 39, "DNAME" },
{ 41, "OPT" },
{ 43, "DS" },
{ 46, "RRSIG" },
{ 47, "NSEC" },
{ 48, "DNSKEY" },
{ 50, "NSEC3" },
{ 51, "NSEC3PARAM" },
{ 52, "TLSA" },
{ 53, "SMIMEA" },
{ 55, "HIP" },
{ 249, "TKEY" },
{ 250, "TSIG" },
{ 251, "IXFR" },
{ 252, "AXFR" },
{ 253, "MAILB" },
{ 254, "MAILA" },
{ 255, "ANY" },
{ 257, "CAA" }
{ 1, "A" }, /* a host address [RFC1035] */
{ 2, "NS" }, /* an authoritative name server [RFC1035] */
{ 3, "MD" }, /* a mail destination (OBSOLETE - use MX) [RFC1035] */
{ 4, "MF" }, /* a mail forwarder (OBSOLETE - use MX) [RFC1035] */
{ 5, "CNAME" }, /* the canonical name for an alias [RFC1035] */
{ 6, "SOA" }, /* marks the start of a zone of authority [RFC1035] */
{ 7, "MB" }, /* a mailbox domain name (EXPERIMENTAL) [RFC1035] */
{ 8, "MG" }, /* a mail group member (EXPERIMENTAL) [RFC1035] */
{ 9, "MR" }, /* a mail rename domain name (EXPERIMENTAL) [RFC1035] */
{ 10, "NULL" }, /* a null RR (EXPERIMENTAL) [RFC1035] */
{ 11, "WKS" }, /* a well known service description [RFC1035] */
{ 12, "PTR" }, /* a domain name pointer [RFC1035] */
{ 13, "HINFO" }, /* host information [RFC1035] */
{ 14, "MINFO" }, /* mailbox or mail list information [RFC1035] */
{ 15, "MX" }, /* mail exchange [RFC1035] */
{ 16, "TXT" }, /* text strings [RFC1035] */
{ 17, "RP" }, /* for Responsible Person [RFC1183] */
{ 18, "AFSDB" }, /* for AFS Data Base location [RFC1183][RFC5864] */
{ 19, "X25" }, /* for X.25 PSDN address [RFC1183] */
{ 20, "ISDN" }, /* for ISDN address [RFC1183] */
{ 21, "RT" }, /* for Route Through [RFC1183] */
{ 22, "NSAP" }, /* for NSAP address, NSAP style A record [RFC1706] */
{ 23, "NSAP_PTR" }, /* for domain name pointer, NSAP style [RFC1348][RFC1637][RFC1706] */
{ 24, "SIG" }, /* for security signature [RFC2535][RFC2536][RFC2537][RFC2931][RFC3008][RFC3110][RFC3755][RFC4034] */
{ 25, "KEY" }, /* for security key [RFC2535][RFC2536][RFC2537][RFC2539][RFC3008][RFC3110][RFC3755][RFC4034] */
{ 26, "PX" }, /* X.400 mail mapping information [RFC2163] */
{ 27, "GPOS" }, /* Geographical Position [RFC1712] */
{ 28, "AAAA" }, /* IP6 Address [RFC3596] */
{ 29, "LOC" }, /* Location Information [RFC1876] */
{ 30, "NXT" }, /* Next Domain (OBSOLETE) [RFC2535][RFC3755] */
{ 31, "EID" }, /* Endpoint Identifier [Michael_Patton][http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt] 1995-06*/
{ 32, "NIMLOC" }, /* Nimrod Locator [1][Michael_Patton][http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt] 1995-06*/
{ 33, "SRV" }, /* Server Selection [1][RFC2782] */
{ 34, "ATMA" }, /* ATM Address [ ATM Forum Technical Committee, "ATM Name System, V2.0", Doc ID: AF-DANS-0152.000, July 2000. Available from and held in escrow by IANA.] */
{ 35, "NAPTR" }, /* Naming Authority Pointer [RFC2168][RFC2915][RFC3403] */
{ 36, "KX" }, /* Key Exchanger [RFC2230] */
{ 37, "CERT" }, /* CERT [RFC4398] */
{ 38, "A6" }, /* A6 (OBSOLETE - use AAAA) [RFC2874][RFC3226][RFC6563] */
{ 39, "DNAME" }, /* DNAME [RFC6672] */
{ 40, "SINK" }, /* SINK [Donald_E_Eastlake][http://tools.ietf.org/html/draft-eastlake-kitchen-sink] 1997-11*/
{ 41, "OPT" }, /* OPT [RFC3225][RFC6891] */
{ 42, "APL" }, /* APL [RFC3123] */
{ 43, "DS" }, /* Delegation Signer [RFC3658][RFC4034] */
{ 44, "SSHFP" }, /* SSH Key Fingerprint [RFC4255] */
{ 45, "IPSECKEY" }, /* IPSECKEY [RFC4025] */
{ 46, "RRSIG" }, /* RRSIG [RFC3755][RFC4034] */
{ 47, "NSEC" }, /* NSEC [RFC3755][RFC4034][RFC9077] */
{ 48, "DNSKEY" }, /* DNSKEY [RFC3755][RFC4034] */
{ 49, "DHCID" }, /* DHCID [RFC4701] */
{ 50, "NSEC3" }, /* NSEC3 [RFC5155][RFC9077] */
{ 51, "NSEC3PARAM" }, /* NSEC3PARAM [RFC5155] */
{ 52, "TLSA" }, /* TLSA [RFC6698] */
{ 53, "SMIMEA" }, /* S/MIME cert association [RFC8162] SMIMEA/smimea-completed-template 2015-12-01*/
{ 55, "HIP" }, /* Host Identity Protocol [RFC8005] */
{ 56, "NINFO" }, /* NINFO [Jim_Reid] NINFO/ninfo-completed-template 2008-01-21*/
{ 57, "RKEY" }, /* RKEY [Jim_Reid] RKEY/rkey-completed-template 2008-01-21*/
{ 58, "TALINK" }, /* Trust Anchor LINK [Wouter_Wijngaards] TALINK/talink-completed-template 2010-02-17*/
{ 59, "CDS" }, /* Child DS [RFC7344] CDS/cds-completed-template 2011-06-06*/
{ 60, "CDNSKEY" }, /* DNSKEY(s) the Child wants reflected in DS [RFC7344] 2014-06-16*/
{ 61, "OPENPGPKEY" }, /* OpenPGP Key [RFC7929] OPENPGPKEY/openpgpkey-completed-template 2014-08-12*/
{ 62, "CSYNC" }, /* Child-To-Parent Synchronization [RFC7477] 2015-01-27*/
{ 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*/
{ 65, "HTTPS" }, /* HTTPS Binding [draft-ietf-dnsop-svcb-https-00] HTTPS/https-completed-template 2020-06-30*/
{ 99, "SPF" }, /* [RFC7208] */
{ 100, "UINFO" }, /* [IANA-Reserved] */
{ 101, "UID" }, /* [IANA-Reserved] */
{ 102, "GID" }, /* [IANA-Reserved] */
{ 103, "UNSPEC" }, /* [IANA-Reserved] */
{ 104, "NID" }, /* [RFC6742] ILNP/nid-completed-template */
{ 105, "L32" }, /* [RFC6742] ILNP/l32-completed-template */
{ 106, "L64" }, /* [RFC6742] ILNP/l64-completed-template */
{ 107, "LP" }, /* [RFC6742] ILNP/lp-completed-template */
{ 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*/
{ 249, "TKEY" }, /* Transaction Key [RFC2930] */
{ 250, "TSIG" }, /* Transaction Signature [RFC8945] */
{ 251, "IXFR" }, /* incremental transfer [RFC1995] */
{ 252, "AXFR" }, /* transfer of an entire zone [RFC1035][RFC5936] */
{ 253, "MAILB" }, /* mailbox-related RRs (MB, MG or MR) [RFC1035] */
{ 254, "MAILA" }, /* mail agent RRs (OBSOLETE - see MX) [RFC1035] */
{ 255, "ANY" }, /* A request for some or all records the server has available [RFC1035][RFC6895][RFC8482] */
{ 256, "URI" }, /* URI [RFC7553] URI/uri-completed-template 2011-02-22*/
{ 257, "CAA" }, /* Certification Authority Restriction [RFC8659] CAA/caa-completed-template 2011-04-07*/
{ 258, "AVC" }, /* Application Visibility and Control [Wolfgang_Riedel] AVC/avc-completed-template 2016-02-26*/
{ 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*/
{ 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] */
};
static void cache_free(struct crec *crecp);
@@ -488,8 +538,6 @@ struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class
else
#endif
{
/* Don't log DNSSEC records here, done elsewhere */
log_query(flags | F_UPSTREAM, name, addr, NULL);
if (daemon->max_cache_ttl != 0 && daemon->max_cache_ttl < ttl)
ttl = daemon->max_cache_ttl;
if (daemon->min_cache_ttl != 0 && daemon->min_cache_ttl > ttl)
@@ -1807,7 +1855,7 @@ char *record_source(unsigned int index)
return "<unknown>";
}
char *querystr(char *desc, unsigned short type)
static char *querystr(char *desc, unsigned short type)
{
unsigned int i;
int len = 10; /* strlen("type=xxxxx") */
@@ -1855,7 +1903,7 @@ char *querystr(char *desc, unsigned short type)
if (types)
sprintf(buff, "<%s>", types);
else
sprintf(buff, "type=%d", type);
sprintf(buff, "<type=%d>", type);
}
}
@@ -1895,19 +1943,30 @@ static char *edestr(int ede)
}
}
void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg)
void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg, unsigned short type)
{
char *source, *dest = daemon->addrbuff;
char *source, *dest = arg;
char *verb = "is";
char *extra = "";
if (!option_bool(OPT_LOG))
return;
/* build query type string if requested */
if(type > 0)
arg = querystr(arg, type);
#ifdef HAVE_DNSSEC
if ((flags & F_DNSSECOK) && option_bool(OPT_EXTRALOG))
extra = " (DNSSEC signed)";
#endif
name = sanitise(name);
if (addr)
{
dest = daemon->addrbuff;
if (flags & F_KEYTAG)
sprintf(daemon->addrbuff, arg, addr->log.keytag, addr->log.algo, addr->log.digest);
else if (flags & F_RCODE)
@@ -1929,13 +1988,12 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg)
sprintf(extra, " (EDE: %s)", edestr(addr->log.ede));
}
}
else
else if (flags & (F_IPV4 | F_IPV6))
inet_ntop(flags & F_IPV4 ? AF_INET : AF_INET6,
addr, daemon->addrbuff, ADDRSTRLEN);
else
dest = arg;
}
else
dest = arg;
if (flags & F_REVERSE)
{
@@ -1974,7 +2032,7 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg)
source = "reply";
else if (flags & F_SECSTAT)
{
if (addr && addr->log.ede != EDE_UNSET)
if (addr && addr->log.ede != EDE_UNSET && option_bool(OPT_EXTRALOG))
{
extra = daemon->addrbuff;
sprintf(extra, " (EDE: %s)", edestr(addr->log.ede));
@@ -2023,5 +2081,5 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg)
}
}
else
my_syslog(LOG_INFO, "%s %s %s %s", source, name, verb, dest);
my_syslog(LOG_INFO, "%s %s %s %s%s", source, name, verb, dest, extra);
}
+36 -1
View File
@@ -79,13 +79,46 @@ ssize_t recv_dhcp_packet(int fd, struct msghdr *msg)
return (msg->msg_flags & MSG_TRUNC) ? -1 : new_sz;
}
/* like match_netid() except that the check can have a trailing * for wildcard */
/* started as a direct copy of match_netid() */
int match_netid_wild(struct dhcp_netid *check, struct dhcp_netid *pool)
{
struct dhcp_netid *tmp1;
for (; check; check = check->next)
{
const int check_len = strlen(check->net);
const int is_wc = (check->net[check_len - 1] == '*');
/* '#' for not is for backwards compat. */
if (check->net[0] != '!' && check->net[0] != '#')
{
for (tmp1 = pool; tmp1; tmp1 = tmp1->next)
if (is_wc ? (strncmp(check->net, tmp1->net, check_len-1) == 0) :
(strcmp(check->net, tmp1->net) == 0))
break;
if (!tmp1)
return 0;
}
else
for (tmp1 = pool; tmp1; tmp1 = tmp1->next)
if (is_wc ? (strncmp((check->net)+1, tmp1->net, check_len-2) == 0) :
(strcmp((check->net)+1, tmp1->net) == 0))
return 0;
}
return 1;
}
struct dhcp_netid *run_tag_if(struct dhcp_netid *tags)
{
struct tag_if *exprs;
struct dhcp_netid_list *list;
/* this now uses match_netid_wild() above so that tag_if can
* be used to set a 'group of interfaces' tag.
*/
for (exprs = daemon->tag_if; exprs; exprs = exprs->next)
if (match_netid(exprs->tag, tags, 1))
if (match_netid_wild(exprs->tag, tags))
for (list = exprs->set; list; list = list->next)
{
list->list->next = tags;
@@ -620,6 +653,8 @@ static const struct opttab_t {
{ "client-arch", 93, 2 | OT_DEC },
{ "client-interface-id", 94, 0 },
{ "client-machine-id", 97, 0 },
{ "posix-timezone", 100, OT_NAME }, /* RFC 4833, Sec. 2 */
{ "tzdb-timezone", 101, OT_NAME }, /* RFC 4833, Sec. 2 */
{ "subnet-select", 118, OT_INTERNAL },
{ "domain-search", 119, OT_RFC1035_NAME },
{ "sip-server", 120, 0 },
+12 -7
View File
@@ -468,8 +468,11 @@ void dhcp_packet(time_t now, int pxe_fd)
/* This can fail when, eg, iptables DROPS destination 255.255.255.255 */
if (errno != 0)
my_syslog(MS_DHCP | LOG_WARNING, _("Error sending DHCP packet to %s: %s"),
inet_ntoa(dest.sin_addr), strerror(errno));
{
inet_ntop(AF_INET, &dest.sin_addr, daemon->addrbuff, ADDRSTRLEN);
my_syslog(MS_DHCP | LOG_WARNING, _("Error sending DHCP packet to %s: %s"),
daemon->addrbuff, strerror(errno));
}
}
/* check against secondary interface addresses */
@@ -521,10 +524,11 @@ static void guess_range_netmask(struct in_addr addr, struct in_addr netmask)
!(is_same_net(addr, context->start, netmask) &&
is_same_net(addr, context->end, netmask)))
{
strcpy(daemon->dhcp_buff, inet_ntoa(context->start));
strcpy(daemon->dhcp_buff2, inet_ntoa(context->end));
inet_ntop(AF_INET, &context->start, daemon->dhcp_buff, DHCP_BUFF_SZ);
inet_ntop(AF_INET, &context->end, daemon->dhcp_buff2, DHCP_BUFF_SZ);
inet_ntop(AF_INET, &netmask, daemon->addrbuff, ADDRSTRLEN);
my_syslog(MS_DHCP | LOG_WARNING, _("DHCP range %s -- %s is not consistent with netmask %s"),
daemon->dhcp_buff, daemon->dhcp_buff2, inet_ntoa(netmask));
daemon->dhcp_buff, daemon->dhcp_buff2, daemon->addrbuff);
}
context->netmask = netmask;
}
@@ -922,7 +926,7 @@ void dhcp_read_ethers(void)
if (!*cp)
{
if ((addr.s_addr = inet_addr(ip)) == (in_addr_t)-1)
if (inet_pton(AF_INET, ip, &addr.s_addr) < 1)
{
my_syslog(MS_DHCP | LOG_ERR, _("bad address at %s line %d"), ETHERSFILE, lineno);
continue;
@@ -1097,7 +1101,8 @@ static int relay_upstream4(struct dhcp_relay *relay, struct dhcp_packet *mess,
if (option_bool(OPT_LOG_OPTS))
{
inet_ntop(AF_INET, &relay->local, daemon->addrbuff, ADDRSTRLEN);
my_syslog(MS_DHCP | LOG_INFO, _("DHCP relay %s -> %s"), daemon->addrbuff, inet_ntoa(relay->server.addr4));
inet_ntop(AF_INET, &relay->server.addr4, daemon->dhcp_buff2, DHCP_BUFF_SZ);
my_syslog(MS_DHCP | LOG_INFO, _("DHCP relay %s -> %s"), daemon->addrbuff, daemon->dhcp_buff2);
}
/* Save this for replies */
+7 -3
View File
@@ -109,7 +109,6 @@ int main (int argc, char **argv)
daemon->packet_buff_sz = daemon->edns_pktsz + MAXDNAME + RRFIXEDSZ;
daemon->packet = safe_malloc(daemon->packet_buff_sz);
daemon->addrbuff = safe_malloc(ADDRSTRLEN);
if (option_bool(OPT_EXTRALOG))
daemon->addrbuff2 = safe_malloc(ADDRSTRLEN);
@@ -212,8 +211,13 @@ int main (int argc, char **argv)
#endif
#ifdef HAVE_CONNTRACK
if (option_bool(OPT_CONNTRACK) && (daemon->query_port != 0 || daemon->osport))
die (_("cannot use --conntrack AND --query-port"), NULL, EC_BADCONF);
if (option_bool(OPT_CONNTRACK))
{
if (daemon->query_port != 0 || daemon->osport)
die (_("cannot use --conntrack AND --query-port"), NULL, EC_BADCONF);
need_cap_net_admin = 1;
}
#else
if (option_bool(OPT_CONNTRACK))
die(_("conntrack support not available: set HAVE_CONNTRACK in src/config.h"), NULL, EC_BADCONF);
+6 -5
View File
@@ -107,6 +107,7 @@ typedef unsigned long long u64;
#endif
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
@@ -273,7 +274,8 @@ struct event_desc {
#define OPT_UMBRELLA 63
#define OPT_UMBRELLA_DEVID 64
#define OPT_CMARK_ALST_EN 65
#define OPT_LAST 66
#define OPT_QUIET_TFTP 66
#define OPT_LAST 67
#define OPTION_BITS (sizeof(unsigned int)*8)
#define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) )
@@ -959,10 +961,10 @@ struct dhcp_bridge {
};
struct cond_domain {
char *domain, *prefix;
char *domain, *prefix; /* prefix is text-prefix on domain name */
struct in_addr start, end;
struct in6_addr start6, end6;
int is6, indexed;
int is6, indexed, prefixlen;
struct cond_domain *next;
};
@@ -1243,9 +1245,8 @@ extern struct daemon {
/* cache.c */
void cache_init(void);
void next_uid(struct crec *crecp);
void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg);
void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg, unsigned short type);
char *record_source(unsigned int index);
char *querystr(char *desc, unsigned short type);
int cache_find_non_terminal(char *name, time_t now);
struct crec *cache_find_by_addr(struct crec *crecp,
union all_addr *addr, time_t now,
+10 -10
View File
@@ -954,9 +954,9 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
a.log.keytag = keytag;
a.log.algo = algo;
if (algo_digest_name(algo))
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu");
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu", 0);
else
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu (not supported)");
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu (not supported)", 0);
}
}
}
@@ -973,7 +973,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
return STAT_OK;
}
log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "BOGUS DNSKEY");
log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "BOGUS DNSKEY", 0);
return STAT_BOGUS | failflags;
}
@@ -1012,7 +1012,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
if (STAT_ISEQUAL(rc, STAT_INSECURE))
{
my_syslog(LOG_WARNING, _("Insecure DS reply received for %s, check domain configuration and upstream DNS server DNSSEC support"), name);
log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "BOGUS DS - not secure");
log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "BOGUS DS - not secure", 0);
return STAT_BOGUS | DNSSEC_FAIL_INDET;
}
@@ -1025,7 +1025,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
from the DS's zone, and not the parent zone. */
if (STAT_ISEQUAL(rc, STAT_NEED_KEY) && hostname_isequal(name, keyname))
{
log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "BOGUS DS");
log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "BOGUS DS", 0);
return STAT_BOGUS;
}
@@ -1081,9 +1081,9 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
a.log.algo = algo;
a.log.digest = digest;
if (ds_digest_name(digest) && algo_digest_name(algo))
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu");
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu", 0);
else
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu (not supported)");
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu (not supported)", 0);
}
}
@@ -1116,7 +1116,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
cache_end_insert();
log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, nons ? "no DS/cut" : "no DS");
log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, nons ? "no DS/cut" : "no DS", 0);
}
return STAT_OK;
@@ -1893,7 +1893,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
/* Find all the targets we're looking for answers to.
The zeroth array element is for the query, subsequent ones
for CNAME targets, unless the query is for a CNAME. */
for CNAME targets, unless the query is for a CNAME or ANY. */
if (!expand_workspace(&targets, &target_sz, 0))
return STAT_BOGUS;
@@ -1912,7 +1912,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
if (qtype == T_RRSIG)
return STAT_INSECURE;
if (qtype != T_CNAME)
if (qtype != T_CNAME && qtype != T_ANY)
for (j = ntohs(header->ancount); j != 0; j--)
{
if (!(p1 = skip_name(p1, header, plen, 10)))
+3 -3
View File
@@ -393,7 +393,7 @@ size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header
union all_addr addr;
if (flags & (F_NXDOMAIN | F_NOERR))
log_query(flags | gotname | F_NEG | F_CONFIG | F_FORWARD, name, NULL, NULL);
log_query(flags | gotname | F_NEG | F_CONFIG | F_FORWARD, name, NULL, NULL, 0);
setup_reply(header, flags, ede);
@@ -412,7 +412,7 @@ size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header
header->ancount = htons(ntohs(header->ancount) + 1);
add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_A, C_IN, "4", &addr);
log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV6, name, (union all_addr *)&addr, NULL);
log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV6, name, (union all_addr *)&addr, NULL, 0);
}
if (flags & gotname & F_IPV6)
@@ -427,7 +427,7 @@ size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header
header->ancount = htons(ntohs(header->ancount) + 1);
add_resource_record(header, limit, &trunc, sizeof(struct dns_header), &p, daemon->local_ttl, NULL, T_AAAA, C_IN, "6", &addr);
log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV4, name, (union all_addr *)&addr, NULL);
log_query((flags | F_CONFIG | F_FORWARD) & ~F_IPV4, name, (union all_addr *)&addr, NULL, 0);
}
if (trunc)
+36 -32
View File
@@ -18,8 +18,9 @@
static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c);
static int match_domain(struct in_addr addr, struct cond_domain *c);
static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c);
static int match_domain6(struct in6_addr *addr, struct cond_domain *c);
int is_name_synthetic(int flags, char *name, union all_addr *addr)
{
@@ -135,28 +136,9 @@ int is_name_synthetic(int flags, char *name, union all_addr *addr)
}
if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, addr))
{
if (prot == AF_INET)
{
if (!c->is6 &&
ntohl(addr->addr4.s_addr) >= ntohl(c->start.s_addr) &&
ntohl(addr->addr4.s_addr) <= ntohl(c->end.s_addr))
found = 1;
}
else
{
u64 addrpart = addr6part(&addr->addr6);
if (c->is6 &&
is_same_net6(&addr->addr6, &c->start6, 64) &&
addrpart >= addr6part(&c->start6) &&
addrpart <= addr6part(&c->end6))
found = 1;
}
}
found = (prot == AF_INET) ? match_domain(addr->addr4, c) : match_domain6(&addr->addr6, c);
}
/* restore name */
for (p = tail; *p; p++)
if (*p == '.' || *p == ':')
@@ -246,14 +228,22 @@ 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))
return 1;
return 0;
}
static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c)
{
for (; c; c = c->next)
if (!c->is6 &&
ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
if (match_domain(addr, c))
return c;
return NULL;
}
@@ -267,16 +257,30 @@ char *get_domain(struct in_addr addr)
return daemon->domain_suffix;
}
static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c)
static int match_domain6(struct in6_addr *addr, struct cond_domain *c)
{
u64 addrpart = addr6part(addr);
if (c->is6)
{
if (c->prefixlen >= 64)
{
if (is_same_net6(addr, &c->start6, 64) &&
addrpart >= addr6part(&c->start6) &&
addrpart <= addr6part(&c->end6))
return 1;
}
else if (is_same_net6(addr, &c->start6, c->prefixlen))
return 1;
}
return 0;
}
static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c)
{
for (; c; c = c->next)
if (c->is6 &&
is_same_net6(addr, &c->start6, 64) &&
addrpart >= addr6part(&c->start6) &&
addrpart <= addr6part(&c->end6))
if (match_domain6(addr, c))
return c;
return NULL;
+50 -47
View File
@@ -119,12 +119,12 @@ static void set_outgoing_mark(struct frec *forward, int fd)
}
#endif
static void log_query_mysockaddr(unsigned int flags, char *name, union mysockaddr *addr, char *arg)
static void log_query_mysockaddr(unsigned int flags, char *name, union mysockaddr *addr, char *arg, unsigned short type)
{
if (addr->sa.sa_family == AF_INET)
log_query(flags | F_IPV4, name, (union all_addr *)&addr->in.sin_addr, arg);
log_query(flags | F_IPV4, name, (union all_addr *)&addr->in.sin_addr, arg, type);
else
log_query(flags | F_IPV6, name, (union all_addr *)&addr->in6.sin6_addr, arg);
log_query(flags | F_IPV6, name, (union all_addr *)&addr->in6.sin6_addr, arg, type);
}
static void server_send(struct server *server, int fd,
@@ -138,12 +138,13 @@ static void server_send(struct server *server, int fd,
#ifdef HAVE_DNSSEC
static void server_send_log(struct server *server, int fd,
const void *header, size_t plen, int dumpflags,
unsigned int logflags, char *name, char *arg)
unsigned int logflags, char *name, char *arg,
unsigned short type)
{
#ifdef HAVE_DUMPFILE
dump_packet(dumpflags, (void *)header, (size_t)plen, NULL, &server->addr);
#endif
log_query_mysockaddr(logflags, name, &server->addr, arg);
log_query_mysockaddr(logflags, name, &server->addr, arg, type);
server_send(server, fd, header, plen, 0);
}
#endif
@@ -255,29 +256,25 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
/* new query */
if (!forward)
{
/* new query */
if (lookup_domain(daemon->namebuff, gotname, &first, &last))
flags = is_local_answer(now, first, daemon->namebuff);
else
{
/* no available server. */
ede = EDE_NOT_READY;
flags = 0;
}
/* don't forward A or AAAA queries for simple names, except the empty name */
if (option_bool(OPT_NODOTS_LOCAL) &&
if (!flags &&
option_bool(OPT_NODOTS_LOCAL) &&
(gotname & (F_IPV4 | F_IPV6)) &&
!strchr(daemon->namebuff, '.') &&
strlen(daemon->namebuff) != 0)
{
flags = F_NOERR;
goto reply;
}
flags = 0;
/* no available server. */
if (!lookup_domain(daemon->namebuff, gotname, &first, &last))
{
ede = EDE_NOT_READY;
goto reply;
}
flags = check_for_local_domain(daemon->namebuff, now) ? F_NOERR : F_NXDOMAIN;
/* Configured answer. */
if ((flags = is_local_answer(now, first, daemon->namebuff)))
if (flags || ede == EDE_NOT_READY)
goto reply;
master = daemon->serverarray[first];
@@ -498,12 +495,12 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
if (!gotname)
strcpy(daemon->namebuff, "query");
log_query_mysockaddr(F_SERVER | F_FORWARD, daemon->namebuff,
&srv->addr, NULL);
&srv->addr, NULL, 0);
}
#ifdef HAVE_DNSSEC
else
log_query_mysockaddr(F_NOEXTRA | F_DNSSEC, daemon->namebuff, &srv->addr,
querystr("dnssec-retry", (forward->flags & FREC_DNSKEY_QUERY) ? T_DNSKEY : T_DS));
"dnssec-retry", (forward->flags & FREC_DNSKEY_QUERY) ? T_DNSKEY : T_DS);
#endif
srv->queries++;
@@ -537,7 +534,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
{
u16 swap = htons((u16)ede);
if (ede != -EDE_UNSET)
if (ede != EDE_UNSET)
plen = add_pseudoheader(header, plen, (unsigned char *)limit, daemon->edns_pktsz, EDNS0_OPTION_EDE, (unsigned char *)&swap, 2, do_bit, 0);
else
plen = add_pseudoheader(header, plen, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
@@ -657,7 +654,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
union all_addr a;
a.log.rcode = rcode;
a.log.ede = ede;
log_query(F_UPSTREAM | F_RCODE, "error", &a, NULL);
log_query(F_UPSTREAM | F_RCODE, "error", &a, NULL, 0);
return resize_packet(header, n, pheader, plen);
}
@@ -893,7 +890,7 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,
#endif
server_send_log(server, fd, header, nn, DUMP_SEC_QUERY,
F_NOEXTRA | F_DNSSEC, daemon->keyname,
querystr("dnssec-query", STAT_ISEQUAL(status, STAT_NEED_KEY) ? T_DNSKEY : T_DS));
"dnssec-query", STAT_ISEQUAL(status, STAT_NEED_KEY) ? T_DNSKEY : T_DS);
server->queries++;
}
@@ -1140,7 +1137,7 @@ static void return_reply(time_t now, struct frec *forward, struct dns_header *he
domain = daemon->namebuff;
}
log_query(F_SECSTAT, domain, &a, result);
log_query(F_SECSTAT, domain, &a, result, 0);
}
}
#endif
@@ -1206,7 +1203,7 @@ static void return_reply(time_t now, struct frec *forward, struct dns_header *he
{
daemon->log_display_id = src->log_id;
daemon->log_source_addr = &src->source;
log_query(F_UPSTREAM, "query", NULL, "duplicate");
log_query(F_UPSTREAM, "query", NULL, "duplicate", 0);
}
}
}
@@ -1513,10 +1510,8 @@ void receive_query(struct listener *listen, time_t now)
#ifdef HAVE_AUTH
struct auth_zone *zone;
#endif
char *types = querystr(auth_dns ? "auth" : "query", type);
log_query_mysockaddr(F_QUERY | F_FORWARD, daemon->namebuff,
&source_addr, types);
&source_addr, auth_dns ? "auth" : "query", type);
#ifdef HAVE_CONNTRACK
is_single_query = 1;
@@ -1812,7 +1807,7 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
daemon->log_display_id = ++daemon->log_id;
log_query_mysockaddr(F_NOEXTRA | F_DNSSEC, keyname, &server->addr,
querystr("dnssec-query", STAT_ISEQUAL(new_status, STAT_NEED_KEY) ? T_DNSKEY : T_DS));
"dnssec-query", STAT_ISEQUAL(new_status, STAT_NEED_KEY) ? T_DNSKEY : T_DS);
new_status = tcp_key_recurse(now, new_status, new_header, m, class, name, keyname, server, have_mark, mark, keycount);
@@ -1950,11 +1945,10 @@ unsigned char *tcp_request(int confd, time_t now,
#ifdef HAVE_AUTH
struct auth_zone *zone;
#endif
char *types = querystr(auth_dns ? "auth" : "query", qtype);
log_query_mysockaddr(F_QUERY | F_FORWARD, daemon->namebuff,
&peer_addr, types);
&peer_addr, auth_dns ? "auth" : "query", qtype);
#ifdef HAVE_CONNTRACK
is_single_query = 1;
#endif
@@ -2037,16 +2031,25 @@ unsigned char *tcp_request(int confd, time_t now,
{
struct server *master;
int start;
if (lookup_domain(daemon->namebuff, gotname, &first, &last))
flags = is_local_answer(now, first, daemon->namebuff);
else
{
/* No configured servers */
ede = EDE_NOT_READY;
flags = 0;
}
/* don't forward A or AAAA queries for simple names, except the empty name */
if (option_bool(OPT_NODOTS_LOCAL) &&
if (!flags &&
option_bool(OPT_NODOTS_LOCAL) &&
(gotname & (F_IPV4 | F_IPV6)) &&
!strchr(daemon->namebuff, '.') &&
strlen(daemon->namebuff) != 0)
flags = F_NOERR;
else if (!lookup_domain(daemon->namebuff, gotname, &first, &last))
ede = EDE_NOT_READY; /* No configured servers */
else if (!(flags = is_local_answer(now, first, daemon->namebuff)))
flags = check_for_local_domain(daemon->namebuff, now) ? F_NOERR : F_NXDOMAIN;
if (!flags && ede != EDE_NOT_READY)
{
master = daemon->serverarray[first];
@@ -2084,7 +2087,7 @@ unsigned char *tcp_request(int confd, time_t now,
/* get query name again for logging - may have been overwritten */
if (!(gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
strcpy(daemon->namebuff, "query");
log_query_mysockaddr(F_SERVER | F_FORWARD, daemon->namebuff, &serv->addr, NULL);
log_query_mysockaddr(F_SERVER | F_FORWARD, daemon->namebuff, &serv->addr, NULL, 0);
#ifdef HAVE_DNSSEC
if (option_bool(OPT_DNSSEC_VALID) && !checking_disabled && (master->flags & SERV_DO_DNSSEC))
@@ -2093,10 +2096,10 @@ unsigned char *tcp_request(int confd, time_t now,
int status = tcp_key_recurse(now, STAT_OK, header, m, 0, daemon->namebuff, daemon->keyname,
serv, have_mark, mark, &keycount);
char *result, *domain = "result";
union all_addr a;
a.log.ede = ede = errflags_to_ede(status);
if (STAT_ISEQUAL(status, STAT_ABANDONED))
{
result = "ABANDONED";
@@ -2116,7 +2119,7 @@ unsigned char *tcp_request(int confd, time_t now,
domain = daemon->namebuff;
}
log_query(F_SECSTAT, domain, &a, result);
log_query(F_SECSTAT, domain, &a, result, 0);
}
#endif
@@ -2137,7 +2140,7 @@ unsigned char *tcp_request(int confd, time_t now,
}
}
}
/* In case of local answer or no connections made. */
if (m == 0)
{
+7 -7
View File
@@ -76,9 +76,9 @@ unsigned char *hash_questions(struct dns_header *header, size_t plen, char *name
#else /* HAVE_DNSSEC || HAVE_CRYPTOHASH */
#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest
typedef unsigned char BYTE; // 8-bit byte
typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines
#define SHA256_BLOCK_SIZE 32 /* SHA256 outputs a 32 byte digest */
typedef unsigned char BYTE; /* 8-bit byte */
typedef unsigned int WORD; /* 32-bit word, change to "long" for 16-bit machines */
typedef struct {
BYTE data[64];
@@ -238,7 +238,7 @@ static void sha256_final(SHA256_CTX *ctx, BYTE hash[])
i = ctx->datalen;
// Pad whatever data is left in the buffer.
/* Pad whatever data is left in the buffer. */
if (ctx->datalen < 56)
{
ctx->data[i++] = 0x80;
@@ -254,7 +254,7 @@ static void sha256_final(SHA256_CTX *ctx, BYTE hash[])
memset(ctx->data, 0, 56);
}
// Append to the padding the total message's length in bits and transform.
/* Append to the padding the total message's length in bits and transform. */
ctx->bitlen += ctx->datalen * 8;
ctx->data[63] = ctx->bitlen;
ctx->data[62] = ctx->bitlen >> 8;
@@ -266,8 +266,8 @@ static void sha256_final(SHA256_CTX *ctx, BYTE hash[])
ctx->data[56] = ctx->bitlen >> 56;
sha256_transform(ctx, ctx->data);
// Since this implementation uses little endian byte ordering and SHA uses big endian,
// reverse all the bytes when copying the final state to the output hash.
/* Since this implementation uses little endian byte ordering and SHA uses big endian,
reverse all the bytes when copying the final state to the output hash. */
for (i = 0; i < 4; ++i)
{
hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
+9 -3
View File
@@ -432,7 +432,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
buf = grab_extradata_lua(buf, end, "relay_address");
else if (data.giaddr.s_addr != 0)
{
lua_pushstring(lua, inet_ntoa(data.giaddr));
inet_ntop(AF_INET, &data.giaddr, daemon->addrbuff, ADDRSTRLEN);
lua_pushstring(lua, daemon->addrbuff);
lua_setfield(lua, -2, "relay_address");
}
@@ -610,8 +611,13 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
if (is6)
buf = grab_extradata(buf, end, "DNSMASQ_RELAY_ADDRESS", &err);
else
my_setenv("DNSMASQ_RELAY_ADDRESS", data.giaddr.s_addr != 0 ? inet_ntoa(data.giaddr) : NULL, &err);
else
{
const char *giaddr = NULL;
if (data.giaddr.s_addr != 0)
giaddr = inet_ntop(AF_INET, &data.giaddr, daemon->addrbuff, ADDRSTRLEN);
my_setenv("DNSMASQ_RELAY_ADDRESS", giaddr, &err);
}
for (i = 0; buf; i++)
{
+1 -1
View File
@@ -1688,7 +1688,7 @@ int reload_servers(char *fname)
memset(&addr, 0, sizeof(addr));
memset(&source_addr, 0, sizeof(source_addr));
if ((addr.in.sin_addr.s_addr = inet_addr(token)) != (in_addr_t) -1)
if (inet_pton(AF_INET, token, &addr.in.sin_addr) > 0)
{
#ifdef HAVE_SOCKADDR_SA_LEN
source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
+87 -39
View File
@@ -173,6 +173,7 @@ struct myoption {
#define LOPT_UMBRELLA 364
#define LOPT_CMARK_ALST_EN 365
#define LOPT_CMARK_ALST 366
#define LOPT_QUIET_TFTP 367
#ifdef HAVE_GETOPT_LONG
static const struct option opts[] =
@@ -351,6 +352,7 @@ static const struct myoption opts[] =
{ "dynamic-host", 1, 0, LOPT_DYNHOST },
{ "log-debug", 0, 0, LOPT_LOG_DEBUG },
{ "umbrella", 2, 0, LOPT_UMBRELLA },
{ "quiet-tftp", 0, 0, LOPT_QUIET_TFTP },
{ NULL, 0, 0, 0 }
};
@@ -536,6 +538,7 @@ static struct {
{ LOPT_DUMPMASK, ARG_ONE, "<hex>", gettext_noop("Mask which packets to dump"), NULL },
{ LOPT_SCRIPT_TIME, OPT_LEASE_RENEW, NULL, gettext_noop("Call dhcp-script when lease expiry changes."), NULL },
{ 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 },
{ 0, 0, NULL, NULL, NULL }
};
@@ -651,7 +654,7 @@ static char *canonicalise_opt(char *s)
return 0;
if (strlen(s) == 0)
return "";
return opt_string_alloc("");
unhide_metas(s);
if (!(ret = canonicalise(s, &nomem)) && nomem)
@@ -965,7 +968,7 @@ static int domain_rev6(char *domain, struct in6_addr *addr, int msize)
{
int i;
if (msize%4)
if (msize > 128 || msize%4)
return 0;
*domain = 0;
@@ -1185,11 +1188,15 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
{
new->u.vendor_class = (unsigned char *)opt_string_alloc(arg+7);
new->flags |= DHOPT_VENDOR;
if ((new->flags & DHOPT_ENCAPSULATE) || flags == DHOPT_MATCH)
goto_err(_("inappropriate vendor:"));
}
else if (strstr(arg, "encap:") == arg)
{
new->u.encap = atoi(arg+6);
new->flags |= DHOPT_ENCAPSULATE;
if ((new->flags & DHOPT_VENDOR) || flags == DHOPT_MATCH)
goto_err(_("inappropriate encap:"));
}
else if (strstr(arg, "vi-encap:") == arg)
{
@@ -2224,7 +2231,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
arg = comma;
comma = split(arg);
daemon->hostmaster = opt_string_alloc(arg);
for (cp = daemon->hostmaster; *cp; cp++)
for (cp = daemon->hostmaster; cp && *cp; cp++)
if (*cp == '@')
*cp = '.';
@@ -2254,10 +2261,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
{
char *d, *d_raw = arg;
comma = split(arg);
if (!(d = canonicalise_opt(arg)))
if (!(d = canonicalise_opt(d_raw)))
ret_err(gen_err);
else
{
free(d); /* allocate this again below. */
if (comma)
{
struct cond_domain *new = opt_malloc(sizeof(struct cond_domain));
@@ -2265,6 +2273,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
new->prefix = NULL;
new->indexed = 0;
new->prefixlen = 0;
unhide_metas(comma);
if ((netpart = split_chr(comma, '/')))
@@ -2276,7 +2285,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
ret_err_free(gen_err, new);
else if (inet_pton(AF_INET, comma, &new->start))
{
int mask = (1 << (32 - msize)) - 1;
int mask;
if (msize > 32)
ret_err_free(_("bad prefix length"), new);
mask = (1 << (32 - msize)) - 1;
new->is6 = 0;
new->start.s_addr = ntohl(htonl(new->start.s_addr) & ~mask);
new->end.s_addr = new->start.s_addr | htonl(mask);
@@ -2307,21 +2321,25 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
else if (inet_pton(AF_INET6, comma, &new->start6))
{
u64 mask = (1LLU << (128 - msize)) - 1LLU;
u64 addrpart = addr6part(&new->start6);
u64 mask, addrpart = addr6part(&new->start6);
if (msize > 128)
ret_err_free(_("bad prefix length"), new);
mask = (1LLU << (128 - msize)) - 1LLU;
new->is6 = 1;
new->prefixlen = msize;
/* prefix==64 overflows the mask calculation above */
if (msize == 64)
if (msize <= 64)
mask = (u64)-1LL;
new->end6 = new->start6;
setaddr6part(&new->start6, addrpart & ~mask);
setaddr6part(&new->end6, addrpart | mask);
if (msize < 64)
ret_err_free(gen_err, new);
else if (arg)
if (arg)
{
if (option != 's')
{
@@ -2381,7 +2399,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
}
new->domain = d;
new->domain = canonicalise_opt(d_raw);
if (option == 's')
{
new->next = daemon->cond_domain;
@@ -2390,19 +2408,21 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
else
{
char *star;
new->next = daemon->synth_domains;
daemon->synth_domains = new;
if (new->prefix &&
(star = strrchr(new->prefix, '*'))
&& *(star+1) == 0)
{
*star = 0;
new->indexed = 1;
if (new->is6 && new->prefixlen < 64)
ret_err_free(_("prefix length too small"), new);
}
new->next = daemon->synth_domains;
daemon->synth_domains = new;
}
}
else if (option == 's')
daemon->domain_suffix = d;
daemon->domain_suffix = canonicalise_opt(d_raw);
else
ret_err(gen_err);
}
@@ -2680,11 +2700,6 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
{
if ((err = parse_server(arg, &serv_addr, &source_addr, interface, &flags)))
ret_err(err);
/* server=//1.2.3.4 is special. */
if (strlen(domain) == 0 && lastdomain)
flags |= SERV_FOR_NODOTS;
}
if (servers_only && option == 'S')
@@ -2692,6 +2707,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
while (1)
{
/* server=//1.2.3.4 is special. */
if (strlen(domain) == 0 && lastdomain)
flags |= SERV_FOR_NODOTS;
else
flags &= ~SERV_FOR_NODOTS;
if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, &addr))
ret_err(gen_err);
@@ -3592,7 +3613,9 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
for (configs = daemon->dhcp_conf; configs; configs = configs->next)
if ((configs->flags & CONFIG_ADDR) && configs->addr.s_addr == in.s_addr)
{
sprintf(errstr, _("duplicate dhcp-host IP address %s"), inet_ntoa(in));
inet_ntop(AF_INET, &in, daemon->addrbuff, ADDRSTRLEN);
sprintf(errstr, _("duplicate dhcp-host IP address %s"),
daemon->addrbuff);
return 0;
}
}
@@ -4163,13 +4186,13 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
comma = split(arg);
new->interface = opt_string_alloc(split(comma));
new->iface_index = 0;
if (inet_pton(AF_INET, arg, &new->local) && inet_pton(AF_INET, comma, &new->server))
if (comma && inet_pton(AF_INET, arg, &new->local) && inet_pton(AF_INET, comma, &new->server))
{
new->next = daemon->relay4;
daemon->relay4 = new;
}
#ifdef HAVE_DHCP6
else if (inet_pton(AF_INET6, arg, &new->local) && inet_pton(AF_INET6, comma, &new->server))
else if (comma && inet_pton(AF_INET6, arg, &new->local) && inet_pton(AF_INET6, comma, &new->server))
{
new->next = daemon->relay6;
daemon->relay6 = new;
@@ -5005,15 +5028,33 @@ static int one_file(char *file, int hard_opt)
return 1;
}
static int file_filter(const struct dirent *ent)
{
size_t lenfile = strlen(ent->d_name);
/* ignore emacs backups and dotfiles */
if (lenfile == 0 ||
ent->d_name[lenfile - 1] == '~' ||
(ent->d_name[0] == '#' && ent->d_name[lenfile - 1] == '#') ||
ent->d_name[0] == '.')
return 0;
return 1;
}
/* expand any name which is a directory */
struct hostsfile *expand_filelist(struct hostsfile *list)
{
unsigned int i;
struct hostsfile *ah;
int entcnt, n;
struct hostsfile *ah, *last, *next, **up;
struct dirent **namelist;
/* find largest used index */
for (i = SRC_AH, ah = list; ah; ah = ah->next)
{
last = ah;
if (i <= ah->index)
i = ah->index + 1;
@@ -5029,46 +5070,48 @@ struct hostsfile *expand_filelist(struct hostsfile *list)
struct stat buf;
if (stat(ah->fname, &buf) != -1 && S_ISDIR(buf.st_mode))
{
DIR *dir_stream;
struct dirent *ent;
/* don't read this as a file */
ah->flags |= AH_INACTIVE;
if (!(dir_stream = opendir(ah->fname)))
entcnt = scandir(ah->fname, &namelist, file_filter, alphasort);
if (entcnt < 0)
my_syslog(LOG_ERR, _("cannot access directory %s: %s"),
ah->fname, strerror(errno));
else
{
while ((ent = readdir(dir_stream)))
for (n = 0; n < entcnt; n++)
{
ent = namelist[n];
size_t lendir = strlen(ah->fname);
size_t lenfile = strlen(ent->d_name);
struct hostsfile *ah1;
char *path;
/* ignore emacs backups and dotfiles */
if (lenfile == 0 ||
ent->d_name[lenfile - 1] == '~' ||
(ent->d_name[0] == '#' && ent->d_name[lenfile - 1] == '#') ||
ent->d_name[0] == '.')
continue;
/* see if we have an existing record.
dir is ah->fname
file is ent->d_name
path to match is ah1->fname */
for (ah1 = list; ah1; ah1 = ah1->next)
for (up = &list, ah1 = list; ah1; ah1 = next)
{
next = ah1->next;
if (lendir < strlen(ah1->fname) &&
strstr(ah1->fname, ah->fname) == ah1->fname &&
ah1->fname[lendir] == '/' &&
strcmp(ah1->fname + lendir + 1, ent->d_name) == 0)
{
ah1->flags &= ~AH_INACTIVE;
/* If found, remove from list to re-insert at the end.
Unless it's already at the end. */
if (last != ah1)
*up = next;
break;
}
up = &ah1->next;
}
/* make new record */
@@ -5089,17 +5132,21 @@ struct hostsfile *expand_filelist(struct hostsfile *list)
ah1->fname = path;
ah1->index = i++;
ah1->flags = AH_DIR;
ah1->next = list;
list = ah1;
}
/* Edge case, may be the last in the list anyway */
if (last != ah1)
last->next = ah1;
ah1->next = NULL;
last = ah1;
/* inactivate record if not regular file */
if ((ah1->flags & AH_DIR) && stat(ah1->fname, &buf) != -1 && !S_ISREG(buf.st_mode))
ah1->flags |= AH_INACTIVE;
}
closedir(dir_stream);
}
free(namelist);
}
}
@@ -5214,7 +5261,8 @@ void read_opts(int argc, char **argv, char *compile_opts)
daemon = opt_malloc(sizeof(struct daemon));
memset(daemon, 0, sizeof(struct daemon));
daemon->namebuff = buff;
daemon->addrbuff = safe_malloc(ADDRSTRLEN);
/* Set defaults - everything else is zero or NULL */
daemon->cachesize = CACHESIZ;
daemon->ftabsize = FTABSIZ;
+26 -26
View File
@@ -20,13 +20,13 @@
#define LOG(...) \
do { \
my_syslog(LOG_WARNING, __VA_ARGS__); \
my_syslog(LOG_DEBUG, __VA_ARGS__); \
} while (0)
#define ASSERT(condition) \
do { \
if (!(condition)) \
LOG("[pattern.c:%d] Assertion failure: %s", __LINE__, #condition); \
my_syslog(LOG_ERR, _("[pattern.c:%d] Assertion failure: %s"), __LINE__, #condition); \
} while (0)
/**
@@ -66,8 +66,8 @@ static int is_string_matching_glob_pattern(
pattern_character -= 'a' - 'A';
if (pattern_character == '*')
{
// zero-or-more-character wildcard
// Try to match at value_index, otherwise restart at value_index + 1 next.
/* zero-or-more-character wildcard */
/* Try to match at value_index, otherwise restart at value_index + 1 next. */
next_pattern_index = pattern_index;
pattern_index++;
if (value_index < num_value_bytes)
@@ -78,7 +78,7 @@ static int is_string_matching_glob_pattern(
}
else
{
// ordinary character
/* ordinary character */
if (value_index < num_value_bytes)
{
char value_character = value[value_index];
@@ -139,7 +139,7 @@ int is_valid_dns_name(const char *value)
(*c < 'A' || *c > 'Z') &&
(*c < 'a' || *c > 'z'))
{
LOG("Invalid DNS name: Invalid character %c.", *c);
LOG(_("Invalid DNS name: Invalid character %c."), *c);
return 0;
}
if (*c)
@@ -148,12 +148,12 @@ int is_valid_dns_name(const char *value)
{
if (!*c || *c == '.')
{
LOG("Invalid DNS name: Empty label.");
LOG(_("Invalid DNS name: Empty label."));
return 0;
}
if (*c == '-')
{
LOG("Invalid DNS name: Label starts with hyphen.");
LOG(_("Invalid DNS name: Label starts with hyphen."));
return 0;
}
label = c;
@@ -167,13 +167,13 @@ int is_valid_dns_name(const char *value)
{
if (c[-1] == '-')
{
LOG("Invalid DNS name: Label ends with hyphen.");
LOG(_("Invalid DNS name: Label ends with hyphen."));
return 0;
}
size_t num_label_bytes = (size_t) (c - label);
if (num_label_bytes > 63)
{
LOG("Invalid DNS name: Label is too long (%zu).", num_label_bytes);
LOG(_("Invalid DNS name: Label is too long (%zu)."), num_label_bytes);
return 0;
}
num_labels++;
@@ -181,12 +181,12 @@ int is_valid_dns_name(const char *value)
{
if (num_labels < 2)
{
LOG("Invalid DNS name: Not enough labels (%zu).", num_labels);
LOG(_("Invalid DNS name: Not enough labels (%zu)."), num_labels);
return 0;
}
if (is_label_numeric)
{
LOG("Invalid DNS name: Final label is fully numeric.");
LOG(_("Invalid DNS name: Final label is fully numeric."));
return 0;
}
if (num_label_bytes == 5 &&
@@ -196,12 +196,12 @@ int is_valid_dns_name(const char *value)
(label[3] == 'a' || label[3] == 'A') &&
(label[4] == 'l' || label[4] == 'L'))
{
LOG("Invalid DNS name: \"local\" pseudo-TLD.");
LOG(_("Invalid DNS name: \"local\" pseudo-TLD."));
return 0;
}
if (num_bytes < 1 || num_bytes > 253)
{
LOG("DNS name has invalid length (%zu).", num_bytes);
LOG(_("DNS name has invalid length (%zu)."), num_bytes);
return 0;
}
return 1;
@@ -249,13 +249,13 @@ int is_valid_dns_name_pattern(const char *value)
for (const char *c = value;; c++)
{
if (*c &&
*c != '*' && // Wildcard.
*c != '*' && /* Wildcard. */
*c != '-' && *c != '.' &&
(*c < '0' || *c > '9') &&
(*c < 'A' || *c > 'Z') &&
(*c < 'a' || *c > 'z'))
{
LOG("Invalid DNS name pattern: Invalid character %c.", *c);
LOG(_("Invalid DNS name pattern: Invalid character %c."), *c);
return 0;
}
if (*c && *c != '*')
@@ -264,12 +264,12 @@ int is_valid_dns_name_pattern(const char *value)
{
if (!*c || *c == '.')
{
LOG("Invalid DNS name pattern: Empty label.");
LOG(_("Invalid DNS name pattern: Empty label."));
return 0;
}
if (*c == '-')
{
LOG("Invalid DNS name pattern: Label starts with hyphen.");
LOG(_("Invalid DNS name pattern: Label starts with hyphen."));
return 0;
}
label = c;
@@ -282,7 +282,7 @@ int is_valid_dns_name_pattern(const char *value)
{
if (num_wildcards >= 2)
{
LOG("Invalid DNS name pattern: Wildcard character used more than twice per label.");
LOG(_("Invalid DNS name pattern: Wildcard character used more than twice per label."));
return 0;
}
num_wildcards++;
@@ -292,13 +292,13 @@ int is_valid_dns_name_pattern(const char *value)
{
if (c[-1] == '-')
{
LOG("Invalid DNS name pattern: Label ends with hyphen.");
LOG(_("Invalid DNS name pattern: Label ends with hyphen."));
return 0;
}
size_t num_label_bytes = (size_t) (c - label) - num_wildcards;
if (num_label_bytes > 63)
{
LOG("Invalid DNS name pattern: Label is too long (%zu).", num_label_bytes);
LOG(_("Invalid DNS name pattern: Label is too long (%zu)."), num_label_bytes);
return 0;
}
num_labels++;
@@ -306,17 +306,17 @@ int is_valid_dns_name_pattern(const char *value)
{
if (num_labels < 2)
{
LOG("Invalid DNS name pattern: Not enough labels (%zu).", num_labels);
LOG(_("Invalid DNS name pattern: Not enough labels (%zu)."), num_labels);
return 0;
}
if (num_wildcards != 0 || previous_label_has_wildcard)
{
LOG("Invalid DNS name pattern: Wildcard within final two labels.");
LOG(_("Invalid DNS name pattern: Wildcard within final two labels."));
return 0;
}
if (is_label_numeric)
{
LOG("Invalid DNS name pattern: Final label is fully numeric.");
LOG(_("Invalid DNS name pattern: Final label is fully numeric."));
return 0;
}
if (num_label_bytes == 5 &&
@@ -326,12 +326,12 @@ int is_valid_dns_name_pattern(const char *value)
(label[3] == 'a' || label[3] == 'A') &&
(label[4] == 'l' || label[4] == 'L'))
{
LOG("Invalid DNS name pattern: \"local\" pseudo-TLD.");
LOG(_("Invalid DNS name pattern: \"local\" pseudo-TLD."));
return 0;
}
if (num_bytes < 1 || num_bytes > 253)
{
LOG("DNS name pattern has invalid length after removing wildcards (%zu).", num_bytes);
LOG(_("DNS name pattern has invalid length after removing wildcards (%zu)."), num_bytes);
return 0;
}
return 1;
+418 -340
View File
File diff suppressed because it is too large. Load diff
+59 -37
View File
@@ -372,9 +372,22 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
if (!context)
{
my_syslog(MS_DHCP | LOG_WARNING, _("no address range available for DHCP request %s %s"),
subnet_addr.s_addr ? _("with subnet selector") : _("via"),
subnet_addr.s_addr ? inet_ntoa(subnet_addr) : (mess->giaddr.s_addr ? inet_ntoa(mess->giaddr) : iface_name));
const char *via;
if (subnet_addr.s_addr)
{
via = _("with subnet selector");
inet_ntop(AF_INET, &subnet_addr, daemon->addrbuff, ADDRSTRLEN);
}
else
{
via = _("via");
if (mess->giaddr.s_addr)
inet_ntop(AF_INET, &mess->giaddr, daemon->addrbuff, ADDRSTRLEN);
else
safe_strncpy(daemon->addrbuff, iface_name, ADDRSTRLEN);
}
my_syslog(MS_DHCP | LOG_WARNING, _("no address range available for DHCP request %s %s"),
via, daemon->addrbuff);
return 0;
}
@@ -383,13 +396,19 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
struct dhcp_context *context_tmp;
for (context_tmp = context; context_tmp; context_tmp = context_tmp->current)
{
strcpy(daemon->namebuff, inet_ntoa(context_tmp->start));
inet_ntop(AF_INET, &context_tmp->start, daemon->namebuff, MAXDNAME);
if (context_tmp->flags & (CONTEXT_STATIC | CONTEXT_PROXY))
my_syslog(MS_DHCP | LOG_INFO, _("%u available DHCP subnet: %s/%s"),
ntohl(mess->xid), daemon->namebuff, inet_ntoa(context_tmp->netmask));
{
inet_ntop(AF_INET, &context_tmp->netmask, daemon->addrbuff, ADDRSTRLEN);
my_syslog(MS_DHCP | LOG_INFO, _("%u available DHCP subnet: %s/%s"),
ntohl(mess->xid), daemon->namebuff, daemon->addrbuff);
}
else
my_syslog(MS_DHCP | LOG_INFO, _("%u available DHCP range: %s -- %s"),
ntohl(mess->xid), daemon->namebuff, inet_ntoa(context_tmp->end));
{
inet_ntop(AF_INET, &context_tmp->end, daemon->addrbuff, ADDRSTRLEN);
my_syslog(MS_DHCP | LOG_INFO, _("%u available DHCP range: %s -- %s"),
ntohl(mess->xid), daemon->namebuff, daemon->addrbuff);
}
}
}
@@ -1031,8 +1050,9 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
config->addr.s_addr == option_addr(opt).s_addr)
{
prettyprint_time(daemon->dhcp_buff, DECLINE_BACKOFF);
inet_ntop(AF_INET, &config->addr, daemon->addrbuff, ADDRSTRLEN);
my_syslog(MS_DHCP | LOG_WARNING, _("disabling DHCP static address %s for %s"),
inet_ntoa(config->addr), daemon->dhcp_buff);
daemon->addrbuff, daemon->dhcp_buff);
config->flags |= CONFIG_DECLINED;
config->decline_time = now;
}
@@ -1078,7 +1098,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
if (have_config(config, CONFIG_ADDR))
{
char *addrs = inet_ntoa(config->addr);
inet_ntop(AF_INET, &config->addr, daemon->addrbuff, ADDRSTRLEN);
if ((ltmp = lease_find_by_addr(config->addr)) &&
ltmp != lease &&
@@ -1088,7 +1108,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
unsigned char *mac = extended_hwaddr(ltmp->hwaddr_type, ltmp->hwaddr_len,
ltmp->hwaddr, ltmp->clid_len, ltmp->clid, &len);
my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it is leased to %s"),
addrs, print_mac(daemon->namebuff, mac, len));
daemon->addrbuff, print_mac(daemon->namebuff, mac, len));
}
else
{
@@ -1097,10 +1117,10 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
if (context->router.s_addr == config->addr.s_addr)
break;
if (tmp)
my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it is in use by the server or relay"), addrs);
my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it is in use by the server or relay"), daemon->addrbuff);
else if (have_config(config, CONFIG_DECLINED) &&
difftime(now, config->decline_time) < (float)DECLINE_BACKOFF)
my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it was previously declined"), addrs);
my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it was previously declined"), daemon->addrbuff);
else
conf = config->addr;
}
@@ -1303,9 +1323,10 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
a lease from one of it's MACs to give the address to another. */
if (config && config_has_mac(config, ltmp->hwaddr, ltmp->hwaddr_len, ltmp->hwaddr_type))
{
inet_ntop(AF_INET, &ltmp->addr, daemon->addrbuff, ADDRSTRLEN);
my_syslog(MS_DHCP | LOG_INFO, _("abandoning lease to %s of %s"),
print_mac(daemon->namebuff, ltmp->hwaddr, ltmp->hwaddr_len),
inet_ntoa(ltmp->addr));
daemon->addrbuff);
lease = ltmp;
}
else
@@ -1674,42 +1695,40 @@ static void add_extradata_opt(struct dhcp_lease *lease, unsigned char *opt)
static void log_packet(char *type, void *addr, unsigned char *ext_mac,
int mac_len, char *interface, char *string, char *err, u32 xid)
{
struct in_addr a;
if (!err && !option_bool(OPT_LOG_OPTS) && option_bool(OPT_QUIET_DHCP))
return;
/* addr may be misaligned */
daemon->addrbuff[0] = 0;
if (addr)
memcpy(&a, addr, sizeof(a));
inet_ntop(AF_INET, addr, daemon->addrbuff, ADDRSTRLEN);
print_mac(daemon->namebuff, ext_mac, mac_len);
if(option_bool(OPT_LOG_OPTS))
my_syslog(MS_DHCP | LOG_INFO, "%u %s(%s) %s%s%s %s%s",
ntohl(xid),
type,
interface,
addr ? inet_ntoa(a) : "",
addr ? " " : "",
daemon->namebuff,
string ? string : "",
err ? err : "");
else
my_syslog(MS_DHCP | LOG_INFO, "%s(%s) %s%s%s %s%s",
if (option_bool(OPT_LOG_OPTS))
my_syslog(MS_DHCP | LOG_INFO, "%u %s(%s) %s%s%s %s%s",
ntohl(xid),
type,
interface,
addr ? inet_ntoa(a) : "",
daemon->addrbuff,
addr ? " " : "",
daemon->namebuff,
string ? string : "",
err ? err : "");
else
my_syslog(MS_DHCP | LOG_INFO, "%s(%s) %s%s%s %s%s",
type,
interface,
daemon->addrbuff,
addr ? " " : "",
daemon->namebuff,
string ? string : "",
err ? err : "");
#ifdef HAVE_UBUS
if (!strcmp(type, "DHCPACK"))
ubus_event_bcast("dhcp.ack", daemon->namebuff, addr ? inet_ntoa(a) : NULL, string ? string : NULL, interface);
else if (!strcmp(type, "DHCPRELEASE"))
ubus_event_bcast("dhcp.release", daemon->namebuff, addr ? inet_ntoa(a) : NULL, string ? string : NULL, interface);
if (!strcmp(type, "DHCPACK"))
ubus_event_bcast("dhcp.ack", daemon->namebuff, addr ? daemon->addrbuff : NULL, string, interface);
else if (!strcmp(type, "DHCPRELEASE"))
ubus_event_bcast("dhcp.release", daemon->namebuff, addr ? daemon->addrbuff : NULL, string, interface);
#endif
}
@@ -1861,7 +1880,10 @@ static size_t dhcp_packet_size(struct dhcp_packet *mess, unsigned char *agent_id
if (option_bool(OPT_LOG_OPTS))
{
if (mess->siaddr.s_addr != 0)
my_syslog(MS_DHCP | LOG_INFO, _("%u next server: %s"), ntohl(mess->xid), inet_ntoa(mess->siaddr));
{
inet_ntop(AF_INET, &mess->siaddr, daemon->addrbuff, ADDRSTRLEN);
my_syslog(MS_DHCP | LOG_INFO, _("%u next server: %s"), ntohl(mess->xid), daemon->addrbuff);
}
if ((mess->flags & htons(0x8000)) && mess->ciaddr.s_addr == 0)
my_syslog(MS_DHCP | LOG_INFO, _("%u broadcast response"), ntohl(mess->xid));
+2 -1
View File
@@ -761,7 +761,8 @@ static ssize_t tftp_err(int err, char *packet, char *message, char *file)
len = snprintf(mess->message, MAXMESSAGE, message, file, errstr);
ret += (len < MAXMESSAGE) ? len + 1 : MAXMESSAGE; /* include terminating zero */
my_syslog(MS_TFTP | LOG_ERR, "%s", mess->message);
if (err != ERR_FNF || !option_bool(OPT_QUIET_TFTP))
my_syslog(MS_TFTP | LOG_ERR, "%s", mess->message);
return ret;
}
+51 -37
View File
@@ -21,7 +21,6 @@
#include <libubus.h>
static struct blob_buf b;
static int notify;
static int error_logged = 0;
static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
@@ -78,17 +77,16 @@ static void ubus_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj)
(void)ctx;
my_syslog(LOG_DEBUG, _("UBus subscription callback: %s subscriber(s)"), obj->has_subscribers ? "1" : "0");
notify = obj->has_subscribers;
}
static void ubus_destroy(struct ubus_context *ubus)
{
// Forces re-initialization when we're reusing the same definitions later on.
ubus_object.id = 0;
ubus_object_type.id = 0;
ubus_free(ubus);
daemon->ubus = NULL;
/* Forces re-initialization when we're reusing the same definitions later on. */
ubus_object.id = 0;
ubus_object_type.id = 0;
}
static void ubus_disconnect_cb(struct ubus_context *ubus)
@@ -173,6 +171,16 @@ void check_ubus_listeners()
}
}
#define CHECK(stmt) \
do { \
int e = (stmt); \
if (e) \
{ \
my_syslog(LOG_ERR, _("UBus command failed: %d (%s)"), e, #stmt); \
return (UBUS_STATUS_UNKNOWN_ERROR); \
} \
} while (0)
static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
@@ -183,12 +191,13 @@ static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj
(void)method;
(void)msg;
blob_buf_init(&b, BLOBMSG_TYPE_TABLE);
CHECK(blob_buf_init(&b, BLOBMSG_TYPE_TABLE));
for (i=0; i < __METRIC_MAX; i++)
blobmsg_add_u32(&b, get_metric_name(i), daemon->metrics[i]);
CHECK(blobmsg_add_u32(&b, get_metric_name(i), daemon->metrics[i]));
return ubus_send_reply(ctx, req, b.head);
CHECK(ubus_send_reply(ctx, req, b.head));
return UBUS_STATUS_OK;
}
#ifdef HAVE_CONNTRACK
@@ -307,66 +316,71 @@ fail:
}
#endif
#undef CHECK
#define CHECK(stmt) \
do { \
int e = (stmt); \
if (e) \
{ \
my_syslog(LOG_ERR, _("UBus command failed: %d (%s)"), e, #stmt); \
return; \
} \
} while (0)
void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface)
{
struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
int ret;
if (!ubus || !notify)
if (!ubus || !ubus_object.has_subscribers)
return;
blob_buf_init(&b, BLOBMSG_TYPE_TABLE);
CHECK(blob_buf_init(&b, BLOBMSG_TYPE_TABLE));
if (mac)
blobmsg_add_string(&b, "mac", mac);
CHECK(blobmsg_add_string(&b, "mac", mac));
if (ip)
blobmsg_add_string(&b, "ip", ip);
CHECK(blobmsg_add_string(&b, "ip", ip));
if (name)
blobmsg_add_string(&b, "name", name);
CHECK(blobmsg_add_string(&b, "name", name));
if (interface)
blobmsg_add_string(&b, "interface", interface);
CHECK(blobmsg_add_string(&b, "interface", interface));
ret = ubus_notify(ubus, &ubus_object, type, b.head, -1);
if (ret)
my_syslog(LOG_ERR, _("Failed to send UBus event: %s"), ubus_strerror(ret));
CHECK(ubus_notify(ubus, &ubus_object, type, b.head, -1));
}
#ifdef HAVE_CONNTRACK
void ubus_event_bcast_connmark_allowlist_refused(u32 mark, const char *name)
{
struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
int ret;
if (!ubus || !notify)
if (!ubus || !ubus_object.has_subscribers)
return;
blob_buf_init(&b, 0);
blobmsg_add_u32(&b, "mark", mark);
blobmsg_add_string(&b, "name", name);
CHECK(blob_buf_init(&b, 0));
CHECK(blobmsg_add_u32(&b, "mark", mark));
CHECK(blobmsg_add_string(&b, "name", name));
ret = ubus_notify(ubus, &ubus_object, "connmark-allowlist.refused", b.head, -1);
if (ret)
my_syslog(LOG_ERR, _("Failed to send UBus event: %s"), ubus_strerror(ret));
CHECK(ubus_notify(ubus, &ubus_object, "connmark-allowlist.refused", b.head, -1));
}
void ubus_event_bcast_connmark_allowlist_resolved(u32 mark, const char *name, const char *value, u32 ttl)
{
struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
int ret;
if (!ubus || !notify)
if (!ubus || !ubus_object.has_subscribers)
return;
blob_buf_init(&b, 0);
blobmsg_add_u32(&b, "mark", mark);
blobmsg_add_string(&b, "name", name);
blobmsg_add_string(&b, "value", value);
blobmsg_add_u32(&b, "ttl", ttl);
CHECK(blob_buf_init(&b, 0));
CHECK(blobmsg_add_u32(&b, "mark", mark));
CHECK(blobmsg_add_string(&b, "name", name));
CHECK(blobmsg_add_string(&b, "value", value));
CHECK(blobmsg_add_u32(&b, "ttl", ttl));
ret = ubus_notify(ubus, &ubus_object, "connmark-allowlist.resolved", b.head, /* timeout: */ 1000);
if (ret)
my_syslog(LOG_ERR, _("Failed to send UBus event: %s"), ubus_strerror(ret));
/* Set timeout to allow UBus subscriber to configure firewall rules before returning. */
CHECK(ubus_notify(ubus, &ubus_object, "connmark-allowlist.resolved", b.head, /* timeout: */ 1000));
}
#endif
#undef CHECK
#endif /* HAVE_UBUS */
+41 -19
View File
@@ -115,7 +115,8 @@ u64 rand64(void)
return (u64)out[outleft+1] + (((u64)out[outleft]) << 32);
}
/* returns 2 if names is OK but contains one or more underscores */
/* returns 1 if name is OK and ascii printable
* returns 2 if name should be processed by IDN */
static int check_name(char *in)
{
/* remove trailing .
@@ -123,7 +124,9 @@ static int check_name(char *in)
size_t dotgap = 0, l = strlen(in);
char c;
int nowhite = 0;
int idn_encode = 0;
int hasuscore = 0;
int hasucase = 0;
if (l == 0 || l > MAXDNAME) return 0;
@@ -136,28 +139,49 @@ static int check_name(char *in)
for (; (c = *in); in++)
{
if (c == '.')
dotgap = 0;
dotgap = 0;
else if (++dotgap > MAXLABEL)
return 0;
return 0;
else if (isascii((unsigned char)c) && iscntrl((unsigned char)c))
/* iscntrl only gives expected results for ascii */
return 0;
#if !defined(HAVE_IDN) && !defined(HAVE_LIBIDN2)
/* iscntrl only gives expected results for ascii */
return 0;
else if (!isascii((unsigned char)c))
return 0;
#if !defined(HAVE_IDN) && !defined(HAVE_LIBIDN2)
return 0;
#else
idn_encode = 1;
#endif
else if (c != ' ')
{
nowhite = 1;
if (c == '_')
hasuscore = 1;
}
{
nowhite = 1;
#if defined(HAVE_LIBIDN2) && (!defined(IDN2_VERSION_NUMBER) || IDN2_VERSION_NUMBER < 0x02000003)
if (c == '_')
hasuscore = 1;
#else
(void)hasuscore;
#endif
#if defined(HAVE_IDN) || defined(HAVE_LIBIDN2)
if (c >= 'A' && c <= 'Z')
hasucase = 1;
#else
(void)hasucase;
#endif
}
}
if (!nowhite)
return 0;
return hasuscore ? 2 : 1;
#if defined(HAVE_LIBIDN2) && (!defined(IDN2_VERSION_NUMBER) || IDN2_VERSION_NUMBER < 0x02000003)
/* Older libidn2 strips underscores, so don't do IDN processing
if the name has an underscore unless it also has non-ascii characters. */
idn_encode = idn_encode || (hasucase && !hasuscore);
#else
idn_encode = idn_encode || hasucase;
#endif
return (idn_encode) ? 2 : 1;
}
/* Hostnames have a more limited valid charset than domain names
@@ -204,12 +228,8 @@ char *canonicalise(char *in, int *nomem)
if (!(rc = check_name(in)))
return NULL;
#if defined(HAVE_LIBIDN2) && (!defined(IDN2_VERSION_NUMBER) || IDN2_VERSION_NUMBER < 0x02000003)
/* older libidn2 strips underscores, so don't do IDN processing
if the name has an underscore (check_name() returned 2) */
if (rc != 2)
#endif
#if defined(HAVE_IDN) || defined(HAVE_LIBIDN2)
if (rc == 2)
{
# ifdef HAVE_LIBIDN2
rc = idn2_to_ascii_lz(in, &ret, IDN2_NONTRANSITIONAL);
@@ -234,12 +254,14 @@ char *canonicalise(char *in, int *nomem)
return ret;
}
#else
(void)rc;
#endif
if ((ret = whine_malloc(strlen(in)+1)))
strcpy(ret, in);
else if (nomem)
*nomem = 1;
*nomem = 1;
return ret;
}