mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-06 15:51:41 +00:00
Compare commits
47
Commits
v2.67rc2
...
v2.68test2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd9d9ce54c | ||
|
|
32b4e4cb7c | ||
|
|
376d48c7f1 | ||
|
|
6586e8352a | ||
|
|
3511a92869 | ||
|
|
44de649e5c | ||
|
|
29c122af83 | ||
|
|
6dbdc972c4 | ||
|
|
7b174c250d | ||
|
|
50d7f721ee | ||
|
|
eec5c1e21c | ||
|
|
1f776a4aa2 | ||
|
|
227ddad9b5 | ||
|
|
a9bf81ad91 | ||
|
|
6008bdbbc1 | ||
|
|
93bafe619d | ||
|
|
8ab91e9f7f | ||
|
|
5731050062 | ||
|
|
fb63dd1345 | ||
|
|
5f8002fcd7 | ||
|
|
19b1689161 | ||
|
|
b485ed97aa | ||
|
|
53c4c5c859 | ||
|
|
dc27e148a1 | ||
|
|
45cca58592 | ||
|
|
e136725c5b | ||
|
|
486479e943 | ||
|
|
3bb51da835 | ||
|
|
806cf78797 | ||
|
|
3b3f441189 | ||
|
|
24b5a5d50b | ||
|
|
d56a604a96 | ||
|
|
8c0b73d3a8 | ||
|
|
6bd3a09fb8 | ||
|
|
f65b0e546b | ||
|
|
8584c502d3 | ||
|
|
c3edf383ff | ||
|
|
c4cd95df68 | ||
|
|
ed4c0767b1 | ||
|
|
043c271f8a | ||
|
|
d4da20f064 | ||
|
|
903650af67 | ||
|
|
ef1d7425e3 | ||
|
|
1d1c795601 | ||
|
|
889d8a156f | ||
|
|
b7f666ff09 | ||
|
|
e4e9b342a7 |
No files matched your search
@@ -1,3 +1,39 @@
|
|||||||
|
version 2.68
|
||||||
|
Use random addresses for DHCPv6 temporary address
|
||||||
|
allocations, instead of algorithmically determined stable
|
||||||
|
addresses.
|
||||||
|
|
||||||
|
Fix bug which meant that the DHCPv6 DUID was not available
|
||||||
|
in DHCP script runs during the lifetime of the dnsmasq
|
||||||
|
process which created the DUID de-novo. Once the DUID was
|
||||||
|
created and stored in the lease file and dnsmasq
|
||||||
|
restarted, this bug disappeared.
|
||||||
|
|
||||||
|
Fix bug introduced in 2.67 which could result in erroneous
|
||||||
|
NXDOMAIN returns to CNAME queries.
|
||||||
|
|
||||||
|
Fix build failures on MacOS X and openBSD.
|
||||||
|
|
||||||
|
Allow subnet specifications in --auth-zone to be interface
|
||||||
|
names as well as address literals. This makes it possible
|
||||||
|
to configure authoritative DNS when local address ranges
|
||||||
|
are dynamic and works much better than the previous
|
||||||
|
work-around which exempted contructed DHCP ranges from the
|
||||||
|
IP address filtering. As a consequence, that work-around
|
||||||
|
is removed. Under certain circumstances, this change wil
|
||||||
|
break existing configuration: if you're relying on the
|
||||||
|
contructed-range exception, you need to change --auth-zone
|
||||||
|
to specify the same interface as is used to construct your
|
||||||
|
DHCP ranges, probably with a trailing "/6" like this:
|
||||||
|
--auth-zone=example.com,eth0/6 to limit the addresses to
|
||||||
|
IPv6 addresses of eth0.
|
||||||
|
|
||||||
|
Fix problems when advertising deleted IPv6 prefixes. If
|
||||||
|
the prefix is deleted (rather than replaced), it doesn't
|
||||||
|
get advertised with zero preferred time. Thanks to Tsachi
|
||||||
|
for the bug report.
|
||||||
|
|
||||||
|
|
||||||
version 2.67
|
version 2.67
|
||||||
Fix crash if upstream server returns SERVFAIL when
|
Fix crash if upstream server returns SERVFAIL when
|
||||||
--conntrack in use. Thanks to Giacomo Tazzari for finding
|
--conntrack in use. Thanks to Giacomo Tazzari for finding
|
||||||
@@ -90,8 +126,6 @@ version 2.67
|
|||||||
smallest valid dhcp-range is sent. Thanks to Uwe Schindler
|
smallest valid dhcp-range is sent. Thanks to Uwe Schindler
|
||||||
for suggesting this.
|
for suggesting this.
|
||||||
|
|
||||||
Add --force-fast-ra option. Another thanks to Uwe Schindler.
|
|
||||||
|
|
||||||
Make --listen-address higher priority than --except-interface
|
Make --listen-address higher priority than --except-interface
|
||||||
in all circumstances. Thanks to Thomas Hood for the bugreport.
|
in all circumstances. Thanks to Thomas Hood for the bugreport.
|
||||||
|
|
||||||
@@ -125,7 +159,36 @@ version 2.67
|
|||||||
range. This was originally to avoid SLAAC addresses, but
|
range. This was originally to avoid SLAAC addresses, but
|
||||||
we now explicitly autoconfig and privacy addresses instead.
|
we now explicitly autoconfig and privacy addresses instead.
|
||||||
|
|
||||||
|
Update Polish translation. Thanks to Jan Psota.
|
||||||
|
|
||||||
|
Fix problem in DHCPv6 vendorclass/userclass matching
|
||||||
|
code. Thanks to Tanguy Bouzeloc for the patch.
|
||||||
|
|
||||||
|
Update Spanish transalation. Thanks to Vicente Soriano.
|
||||||
|
|
||||||
|
Add --ra-param option. Thanks to Vladislav Grishenko for
|
||||||
|
inspiration on this.
|
||||||
|
|
||||||
|
Add --add-subnet configuration, to tell upstream DNS
|
||||||
|
servers where the original client is. Thanks to DNSthingy
|
||||||
|
for sponsoring this feature.
|
||||||
|
|
||||||
|
Add --quiet-dhcp, --quiet-dhcp6 and --quiet-ra. Thanks to
|
||||||
|
Kevin Darbyshire-Bryant for the initial patch.
|
||||||
|
|
||||||
|
Allow A/AAAA records created by --interface-name to be the
|
||||||
|
target of --cname. Thanks to Hadmut Danisch for the
|
||||||
|
suggestion.
|
||||||
|
|
||||||
|
Avoid treating a --dhcp-host which has an IPv6 address
|
||||||
|
as eligable for use with DHCPv4 on the grounds that it has
|
||||||
|
no address, and vice-versa. Thanks to Yury Konovalov for
|
||||||
|
spotting the problem.
|
||||||
|
|
||||||
|
Do a better job caching dangling CNAMEs. Thanks to Yves
|
||||||
|
Dorfsman for spotting the problem.
|
||||||
|
|
||||||
|
|
||||||
version 2.66
|
version 2.66
|
||||||
Add the ability to act as an authoritative DNS
|
Add the ability to act as an authoritative DNS
|
||||||
server. Dnsmasq can now answer queries from the wider 'net
|
server. Dnsmasq can now answer queries from the wider 'net
|
||||||
|
|||||||
@@ -114,6 +114,11 @@ merge :
|
|||||||
echo -n msgmerge $(PO)/$$f && $(MSGMERGE) --no-wrap -U $(PO)/$$f $(BUILDDIR)/dnsmasq.pot; \
|
echo -n msgmerge $(PO)/$$f && $(MSGMERGE) --no-wrap -U $(PO)/$$f $(BUILDDIR)/dnsmasq.pot; \
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Cannonicalise .po file.
|
||||||
|
%.po :
|
||||||
|
@cd $(BUILDDIR) && $(MAKE) -f $(top)/Makefile dnsmasq.pot
|
||||||
|
mv $(PO)/$*.po $(PO)/$*.po.orig && $(MSGMERGE) --no-wrap $(PO)/$*.po.orig $(BUILDDIR)/dnsmasq.pot >$(PO)/$*.po;
|
||||||
|
|
||||||
$(BUILDDIR):
|
$(BUILDDIR):
|
||||||
mkdir -p $(BUILDDIR)
|
mkdir -p $(BUILDDIR)
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -25,7 +25,7 @@ DEB_BUILD_ARCH_OS := $(shell dpkg-architecture -qDEB_BUILD_ARCH_OS)
|
|||||||
|
|
||||||
# Force package version based on git tags.
|
# Force package version based on git tags.
|
||||||
ifneq (,$(filter gitversion,$(DEB_BUILD_OPTIONS)))
|
ifneq (,$(filter gitversion,$(DEB_BUILD_OPTIONS)))
|
||||||
PACKAGE_VERSION = $(shell bld/get-version `pwd` | sed 's/[a-z]/~&/; s/-/./g; s/$$/-1/; s/^/-v/';)
|
PACKAGE_VERSION = $(shell bld/get-version `pwd` | sed 's/test/~&/; s/[a-z]/~&/; s/-/./g; s/$$/-1/; s/^/-v/';)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq (,$(filter nodbus,$(DEB_BUILD_OPTIONS)))
|
ifeq (,$(filter nodbus,$(DEB_BUILD_OPTIONS)))
|
||||||
|
|||||||
+60
-25
@@ -497,7 +497,7 @@ Return an NAPTR DNS record, as specified in RFC3403.
|
|||||||
Return a CNAME record which indicates that <cname> is really
|
Return a CNAME record which indicates that <cname> is really
|
||||||
<target>. There are significant limitations on the target; it must be a
|
<target>. There are significant limitations on the target; it must be a
|
||||||
DNS name which is known to dnsmasq from /etc/hosts (or additional
|
DNS name which is known to dnsmasq from /etc/hosts (or additional
|
||||||
hosts files), from DHCP or from another
|
hosts files), from DHCP, from --interface-name or from another
|
||||||
.B --cname.
|
.B --cname.
|
||||||
If the target does not satisfy this
|
If the target does not satisfy this
|
||||||
criteria, the whole cname is ignored. The cname must be unique, but it
|
criteria, the whole cname is ignored. The cname must be unique, but it
|
||||||
@@ -543,7 +543,20 @@ server. The MAC address can only be added if the requestor is on the same
|
|||||||
subnet as the dnsmasq server. Note that the mechanism used to achieve this (an EDNS0 option)
|
subnet as the dnsmasq server. Note that the mechanism used to achieve this (an EDNS0 option)
|
||||||
is not yet standardised, so this should be considered
|
is not yet standardised, so this should be considered
|
||||||
experimental. Also note that exposing MAC addresses in this way may
|
experimental. Also note that exposing MAC addresses in this way may
|
||||||
have security and privacy implications.
|
have security and privacy implications. The warning about caching
|
||||||
|
given for --add-subnet applies to --add-mac too.
|
||||||
|
.TP
|
||||||
|
.B --add-subnet[[=<IPv4 prefix length>],<IPv6 prefix length>]
|
||||||
|
Add the subnet address of the requestor to the DNS queries which are
|
||||||
|
forwarded upstream. The amount of the address forwarded depends on the
|
||||||
|
prefix length parameter: 32 (128 for IPv6) forwards the whole address,
|
||||||
|
zero forwards none of it but still marks the request so that no
|
||||||
|
upstream nameserver will add client address information either. The
|
||||||
|
default is zero for both IPv4 and IPv6. Note that upstream nameservers
|
||||||
|
may be configured to return different results based on this
|
||||||
|
information, but the dnsmasq cache does not take account. If a dnsmasq
|
||||||
|
instance is configured such that different results may be encountered,
|
||||||
|
caching should be disabled.
|
||||||
.TP
|
.TP
|
||||||
.B \-c, --cache-size=<cachesize>
|
.B \-c, --cache-size=<cachesize>
|
||||||
Set the size of dnsmasq's cache. The default is 150 names. Setting the cache size to zero disables caching.
|
Set the size of dnsmasq's cache. The default is 150 names. Setting the cache size to zero disables caching.
|
||||||
@@ -576,10 +589,19 @@ needed for a client to do validation itself.
|
|||||||
.B --auth-zone=<domain>[,<subnet>[/<prefix length>][,<subnet>[/<prefix length>].....]]
|
.B --auth-zone=<domain>[,<subnet>[/<prefix length>][,<subnet>[/<prefix length>].....]]
|
||||||
Define a DNS zone for which dnsmasq acts as authoritative server. Locally defined DNS records which are in the domain
|
Define a DNS zone for which dnsmasq acts as authoritative server. Locally defined DNS records which are in the domain
|
||||||
will be served. A and AAAA records must be in one of the
|
will be served. A and AAAA records must be in one of the
|
||||||
specified subnets, or in a subnet corresponding to a constructed DHCP
|
specified subnets. As alternative to directly specifying the subnets, it's possible to
|
||||||
range. (This can be overridden with
|
give the name of an interface, in which case the subnets implied by
|
||||||
.B constructor-noauth:
|
that interface's configured addresses and netmask/prefix-length are
|
||||||
) The subnet(s) are also used to define in-addr.arpa and
|
used; this is useful when using constructed DHCP ranges as the actual
|
||||||
|
address is dynamic and not known when configuring dnsmasq. The
|
||||||
|
interface addresses may be confined to only IPv6 addresses using
|
||||||
|
<interface>/6 or to only IPv4 using <interface>/4. This is useful when
|
||||||
|
an interface has dynamically determined global IPv6 addresses which should
|
||||||
|
appear in the zone, but RFC1918 IPv4 addresses which should not.
|
||||||
|
Interface-name and address-literal subnet specifications may be used
|
||||||
|
freely in the same --auth-zone declaration.
|
||||||
|
|
||||||
|
The subnet(s) are also used to define in-addr.arpa and
|
||||||
ipv6.arpa domains which are served for reverse-DNS queries. If not
|
ipv6.arpa domains which are served for reverse-DNS queries. If not
|
||||||
specified, the prefix length defaults to 24 for IPv4 and 64 for IPv6.
|
specified, the prefix length defaults to 24 for IPv4 and 64 for IPv6.
|
||||||
For IPv4 subnets, the prefix length should be have the value 8, 16 or 24
|
For IPv4 subnets, the prefix length should be have the value 8, 16 or 24
|
||||||
@@ -667,12 +689,6 @@ then the address can be simply ::
|
|||||||
.B --dhcp-range=::,constructor:eth0
|
.B --dhcp-range=::,constructor:eth0
|
||||||
|
|
||||||
|
|
||||||
There is a variant of the constructor: syntax using the keyword
|
|
||||||
.B constructor-noauth.
|
|
||||||
See
|
|
||||||
.B --auth-zone
|
|
||||||
for an explanation of this.
|
|
||||||
|
|
||||||
The optional
|
The optional
|
||||||
.B set:<tag>
|
.B set:<tag>
|
||||||
sets an alphanumeric label which marks this network so that
|
sets an alphanumeric label which marks this network so that
|
||||||
@@ -1247,6 +1263,11 @@ tried. This flag disables this check. Use with caution.
|
|||||||
Extra logging for DHCP: log all the options sent to DHCP clients and
|
Extra logging for DHCP: log all the options sent to DHCP clients and
|
||||||
the tags used to determine them.
|
the tags used to determine them.
|
||||||
.TP
|
.TP
|
||||||
|
.B --quiet-dhcp, --quiet-dhcp6, --quiet-ra
|
||||||
|
Suppress logging of the routine operation of these protocols. Errors and
|
||||||
|
problems will still be logged. --quiet-dhcp and quiet-dhcp6 are
|
||||||
|
over-ridden by --log-dhcp.
|
||||||
|
.TP
|
||||||
.B \-l, --dhcp-leasefile=<path>
|
.B \-l, --dhcp-leasefile=<path>
|
||||||
Use the specified file to store DHCP lease information.
|
Use the specified file to store DHCP lease information.
|
||||||
.TP
|
.TP
|
||||||
@@ -1525,11 +1546,19 @@ the relevant link-local address of the machine running dnsmasq is sent
|
|||||||
as recursive DNS server. If provided, the DHCPv6 options dns-server and
|
as recursive DNS server. If provided, the DHCPv6 options dns-server and
|
||||||
domain-search are used for RDNSS and DNSSL.
|
domain-search are used for RDNSS and DNSSL.
|
||||||
.TP
|
.TP
|
||||||
.B --force-fast-ra
|
.B --ra-param=<interface>,[high|low],[[<ra-interval>],<router lifetime>]
|
||||||
Normally, dnsmasq advertises a new IPv6 prefix frequently (every 10 seconds or so) for the first minute, and then
|
Set non-default values for router advertisements sent via an
|
||||||
drops back to sending "maintenance" advertisements every 10 minutes or so. This option forces dnsmasq to be always in
|
interface. The priority field for the router may be altered from the
|
||||||
frequent RA mode. It's a bug workaround for mobile devices which go deaf to RAs during sleep and therefore
|
default of medium with eg
|
||||||
lose conectivity; with frequent RAs they recover in a reasonable time after wakeup.
|
.B --ra-param=eth0,high.
|
||||||
|
The interval between router advertisements may be set (in seconds) with
|
||||||
|
.B --ra-param=eth0,60.
|
||||||
|
The lifetime of the route may be changed or set to zero, which allows
|
||||||
|
a router to advertise prefixes but not a route via itself.
|
||||||
|
.B --ra-parm=eth0,0,0
|
||||||
|
(A value of zero for the interval means the default value.) All three parameters may be set at once.
|
||||||
|
.B --ra-param=low,60,1200
|
||||||
|
The interface field may include a wildcard.
|
||||||
.TP
|
.TP
|
||||||
.B --enable-tftp[=<interface>[,<interface>]]
|
.B --enable-tftp[=<interface>[,<interface>]]
|
||||||
Enable the TFTP server function. This is deliberately limited to that
|
Enable the TFTP server function. This is deliberately limited to that
|
||||||
@@ -1873,9 +1902,13 @@ Something like:
|
|||||||
.nf
|
.nf
|
||||||
.B auth-server=our.zone.com,eth0
|
.B auth-server=our.zone.com,eth0
|
||||||
.B interface-name=our.zone.com,eth0
|
.B interface-name=our.zone.com,eth0
|
||||||
.B auth-zone=our.zone.com,1.2.3.0/24
|
.B auth-zone=our.zone.com,1.2.3.0/24,eth0
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
|
(The "eth0" argument in auth-zone adds the subnet containing eth0's
|
||||||
|
dynamic address to the zone, so that the interface-name returns the
|
||||||
|
address in outside queries.)
|
||||||
|
|
||||||
Our final configuration builds on that above, but also adds a
|
Our final configuration builds on that above, but also adds a
|
||||||
secondary DNS server. This is another DNS server which learns the DNS data
|
secondary DNS server. This is another DNS server which learns the DNS data
|
||||||
for the zone by doing zones transfer, and acts as a backup should
|
for the zone by doing zones transfer, and acts as a backup should
|
||||||
@@ -1933,18 +1966,20 @@ IPv4 and IPv6 addresses from /etc/hosts (and
|
|||||||
.B --addn-hosts
|
.B --addn-hosts
|
||||||
) and
|
) and
|
||||||
.B --host-record
|
.B --host-record
|
||||||
|
and
|
||||||
|
.B --interface-name
|
||||||
provided the address falls into one of the subnets specified in the
|
provided the address falls into one of the subnets specified in the
|
||||||
.B --auth-zone.
|
.B --auth-zone.
|
||||||
.PP
|
|
||||||
Addresses specified by
|
|
||||||
.B --interface-name.
|
|
||||||
In this case, the address is not contrained to a subnet from
|
|
||||||
.B --auth-zone.
|
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
Addresses of DHCP leases, provided the address falls into one of the subnets specified in the
|
Addresses of DHCP leases, provided the address falls into one of the subnets specified in the
|
||||||
|
.B --auth-zone.
|
||||||
|
(If contructed DHCP ranges are is use, which depend on the address dynamically
|
||||||
|
assigned to an interface, then the form of
|
||||||
.B --auth-zone
|
.B --auth-zone
|
||||||
OR a constructed DHCP range. In the default mode, where a DHCP lease
|
which defines subnets by the dynamic address of an interface should
|
||||||
|
be used to ensure this condition is met.)
|
||||||
|
.PP
|
||||||
|
In the default mode, where a DHCP lease
|
||||||
has an unqualified name, and possibly a qualified name constructed
|
has an unqualified name, and possibly a qualified name constructed
|
||||||
using
|
using
|
||||||
.B --domain
|
.B --domain
|
||||||
|
|||||||
+142
-22
@@ -403,7 +403,8 @@ noms de domains entourés par des '/', selon une syntaxe similaire à l'option
|
|||||||
Ne pas vérifier régulièrement si le fichier /etc/resolv.conf a été modifié.
|
Ne pas vérifier régulièrement si le fichier /etc/resolv.conf a été modifié.
|
||||||
.TP
|
.TP
|
||||||
.B --clear-on-reload
|
.B --clear-on-reload
|
||||||
Lorsque le fichier /etc/resolv.conf est relu, vider le cache DNS.
|
Lorsque le fichier /etc/resolv.conf est relu, ou si les serveurs amonts sont
|
||||||
|
configurés via DBus, vider le cache DNS.
|
||||||
Cela est utile si les nouveaux serveurs sont susceptibles d'avoir des données
|
Cela est utile si les nouveaux serveurs sont susceptibles d'avoir des données
|
||||||
différentes de celles stockées dans le cache.
|
différentes de celles stockées dans le cache.
|
||||||
.TP
|
.TP
|
||||||
@@ -596,9 +597,9 @@ Retourne un enregistrement de type NAPTR, tel que spécifié dans le RFC3403.
|
|||||||
.TP
|
.TP
|
||||||
.B --cname=<cname>,<cible>
|
.B --cname=<cname>,<cible>
|
||||||
Retourne un enregistrement de type CNAME qui indique que <cname> est en
|
Retourne un enregistrement de type CNAME qui indique que <cname> est en
|
||||||
réalité <cible>. Il existe des contraintes significatives sur la valeur
|
réalité <cible>. Il existe des contraintes importantes sur la valeur
|
||||||
de cible; il doit s'agir d'un nom DNS qui est connu de dnsmasq via /etc/hosts
|
cible; il doit s'agir d'un nom DNS qui est connu de dnsmasq via /etc/hosts
|
||||||
(ou un fichier hôtes additionnel), ou via DHCP, ou par un autre
|
(ou un fichier hôtes additionnel), via DHCP, via interface--name ou par un autre
|
||||||
.B --cname.
|
.B --cname.
|
||||||
Si une cible ne satisfait pas ces critères, le CNAME est ignoré. Le CNAME
|
Si une cible ne satisfait pas ces critères, le CNAME est ignoré. Le CNAME
|
||||||
doit être unique, mais il est autorisé d'avoir plus d'un CNAME pointant
|
doit être unique, mais il est autorisé d'avoir plus d'un CNAME pointant
|
||||||
@@ -622,6 +623,24 @@ Plus d'un nom peut être associé à une interface donnée en répétant cette o
|
|||||||
plusieurs fois; dans ce cas, l'enregistrement inverse pointe vers le nom fourni
|
plusieurs fois; dans ce cas, l'enregistrement inverse pointe vers le nom fourni
|
||||||
dans la première instance de cette option.
|
dans la première instance de cette option.
|
||||||
.TP
|
.TP
|
||||||
|
.B --synth-domain=<domaine>,<plage d'adresses>[,<préfixe>]
|
||||||
|
Créé des enregistrements A/AAAA ou PTR pour une plage d'adresses. Les
|
||||||
|
enregistrements utilisent l'adresse ainsi que les points (ou les deux points
|
||||||
|
dans le cas d'IPv6) remplacés par des tirets.
|
||||||
|
|
||||||
|
Un exemple devrait rendre cela plus clair :
|
||||||
|
La configuration
|
||||||
|
.B --synth-domain=thekelleys.org.uk,192.168.0.0/24,internal-
|
||||||
|
permet de retourner internal-192-168-0-56.thekelleys.org.uk lors d'une requête
|
||||||
|
sur l'adresse 192.168.0.56 et vice-versa pour la requête inverse. La même
|
||||||
|
logique s'applique pour IPv6, avec la particularité suivante : les adresses
|
||||||
|
IPv6 pouvant commencer par '::', mais les noms DNS ne pouvant pas commencer
|
||||||
|
par '-', si aucun préfixe n'est donné, un zéro est ajouté en début de nom.
|
||||||
|
Ainsi, ::1 devient 0--1.
|
||||||
|
|
||||||
|
La plage d'adresses peut-être de la forme
|
||||||
|
<adresse IP>,<adresse IP> ou <adresse IP>/<masque réseau>
|
||||||
|
.TP
|
||||||
.B --add-mac
|
.B --add-mac
|
||||||
Ajoute l'adresse MAC du requêteur aux requêtes DNS transmises aux serveurs
|
Ajoute l'adresse MAC du requêteur aux requêtes DNS transmises aux serveurs
|
||||||
amonts. Cela peut être utilisé dans un but de filtrage DNS par les serveurs
|
amonts. Cela peut être utilisé dans un but de filtrage DNS par les serveurs
|
||||||
@@ -630,7 +649,20 @@ même sous-réseau que le serveur dnsmasq. Veuillez noter que le mécanisme
|
|||||||
utilisé pour effectuer cela (une option EDNS0) n'est pas encore standardisée,
|
utilisé pour effectuer cela (une option EDNS0) n'est pas encore standardisée,
|
||||||
aussi cette fonctionalité doit être considérée comme expérimentale. Notez
|
aussi cette fonctionalité doit être considérée comme expérimentale. Notez
|
||||||
également qu'exposer les adresses MAC de la sorte peut avoir des implications
|
également qu'exposer les adresses MAC de la sorte peut avoir des implications
|
||||||
en termes de sécurité et de vie privée.
|
en termes de sécurité et de vie privée. L'avertissement donné pour --add-subnet
|
||||||
|
s'applique également ici.
|
||||||
|
.TP
|
||||||
|
.B --add-subnet[[=<longueur de préfixe IPv4>],<longueur de préfixe IPv6>]
|
||||||
|
Rajoute l'adresse de sous-réseau du requêteur aux requêtes DNS transmises
|
||||||
|
aux serveurs amonts. La quantité d'adresses transmises dépend du paramètre
|
||||||
|
longueur du préfixe : 32 (ou 128 dans le cas d'IPv6) transmet la totalité
|
||||||
|
de l'adresse, 0 n'en transmet aucun mais marque néanmoins la requête ce qui
|
||||||
|
fait qu'aucun serveur amont ne rajoutera d'adresse client. La valeur par
|
||||||
|
défaut est zéro et pour IPv4 et pour IPv6. A noter que les serveurs amonts
|
||||||
|
peuvent-être configurés pour retourner des valeurs différentes en fonction
|
||||||
|
de cette information mais que le cache de dnsmasq n'en tient pas compte.
|
||||||
|
Si une instance de dnsmasq est configurée de telle maniêre que des valeurs
|
||||||
|
différentes pourraient-être rencontrés, alors le cache devrait être désactivé.
|
||||||
.TP
|
.TP
|
||||||
.B \-c, --cache-size=<taille>
|
.B \-c, --cache-size=<taille>
|
||||||
Définit la taille du cache de Dnsmasq. La valeur par défaut est de 150 noms.
|
Définit la taille du cache de Dnsmasq. La valeur par défaut est de 150 noms.
|
||||||
@@ -665,15 +697,20 @@ Si vous utilisez le premier mode DNSSEC, la validation par le resolveur des
|
|||||||
clients, cette option n'est pas requise. Dnsmasq retourne toujours toutes les
|
clients, cette option n'est pas requise. Dnsmasq retourne toujours toutes les
|
||||||
données nécessaires par un client pour effectuer la validation lui-même.
|
données nécessaires par un client pour effectuer la validation lui-même.
|
||||||
.TP
|
.TP
|
||||||
.B --auth-zone=<domaine>[,<sous-réseau>[,<sous-réseau>.....]]
|
|
||||||
|
.B --auth-zone=<domaine>[,<sous-réseau>[/<longueur de préfixe>][,<sous-réseau>[/<longueur de préfixe>].....]]
|
||||||
Définie une zone DNS pour laquelle dnsmasq agit en temps que serveur faisant
|
Définie une zone DNS pour laquelle dnsmasq agit en temps que serveur faisant
|
||||||
autorité. Les enregistrements DNS définis localement et correspondant à ce
|
autorité. Les enregistrements DNS définis localement et correspondant à ce
|
||||||
domaine seront fournis, à ceci près que les enregistrements A et AAAA doivent
|
domaine seront fournis. Les enregistrements A et AAAA doivent se situer dans
|
||||||
se situer dans l'un des sous-réseaux précisés si ceux-ci sont définis, ou dans
|
l'un des sous-réseaux définis, ou dans un réseau correspondant à une plage DHCP
|
||||||
un réseau correspondant à une plage DHCP. Le ou les sous-réseaux sont également
|
(ce comportement peut-être désactivé par
|
||||||
utilisé pour définir les domaines in-addr.arpa et ipv6.arpa servant à
|
.B constructor-noauth:
|
||||||
l'interrogation DNS inverse. Dans le cas d'IPv4, la longueur du masque de
|
). Le ou les sous-réseaux sont également utilisé(s) pour définir les domaines
|
||||||
réseau doit être de 8, 16 ou 24.
|
in-addr.arpa et ipv6.arpa servant à l'interrogation DNS inverse. Si la longueur
|
||||||
|
de préfixe n'est pas spécifiée, elle sera par défaut de 24 pour IPv4 et 64 pour
|
||||||
|
IPv6. Dans le cas d'IPv4, la longueur du masque de réseau devrait-être de 8, 16
|
||||||
|
ou 24, sauf si en cas de mise en place d'une délégation de la zone in-addr.arpa
|
||||||
|
conforme au RFC 2317.
|
||||||
.TP
|
.TP
|
||||||
.B --auth-soa=<numéro de série>[,<mainteneur de zone (hostmaster)>[,<rafraichissement>[,<nombre de réessais>[,<expiration>]]]]
|
.B --auth-soa=<numéro de série>[,<mainteneur de zone (hostmaster)>[,<rafraichissement>[,<nombre de réessais>[,<expiration>]]]]
|
||||||
Spécifie les champs de l'enregistrement de type SOA (Start Of Authority)
|
Spécifie les champs de l'enregistrement de type SOA (Start Of Authority)
|
||||||
@@ -762,6 +799,27 @@ rendues obsolètes puis supprimées lorsque l'adress est rendue obsolète puis
|
|||||||
supprimée. Le nom de l'interface peut être spécifié avec un caractère joker '*'
|
supprimée. Le nom de l'interface peut être spécifié avec un caractère joker '*'
|
||||||
final.
|
final.
|
||||||
|
|
||||||
|
provoque la recherche d'adresses sur eth0 et crée une plage allant de
|
||||||
|
<réseau>::1 à <réseau>:400. Si l'interface est assignée à
|
||||||
|
plus d'un réseau, les plages correspondantes seront respectivement
|
||||||
|
automatiquement créées, rendues obsolètes et supprimées lorsque l'adresse
|
||||||
|
est rendue obsolète et supprimée. Le nom de l'interface peut être spécifié avec
|
||||||
|
un caractère joker '*' final. Les adresses autoconfigurées, privées ou
|
||||||
|
obsolètes ne conviennent pas.
|
||||||
|
|
||||||
|
Si une plage dhcp-range est uniquement utilisée pour du DHCP sans-état
|
||||||
|
("stateless") ou de l'autoconfiguration sans état ("SLAAC"), alors l'adresse
|
||||||
|
peut-être indiquée sous la forme '::'
|
||||||
|
|
||||||
|
.B --dhcp-range=::,constructor:eth0
|
||||||
|
|
||||||
|
Il existe une variante de la syntaxe constructor: qui consiste en l'utilisation
|
||||||
|
du mot-clef
|
||||||
|
.B constructor-noauth.
|
||||||
|
Voir
|
||||||
|
.B --auth-zone
|
||||||
|
pour des explications à ce sujet.
|
||||||
|
|
||||||
L'identifiant de label optionnel
|
L'identifiant de label optionnel
|
||||||
.B set:<label>
|
.B set:<label>
|
||||||
fournie une étiquette alphanumérique qui identifie ce réseau, afin de permettre
|
fournie une étiquette alphanumérique qui identifie ce réseau, afin de permettre
|
||||||
@@ -853,9 +911,9 @@ sous-réseau qu'une plage dhcp-range valide. Pour les sous-réseaux qui n'ont pa
|
|||||||
besoin d'adresses dynamiquement allouées, utiliser le mot-clef "static" dans la
|
besoin d'adresses dynamiquement allouées, utiliser le mot-clef "static" dans la
|
||||||
déclaration de plage d'adresses dhcp-range.
|
déclaration de plage d'adresses dhcp-range.
|
||||||
|
|
||||||
Il est possible
|
Il est possible d'utiliser des identifiants clients (appellé "DUID client" dans
|
||||||
d'utiliser des identifiants clients plutôt que des adresses matérielles pour
|
le monde IPv6) plutôt que des adresses matérielles pour identifier les hôtes,
|
||||||
identifier les hôtes, en préfixant par ceux-ci par 'id:'. Ainsi,
|
en préfixant ceux-ci par 'id:'. Ainsi,
|
||||||
.B --dhcp-host=id:01:02:03:04,.....
|
.B --dhcp-host=id:01:02:03:04,.....
|
||||||
réfère à l'hôte d'identifiant 01:02:03:04. Il est également possible de
|
réfère à l'hôte d'identifiant 01:02:03:04. Il est également possible de
|
||||||
spécifier l'identifiant client sous la forme d'une chaîne de caractères, comme
|
spécifier l'identifiant client sous la forme d'une chaîne de caractères, comme
|
||||||
@@ -871,11 +929,13 @@ Les adresses IPv6 peuvent ne contenir que la partie identifiant de client :
|
|||||||
.B --dhcp-host=laptop,[::56]
|
.B --dhcp-host=laptop,[::56]
|
||||||
Dans ce cas, lorsque des plages dhcp sont définies automatiquement par le biais
|
Dans ce cas, lorsque des plages dhcp sont définies automatiquement par le biais
|
||||||
de constructeurs, la partie réseau correspondante est rajoutée à l'adresse.
|
de constructeurs, la partie réseau correspondante est rajoutée à l'adresse.
|
||||||
A noter que pour le DHCP IPv6, l'adresse matérielle n'est en principe pas
|
|
||||||
disponible, aussi un client doit-être identifié par un identifiant de client
|
|
||||||
(appellé "DUID client") ou un nom d'hôte.
|
|
||||||
|
|
||||||
L'option spéciale id:* signifie : "ignorer tout identifiant client et n'utiliser
|
A noter que pour le DHCP IPv6, l'adresse matérielle n'est pas toujours
|
||||||
|
disponible, bien que ce soit toujours le cas pour des clients directement
|
||||||
|
connectés (sur le même domaine de broadcast) ou pour des clients utilisant
|
||||||
|
des relais DHCP qui supportent la RFC 6939.
|
||||||
|
|
||||||
|
En DHCPv4, l'option spéciale id:* signifie : "ignorer tout identifiant client et n'utiliser
|
||||||
que l'adresse matérielle". Cela est utile lorsqu'un client présente un
|
que l'adresse matérielle". Cela est utile lorsqu'un client présente un
|
||||||
identifiant client mais pas les autres.
|
identifiant client mais pas les autres.
|
||||||
|
|
||||||
@@ -1079,6 +1139,40 @@ quelques rares cas, perturber des clients vieux ou défectueux. Cette
|
|||||||
option force le comportement à l'utilisation des valeurs "simples et sûres"
|
option force le comportement à l'utilisation des valeurs "simples et sûres"
|
||||||
afin d'éviter des problèmes dans de tels cas.
|
afin d'éviter des problèmes dans de tels cas.
|
||||||
.TP
|
.TP
|
||||||
|
.B --dhcp-relay=<adresse locale>,<adresse de serveur>[,<interface]
|
||||||
|
Configure dnsmasq en temps que relais DHCP. L'adresse locale est une
|
||||||
|
adresse allouée à l'une interface de la machine sur laquelle tourne dnsmasq.
|
||||||
|
Toutes les requêtes DHCP arrivant sur cette interface seront relayées au
|
||||||
|
serveur DHCP distant correspondant à l'adresse de serveur indiquée. Il est
|
||||||
|
possible de relayer depuis une unique adresse locale vers différents serveurs
|
||||||
|
distant en spécifiant plusieurs fois l'option dhcp-relay avec la même adresse
|
||||||
|
locale et différentes adresses de serveur. L'adresse de serveur doit-être
|
||||||
|
sous forme numérique. Dans le cas de DHCPv6, l'adresse de serveur peut-être
|
||||||
|
l'adresse de multicast ff05::1:3 correspondant à tous les serveurs DHCP. Dans
|
||||||
|
ce cas, l'interface doit-étre spécifiée et ne peut comporter de caractère
|
||||||
|
joker. Elle sera utilisée pour indiquer l'interface à partir de laquelle le
|
||||||
|
multicast pourra atteindre le serveur DHCP.
|
||||||
|
|
||||||
|
Le contrôle d'accès pour les clients DHCP suivent les mêmes règles que pour
|
||||||
|
les serveurs DHCP : voir --interface, --except-interface, etc. Le nom
|
||||||
|
d'interface optionel dans l'option dhcp-relay comporte une autre fonction :
|
||||||
|
il contrôle l'interface sur laquelle la réponse du serveur sera acceptée. Cela
|
||||||
|
sert par exemple dans des configurations à 3 interfaces : une à partir de
|
||||||
|
laquelle les requêtes sont relayées, une seconde permettant de se connecter à
|
||||||
|
un serveur DHCP, et une troisième reliée à un réseau non-sécurisé tel
|
||||||
|
qu'internet. Cela permet d'éviter l'arrivée de requêtes usurpées via cette
|
||||||
|
troisième interface.
|
||||||
|
|
||||||
|
Il est permis de configurer dnsmasq pour fonctionner comme serveur DHCP sur
|
||||||
|
certaines interfaces et en temps que relais sur d'autres. Cependant, même s'il
|
||||||
|
est possible de configurer dnsmasq de telle manière qu'il soit à la fois
|
||||||
|
serveur et relais pour une même interface, cela n'est pas supporté et la
|
||||||
|
fonction de relais prendra le dessus.
|
||||||
|
|
||||||
|
Le relais DHCPv4 et le relais DHCPv6 sont tous les deux supportés, mais il
|
||||||
|
n'est pas possible de relayer des requêtes DHCPv4 à un serveur DHCPv6 et
|
||||||
|
vice-versa.
|
||||||
|
.TP
|
||||||
.B \-U, --dhcp-vendorclass=set:<label>,[enterprise:<numéro IANA d'enterprise>,]<classe de vendeur>
|
.B \-U, --dhcp-vendorclass=set:<label>,[enterprise:<numéro IANA d'enterprise>,]<classe de vendeur>
|
||||||
|
|
||||||
Associe une chaîne de classe de vendeur à un label. La plupart
|
Associe une chaîne de classe de vendeur à un label. La plupart
|
||||||
@@ -1113,7 +1207,7 @@ d'impression différent pour les hôtes de la classe "comptes" et ceux de la
|
|||||||
classe "ingénierie".
|
classe "ingénierie".
|
||||||
.TP
|
.TP
|
||||||
.B \-4, --dhcp-mac=set:<label>,<adresse MAC>
|
.B \-4, --dhcp-mac=set:<label>,<adresse MAC>
|
||||||
(IPv4 uniquement) Associe une adresse matérielle (MAC) à un label. L'adresse
|
Associe une adresse matérielle (MAC) à un label. L'adresse
|
||||||
matérielle peut inclure des jokers. Par exemple
|
matérielle peut inclure des jokers. Par exemple
|
||||||
.B --dhcp-mac=set:3com,01:34:23:*:*:*
|
.B --dhcp-mac=set:3com,01:34:23:*:*:*
|
||||||
permet de définir le label "3com" pour n'importe quel hôte dont l'adresse
|
permet de définir le label "3com" pour n'importe quel hôte dont l'adresse
|
||||||
@@ -1354,6 +1448,11 @@ Traces additionnelles pour le service DHCP : enregistre toutes les options
|
|||||||
envoyées aux clients DHCP et les labels utilisés pour la
|
envoyées aux clients DHCP et les labels utilisés pour la
|
||||||
détermination de celles-ci.
|
détermination de celles-ci.
|
||||||
.TP
|
.TP
|
||||||
|
.B --quiet-dhcp, --quiet-dhcp6, --quiet-ra
|
||||||
|
Supprime les logs des opérations de routine des protocoles concernés. Les
|
||||||
|
erreurs et les problèmes seront toujours enregistrés. L'option --log-dhcp
|
||||||
|
prends le pas sur --quiet-dhcp et quiet-dhcp6.
|
||||||
|
.TP
|
||||||
.B \-l, --dhcp-leasefile=<chemin de fichier>
|
.B \-l, --dhcp-leasefile=<chemin de fichier>
|
||||||
Utilise le fichier dont le chemin est fourni pour stocker les informations de
|
Utilise le fichier dont le chemin est fourni pour stocker les informations de
|
||||||
baux DHCP.
|
baux DHCP.
|
||||||
@@ -1447,6 +1546,8 @@ pour chaque appel au script.
|
|||||||
DNSMASQ_IAID contenant l'IAID pour le bail. Si le bail est une allocation
|
DNSMASQ_IAID contenant l'IAID pour le bail. Si le bail est une allocation
|
||||||
temporaire, cela est préfixé par le caractère 'T'.
|
temporaire, cela est préfixé par le caractère 'T'.
|
||||||
|
|
||||||
|
DNSMASQ_MAC contient l'adresse MAC du client, si celle-ci est connue.
|
||||||
|
|
||||||
A noter que le nom d'hôte fourni, la classe de vendeur ou les données de classe
|
A noter que le nom d'hôte fourni, la classe de vendeur ou les données de classe
|
||||||
d'utilisateur sont uniquement fournies pour les actions "add" ou l'action "old"
|
d'utilisateur sont uniquement fournies pour les actions "add" ou l'action "old"
|
||||||
lorsqu'un hôte reprend un bail existant, puisque ces informations ne sont pas
|
lorsqu'un hôte reprend un bail existant, puisque ces informations ne sont pas
|
||||||
@@ -1649,11 +1750,30 @@ dnsmasq est spécifiée comme DNS récursif. Si elles sont fournies, les
|
|||||||
options dns-server et domain-search sont utilisées respectivement pour RDNSS et
|
options dns-server et domain-search sont utilisées respectivement pour RDNSS et
|
||||||
DNSSL.
|
DNSSL.
|
||||||
.TP
|
.TP
|
||||||
.B --enable-tftp
|
.B --ra-param=<interface>,[high|low],[[<intervalle d'annonce routeur>],<durée de vie route>]
|
||||||
|
Configure pour une interface donnée des valeurs pour les annonces routeurs
|
||||||
|
différentes des valeurs par défaut. La valeur par défaut du champ priorité
|
||||||
|
pour le routeur peut-être changée de "medium" (moyen) à "high" (haute) ou
|
||||||
|
"low" (basse). Par exemple :
|
||||||
|
.B --ra-param=eth0,high.
|
||||||
|
Un intervalle (en secondes) entre les annonces routeur peut-être fourni par :
|
||||||
|
.B --ra-param=eth0,60.
|
||||||
|
La durée de vie de la route peut-être changée ou mise à zéro, auquel cas
|
||||||
|
le routeur peut annoncer les préfixes mais pas de route :
|
||||||
|
.B --ra-parm=eth0,0,0
|
||||||
|
(une valeur de zéro pour l'intervalle signifie qu'il garde la valeur par défaut).
|
||||||
|
Ces trois paramètres peuvent-être configurés en une fois :
|
||||||
|
.B --ra-param=low,60,1200
|
||||||
|
La valeur pour l'interface peut inclure un caractère joker.
|
||||||
|
.TP
|
||||||
|
.B --enable-tftp[=<interface>[,<interface>]]
|
||||||
Active la fonction serveur TFTP. Celui-ci est de manière délibérée limité aux
|
Active la fonction serveur TFTP. Celui-ci est de manière délibérée limité aux
|
||||||
fonctions nécessaires au démarrage par le réseau ("net-boot") d'un client. Seul
|
fonctions nécessaires au démarrage par le réseau ("net-boot") d'un client. Seul
|
||||||
un accès en lecture est possible; les extensions tsize et blksize sont supportées
|
un accès en lecture est possible; les extensions tsize et blksize sont supportées
|
||||||
(tsize est seulement supporté en mode octet).
|
(tsize est seulement supporté en mode octet). Sans argument optionel, le service
|
||||||
|
TFTP est fourni sur les mêmes interfaces que le service DHCP. Si une liste
|
||||||
|
d'interfaces est fournie, cela définit les interfaces sur lesquelles le
|
||||||
|
service TFTP sera activé.
|
||||||
.TP
|
.TP
|
||||||
.B --tftp-root=<répertoire>[,<interface>]
|
.B --tftp-root=<répertoire>[,<interface>]
|
||||||
Les fichiers à fournir dans les transferts TFTP seront cherchés en prenant le
|
Les fichiers à fournir dans les transferts TFTP seront cherchés en prenant le
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
# Translation completed by Gildas Le Nadan <3ntr0p13@gmail.com>
|
# Translation completed by Gildas Le Nadan <3ntr0p13@gmail.com>
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: dnsmasq 2.66\n"
|
"Project-Id-Version: dnsmasq 2.67\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2009-06-18 12:24+0100\n"
|
"POT-Creation-Date: 2009-06-18 12:24+0100\n"
|
||||||
"PO-Revision-Date: 2013-03-26 21:12+1100\n"
|
"PO-Revision-Date: 2013-10-24 19:24+1100\n"
|
||||||
"Last-Translator: Gildas Le Nadan <3ntr0p13@gmail.com>\n"
|
"Last-Translator: Gildas Le Nadan <3ntr0p13@gmail.com>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=ISO-8859-1\n"
|
"Content-Type: text/plain; charset=ISO-8859-1\n"
|
||||||
@@ -541,7 +541,7 @@ msgstr "Utilise ces relais DHCP en temps que proxy complets."
|
|||||||
|
|
||||||
#: option.c:394
|
#: option.c:394
|
||||||
msgid "Relay DHCP requests to a remote server"
|
msgid "Relay DHCP requests to a remote server"
|
||||||
msgstr ""
|
msgstr "Requêtes de relais DHCP à un serveur distant"
|
||||||
|
|
||||||
#: option.c:395
|
#: option.c:395
|
||||||
msgid "Specify alias name for LOCAL DNS name."
|
msgid "Specify alias name for LOCAL DNS name."
|
||||||
@@ -582,11 +582,11 @@ msgstr "Autoriser les clients DHCP
|
|||||||
|
|
||||||
#: option.c:404
|
#: option.c:404
|
||||||
msgid "Send router-advertisements for interfaces doing DHCPv6"
|
msgid "Send router-advertisements for interfaces doing DHCPv6"
|
||||||
msgstr "envoyer des annonces de routeurs pour toutes les interfaces faisant du DHCPv6"
|
msgstr "Envoyer des annonces de routeurs pour toutes les interfaces faisant du DHCPv6"
|
||||||
|
|
||||||
#: option.c:405
|
#: option.c:405
|
||||||
msgid "Always send frequent router-advertisements"
|
msgid "Always send frequent router-advertisements"
|
||||||
msgstr ""
|
msgstr "Envoyer des annonces de routeurs fréquentes"
|
||||||
|
|
||||||
#: option.c:406
|
#: option.c:406
|
||||||
msgid "Specify DUID_EN-type DHCPv6 server DUID"
|
msgid "Specify DUID_EN-type DHCPv6 server DUID"
|
||||||
@@ -634,7 +634,7 @@ msgstr "Sp
|
|||||||
|
|
||||||
#: option.c:417
|
#: option.c:417
|
||||||
msgid "Specify a domain and address range for sythesised names"
|
msgid "Specify a domain and address range for sythesised names"
|
||||||
msgstr ""
|
msgstr "Spécifie un domaine et une plage d'adresses pour les noms auto-générés"
|
||||||
|
|
||||||
#: option.c:419
|
#: option.c:419
|
||||||
msgid "Specify DHCPv6 prefix class"
|
msgid "Specify DHCPv6 prefix class"
|
||||||
@@ -787,17 +787,14 @@ msgid "inconsistent DHCP range"
|
|||||||
msgstr "plage d'adresses DHCP incohérente"
|
msgstr "plage d'adresses DHCP incohérente"
|
||||||
|
|
||||||
#: option.c:2459
|
#: option.c:2459
|
||||||
#, fuzzy
|
|
||||||
msgid "prefix length must be exactly 64 for RA subnets"
|
msgid "prefix length must be exactly 64 for RA subnets"
|
||||||
msgstr "la taille du préfixe doit être exactement 64 pour les sous-réseaux d'annonces de routeurs (RA)"
|
msgstr "la taille du préfixe doit être exactement 64 pour les sous-réseaux d'annonces de routeurs (RA)"
|
||||||
|
|
||||||
#: option.c:2461
|
#: option.c:2461
|
||||||
#, fuzzy
|
|
||||||
msgid "prefix length must be exactly 64 for subnet constructors"
|
msgid "prefix length must be exactly 64 for subnet constructors"
|
||||||
msgstr "la taille du préfixe doit être exactement 64 pour le constructeur de sous-réseaux"
|
msgstr "la taille du préfixe doit être exactement 64 pour le constructeur de sous-réseaux"
|
||||||
|
|
||||||
#: option.c:2465
|
#: option.c:2465
|
||||||
#, fuzzy
|
|
||||||
msgid "prefix length must be at least 64"
|
msgid "prefix length must be at least 64"
|
||||||
msgstr "la taille de préfixe doit être au minimum 64"
|
msgstr "la taille de préfixe doit être au minimum 64"
|
||||||
|
|
||||||
@@ -806,9 +803,8 @@ msgid "inconsistent DHCPv6 range"
|
|||||||
msgstr "plage d'adresses DHCPv6 incohérente"
|
msgstr "plage d'adresses DHCPv6 incohérente"
|
||||||
|
|
||||||
#: option.c:2479
|
#: option.c:2479
|
||||||
#, fuzzy
|
|
||||||
msgid "prefix must be zero with \"constructor:\" argument"
|
msgid "prefix must be zero with \"constructor:\" argument"
|
||||||
msgstr "la taille du préfixe doit être exactement 64 pour le constructeur de sous-réseaux"
|
msgstr "le préfixe doit avoir une taille de 0 lorsque l'argument \"constructor:\" est utilisé"
|
||||||
|
|
||||||
#: option.c:2590 option.c:2638
|
#: option.c:2590 option.c:2638
|
||||||
msgid "bad hex constant"
|
msgid "bad hex constant"
|
||||||
@@ -842,9 +838,8 @@ msgid "bad dhcp-proxy address"
|
|||||||
msgstr "adresse dhcp-proxy incorrecte"
|
msgstr "adresse dhcp-proxy incorrecte"
|
||||||
|
|
||||||
#: option.c:3210
|
#: option.c:3210
|
||||||
#, fuzzy
|
|
||||||
msgid "Bad dhcp-relay"
|
msgid "Bad dhcp-relay"
|
||||||
msgstr "plage d'adresses DHCP (dhcp-range) incorrecte"
|
msgstr "valeur incorrecte pour le relais DHCP (dhcp-relay)"
|
||||||
|
|
||||||
#: option.c:3220
|
#: option.c:3220
|
||||||
msgid "bad DUID"
|
msgid "bad DUID"
|
||||||
@@ -1039,9 +1034,9 @@ msgid "possible DNS-rebind attack detected: %s"
|
|||||||
msgstr "détection d'une possible attaque de type DNS-rebind: %s"
|
msgstr "détection d'une possible attaque de type DNS-rebind: %s"
|
||||||
|
|
||||||
#: forward.c:1216
|
#: forward.c:1216
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "Maximum number of concurrent DNS queries reached (max: %d)"
|
msgid "Maximum number of concurrent DNS queries reached (max: %d)"
|
||||||
msgstr "Spécifie le nombre maximum de requêtes DHCP concurrentes (par défaut : %s)."
|
msgstr "Nombre maximum de requêtes DNS concurrentes atteint (maximum : %d)."
|
||||||
|
|
||||||
#: network.c:551
|
#: network.c:551
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -1391,7 +1386,7 @@ msgstr "ignore %s
|
|||||||
#: dhcp.c:993 rfc3315.c:2047
|
#: dhcp.c:993 rfc3315.c:2047
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "DHCP relay %s -> %s"
|
msgid "DHCP relay %s -> %s"
|
||||||
msgstr ""
|
msgstr "Relais DHCP %s -> %s"
|
||||||
|
|
||||||
#: lease.c:61
|
#: lease.c:61
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -1709,9 +1704,9 @@ msgid "%u vendor class: %u"
|
|||||||
msgstr "%u Classe de vendeur ('Vendor Class') : %u"
|
msgstr "%u Classe de vendeur ('Vendor Class') : %u"
|
||||||
|
|
||||||
#: rfc3315.c:418
|
#: rfc3315.c:418
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "%u client MAC address: %s"
|
msgid "%u client MAC address: %s"
|
||||||
msgstr "le client %u fourni le nom : %s"
|
msgstr "%u MAC adresse du client : %s"
|
||||||
|
|
||||||
#: rfc3315.c:650
|
#: rfc3315.c:650
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -1760,7 +1755,7 @@ msgstr "lib
|
|||||||
|
|
||||||
#: rfc3315.c:2038
|
#: rfc3315.c:2038
|
||||||
msgid "Cannot multicast to DHCPv6 server without correct interface"
|
msgid "Cannot multicast to DHCPv6 server without correct interface"
|
||||||
msgstr ""
|
msgstr "Impossible de faire du multicast au server DHCPv6 sans interface valide"
|
||||||
|
|
||||||
#: dhcp-common.c:145
|
#: dhcp-common.c:145
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -1839,12 +1834,12 @@ msgstr "annonces de routeurs sur %s%s"
|
|||||||
#: dhcp-common.c:875
|
#: dhcp-common.c:875
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "DHCP relay from %s to %s via %s"
|
msgid "DHCP relay from %s to %s via %s"
|
||||||
msgstr ""
|
msgstr "Relais DHCP de %s à %s via %s"
|
||||||
|
|
||||||
#: dhcp-common.c:877
|
#: dhcp-common.c:877
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "DHCP relay from %s to %s"
|
msgid "DHCP relay from %s to %s"
|
||||||
msgstr ""
|
msgstr "Relais DHCP de %s à %s"
|
||||||
|
|
||||||
#: radv.c:93
|
#: radv.c:93
|
||||||
#, c-format
|
#, c-format
|
||||||
|
|||||||
@@ -10,15 +10,15 @@ msgstr ""
|
|||||||
"Project-Id-Version: pl\n"
|
"Project-Id-Version: pl\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2009-06-10 20:57+0100\n"
|
"POT-Creation-Date: 2009-06-10 20:57+0100\n"
|
||||||
"PO-Revision-Date: 2013-04-02 01:44+0200\n"
|
"PO-Revision-Date: 2013-10-01 23:23+0200\n"
|
||||||
"Last-Translator: Jan Psota <jasiupsota@gmail.com>\n"
|
"Last-Translator: Jan Psota <jasiupsota@gmail.com>\n"
|
||||||
"Language-Team: polski <>\n"
|
"Language-Team: polski <>\n"
|
||||||
"Language: \n"
|
"Language: pl\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bits\n"
|
||||||
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
|
||||||
"X-Generator: poedit-1.4.6.1\n"
|
"X-Generator: Gtranslator 2.91.6\n"
|
||||||
"X-Language: pl_PL\n"
|
"X-Language: pl_PL\n"
|
||||||
|
|
||||||
#: cache.c:808
|
#: cache.c:808
|
||||||
@@ -535,7 +535,7 @@ msgstr "Traktowanie wskazanych serwerów pośredniczących DHCP jako działając
|
|||||||
|
|
||||||
#: option.c:394
|
#: option.c:394
|
||||||
msgid "Relay DHCP requests to a remote server"
|
msgid "Relay DHCP requests to a remote server"
|
||||||
msgstr ""
|
msgstr "Przekazywanie żądań DHCP do zdalnego serwera"
|
||||||
|
|
||||||
#: option.c:395
|
#: option.c:395
|
||||||
msgid "Specify alias name for LOCAL DNS name."
|
msgid "Specify alias name for LOCAL DNS name."
|
||||||
@@ -579,7 +579,7 @@ msgstr "Załączenie anonsowania (RA) na interfejsach serwujących DHCPv6"
|
|||||||
|
|
||||||
#: option.c:405
|
#: option.c:405
|
||||||
msgid "Always send frequent router-advertisements"
|
msgid "Always send frequent router-advertisements"
|
||||||
msgstr ""
|
msgstr "Rozsyłanie wielokrotne anonsów rutera (RA)"
|
||||||
|
|
||||||
#: option.c:406
|
#: option.c:406
|
||||||
msgid "Specify DUID_EN-type DHCPv6 server DUID"
|
msgid "Specify DUID_EN-type DHCPv6 server DUID"
|
||||||
@@ -627,7 +627,7 @@ msgstr "Wyszczególnienie ipset-ów, do których będą dopisywane adresy IP le
|
|||||||
|
|
||||||
#: option.c:417
|
#: option.c:417
|
||||||
msgid "Specify a domain and address range for sythesised names"
|
msgid "Specify a domain and address range for sythesised names"
|
||||||
msgstr ""
|
msgstr "Określenie domeny i zakresu adresów dla tworzonych nazw"
|
||||||
|
|
||||||
#: option.c:419
|
#: option.c:419
|
||||||
msgid "Specify DHCPv6 prefix class"
|
msgid "Specify DHCPv6 prefix class"
|
||||||
@@ -775,28 +775,24 @@ msgid "inconsistent DHCP range"
|
|||||||
msgstr "niespójny zakres adresów DHCP"
|
msgstr "niespójny zakres adresów DHCP"
|
||||||
|
|
||||||
#: option.c:2459
|
#: option.c:2459
|
||||||
#, fuzzy
|
|
||||||
msgid "prefix length must be exactly 64 for RA subnets"
|
msgid "prefix length must be exactly 64 for RA subnets"
|
||||||
msgstr "prefix musi mieć wartość =64 dla podsieci RA"
|
msgstr "długość prefiksu musi wynosić dokładnie 64 dla podsieci RA"
|
||||||
|
|
||||||
#: option.c:2461
|
#: option.c:2461
|
||||||
#, fuzzy
|
|
||||||
msgid "prefix length must be exactly 64 for subnet constructors"
|
msgid "prefix length must be exactly 64 for subnet constructors"
|
||||||
msgstr "prefix dla podsieci musi wynosić równo 64"
|
msgstr "długość prefiksu musi wynosić dokładnie 64 dla konstruktorów podsieci"
|
||||||
|
|
||||||
#: option.c:2465
|
#: option.c:2465
|
||||||
#, fuzzy
|
|
||||||
msgid "prefix length must be at least 64"
|
msgid "prefix length must be at least 64"
|
||||||
msgstr "prefix musi mieć wartość >=64"
|
msgstr "długość prefiksu musi wynosić co najmniej 64"
|
||||||
|
|
||||||
#: option.c:2468
|
#: option.c:2468
|
||||||
msgid "inconsistent DHCPv6 range"
|
msgid "inconsistent DHCPv6 range"
|
||||||
msgstr "niespójny zakres adresów DHCPv6"
|
msgstr "niespójny zakres adresów DHCPv6"
|
||||||
|
|
||||||
#: option.c:2479
|
#: option.c:2479
|
||||||
#, fuzzy
|
|
||||||
msgid "prefix must be zero with \"constructor:\" argument"
|
msgid "prefix must be zero with \"constructor:\" argument"
|
||||||
msgstr "prefix dla podsieci musi wynosić równo 64"
|
msgstr "prefiks musi wynosić zero z argumentem \"constructor:\""
|
||||||
|
|
||||||
#: option.c:2590 option.c:2638
|
#: option.c:2590 option.c:2638
|
||||||
msgid "bad hex constant"
|
msgid "bad hex constant"
|
||||||
@@ -828,9 +824,8 @@ msgid "bad dhcp-proxy address"
|
|||||||
msgstr "zły adres dhcp-proxy"
|
msgstr "zły adres dhcp-proxy"
|
||||||
|
|
||||||
#: option.c:3210
|
#: option.c:3210
|
||||||
#, fuzzy
|
|
||||||
msgid "Bad dhcp-relay"
|
msgid "Bad dhcp-relay"
|
||||||
msgstr "nieprawidłowy zakres dhcp-range"
|
msgstr "zły dhcp-relay"
|
||||||
|
|
||||||
#: option.c:3220
|
#: option.c:3220
|
||||||
msgid "bad DUID"
|
msgid "bad DUID"
|
||||||
@@ -1020,9 +1015,9 @@ msgid "possible DNS-rebind attack detected: %s"
|
|||||||
msgstr "prawdopodobnie wykryto atak DNS-rebind: %s"
|
msgstr "prawdopodobnie wykryto atak DNS-rebind: %s"
|
||||||
|
|
||||||
#: forward.c:1216
|
#: forward.c:1216
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "Maximum number of concurrent DNS queries reached (max: %d)"
|
msgid "Maximum number of concurrent DNS queries reached (max: %d)"
|
||||||
msgstr "Maksymalna liczba jednocześnie obsługiwanych zapytań DNS (domyślnie: %s)"
|
msgstr "Osiągnięto graniczną ilość jednocześnie obsługiwanych zapytań DNS (maks: %d)"
|
||||||
|
|
||||||
#: network.c:551
|
#: network.c:551
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -1212,7 +1207,7 @@ msgstr "włączono asynchroniczny tryb zapisu do logów z kolejką na %d komunik
|
|||||||
|
|
||||||
#: dnsmasq.c:659
|
#: dnsmasq.c:659
|
||||||
msgid "IPv6 router advertisement enabled"
|
msgid "IPv6 router advertisement enabled"
|
||||||
msgstr "anonsowanie routera IPv4 włączone"
|
msgstr "anonsowanie rutera IPv6 włączone"
|
||||||
|
|
||||||
#: dnsmasq.c:676
|
#: dnsmasq.c:676
|
||||||
msgid "root is "
|
msgid "root is "
|
||||||
@@ -1367,7 +1362,7 @@ msgstr "w %s pomijam linię %d -- powtórzona nazwa lub adres IP"
|
|||||||
#: dhcp.c:993 rfc3315.c:2047
|
#: dhcp.c:993 rfc3315.c:2047
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "DHCP relay %s -> %s"
|
msgid "DHCP relay %s -> %s"
|
||||||
msgstr ""
|
msgstr "przekazywanie DHCP %s -> %s"
|
||||||
|
|
||||||
#: lease.c:61
|
#: lease.c:61
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -1685,9 +1680,9 @@ msgid "%u vendor class: %u"
|
|||||||
msgstr "%u klasa dostawcy: %u"
|
msgstr "%u klasa dostawcy: %u"
|
||||||
|
|
||||||
#: rfc3315.c:418
|
#: rfc3315.c:418
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "%u client MAC address: %s"
|
msgid "%u client MAC address: %s"
|
||||||
msgstr "klient %u przedstawia się jako %s"
|
msgstr "adres MAC klienta %u: %s"
|
||||||
|
|
||||||
#: rfc3315.c:650
|
#: rfc3315.c:650
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -1736,7 +1731,7 @@ msgstr "adres został zwolniony"
|
|||||||
|
|
||||||
#: rfc3315.c:2038
|
#: rfc3315.c:2038
|
||||||
msgid "Cannot multicast to DHCPv6 server without correct interface"
|
msgid "Cannot multicast to DHCPv6 server without correct interface"
|
||||||
msgstr ""
|
msgstr "Nie mogę rozesłać do serwerów DHCPv6 nie mając prawidłowego interfejsu"
|
||||||
|
|
||||||
#: dhcp-common.c:145
|
#: dhcp-common.c:145
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -1802,25 +1797,25 @@ msgstr "%s, wykryto pośrednika na podsieci %.0s%s%.0s%.0s"
|
|||||||
msgid "%s, IP range %s -- %s%s%.0s"
|
msgid "%s, IP range %s -- %s%s%.0s"
|
||||||
msgstr "%s, zakres IP %s -- %s%s%.0s"
|
msgstr "%s, zakres IP %s -- %s%s%.0s"
|
||||||
|
|
||||||
#: dhcp-common.c:861
|
#: dhcp-common.c:866
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "DHCPv4-derived IPv6 names on %s%s"
|
msgid "DHCPv4-derived IPv6 names on %s%s"
|
||||||
msgstr "pochodzące z DHCPv4 nazwy IPv6 na %s%s"
|
msgstr "pochodzące z DHCPv4 nazwy IPv6 na %s%s"
|
||||||
|
|
||||||
#: dhcp-common.c:864
|
#: dhcp-common.c:869
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "router advertisement on %s%s"
|
msgid "router advertisement on %s%s"
|
||||||
msgstr "anonsowanie routera na %s%s"
|
msgstr "anonsowanie rutera na %s%s"
|
||||||
|
|
||||||
#: dhcp-common.c:875
|
#: dhcp-common.c:880
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "DHCP relay from %s to %s via %s"
|
msgid "DHCP relay from %s to %s via %s"
|
||||||
msgstr ""
|
msgstr "przekazywanie DHCP z %s do %s za pomocą %s"
|
||||||
|
|
||||||
#: dhcp-common.c:877
|
#: dhcp-common.c:882
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "DHCP relay from %s to %s"
|
msgid "DHCP relay from %s to %s"
|
||||||
msgstr ""
|
msgstr "przekazywanie DHCP z %s do %s"
|
||||||
|
|
||||||
#: radv.c:93
|
#: radv.c:93
|
||||||
#, c-format
|
#, c-format
|
||||||
|
|||||||
+77
-79
@@ -18,27 +18,26 @@
|
|||||||
|
|
||||||
#ifdef HAVE_AUTH
|
#ifdef HAVE_AUTH
|
||||||
|
|
||||||
static struct subnet *filter_zone(struct auth_zone *zone, int flag, struct all_addr *addr_u)
|
static struct addrlist *filter_zone(struct auth_zone *zone, int flag, struct all_addr *addr_u)
|
||||||
{
|
{
|
||||||
struct subnet *subnet;
|
struct addrlist *subnet;
|
||||||
|
|
||||||
for (subnet = zone->subnet; subnet; subnet = subnet->next)
|
for (subnet = zone->subnet; subnet; subnet = subnet->next)
|
||||||
{
|
{
|
||||||
if (subnet->is6 && (flag & F_IPV4))
|
if (!(subnet->flags & ADDRLIST_IPV6))
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!subnet->is6)
|
|
||||||
{
|
{
|
||||||
struct in_addr addr = addr_u->addr.addr4;
|
struct in_addr netmask, addr = addr_u->addr.addr4;
|
||||||
struct in_addr mask;
|
|
||||||
|
if (!(flag & F_IPV4))
|
||||||
|
continue;
|
||||||
|
|
||||||
mask.s_addr = htonl(~((1 << (32 - subnet->prefixlen)) - 1));
|
netmask.s_addr = htonl(~((1 << (32 - subnet->prefixlen)) - 1));
|
||||||
|
|
||||||
if (is_same_net(addr, subnet->addr4, mask))
|
if (is_same_net(addr, subnet->addr.addr.addr4, netmask))
|
||||||
return subnet;
|
return subnet;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
else if (is_same_net6(&(addr_u->addr.addr6), &subnet->addr6, subnet->prefixlen))
|
else if (is_same_net6(&(addr_u->addr.addr6), &subnet->addr.addr.addr6, subnet->prefixlen))
|
||||||
return subnet;
|
return subnet;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -46,23 +45,7 @@ static struct subnet *filter_zone(struct auth_zone *zone, int flag, struct all_a
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int filter_constructed_dhcp(struct auth_zone *zone, int flag, struct all_addr *addr_u)
|
int in_zone(struct auth_zone *zone, char *name, char **cut)
|
||||||
{
|
|
||||||
#ifdef HAVE_DHCP6
|
|
||||||
struct dhcp_context *context;
|
|
||||||
|
|
||||||
if (flag & F_IPV6)
|
|
||||||
for (context = daemon->dhcp6; context; context = context->next)
|
|
||||||
if ((context->flags & CONTEXT_CONSTRUCTED) &&
|
|
||||||
!(context->flags & CONTEXT_NOAUTH) &&
|
|
||||||
is_same_net6(&(addr_u->addr.addr6), &context->start6, context->prefix))
|
|
||||||
return 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return filter_zone(zone, flag, addr_u) != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int in_zone(struct auth_zone *zone, char *name, char **cut)
|
|
||||||
{
|
{
|
||||||
size_t namelen = strlen(name);
|
size_t namelen = strlen(name);
|
||||||
size_t domainlen = strlen(zone->domain);
|
size_t domainlen = strlen(zone->domain);
|
||||||
@@ -89,7 +72,7 @@ static int in_zone(struct auth_zone *zone, char *name, char **cut)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now, union mysockaddr *peer_addr)
|
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now, union mysockaddr *peer_addr, int local_query)
|
||||||
{
|
{
|
||||||
char *name = daemon->namebuff;
|
char *name = daemon->namebuff;
|
||||||
unsigned char *p, *ansp;
|
unsigned char *p, *ansp;
|
||||||
@@ -97,9 +80,9 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
int nameoffset, axfroffset = 0;
|
int nameoffset, axfroffset = 0;
|
||||||
int q, anscount = 0, authcount = 0;
|
int q, anscount = 0, authcount = 0;
|
||||||
struct crec *crecp;
|
struct crec *crecp;
|
||||||
int auth = 1, trunc = 0, nxdomain = 1, soa = 0, ns = 0, axfr = 0;
|
int auth = !local_query, trunc = 0, nxdomain = 1, soa = 0, ns = 0, axfr = 0;
|
||||||
struct auth_zone *zone = NULL;
|
struct auth_zone *zone = NULL;
|
||||||
struct subnet *subnet = NULL;
|
struct addrlist *subnet = NULL;
|
||||||
char *cut;
|
char *cut;
|
||||||
struct mx_srv_record *rec, *move, **up;
|
struct mx_srv_record *rec, *move, **up;
|
||||||
struct txt_record *txt;
|
struct txt_record *txt;
|
||||||
@@ -110,7 +93,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
|
|
||||||
if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
|
if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* determine end of question section (we put answers there) */
|
/* determine end of question section (we put answers there) */
|
||||||
if (!(ansp = skip_questions(header, qlen)))
|
if (!(ansp = skip_questions(header, qlen)))
|
||||||
return 0; /* bad packet */
|
return 0; /* bad packet */
|
||||||
@@ -144,16 +127,19 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
if (!(flag = in_arpa_name_2_addr(name, &addr)))
|
if (!(flag = in_arpa_name_2_addr(name, &addr)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (zone = daemon->auth_zones; zone; zone = zone->next)
|
if (!local_query)
|
||||||
if ((subnet = filter_zone(zone, flag, &addr)))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!zone)
|
|
||||||
{
|
{
|
||||||
auth = 0;
|
for (zone = daemon->auth_zones; zone; zone = zone->next)
|
||||||
continue;
|
if ((subnet = filter_zone(zone, flag, &addr)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!zone)
|
||||||
|
{
|
||||||
|
auth = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
intr = NULL;
|
intr = NULL;
|
||||||
|
|
||||||
if (flag == F_IPV4)
|
if (flag == F_IPV4)
|
||||||
@@ -161,8 +147,8 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
{
|
{
|
||||||
struct addrlist *addrlist;
|
struct addrlist *addrlist;
|
||||||
|
|
||||||
for (addrlist = intr->addr4; addrlist; addrlist = addrlist->next)
|
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
|
||||||
if (addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr)
|
if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (addrlist)
|
if (addrlist)
|
||||||
@@ -177,8 +163,8 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
{
|
{
|
||||||
struct addrlist *addrlist;
|
struct addrlist *addrlist;
|
||||||
|
|
||||||
for (addrlist = intr->addr6; addrlist; addrlist = addrlist->next)
|
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
|
||||||
if (IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6))
|
if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (addrlist)
|
if (addrlist)
|
||||||
@@ -194,7 +180,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
if (in_zone(zone, intr->name, NULL))
|
if (in_zone(zone, intr->name, NULL))
|
||||||
{
|
{
|
||||||
found = 1;
|
found = 1;
|
||||||
log_query(flag| F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
|
log_query(flag | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
|
||||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||||
daemon->auth_ttl, NULL,
|
daemon->auth_ttl, NULL,
|
||||||
T_PTR, C_IN, "d", intr->name))
|
T_PTR, C_IN, "d", intr->name))
|
||||||
@@ -358,25 +344,22 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
if (hostname_isequal(name, intr->name))
|
if (hostname_isequal(name, intr->name))
|
||||||
{
|
{
|
||||||
struct addrlist *addrlist;
|
struct addrlist *addrlist;
|
||||||
|
|
||||||
addrlist = intr->addr4;
|
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
if (qtype == T_AAAA)
|
|
||||||
addrlist = intr->addr6;
|
|
||||||
#endif
|
|
||||||
nxdomain = 0;
|
nxdomain = 0;
|
||||||
|
|
||||||
for (; addrlist; addrlist = addrlist->next)
|
if (flag)
|
||||||
if (filter_constructed_dhcp(zone, flag, &addrlist->addr))
|
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
|
||||||
{
|
if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == qtype &&
|
||||||
found = 1;
|
(local_query || filter_zone(zone, flag, &addrlist->addr)))
|
||||||
log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
|
{
|
||||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
found = 1;
|
||||||
daemon->auth_ttl, NULL, qtype, C_IN,
|
log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
|
||||||
qtype == T_A ? "4" : "6", &addrlist->addr))
|
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||||
anscount++;
|
daemon->auth_ttl, NULL, qtype, C_IN,
|
||||||
}
|
qtype == T_A ? "4" : "6", &addrlist->addr))
|
||||||
}
|
anscount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (a = daemon->cnames; a; a = a->next)
|
for (a = daemon->cnames; a; a = a->next)
|
||||||
if (hostname_isequal(name, a->alias) )
|
if (hostname_isequal(name, a->alias) )
|
||||||
@@ -390,7 +373,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
}
|
}
|
||||||
found = 1;
|
found = 1;
|
||||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||||
daemon->auth_ttl, NULL,
|
daemon->auth_ttl, &nameoffset,
|
||||||
T_CNAME, C_IN, "d", name))
|
T_CNAME, C_IN, "d", name))
|
||||||
anscount++;
|
anscount++;
|
||||||
|
|
||||||
@@ -403,7 +386,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
|
|
||||||
if (qtype == T_SOA)
|
if (qtype == T_SOA)
|
||||||
{
|
{
|
||||||
soa = 1; /* inhibits auth section */
|
auth = soa = 1; /* inhibits auth section */
|
||||||
found = 1;
|
found = 1;
|
||||||
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>");
|
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>");
|
||||||
}
|
}
|
||||||
@@ -436,6 +419,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auth = 1;
|
||||||
soa = 1; /* inhibits auth section */
|
soa = 1; /* inhibits auth section */
|
||||||
ns = 1; /* ensure we include NS records! */
|
ns = 1; /* ensure we include NS records! */
|
||||||
axfr = 1;
|
axfr = 1;
|
||||||
@@ -445,6 +429,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
}
|
}
|
||||||
else if (qtype == T_NS)
|
else if (qtype == T_NS)
|
||||||
{
|
{
|
||||||
|
auth = 1;
|
||||||
ns = 1; /* inhibits auth section */
|
ns = 1; /* inhibits auth section */
|
||||||
found = 1;
|
found = 1;
|
||||||
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>");
|
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>");
|
||||||
@@ -462,7 +447,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
{
|
{
|
||||||
nxdomain = 0;
|
nxdomain = 0;
|
||||||
if ((crecp->flags & flag) &&
|
if ((crecp->flags & flag) &&
|
||||||
(filter_constructed_dhcp(zone, flag, &(crecp->addr.addr))))
|
(local_query || filter_zone(zone, flag, &(crecp->addr.addr))))
|
||||||
{
|
{
|
||||||
*cut = '.'; /* restore domain part */
|
*cut = '.'; /* restore domain part */
|
||||||
log_query(crecp->flags, name, &crecp->addr.addr, record_source(crecp->uid));
|
log_query(crecp->flags, name, &crecp->addr.addr, record_source(crecp->uid));
|
||||||
@@ -485,7 +470,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
nxdomain = 0;
|
nxdomain = 0;
|
||||||
if ((crecp->flags & flag) && filter_constructed_dhcp(zone, flag, &(crecp->addr.addr)))
|
if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr.addr))))
|
||||||
{
|
{
|
||||||
log_query(crecp->flags, name, &crecp->addr.addr, record_source(crecp->uid));
|
log_query(crecp->flags, name, &crecp->addr.addr, record_source(crecp->uid));
|
||||||
found = 1;
|
found = 1;
|
||||||
@@ -516,9 +501,9 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
|
|
||||||
authname = name;
|
authname = name;
|
||||||
|
|
||||||
if (!subnet->is6)
|
if (!(subnet->flags & ADDRLIST_IPV6))
|
||||||
{
|
{
|
||||||
in_addr_t a = ntohl(subnet->addr4.s_addr) >> 8;
|
in_addr_t a = ntohl(subnet->addr.addr.addr4.s_addr) >> 8;
|
||||||
char *p = name;
|
char *p = name;
|
||||||
|
|
||||||
if (subnet->prefixlen >= 24)
|
if (subnet->prefixlen >= 24)
|
||||||
@@ -538,7 +523,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
|
|
||||||
for (i = subnet->prefixlen-1; i >= 0; i -= 4)
|
for (i = subnet->prefixlen-1; i >= 0; i -= 4)
|
||||||
{
|
{
|
||||||
int dig = ((unsigned char *)&subnet->addr6)[i>>3];
|
int dig = ((unsigned char *)&subnet->addr.addr.addr6)[i>>3];
|
||||||
p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
|
p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
|
||||||
}
|
}
|
||||||
p += sprintf(p, "ip6.arpa");
|
p += sprintf(p, "ip6.arpa");
|
||||||
@@ -674,15 +659,17 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
if (cut)
|
if (cut)
|
||||||
*cut = 0;
|
*cut = 0;
|
||||||
|
|
||||||
for (addrlist = intr->addr4; addrlist; addrlist = addrlist->next)
|
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
|
||||||
if (filter_constructed_dhcp(zone, F_IPV4, &addrlist->addr) &&
|
if (!(subnet->flags & ADDRLIST_IPV6) &&
|
||||||
|
(local_query || filter_zone(zone, F_IPV4, &addrlist->addr)) &&
|
||||||
add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
|
add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
|
||||||
daemon->auth_ttl, NULL, T_A, C_IN, "4", cut ? intr->name : NULL, &addrlist->addr))
|
daemon->auth_ttl, NULL, T_A, C_IN, "4", cut ? intr->name : NULL, &addrlist->addr))
|
||||||
anscount++;
|
anscount++;
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
for (addrlist = intr->addr6; addrlist; addrlist = addrlist->next)
|
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
|
||||||
if (filter_constructed_dhcp(zone, F_IPV6, &addrlist->addr) &&
|
if ((subnet->flags & ADDRLIST_IPV6) &&
|
||||||
|
(local_query || filter_zone(zone, F_IPV6, &addrlist->addr)) &&
|
||||||
add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
|
add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
|
||||||
daemon->auth_ttl, NULL, T_AAAA, C_IN, "6", cut ? intr->name : NULL, &addrlist->addr))
|
daemon->auth_ttl, NULL, T_AAAA, C_IN, "6", cut ? intr->name : NULL, &addrlist->addr))
|
||||||
anscount++;
|
anscount++;
|
||||||
@@ -722,7 +709,8 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
if ((crecp->flags & F_DHCP) && !option_bool(OPT_DHCP_FQDN))
|
if ((crecp->flags & F_DHCP) && !option_bool(OPT_DHCP_FQDN))
|
||||||
{
|
{
|
||||||
char *cache_name = cache_get_name(crecp);
|
char *cache_name = cache_get_name(crecp);
|
||||||
if (!strchr(cache_name, '.') && filter_constructed_dhcp(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr)))
|
if (!strchr(cache_name, '.') &&
|
||||||
|
(local_query || filter_zone(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr))))
|
||||||
{
|
{
|
||||||
qtype = T_A;
|
qtype = T_A;
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
@@ -739,7 +727,8 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
if ((crecp->flags & F_HOSTS) || (((crecp->flags & F_DHCP) && option_bool(OPT_DHCP_FQDN))))
|
if ((crecp->flags & F_HOSTS) || (((crecp->flags & F_DHCP) && option_bool(OPT_DHCP_FQDN))))
|
||||||
{
|
{
|
||||||
strcpy(name, cache_get_name(crecp));
|
strcpy(name, cache_get_name(crecp));
|
||||||
if (in_zone(zone, name, &cut) && filter_constructed_dhcp(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr)))
|
if (in_zone(zone, name, &cut) &&
|
||||||
|
(local_query || filter_zone(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr))))
|
||||||
{
|
{
|
||||||
qtype = T_A;
|
qtype = T_A;
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
@@ -774,8 +763,17 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
/* done all questions, set up header and return length of result */
|
/* done all questions, set up header and return length of result */
|
||||||
/* clear authoritative and truncated flags, set QR flag */
|
/* clear authoritative and truncated flags, set QR flag */
|
||||||
header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
|
header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
|
||||||
/* clear RA flag */
|
|
||||||
header->hb4 &= ~HB4_RA;
|
if (local_query)
|
||||||
|
{
|
||||||
|
/* set RA flag */
|
||||||
|
header->hb4 |= HB4_RA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* clear RA flag */
|
||||||
|
header->hb4 &= ~HB4_RA;
|
||||||
|
}
|
||||||
|
|
||||||
/* authoritive */
|
/* authoritive */
|
||||||
if (auth)
|
if (auth)
|
||||||
@@ -785,7 +783,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
if (trunc)
|
if (trunc)
|
||||||
header->hb3 |= HB3_TC;
|
header->hb3 |= HB3_TC;
|
||||||
|
|
||||||
if (anscount == 0 && auth && nxdomain)
|
if ((auth || local_query) && nxdomain)
|
||||||
SET_RCODE(header, NXDOMAIN);
|
SET_RCODE(header, NXDOMAIN);
|
||||||
else
|
else
|
||||||
SET_RCODE(header, NOERROR); /* no error */
|
SET_RCODE(header, NOERROR); /* no error */
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
# include <net/if_var.h>
|
# include <net/if_var.h>
|
||||||
#endif
|
#endif
|
||||||
#include <netinet/in_var.h>
|
#include <netinet/in_var.h>
|
||||||
|
#include <netinet6/in6_var.h>
|
||||||
|
|
||||||
#ifndef SA_SIZE
|
#ifndef SA_SIZE
|
||||||
#define SA_SIZE(sa) \
|
#define SA_SIZE(sa) \
|
||||||
@@ -145,7 +146,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
|||||||
int i, j, prefix = 0;
|
int i, j, prefix = 0;
|
||||||
u32 valid = 0xffffffff, preferred = 0xffffffff;
|
u32 valid = 0xffffffff, preferred = 0xffffffff;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
#ifdef HAVE_BSD_NETWORK
|
#if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
|
||||||
struct in6_ifreq ifr6;
|
struct in6_ifreq ifr6;
|
||||||
|
|
||||||
memset(&ifr6, 0, sizeof(ifr6));
|
memset(&ifr6, 0, sizeof(ifr6));
|
||||||
|
|||||||
+45
-13
@@ -24,7 +24,7 @@ static struct crec *new_chain = NULL;
|
|||||||
static int cache_inserted = 0, cache_live_freed = 0, insert_error;
|
static int cache_inserted = 0, cache_live_freed = 0, insert_error;
|
||||||
static union bigname *big_free = NULL;
|
static union bigname *big_free = NULL;
|
||||||
static int bignames_left, hash_size;
|
static int bignames_left, hash_size;
|
||||||
static int uid = 0;
|
static int uid = 1;
|
||||||
#ifdef HAVE_DNSSEC
|
#ifdef HAVE_DNSSEC
|
||||||
static struct keydata *keyblock_free = NULL;
|
static struct keydata *keyblock_free = NULL;
|
||||||
#endif
|
#endif
|
||||||
@@ -76,7 +76,7 @@ void cache_init(void)
|
|||||||
{
|
{
|
||||||
struct crec *crecp;
|
struct crec *crecp;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
bignames_left = daemon->cachesize/10;
|
bignames_left = daemon->cachesize/10;
|
||||||
|
|
||||||
if (daemon->cachesize > 0)
|
if (daemon->cachesize > 0)
|
||||||
@@ -177,7 +177,10 @@ static void cache_free(struct crec *crecp)
|
|||||||
crecp->flags &= ~F_FORWARD;
|
crecp->flags &= ~F_FORWARD;
|
||||||
crecp->flags &= ~F_REVERSE;
|
crecp->flags &= ~F_REVERSE;
|
||||||
crecp->uid = uid++; /* invalidate CNAMES pointing to this. */
|
crecp->uid = uid++; /* invalidate CNAMES pointing to this. */
|
||||||
|
|
||||||
|
if (uid == -1)
|
||||||
|
uid++;
|
||||||
|
|
||||||
if (cache_tail)
|
if (cache_tail)
|
||||||
cache_tail->next = crecp;
|
cache_tail->next = crecp;
|
||||||
else
|
else
|
||||||
@@ -235,6 +238,16 @@ char *cache_get_name(struct crec *crecp)
|
|||||||
return crecp->name.sname;
|
return crecp->name.sname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *cache_get_cname_target(struct crec *crecp)
|
||||||
|
{
|
||||||
|
if (crecp->addr.cname.uid != -1)
|
||||||
|
return cache_get_name(crecp->addr.cname.target.cache);
|
||||||
|
|
||||||
|
return crecp->addr.cname.target.int_name->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct crec *cache_enumerate(int init)
|
struct crec *cache_enumerate(int init)
|
||||||
{
|
{
|
||||||
static int bucket;
|
static int bucket;
|
||||||
@@ -260,14 +273,14 @@ struct crec *cache_enumerate(int init)
|
|||||||
|
|
||||||
static int is_outdated_cname_pointer(struct crec *crecp)
|
static int is_outdated_cname_pointer(struct crec *crecp)
|
||||||
{
|
{
|
||||||
if (!(crecp->flags & F_CNAME))
|
if (!(crecp->flags & F_CNAME) || crecp->addr.cname.uid == -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* NB. record may be reused as DS or DNSKEY, where uid is
|
/* NB. record may be reused as DS or DNSKEY, where uid is
|
||||||
overloaded for something completely different */
|
overloaded for something completely different */
|
||||||
if (crecp->addr.cname.cache &&
|
if (crecp->addr.cname.target.cache &&
|
||||||
(crecp->addr.cname.cache->flags & (F_IPV4 | F_IPV6 | F_CNAME)) &&
|
(crecp->addr.cname.target.cache->flags & (F_IPV4 | F_IPV6 | F_CNAME)) &&
|
||||||
crecp->addr.cname.uid == crecp->addr.cname.cache->uid)
|
crecp->addr.cname.uid == crecp->addr.cname.target.cache->uid)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -317,7 +330,7 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
|
|||||||
((flags & crecp->flags & F_TYPE) || ((crecp->flags | flags) & F_CNAME)) &&
|
((flags & crecp->flags & F_TYPE) || ((crecp->flags | flags) & F_CNAME)) &&
|
||||||
hostname_isequal(cache_get_name(crecp), name))
|
hostname_isequal(cache_get_name(crecp), name))
|
||||||
{
|
{
|
||||||
if (crecp->flags & (F_HOSTS | F_DHCP))
|
if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))
|
||||||
return 0;
|
return 0;
|
||||||
*up = crecp->hash_next;
|
*up = crecp->hash_next;
|
||||||
cache_unlink(crecp);
|
cache_unlink(crecp);
|
||||||
@@ -680,9 +693,9 @@ static void add_hosts_cname(struct crec *target)
|
|||||||
if (hostname_isequal(cache_get_name(target), a->target) &&
|
if (hostname_isequal(cache_get_name(target), a->target) &&
|
||||||
(crec = whine_malloc(sizeof(struct crec))))
|
(crec = whine_malloc(sizeof(struct crec))))
|
||||||
{
|
{
|
||||||
crec->flags = F_FORWARD | F_IMMORTAL | F_NAMEP | F_HOSTS | F_CNAME;
|
crec->flags = F_FORWARD | F_IMMORTAL | F_NAMEP | F_CONFIG | F_CNAME;
|
||||||
crec->name.namep = a->alias;
|
crec->name.namep = a->alias;
|
||||||
crec->addr.cname.cache = target;
|
crec->addr.cname.target.cache = target;
|
||||||
crec->addr.cname.uid = target->uid;
|
crec->addr.cname.uid = target->uid;
|
||||||
cache_hash(crec);
|
cache_hash(crec);
|
||||||
add_hosts_cname(crec); /* handle chains */
|
add_hosts_cname(crec); /* handle chains */
|
||||||
@@ -901,6 +914,8 @@ void cache_reload(void)
|
|||||||
struct hostsfile *ah;
|
struct hostsfile *ah;
|
||||||
struct host_record *hr;
|
struct host_record *hr;
|
||||||
struct name_list *nl;
|
struct name_list *nl;
|
||||||
|
struct cname *a;
|
||||||
|
struct interface_name *intr;
|
||||||
|
|
||||||
cache_inserted = cache_live_freed = 0;
|
cache_inserted = cache_live_freed = 0;
|
||||||
|
|
||||||
@@ -927,6 +942,20 @@ void cache_reload(void)
|
|||||||
up = &cache->hash_next;
|
up = &cache->hash_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add CNAMEs to interface_names to the cache */
|
||||||
|
for (a = daemon->cnames; a; a = a->next)
|
||||||
|
for (intr = daemon->int_names; intr; intr = intr->next)
|
||||||
|
if (hostname_isequal(a->target, intr->name))
|
||||||
|
{
|
||||||
|
struct crec *aliasc = safe_malloc(sizeof(struct crec));
|
||||||
|
aliasc->flags = F_FORWARD | F_NAMEP | F_CNAME | F_IMMORTAL | F_CONFIG;
|
||||||
|
aliasc->name.namep = a->alias;
|
||||||
|
aliasc->addr.cname.target.int_name = intr;
|
||||||
|
aliasc->addr.cname.uid = -1;
|
||||||
|
cache_hash(aliasc);
|
||||||
|
add_hosts_cname(aliasc); /* handle chains */
|
||||||
|
}
|
||||||
|
|
||||||
/* borrow the packet buffer for a temporary by-address hash */
|
/* borrow the packet buffer for a temporary by-address hash */
|
||||||
memset(daemon->packet, 0, daemon->packet_buff_sz);
|
memset(daemon->packet, 0, daemon->packet_buff_sz);
|
||||||
revhashsz = daemon->packet_buff_sz / sizeof(struct crec *);
|
revhashsz = daemon->packet_buff_sz / sizeof(struct crec *);
|
||||||
@@ -1019,13 +1048,13 @@ static void add_dhcp_cname(struct crec *target, time_t ttd)
|
|||||||
|
|
||||||
if (aliasc)
|
if (aliasc)
|
||||||
{
|
{
|
||||||
aliasc->flags = F_FORWARD | F_NAMEP | F_DHCP | F_CNAME;
|
aliasc->flags = F_FORWARD | F_NAMEP | F_DHCP | F_CNAME | F_CONFIG;
|
||||||
if (ttd == 0)
|
if (ttd == 0)
|
||||||
aliasc->flags |= F_IMMORTAL;
|
aliasc->flags |= F_IMMORTAL;
|
||||||
else
|
else
|
||||||
aliasc->ttd = ttd;
|
aliasc->ttd = ttd;
|
||||||
aliasc->name.namep = a->alias;
|
aliasc->name.namep = a->alias;
|
||||||
aliasc->addr.cname.cache = target;
|
aliasc->addr.cname.target.cache = target;
|
||||||
aliasc->addr.cname.uid = target->uid;
|
aliasc->addr.cname.uid = target->uid;
|
||||||
cache_hash(aliasc);
|
cache_hash(aliasc);
|
||||||
add_dhcp_cname(aliasc, ttd);
|
add_dhcp_cname(aliasc, ttd);
|
||||||
@@ -1132,6 +1161,9 @@ void dump_cache(time_t now)
|
|||||||
daemon->cachesize, cache_live_freed, cache_inserted);
|
daemon->cachesize, cache_live_freed, cache_inserted);
|
||||||
my_syslog(LOG_INFO, _("queries forwarded %u, queries answered locally %u"),
|
my_syslog(LOG_INFO, _("queries forwarded %u, queries answered locally %u"),
|
||||||
daemon->queries_forwarded, daemon->local_answer);
|
daemon->queries_forwarded, daemon->local_answer);
|
||||||
|
#ifdef HAVE_AUTH
|
||||||
|
my_syslog(LOG_INFO, _("queries for authoritative zones %u"), daemon->auth_answer);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* sum counts from different records for same server */
|
/* sum counts from different records for same server */
|
||||||
for (serv = daemon->servers; serv; serv = serv->next)
|
for (serv = daemon->servers; serv; serv = serv->next)
|
||||||
@@ -1173,7 +1205,7 @@ void dump_cache(time_t now)
|
|||||||
{
|
{
|
||||||
a = "";
|
a = "";
|
||||||
if (!is_outdated_cname_pointer(cache))
|
if (!is_outdated_cname_pointer(cache))
|
||||||
a = cache_get_name(cache->addr.cname.cache);
|
a = cache_get_cname_target(cache);
|
||||||
}
|
}
|
||||||
#ifdef HAVE_DNSSEC
|
#ifdef HAVE_DNSSEC
|
||||||
else if (cache->flags & F_DNSKEY)
|
else if (cache->flags & F_DNSKEY)
|
||||||
|
|||||||
+4
-3
@@ -39,14 +39,12 @@
|
|||||||
#define TFTP_MAX_CONNECTIONS 50 /* max simultaneous connections */
|
#define TFTP_MAX_CONNECTIONS 50 /* max simultaneous connections */
|
||||||
#define LOG_MAX 5 /* log-queue length */
|
#define LOG_MAX 5 /* log-queue length */
|
||||||
#define RANDFILE "/dev/urandom"
|
#define RANDFILE "/dev/urandom"
|
||||||
#define EDNS0_OPTION_MAC 5 /* dyndns.org temporary assignment */
|
|
||||||
#define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq" /* Default - may be overridden by config */
|
#define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq" /* Default - may be overridden by config */
|
||||||
#define DNSMASQ_PATH "/uk/org/thekelleys/dnsmasq"
|
#define DNSMASQ_PATH "/uk/org/thekelleys/dnsmasq"
|
||||||
#define AUTH_TTL 600 /* default TTL for auth DNS */
|
#define AUTH_TTL 600 /* default TTL for auth DNS */
|
||||||
#define SOA_REFRESH 1200 /* SOA refresh default */
|
#define SOA_REFRESH 1200 /* SOA refresh default */
|
||||||
#define SOA_RETRY 180 /* SOA retry default */
|
#define SOA_RETRY 180 /* SOA retry default */
|
||||||
#define SOA_EXPIRY 1209600 /* SOA expiry default */
|
#define SOA_EXPIRY 1209600 /* SOA expiry default */
|
||||||
#define RA_INTERVAL 600 /* Send unsolicited RA's this often when not provoked. */
|
|
||||||
|
|
||||||
/* compile-time options: uncomment below to enable or do eg.
|
/* compile-time options: uncomment below to enable or do eg.
|
||||||
make COPTS=-DHAVE_BROKEN_RTC
|
make COPTS=-DHAVE_BROKEN_RTC
|
||||||
@@ -256,7 +254,10 @@ HAVE_SOCKADDR_SA_LEN
|
|||||||
#define HAVE_SOCKADDR_SA_LEN
|
#define HAVE_SOCKADDR_SA_LEN
|
||||||
/* Define before sys/socket.h is included so we get socklen_t */
|
/* Define before sys/socket.h is included so we get socklen_t */
|
||||||
#define _BSD_SOCKLEN_T_
|
#define _BSD_SOCKLEN_T_
|
||||||
|
/* Select the RFC_3542 version of the IPv6 socket API.
|
||||||
|
Define before netinet6/in6.h is included. */
|
||||||
|
#define __APPLE_USE_RFC_3542
|
||||||
|
|
||||||
#elif defined(__NetBSD__)
|
#elif defined(__NetBSD__)
|
||||||
#define HAVE_BSD_NETWORK
|
#define HAVE_BSD_NETWORK
|
||||||
#define HAVE_GETOPT_LONG
|
#define HAVE_GETOPT_LONG
|
||||||
|
|||||||
+73
-48
@@ -272,27 +272,26 @@ static int is_config_in_context(struct dhcp_context *context, struct dhcp_config
|
|||||||
if (!context) /* called via find_config() from lease_update_from_configs() */
|
if (!context) /* called via find_config() from lease_update_from_configs() */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!(context->flags & CONTEXT_V6))
|
if (!(config->flags & (CONFIG_ADDR | CONFIG_ADDR6)))
|
||||||
{
|
return 1;
|
||||||
if (!(config->flags & CONFIG_ADDR))
|
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
|
if ((context->flags & CONTEXT_V6) && (config->flags & CONFIG_WILDCARD))
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (; context; context = context->current)
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
|
if (context->flags & CONTEXT_V6)
|
||||||
|
{
|
||||||
|
if ((config->flags & CONFIG_ADDR6) && is_same_net6(&config->addr6, &context->start6, context->prefix))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if ((config->flags & CONFIG_ADDR) && is_same_net(config->addr, context->start, context->netmask))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
for (; context; context = context->current)
|
|
||||||
if (is_same_net(config->addr, context->start, context->netmask))
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#ifdef HAVE_DHCP6
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!(config->flags & CONFIG_ADDR6) || (config->flags & CONFIG_WILDCARD))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
for (; context; context = context->current)
|
|
||||||
if (is_same_net6(&config->addr6, &context->start6, context->prefix))
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,8 +315,9 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
|
|||||||
return config;
|
return config;
|
||||||
|
|
||||||
/* dhcpcd prefixes ASCII client IDs by zero which is wrong, but we try and
|
/* dhcpcd prefixes ASCII client IDs by zero which is wrong, but we try and
|
||||||
cope with that here */
|
cope with that here. This is IPv4 only. context==NULL implies IPv4,
|
||||||
if (!(context->flags & CONTEXT_V6) && *clid == 0 && config->clid_len == clid_len-1 &&
|
see lease_update_from_configs() */
|
||||||
|
if ((!context || !(context->flags & CONTEXT_V6)) && *clid == 0 && config->clid_len == clid_len-1 &&
|
||||||
memcmp(config->clid, clid+1, clid_len-1) == 0 &&
|
memcmp(config->clid, clid+1, clid_len-1) == 0 &&
|
||||||
is_config_in_context(context, config))
|
is_config_in_context(context, config))
|
||||||
return config;
|
return config;
|
||||||
@@ -445,7 +445,7 @@ void dhcp_update_configs(struct dhcp_config *configs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LINUX_NETWORK
|
#ifdef HAVE_LINUX_NETWORK
|
||||||
void bindtodevice(int fd)
|
char *whichdevice(void)
|
||||||
{
|
{
|
||||||
/* If we are doing DHCP on exactly one interface, and running linux, do SO_BINDTODEVICE
|
/* If we are doing DHCP on exactly one interface, and running linux, do SO_BINDTODEVICE
|
||||||
to that device. This is for the use case of (eg) OpenStack, which runs a new
|
to that device. This is for the use case of (eg) OpenStack, which runs a new
|
||||||
@@ -453,17 +453,20 @@ void bindtodevice(int fd)
|
|||||||
individual processes don't always see the packets they should.
|
individual processes don't always see the packets they should.
|
||||||
SO_BINDTODEVICE is only available Linux.
|
SO_BINDTODEVICE is only available Linux.
|
||||||
|
|
||||||
Note that if wildcards are used in --interface, or a configured interface doesn't
|
Note that if wildcards are used in --interface, or --interface is not used at all,
|
||||||
yet exist, then more interfaces may arrive later, so we can't safely assert there
|
or a configured interface doesn't yet exist, then more interfaces may arrive later,
|
||||||
is only one interface and proceed.
|
so we can't safely assert there is only one interface and proceed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct irec *iface, *found;
|
struct irec *iface, *found;
|
||||||
struct iname *if_tmp;
|
struct iname *if_tmp;
|
||||||
|
|
||||||
|
if (!daemon->if_names)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
|
for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
|
||||||
if (if_tmp->name && (!if_tmp->used || strchr(if_tmp->name, '*')))
|
if (if_tmp->name && (!if_tmp->used || strchr(if_tmp->name, '*')))
|
||||||
return;
|
return NULL;
|
||||||
|
|
||||||
for (found = NULL, iface = daemon->interfaces; iface; iface = iface->next)
|
for (found = NULL, iface = daemon->interfaces; iface; iface = iface->next)
|
||||||
if (iface->dhcp_ok)
|
if (iface->dhcp_ok)
|
||||||
@@ -471,18 +474,24 @@ void bindtodevice(int fd)
|
|||||||
if (!found)
|
if (!found)
|
||||||
found = iface;
|
found = iface;
|
||||||
else if (strcmp(found->name, iface->name) != 0)
|
else if (strcmp(found->name, iface->name) != 0)
|
||||||
return; /* more than one. */
|
return NULL; /* more than one. */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
{
|
return found->name;
|
||||||
struct ifreq ifr;
|
|
||||||
strcpy(ifr.ifr_name, found->name);
|
return NULL;
|
||||||
/* only allowed by root. */
|
}
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) == -1 &&
|
|
||||||
errno != EPERM)
|
void bindtodevice(char *device, int fd)
|
||||||
die(_("failed to set SO_BINDTODEVICE on DHCP socket: %s"), NULL, EC_BADNET);
|
{
|
||||||
}
|
struct ifreq ifr;
|
||||||
|
|
||||||
|
strcpy(ifr.ifr_name, device);
|
||||||
|
/* only allowed by root. */
|
||||||
|
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) == -1 &&
|
||||||
|
errno != EPERM)
|
||||||
|
die(_("failed to set SO_BINDTODEVICE on DHCP socket: %s"), NULL, EC_BADNET);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -830,11 +839,11 @@ void log_context(int family, struct dhcp_context *context)
|
|||||||
if (indextoname(daemon->icmp6fd, context->if_index, ifrn_name))
|
if (indextoname(daemon->icmp6fd, context->if_index, ifrn_name))
|
||||||
sprintf(p, "%s for %s", (context->flags & CONTEXT_OLD) ? "old prefix" : "constructed", ifrn_name);
|
sprintf(p, "%s for %s", (context->flags & CONTEXT_OLD) ? "old prefix" : "constructed", ifrn_name);
|
||||||
}
|
}
|
||||||
else if (context->flags & CONTEXT_TEMPLATE)
|
else if (context->flags & CONTEXT_TEMPLATE && !(context->flags & CONTEXT_RA_STATELESS))
|
||||||
{
|
{
|
||||||
template = p;
|
template = p;
|
||||||
p += sprintf(p, ", ");
|
p += sprintf(p, ", ");
|
||||||
|
|
||||||
sprintf(p, "template for %s", context->template_interface);
|
sprintf(p, "template for %s", context->template_interface);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -842,21 +851,37 @@ void log_context(int family, struct dhcp_context *context)
|
|||||||
if (!(context->flags & CONTEXT_OLD) &&
|
if (!(context->flags & CONTEXT_OLD) &&
|
||||||
((context->flags & CONTEXT_DHCP) || family == AF_INET))
|
((context->flags & CONTEXT_DHCP) || family == AF_INET))
|
||||||
{
|
{
|
||||||
inet_ntop(family, start, daemon->dhcp_buff, 256);
|
#ifdef HAVE_DHCP6
|
||||||
|
if (context->flags & CONTEXT_RA_STATELESS)
|
||||||
|
{
|
||||||
|
if (context->flags & CONTEXT_TEMPLATE)
|
||||||
|
strncpy(daemon->dhcp_buff, context->template_interface, 256);
|
||||||
|
else
|
||||||
|
strcpy(daemon->dhcp_buff, daemon->addrbuff);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
inet_ntop(family, start, daemon->dhcp_buff, 256);
|
||||||
inet_ntop(family, end, daemon->dhcp_buff3, 256);
|
inet_ntop(family, end, daemon->dhcp_buff3, 256);
|
||||||
my_syslog(MS_DHCP | LOG_INFO,
|
my_syslog(MS_DHCP | LOG_INFO,
|
||||||
(context->flags & CONTEXT_RA_STATELESS) ?
|
(context->flags & CONTEXT_RA_STATELESS) ?
|
||||||
_("%s stateless on %s%.0s%.0s%s") :
|
_("%s stateless on %s%.0s%.0s%s") :
|
||||||
(context->flags & CONTEXT_STATIC) ?
|
(context->flags & CONTEXT_STATIC) ?
|
||||||
_("%s, static leases only on %.0s%s%s%.0s") :
|
_("%s, static leases only on %.0s%s%s%.0s") :
|
||||||
(context->flags & CONTEXT_PROXY) ?
|
(context->flags & CONTEXT_PROXY) ?
|
||||||
_("%s, proxy on subnet %.0s%s%.0s%.0s") :
|
_("%s, proxy on subnet %.0s%s%.0s%.0s") :
|
||||||
_("%s, IP range %s -- %s%s%.0s"),
|
_("%s, IP range %s -- %s%s%.0s"),
|
||||||
(family != AF_INET) ? "DHCPv6" : "DHCP",
|
(family != AF_INET) ? "DHCPv6" : "DHCP",
|
||||||
daemon->dhcp_buff, daemon->dhcp_buff3, daemon->namebuff, template);
|
daemon->dhcp_buff, daemon->dhcp_buff3, daemon->namebuff, template);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
|
if (context->flags & CONTEXT_TEMPLATE)
|
||||||
|
{
|
||||||
|
strcpy(daemon->addrbuff, context->template_interface);
|
||||||
|
template = "";
|
||||||
|
}
|
||||||
|
|
||||||
if ((context->flags & CONTEXT_RA_NAME) && !(context->flags & CONTEXT_OLD))
|
if ((context->flags & CONTEXT_RA_NAME) && !(context->flags & CONTEXT_OLD))
|
||||||
my_syslog(MS_DHCP | LOG_INFO, _("DHCPv4-derived IPv6 names on %s%s"), daemon->addrbuff, template);
|
my_syslog(MS_DHCP | LOG_INFO, _("DHCPv4-derived IPv6 names on %s%s"), daemon->addrbuff, template);
|
||||||
|
|
||||||
|
|||||||
+38
-21
@@ -394,7 +394,7 @@ struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len,
|
struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len, int temp_addr,
|
||||||
int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans)
|
int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans)
|
||||||
{
|
{
|
||||||
/* Find a free address: exclude anything in use and anything allocated to
|
/* Find a free address: exclude anything in use and anything allocated to
|
||||||
@@ -411,9 +411,13 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
|
|||||||
u64 j;
|
u64 j;
|
||||||
|
|
||||||
/* hash hwaddr: use the SDBM hashing algorithm. This works
|
/* hash hwaddr: use the SDBM hashing algorithm. This works
|
||||||
for MAC addresses, let's see how it manages with client-ids! */
|
for MAC addresses, let's see how it manages with client-ids!
|
||||||
for (j = iaid, i = 0; i < clid_len; i++)
|
For temporary addresses, we generate a new random one each time. */
|
||||||
j += clid[i] + (j << 6) + (j << 16) - j;
|
if (temp_addr)
|
||||||
|
j = rand64();
|
||||||
|
else
|
||||||
|
for (j = iaid, i = 0; i < clid_len; i++)
|
||||||
|
j += clid[i] + (j << 6) + (j << 16) - j;
|
||||||
|
|
||||||
for (pass = 0; pass <= plain_range ? 1 : 0; pass++)
|
for (pass = 0; pass <= plain_range ? 1 : 0; pass++)
|
||||||
for (c = context; c; c = c->current)
|
for (c = context; c; c = c->current)
|
||||||
@@ -423,7 +427,7 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
|
|||||||
continue;
|
continue;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (option_bool(OPT_CONSEC_ADDR))
|
if (!temp_addr && option_bool(OPT_CONSEC_ADDR))
|
||||||
/* seed is largest extant lease addr in this context */
|
/* seed is largest extant lease addr in this context */
|
||||||
start = lease_find_max_addr6(c) + serial;
|
start = lease_find_max_addr6(c) + serial;
|
||||||
else
|
else
|
||||||
@@ -523,6 +527,8 @@ int config_valid(struct dhcp_config *config, struct dhcp_context *context, struc
|
|||||||
|
|
||||||
void make_duid(time_t now)
|
void make_duid(time_t now)
|
||||||
{
|
{
|
||||||
|
(void)now;
|
||||||
|
|
||||||
if (daemon->duid_config)
|
if (daemon->duid_config)
|
||||||
{
|
{
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
@@ -535,8 +541,14 @@ void make_duid(time_t now)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
time_t newnow = 0;
|
||||||
|
|
||||||
|
/* If we have no persistent lease database, or a non-stable RTC, use DUID_LL (newnow == 0) */
|
||||||
|
#ifndef HAVE_BROKEN_RTC
|
||||||
/* rebase epoch to 1/1/2000 */
|
/* rebase epoch to 1/1/2000 */
|
||||||
time_t newnow = now - 946684800;
|
if (!option_bool(OPT_LEASE_RO) || daemon->lease_change_command)
|
||||||
|
newnow = now - 946684800;
|
||||||
|
#endif
|
||||||
|
|
||||||
iface_enumerate(AF_LOCAL, &newnow, make_duid1);
|
iface_enumerate(AF_LOCAL, &newnow, make_duid1);
|
||||||
|
|
||||||
@@ -555,23 +567,27 @@ static int make_duid1(int index, unsigned int type, char *mac, size_t maclen, vo
|
|||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
(void)index;
|
(void)index;
|
||||||
(void)parm;
|
(void)parm;
|
||||||
|
time_t newnow = *((time_t *)parm);
|
||||||
|
|
||||||
if (type >= 256)
|
if (type >= 256)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
#ifdef HAVE_BROKEN_RTC
|
if (newnow == 0)
|
||||||
daemon->duid = p = safe_malloc(maclen + 4);
|
{
|
||||||
daemon->duid_len = maclen + 4;
|
daemon->duid = p = safe_malloc(maclen + 4);
|
||||||
PUTSHORT(3, p); /* DUID_LL */
|
daemon->duid_len = maclen + 4;
|
||||||
PUTSHORT(type, p); /* address type */
|
PUTSHORT(3, p); /* DUID_LL */
|
||||||
#else
|
PUTSHORT(type, p); /* address type */
|
||||||
daemon->duid = p = safe_malloc(maclen + 8);
|
}
|
||||||
daemon->duid_len = maclen + 8;
|
else
|
||||||
PUTSHORT(1, p); /* DUID_LLT */
|
{
|
||||||
PUTSHORT(type, p); /* address type */
|
daemon->duid = p = safe_malloc(maclen + 8);
|
||||||
PUTLONG(*((time_t *)parm), p); /* time */
|
daemon->duid_len = maclen + 8;
|
||||||
#endif
|
PUTSHORT(1, p); /* DUID_LLT */
|
||||||
|
PUTSHORT(type, p); /* address type */
|
||||||
|
PUTLONG(*((time_t *)parm), p); /* time */
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(p, mac, maclen);
|
memcpy(p, mac, maclen);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -624,7 +640,8 @@ static int construct_worker(struct in6_addr *local, int prefix,
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (wildcard_match(template->template_interface, ifrn_name))
|
else if (wildcard_match(template->template_interface, ifrn_name) &&
|
||||||
|
template->prefix == prefix)
|
||||||
{
|
{
|
||||||
start6 = *local;
|
start6 = *local;
|
||||||
setaddr6part(&start6, addr6part(&template->start6));
|
setaddr6part(&start6, addr6part(&template->start6));
|
||||||
|
|||||||
@@ -56,6 +56,10 @@
|
|||||||
#define T_MAILB 253
|
#define T_MAILB 253
|
||||||
#define T_ANY 255
|
#define T_ANY 255
|
||||||
|
|
||||||
|
#define EDNS0_OPTION_MAC 65001 /* dyndns.org temporary assignment */
|
||||||
|
#define EDNS0_OPTION_CLIENT_SUBNET 8 /* IANA */
|
||||||
|
|
||||||
|
|
||||||
struct dns_header {
|
struct dns_header {
|
||||||
u16 id;
|
u16 id;
|
||||||
u8 hb3,hb4;
|
u8 hb3,hb4;
|
||||||
|
|||||||
+30
-6
@@ -50,6 +50,8 @@ int main (int argc, char **argv)
|
|||||||
#if defined(HAVE_LINUX_NETWORK)
|
#if defined(HAVE_LINUX_NETWORK)
|
||||||
cap_user_header_t hdr = NULL;
|
cap_user_header_t hdr = NULL;
|
||||||
cap_user_data_t data = NULL;
|
cap_user_data_t data = NULL;
|
||||||
|
char *bound_device = NULL;
|
||||||
|
int did_bind = 0;
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
|
#if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
|
||||||
struct dhcp_context *context;
|
struct dhcp_context *context;
|
||||||
@@ -239,18 +241,29 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP)
|
#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP)
|
||||||
/* after enumerate_interfaces() */
|
/* after enumerate_interfaces() */
|
||||||
|
bound_device = whichdevice();
|
||||||
|
|
||||||
if (daemon->dhcp)
|
if (daemon->dhcp)
|
||||||
{
|
{
|
||||||
if (!daemon->relay4)
|
if (!daemon->relay4 && bound_device)
|
||||||
bindtodevice(daemon->dhcpfd);
|
{
|
||||||
if (daemon->enable_pxe)
|
bindtodevice(bound_device, daemon->dhcpfd);
|
||||||
bindtodevice(daemon->pxefd);
|
did_bind = 1;
|
||||||
|
}
|
||||||
|
if (daemon->enable_pxe && bound_device)
|
||||||
|
{
|
||||||
|
bindtodevice(bound_device, daemon->pxefd);
|
||||||
|
did_bind = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP6)
|
#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP6)
|
||||||
if (daemon->doing_dhcp6 && !daemon->relay6)
|
if (daemon->doing_dhcp6 && !daemon->relay6 && bound_device)
|
||||||
bindtodevice(daemon->dhcp6fd);
|
{
|
||||||
|
bindtodevice(bound_device, daemon->dhcp6fd);
|
||||||
|
did_bind = 1;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -260,6 +273,9 @@ int main (int argc, char **argv)
|
|||||||
/* after enumerate_interfaces() */
|
/* after enumerate_interfaces() */
|
||||||
if (daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
|
if (daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
|
||||||
join_multicast(1);
|
join_multicast(1);
|
||||||
|
|
||||||
|
/* After netlink_init() and before create_helper() */
|
||||||
|
lease_make_duid(now);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (daemon->port != 0)
|
if (daemon->port != 0)
|
||||||
@@ -619,6 +635,8 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
if (bind_fallback)
|
if (bind_fallback)
|
||||||
my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
|
my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
|
||||||
|
|
||||||
|
warn_bound_listeners();
|
||||||
|
|
||||||
if (!option_bool(OPT_NOWILD))
|
if (!option_bool(OPT_NOWILD))
|
||||||
for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
|
for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
|
||||||
@@ -659,6 +677,11 @@ int main (int argc, char **argv)
|
|||||||
my_syslog(MS_DHCP | LOG_INFO, _("IPv6 router advertisement enabled"));
|
my_syslog(MS_DHCP | LOG_INFO, _("IPv6 router advertisement enabled"));
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# ifdef HAVE_LINUX_NETWORK
|
||||||
|
if (did_bind)
|
||||||
|
my_syslog(MS_DHCP | LOG_INFO, _("DHCP, sockets bound exclusively to interface %s"), bound_device);
|
||||||
|
# endif
|
||||||
|
|
||||||
/* after dhcp_contruct_contexts */
|
/* after dhcp_contruct_contexts */
|
||||||
if (daemon->dhcp || daemon->doing_dhcp6)
|
if (daemon->dhcp || daemon->doing_dhcp6)
|
||||||
lease_find_interfaces(now);
|
lease_find_interfaces(now);
|
||||||
@@ -838,6 +861,7 @@ int main (int argc, char **argv)
|
|||||||
enumerate_interfaces(0);
|
enumerate_interfaces(0);
|
||||||
/* NB, is_dad_listeners() == 1 --> we're binding interfaces */
|
/* NB, is_dad_listeners() == 1 --> we're binding interfaces */
|
||||||
create_bound_listeners(0);
|
create_bound_listeners(0);
|
||||||
|
warn_bound_listeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LINUX_NETWORK
|
#ifdef HAVE_LINUX_NETWORK
|
||||||
|
|||||||
+56
-27
@@ -221,8 +221,11 @@ struct event_desc {
|
|||||||
#define OPT_TFTP_LC 38
|
#define OPT_TFTP_LC 38
|
||||||
#define OPT_CLEVERBIND 39
|
#define OPT_CLEVERBIND 39
|
||||||
#define OPT_TFTP 40
|
#define OPT_TFTP 40
|
||||||
#define OPT_FAST_RA 41
|
#define OPT_CLIENT_SUBNET 41
|
||||||
#define OPT_LAST 42
|
#define OPT_QUIET_DHCP 42
|
||||||
|
#define OPT_QUIET_DHCP6 43
|
||||||
|
#define OPT_QUIET_RA 44
|
||||||
|
#define OPT_LAST 45
|
||||||
|
|
||||||
/* extra flags for my_syslog, we use a couple of facilities since they are known
|
/* extra flags for my_syslog, we use a couple of facilities since they are known
|
||||||
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
|
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
|
||||||
@@ -277,18 +280,28 @@ struct ptr_record {
|
|||||||
struct cname {
|
struct cname {
|
||||||
char *alias, *target;
|
char *alias, *target;
|
||||||
struct cname *next;
|
struct cname *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ADDRLIST_LITERAL 1
|
||||||
|
#define ADDRLIST_IPV6 2
|
||||||
|
|
||||||
|
struct addrlist {
|
||||||
|
struct all_addr addr;
|
||||||
|
int flags, prefixlen;
|
||||||
|
struct addrlist *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define AUTH6 1
|
||||||
|
#define AUTH4 2
|
||||||
|
|
||||||
struct auth_zone {
|
struct auth_zone {
|
||||||
char *domain;
|
char *domain;
|
||||||
struct subnet {
|
struct auth_name_list {
|
||||||
int is6, prefixlen;
|
char *name;
|
||||||
struct in_addr addr4;
|
int flags;
|
||||||
#ifdef HAVE_IPV6
|
struct auth_name_list *next;
|
||||||
struct in6_addr addr6;
|
} *interface_names;
|
||||||
#endif
|
struct addrlist *subnet;
|
||||||
struct subnet *next;
|
|
||||||
} *subnet;
|
|
||||||
struct auth_zone *next;
|
struct auth_zone *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -308,13 +321,7 @@ struct host_record {
|
|||||||
struct interface_name {
|
struct interface_name {
|
||||||
char *name; /* domain name */
|
char *name; /* domain name */
|
||||||
char *intr; /* interface name */
|
char *intr; /* interface name */
|
||||||
struct addrlist {
|
struct addrlist *addr;
|
||||||
struct all_addr addr;
|
|
||||||
struct addrlist *next;
|
|
||||||
} *addr4;
|
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
struct addrlist *addr6;
|
|
||||||
#endif
|
|
||||||
struct interface_name *next;
|
struct interface_name *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -334,8 +341,11 @@ struct crec {
|
|||||||
union {
|
union {
|
||||||
struct all_addr addr;
|
struct all_addr addr;
|
||||||
struct {
|
struct {
|
||||||
struct crec *cache;
|
union {
|
||||||
int uid;
|
struct crec *cache;
|
||||||
|
struct interface_name *int_name;
|
||||||
|
} target;
|
||||||
|
int uid; /* -1 if union is interface-name */
|
||||||
} cname;
|
} cname;
|
||||||
struct {
|
struct {
|
||||||
struct keydata *keydata;
|
struct keydata *keydata;
|
||||||
@@ -448,7 +458,7 @@ struct ipsets {
|
|||||||
struct irec {
|
struct irec {
|
||||||
union mysockaddr addr;
|
union mysockaddr addr;
|
||||||
struct in_addr netmask; /* only valid for IPv4 */
|
struct in_addr netmask; /* only valid for IPv4 */
|
||||||
int tftp_ok, dhcp_ok, mtu, done, dad, dns_auth, index, multicast_done;
|
int tftp_ok, dhcp_ok, mtu, done, warned, dad, dns_auth, index, multicast_done;
|
||||||
char *name;
|
char *name;
|
||||||
struct irec *next;
|
struct irec *next;
|
||||||
};
|
};
|
||||||
@@ -487,6 +497,7 @@ struct hostsfile {
|
|||||||
|
|
||||||
#define FREC_NOREBIND 1
|
#define FREC_NOREBIND 1
|
||||||
#define FREC_CHECKING_DISABLED 2
|
#define FREC_CHECKING_DISABLED 2
|
||||||
|
#define FREC_HAS_SUBNET 4
|
||||||
|
|
||||||
struct frec {
|
struct frec {
|
||||||
union mysockaddr source;
|
union mysockaddr source;
|
||||||
@@ -701,6 +712,12 @@ struct prefix_class {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct ra_interface {
|
||||||
|
char *name;
|
||||||
|
int interval, lifetime, prio;
|
||||||
|
struct ra_interface *next;
|
||||||
|
};
|
||||||
|
|
||||||
struct dhcp_context {
|
struct dhcp_context {
|
||||||
unsigned int lease_time, addr_epoch;
|
unsigned int lease_time, addr_epoch;
|
||||||
struct in_addr netmask, broadcast;
|
struct in_addr netmask, broadcast;
|
||||||
@@ -735,9 +752,8 @@ struct dhcp_context {
|
|||||||
#define CONTEXT_RA (1u<<13)
|
#define CONTEXT_RA (1u<<13)
|
||||||
#define CONTEXT_CONF_USED (1u<<14)
|
#define CONTEXT_CONF_USED (1u<<14)
|
||||||
#define CONTEXT_USED (1u<<15)
|
#define CONTEXT_USED (1u<<15)
|
||||||
#define CONTEXT_NOAUTH (1u<<16)
|
#define CONTEXT_OLD (1u<<16)
|
||||||
#define CONTEXT_OLD (1u<<17)
|
#define CONTEXT_V6 (1u<<17)
|
||||||
#define CONTEXT_V6 (1u<<18)
|
|
||||||
|
|
||||||
|
|
||||||
struct ping_result {
|
struct ping_result {
|
||||||
@@ -802,6 +818,8 @@ extern struct daemon {
|
|||||||
struct auth_zone *auth_zones;
|
struct auth_zone *auth_zones;
|
||||||
struct interface_name *int_names;
|
struct interface_name *int_names;
|
||||||
char *mxtarget;
|
char *mxtarget;
|
||||||
|
int addr4_netmask;
|
||||||
|
int addr6_netmask;
|
||||||
char *lease_file;
|
char *lease_file;
|
||||||
char *username, *groupname, *scriptuser;
|
char *username, *groupname, *scriptuser;
|
||||||
char *luascript;
|
char *luascript;
|
||||||
@@ -825,6 +843,7 @@ extern struct daemon {
|
|||||||
unsigned long local_ttl, neg_ttl, max_ttl, max_cache_ttl, auth_ttl;
|
unsigned long local_ttl, neg_ttl, max_ttl, max_cache_ttl, auth_ttl;
|
||||||
struct hostsfile *addn_hosts;
|
struct hostsfile *addn_hosts;
|
||||||
struct dhcp_context *dhcp, *dhcp6;
|
struct dhcp_context *dhcp, *dhcp6;
|
||||||
|
struct ra_interface *ra_interfaces;
|
||||||
struct dhcp_config *dhcp_conf;
|
struct dhcp_config *dhcp_conf;
|
||||||
struct dhcp_opt *dhcp_opts, *dhcp_match, *dhcp_opts6, *dhcp_match6;
|
struct dhcp_opt *dhcp_opts, *dhcp_match, *dhcp_opts6, *dhcp_match6;
|
||||||
struct dhcp_vendor *dhcp_vendors;
|
struct dhcp_vendor *dhcp_vendors;
|
||||||
@@ -860,7 +879,7 @@ extern struct daemon {
|
|||||||
char *packet; /* packet buffer */
|
char *packet; /* packet buffer */
|
||||||
int packet_buff_sz; /* size of above */
|
int packet_buff_sz; /* size of above */
|
||||||
char *namebuff; /* MAXDNAME size buffer */
|
char *namebuff; /* MAXDNAME size buffer */
|
||||||
unsigned int local_answer, queries_forwarded;
|
unsigned int local_answer, queries_forwarded, auth_answer;
|
||||||
struct frec *frec_list;
|
struct frec *frec_list;
|
||||||
struct serverfd *sfds;
|
struct serverfd *sfds;
|
||||||
struct irec *interfaces;
|
struct irec *interfaces;
|
||||||
@@ -928,6 +947,7 @@ struct in_addr a_record_from_hosts(char *name, time_t now);
|
|||||||
void cache_unhash_dhcp(void);
|
void cache_unhash_dhcp(void);
|
||||||
void dump_cache(time_t now);
|
void dump_cache(time_t now);
|
||||||
char *cache_get_name(struct crec *crecp);
|
char *cache_get_name(struct crec *crecp);
|
||||||
|
char *cache_get_cname_target(struct crec *crecp);
|
||||||
struct crec *cache_enumerate(int init);
|
struct crec *cache_enumerate(int init);
|
||||||
#ifdef HAVE_DNSSEC
|
#ifdef HAVE_DNSSEC
|
||||||
struct keydata *keydata_alloc(char *data, size_t len);
|
struct keydata *keydata_alloc(char *data, size_t len);
|
||||||
@@ -962,6 +982,8 @@ unsigned int questions_crc(struct dns_header *header, size_t plen, char *buff);
|
|||||||
size_t resize_packet(struct dns_header *header, size_t plen,
|
size_t resize_packet(struct dns_header *header, size_t plen,
|
||||||
unsigned char *pheader, size_t hlen);
|
unsigned char *pheader, size_t hlen);
|
||||||
size_t add_mac(struct dns_header *header, size_t plen, char *limit, union mysockaddr *l3);
|
size_t add_mac(struct dns_header *header, size_t plen, char *limit, union mysockaddr *l3);
|
||||||
|
size_t add_source_addr(struct dns_header *header, size_t plen, char *limit, union mysockaddr *source);
|
||||||
|
int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer);
|
||||||
int add_resource_record(struct dns_header *header, char *limit, int *truncp,
|
int add_resource_record(struct dns_header *header, char *limit, int *truncp,
|
||||||
int nameoffset, unsigned char **pp, unsigned long ttl,
|
int nameoffset, unsigned char **pp, unsigned long ttl,
|
||||||
int *offset, unsigned short type, unsigned short class, char *format, ...);
|
int *offset, unsigned short type, unsigned short class, char *format, ...);
|
||||||
@@ -969,15 +991,19 @@ unsigned char *skip_questions(struct dns_header *header, size_t plen);
|
|||||||
int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
|
int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
|
||||||
char *name, int isExtract, int extrabytes);
|
char *name, int isExtract, int extrabytes);
|
||||||
int in_arpa_name_2_addr(char *namein, struct all_addr *addrp);
|
int in_arpa_name_2_addr(char *namein, struct all_addr *addrp);
|
||||||
|
int private_net(struct in_addr addr, int ban_localhost);
|
||||||
|
|
||||||
/* auth.c */
|
/* auth.c */
|
||||||
#ifdef HAVE_AUTH
|
#ifdef HAVE_AUTH
|
||||||
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now, union mysockaddr *peer_addr);
|
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen,
|
||||||
|
time_t now, union mysockaddr *peer_addr, int local_query);
|
||||||
|
int in_zone(struct auth_zone *zone, char *name, char **cut);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* util.c */
|
/* util.c */
|
||||||
void rand_init(void);
|
void rand_init(void);
|
||||||
unsigned short rand16(void);
|
unsigned short rand16(void);
|
||||||
|
u64 rand64(void);
|
||||||
int legal_hostname(char *c);
|
int legal_hostname(char *c);
|
||||||
char *canonicalise(char *s, int *nomem);
|
char *canonicalise(char *s, int *nomem);
|
||||||
unsigned char *do_rfc1035_name(unsigned char *p, char *sval);
|
unsigned char *do_rfc1035_name(unsigned char *p, char *sval);
|
||||||
@@ -1049,6 +1075,7 @@ void check_servers(void);
|
|||||||
int enumerate_interfaces(int reset);
|
int enumerate_interfaces(int reset);
|
||||||
void create_wildcard_listeners(void);
|
void create_wildcard_listeners(void);
|
||||||
void create_bound_listeners(int die);
|
void create_bound_listeners(int die);
|
||||||
|
void warn_bound_listeners(void);
|
||||||
int is_dad_listeners(void);
|
int is_dad_listeners(void);
|
||||||
int iface_check(int family, struct all_addr *addr, char *name, int *auth_dns);
|
int iface_check(int family, struct all_addr *addr, char *name, int *auth_dns);
|
||||||
int loopback_exception(int fd, int family, struct all_addr *addr, char *name);
|
int loopback_exception(int fd, int family, struct all_addr *addr, char *name);
|
||||||
@@ -1097,6 +1124,7 @@ u64 lease_find_max_addr6(struct dhcp_context *context);
|
|||||||
void lease_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface);
|
void lease_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface);
|
||||||
void lease_update_slaac(time_t now);
|
void lease_update_slaac(time_t now);
|
||||||
void lease_set_iaid(struct dhcp_lease *lease, int iaid);
|
void lease_set_iaid(struct dhcp_lease *lease, int iaid);
|
||||||
|
void lease_make_duid(time_t now);
|
||||||
#endif
|
#endif
|
||||||
void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
|
void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
|
||||||
unsigned char *clid, int hw_len, int hw_type, int clid_len, time_t now, int force);
|
unsigned char *clid, int hw_len, int hw_type, int clid_len, time_t now, int force);
|
||||||
@@ -1197,7 +1225,7 @@ int get_incoming_mark(union mysockaddr *peer_addr, struct all_addr *local_addr,
|
|||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
void dhcp6_init(void);
|
void dhcp6_init(void);
|
||||||
void dhcp6_packet(time_t now);
|
void dhcp6_packet(time_t now);
|
||||||
struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len,
|
struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len, int temp_addr,
|
||||||
int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans);
|
int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans);
|
||||||
int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr);
|
int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr);
|
||||||
struct dhcp_context *address6_available(struct dhcp_context *context,
|
struct dhcp_context *address6_available(struct dhcp_context *context,
|
||||||
@@ -1249,7 +1277,8 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
|
|||||||
int hw_type, char *hostname);
|
int hw_type, char *hostname);
|
||||||
int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type);
|
int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type);
|
||||||
#ifdef HAVE_LINUX_NETWORK
|
#ifdef HAVE_LINUX_NETWORK
|
||||||
void bindtodevice(int fd);
|
char *whichdevice(void);
|
||||||
|
void bindtodevice(char *device, int fd);
|
||||||
#endif
|
#endif
|
||||||
# ifdef HAVE_DHCP6
|
# ifdef HAVE_DHCP6
|
||||||
void display_opts6(void);
|
void display_opts6(void);
|
||||||
|
|||||||
+88
-20
@@ -284,6 +284,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
forward->fd = udpfd;
|
forward->fd = udpfd;
|
||||||
forward->crc = crc;
|
forward->crc = crc;
|
||||||
forward->forwardall = 0;
|
forward->forwardall = 0;
|
||||||
|
forward->flags = 0;
|
||||||
if (norebind)
|
if (norebind)
|
||||||
forward->flags |= FREC_NOREBIND;
|
forward->flags |= FREC_NOREBIND;
|
||||||
if (header->hb4 & HB4_CD)
|
if (header->hb4 & HB4_CD)
|
||||||
@@ -331,6 +332,16 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
if (option_bool(OPT_ADD_MAC))
|
if (option_bool(OPT_ADD_MAC))
|
||||||
plen = add_mac(header, plen, ((char *) header) + PACKETSZ, &forward->source);
|
plen = add_mac(header, plen, ((char *) header) + PACKETSZ, &forward->source);
|
||||||
|
|
||||||
|
if (option_bool(OPT_CLIENT_SUBNET))
|
||||||
|
{
|
||||||
|
size_t new = add_source_addr(header, plen, ((char *) header) + PACKETSZ, &forward->source);
|
||||||
|
if (new != plen)
|
||||||
|
{
|
||||||
|
plen = new;
|
||||||
|
forward->flags |= FREC_HAS_SUBNET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* only send to servers dealing with our domain.
|
/* only send to servers dealing with our domain.
|
||||||
@@ -435,8 +446,8 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t process_reply(struct dns_header *header, time_t now,
|
static size_t process_reply(struct dns_header *header, time_t now, struct server *server, size_t n, int check_rebind,
|
||||||
struct server *server, size_t n, int check_rebind, int checking_disabled)
|
int checking_disabled, int check_subnet, union mysockaddr *query_source)
|
||||||
{
|
{
|
||||||
unsigned char *pheader, *sizep;
|
unsigned char *pheader, *sizep;
|
||||||
char **sets = 0;
|
char **sets = 0;
|
||||||
@@ -465,19 +476,29 @@ static size_t process_reply(struct dns_header *header, time_t now,
|
|||||||
than we allow, trim it so that we don't get overlarge
|
than we allow, trim it so that we don't get overlarge
|
||||||
requests for the client. We can't do this for signed packets. */
|
requests for the client. We can't do this for signed packets. */
|
||||||
|
|
||||||
if ((pheader = find_pseudoheader(header, n, &plen, &sizep, &is_sign)) && !is_sign)
|
if ((pheader = find_pseudoheader(header, n, &plen, &sizep, &is_sign)))
|
||||||
{
|
{
|
||||||
unsigned short udpsz;
|
if (!is_sign)
|
||||||
unsigned char *psave = sizep;
|
{
|
||||||
|
unsigned short udpsz;
|
||||||
|
unsigned char *psave = sizep;
|
||||||
|
|
||||||
|
GETSHORT(udpsz, sizep);
|
||||||
|
if (udpsz > daemon->edns_pktsz)
|
||||||
|
PUTSHORT(daemon->edns_pktsz, psave);
|
||||||
|
}
|
||||||
|
|
||||||
GETSHORT(udpsz, sizep);
|
if (check_subnet && !check_source(header, plen, pheader, query_source))
|
||||||
if (udpsz > daemon->edns_pktsz)
|
{
|
||||||
PUTSHORT(daemon->edns_pktsz, psave);
|
my_syslog(LOG_WARNING, _("discarding DNS reply: subnet option mismatch"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* RFC 4035 sect 4.6 para 3 */
|
/* RFC 4035 sect 4.6 para 3 */
|
||||||
if (!is_sign && !option_bool(OPT_DNSSEC))
|
if (!is_sign && !option_bool(OPT_DNSSEC))
|
||||||
header->hb4 &= ~HB4_AD;
|
header->hb4 &= ~HB4_AD;
|
||||||
|
|
||||||
if (OPCODE(header) != QUERY || (RCODE(header) != NOERROR && RCODE(header) != NXDOMAIN))
|
if (OPCODE(header) != QUERY || (RCODE(header) != NOERROR && RCODE(header) != NXDOMAIN))
|
||||||
return n;
|
return n;
|
||||||
@@ -632,7 +653,8 @@ void reply_query(int fd, int family, time_t now)
|
|||||||
if (!option_bool(OPT_NO_REBIND))
|
if (!option_bool(OPT_NO_REBIND))
|
||||||
check_rebind = 0;
|
check_rebind = 0;
|
||||||
|
|
||||||
if ((nn = process_reply(header, now, server, (size_t)n, check_rebind, forward->flags & FREC_CHECKING_DISABLED)))
|
if ((nn = process_reply(header, now, server, (size_t)n, check_rebind, forward->flags & FREC_CHECKING_DISABLED,
|
||||||
|
forward->flags & FREC_HAS_SUBNET, &forward->source)))
|
||||||
{
|
{
|
||||||
header->id = htons(forward->orig_id);
|
header->id = htons(forward->orig_id);
|
||||||
header->hb4 |= HB4_RA; /* recursion if available */
|
header->hb4 |= HB4_RA; /* recursion if available */
|
||||||
@@ -654,7 +676,7 @@ void receive_query(struct listener *listen, time_t now)
|
|||||||
size_t m;
|
size_t m;
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
int if_index = 0;
|
int if_index = 0;
|
||||||
int auth_dns = 0;
|
int local_auth = 0, auth_dns = 0;
|
||||||
struct iovec iov[1];
|
struct iovec iov[1];
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct cmsghdr *cmptr;
|
struct cmsghdr *cmptr;
|
||||||
@@ -826,6 +848,9 @@ void receive_query(struct listener *listen, time_t now)
|
|||||||
if (extract_request(header, (size_t)n, daemon->namebuff, &type))
|
if (extract_request(header, (size_t)n, daemon->namebuff, &type))
|
||||||
{
|
{
|
||||||
char types[20];
|
char types[20];
|
||||||
|
#ifdef HAVE_AUTH
|
||||||
|
struct auth_zone *zone;
|
||||||
|
#endif
|
||||||
|
|
||||||
querystr(auth_dns ? "auth" : "query", types, type);
|
querystr(auth_dns ? "auth" : "query", types, type);
|
||||||
|
|
||||||
@@ -837,15 +862,30 @@ void receive_query(struct listener *listen, time_t now)
|
|||||||
log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
|
log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
|
||||||
(struct all_addr *)&source_addr.in6.sin6_addr, types);
|
(struct all_addr *)&source_addr.in6.sin6_addr, types);
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
|
#ifdef HAVE_AUTH
|
||||||
|
/* find queries for zones we're authoritative for, and answer them directly */
|
||||||
|
if (!auth_dns)
|
||||||
|
for (zone = daemon->auth_zones; zone; zone = zone->next)
|
||||||
|
if (in_zone(zone, daemon->namebuff, NULL))
|
||||||
|
{
|
||||||
|
auth_dns = 1;
|
||||||
|
local_auth = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_AUTH
|
#ifdef HAVE_AUTH
|
||||||
if (auth_dns)
|
if (auth_dns)
|
||||||
{
|
{
|
||||||
m = answer_auth(header, ((char *) header) + PACKETSZ, (size_t)n, now, &source_addr);
|
m = answer_auth(header, ((char *) header) + PACKETSZ, (size_t)n, now, &source_addr, local_auth);
|
||||||
if (m >= 1)
|
if (m >= 1)
|
||||||
send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
|
{
|
||||||
(char *)header, m, &source_addr, &dst_addr, if_index);
|
send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
|
||||||
|
(char *)header, m, &source_addr, &dst_addr, if_index);
|
||||||
|
daemon->auth_answer++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@@ -876,7 +916,8 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
{
|
{
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
int norebind = 0;
|
int norebind = 0;
|
||||||
int checking_disabled;
|
int local_auth = 0;
|
||||||
|
int checking_disabled, check_subnet;
|
||||||
size_t m;
|
size_t m;
|
||||||
unsigned short qtype;
|
unsigned short qtype;
|
||||||
unsigned int gotname;
|
unsigned int gotname;
|
||||||
@@ -906,6 +947,8 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
if (size < (int)sizeof(struct dns_header))
|
if (size < (int)sizeof(struct dns_header))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
check_subnet = 0;
|
||||||
|
|
||||||
/* save state of "cd" flag in query */
|
/* save state of "cd" flag in query */
|
||||||
checking_disabled = header->hb4 & HB4_CD;
|
checking_disabled = header->hb4 & HB4_CD;
|
||||||
|
|
||||||
@@ -915,7 +958,9 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
if ((gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
|
if ((gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
|
||||||
{
|
{
|
||||||
char types[20];
|
char types[20];
|
||||||
|
#ifdef HAVE_AUTH
|
||||||
|
struct auth_zone *zone;
|
||||||
|
#endif
|
||||||
querystr(auth_dns ? "auth" : "query", types, qtype);
|
querystr(auth_dns ? "auth" : "query", types, qtype);
|
||||||
|
|
||||||
if (peer_addr.sa.sa_family == AF_INET)
|
if (peer_addr.sa.sa_family == AF_INET)
|
||||||
@@ -926,6 +971,18 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
|
log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
|
||||||
(struct all_addr *)&peer_addr.in6.sin6_addr, types);
|
(struct all_addr *)&peer_addr.in6.sin6_addr, types);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_AUTH
|
||||||
|
/* find queries for zones we're authoritative for, and answer them directly */
|
||||||
|
if (!auth_dns)
|
||||||
|
for (zone = daemon->auth_zones; zone; zone = zone->next)
|
||||||
|
if (in_zone(zone, daemon->namebuff, NULL))
|
||||||
|
{
|
||||||
|
auth_dns = 1;
|
||||||
|
local_auth = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (local_addr->sa.sa_family == AF_INET)
|
if (local_addr->sa.sa_family == AF_INET)
|
||||||
@@ -935,7 +992,7 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
|
|
||||||
#ifdef HAVE_AUTH
|
#ifdef HAVE_AUTH
|
||||||
if (auth_dns)
|
if (auth_dns)
|
||||||
m = answer_auth(header, ((char *) header) + 65536, (size_t)size, now, &peer_addr);
|
m = answer_auth(header, ((char *) header) + 65536, (size_t)size, now, &peer_addr, local_auth);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
@@ -955,7 +1012,17 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
|
|
||||||
if (option_bool(OPT_ADD_MAC))
|
if (option_bool(OPT_ADD_MAC))
|
||||||
size = add_mac(header, size, ((char *) header) + 65536, &peer_addr);
|
size = add_mac(header, size, ((char *) header) + 65536, &peer_addr);
|
||||||
|
|
||||||
|
if (option_bool(OPT_CLIENT_SUBNET))
|
||||||
|
{
|
||||||
|
size_t new = add_source_addr(header, size, ((char *) header) + 65536, &peer_addr);
|
||||||
|
if (size != new)
|
||||||
|
{
|
||||||
|
size = new;
|
||||||
|
check_subnet = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (gotname)
|
if (gotname)
|
||||||
flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
|
flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
|
||||||
|
|
||||||
@@ -1056,7 +1123,8 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
sending replies containing questions and bogus answers. */
|
sending replies containing questions and bogus answers. */
|
||||||
if (crc == questions_crc(header, (unsigned int)m, daemon->namebuff))
|
if (crc == questions_crc(header, (unsigned int)m, daemon->namebuff))
|
||||||
m = process_reply(header, now, last_server, (unsigned int)m,
|
m = process_reply(header, now, last_server, (unsigned int)m,
|
||||||
option_bool(OPT_NO_REBIND) && !norebind, checking_disabled);
|
option_bool(OPT_NO_REBIND) && !norebind, checking_disabled,
|
||||||
|
check_subnet, &peer_addr);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+49
-48
@@ -64,8 +64,10 @@ struct script_data
|
|||||||
#ifdef HAVE_TFTP
|
#ifdef HAVE_TFTP
|
||||||
off_t file_len;
|
off_t file_len;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_IPV6
|
||||||
struct in6_addr addr6;
|
struct in6_addr addr6;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
int iaid, vendorclass_count;
|
int iaid, vendorclass_count;
|
||||||
#endif
|
#endif
|
||||||
unsigned char hwaddr[DHCP_CHADDR_MAX];
|
unsigned char hwaddr[DHCP_CHADDR_MAX];
|
||||||
@@ -479,20 +481,13 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
if (data.action != ACTION_TFTP)
|
if (data.action != ACTION_TFTP)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
if (is6)
|
my_setenv("DNSMASQ_IAID", is6 ? daemon->dhcp_buff3 : NULL, &err);
|
||||||
{
|
my_setenv("DNSMASQ_SERVER_DUID", is6 ? daemon->dhcp_packet.iov_base : NULL, &err);
|
||||||
my_setenv("DNSMASQ_IAID", daemon->dhcp_buff3, &err);
|
my_setenv("DNSMASQ_MAC", is6 && data.hwaddr_len != 0 ? daemon->dhcp_buff : NULL, &err);
|
||||||
my_setenv("DNSMASQ_SERVER_DUID", daemon->dhcp_packet.iov_base, &err);
|
|
||||||
if (data.hwaddr_len != 0)
|
|
||||||
my_setenv("DNSMASQ_MAC", daemon->dhcp_buff, &err);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!is6 && data.clid_len != 0)
|
my_setenv("DNSMASQ_CLIENT_ID", !is6 && data.clid_len != 0 ? daemon->packet : NULL, &err);
|
||||||
my_setenv("DNSMASQ_CLIENT_ID", daemon->packet, &err);
|
my_setenv("DNSMASQ_INTERFACE", strlen(data.interface) != 0 ? data.interface : NULL, &err);
|
||||||
|
|
||||||
if (strlen(data.interface) != 0)
|
|
||||||
my_setenv("DNSMASQ_INTERFACE", data.interface, &err);
|
|
||||||
|
|
||||||
#ifdef HAVE_BROKEN_RTC
|
#ifdef HAVE_BROKEN_RTC
|
||||||
sprintf(daemon->dhcp_buff2, "%u", data.length);
|
sprintf(daemon->dhcp_buff2, "%u", data.length);
|
||||||
@@ -502,8 +497,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
my_setenv("DNSMASQ_LEASE_EXPIRES", daemon->dhcp_buff2, &err);
|
my_setenv("DNSMASQ_LEASE_EXPIRES", daemon->dhcp_buff2, &err);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (domain)
|
my_setenv("DNSMASQ_DOMAIN", domain, &err);
|
||||||
my_setenv("DNSMASQ_DOMAIN", domain, &err);
|
|
||||||
|
|
||||||
end = extradata + data.ed_len;
|
end = extradata + data.ed_len;
|
||||||
buf = extradata;
|
buf = extradata;
|
||||||
@@ -541,8 +535,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
|
|
||||||
if (is6)
|
if (is6)
|
||||||
buf = grab_extradata(buf, end, "DNSMASQ_RELAY_ADDRESS", &err);
|
buf = grab_extradata(buf, end, "DNSMASQ_RELAY_ADDRESS", &err);
|
||||||
else if (data.giaddr.s_addr != 0)
|
else
|
||||||
my_setenv("DNSMASQ_RELAY_ADDRESS", inet_ntoa(data.giaddr), &err);
|
my_setenv("DNSMASQ_RELAY_ADDRESS", data.giaddr.s_addr != 0 ? inet_ntoa(data.giaddr) : NULL, &err);
|
||||||
|
|
||||||
for (i = 0; buf; i++)
|
for (i = 0; buf; i++)
|
||||||
{
|
{
|
||||||
@@ -550,22 +544,16 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
buf = grab_extradata(buf, end, daemon->dhcp_buff2, &err);
|
buf = grab_extradata(buf, end, daemon->dhcp_buff2, &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.action != ACTION_DEL && data.remaining_time != 0)
|
sprintf(daemon->dhcp_buff2, "%u", data.remaining_time);
|
||||||
{
|
my_setenv("DNSMASQ_TIME_REMAINING", data.action != ACTION_DEL && data.remaining_time != 0 ? daemon->dhcp_buff2 : NULL, &err);
|
||||||
sprintf(daemon->dhcp_buff2, "%u", data.remaining_time);
|
|
||||||
my_setenv("DNSMASQ_TIME_REMAINING", daemon->dhcp_buff2, &err);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.action == ACTION_OLD_HOSTNAME && hostname)
|
my_setenv("DNSMASQ_OLD_HOSTNAME", data.action == ACTION_OLD_HOSTNAME ? hostname : NULL, &err);
|
||||||
{
|
if (data.action == ACTION_OLD_HOSTNAME)
|
||||||
my_setenv("DNSMASQ_OLD_HOSTNAME", hostname, &err);
|
hostname = NULL;
|
||||||
hostname = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option_bool(OPT_LOG_OPTS))
|
my_setenv("DNSMASQ_LOG_DHCP", option_bool(OPT_LOG_OPTS) ? "1" : NULL, &err);
|
||||||
my_setenv("DNSMASQ_LOG_DHCP", "1", &err);
|
|
||||||
|
|
||||||
/* we need to have the event_fd around if exec fails */
|
/* we need to have the event_fd around if exec fails */
|
||||||
if ((i = fcntl(event_fd, F_GETFD)) != -1)
|
if ((i = fcntl(event_fd, F_GETFD)) != -1)
|
||||||
fcntl(event_fd, F_SETFD, i | FD_CLOEXEC);
|
fcntl(event_fd, F_SETFD, i | FD_CLOEXEC);
|
||||||
@@ -588,31 +576,44 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
|
|
||||||
static void my_setenv(const char *name, const char *value, int *error)
|
static void my_setenv(const char *name, const char *value, int *error)
|
||||||
{
|
{
|
||||||
if (*error == 0 && setenv(name, value, 1) != 0)
|
if (*error == 0)
|
||||||
*error = errno;
|
{
|
||||||
|
if (!value)
|
||||||
|
unsetenv(name);
|
||||||
|
else if (setenv(name, value, 1) != 0)
|
||||||
|
*error = errno;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char *grab_extradata(unsigned char *buf, unsigned char *end, char *env, int *err)
|
static unsigned char *grab_extradata(unsigned char *buf, unsigned char *end, char *env, int *err)
|
||||||
{
|
{
|
||||||
unsigned char *next;
|
unsigned char *next = NULL;
|
||||||
|
char *val = NULL;
|
||||||
|
|
||||||
if (!buf || (buf == end))
|
if (buf && (buf != end))
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (next = buf; *next != 0; next++)
|
|
||||||
if (next == end)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (next != buf)
|
|
||||||
{
|
{
|
||||||
char *p;
|
for (next = buf; ; next++)
|
||||||
/* No "=" in value */
|
if (next == end)
|
||||||
if ((p = strchr((char *)buf, '=')))
|
{
|
||||||
*p = 0;
|
next = NULL;
|
||||||
my_setenv(env, (char *)buf, err);
|
break;
|
||||||
}
|
}
|
||||||
|
else if (*next == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
return next + 1;
|
if (next && (next != buf))
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
/* No "=" in value */
|
||||||
|
if ((p = strchr((char *)buf, '=')))
|
||||||
|
*p = 0;
|
||||||
|
val = (char *)buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
my_setenv(env, val, err);
|
||||||
|
|
||||||
|
return next ? next + 1 : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LUASCRIPT
|
#ifdef HAVE_LUASCRIPT
|
||||||
|
|||||||
+8
-2
@@ -417,15 +417,21 @@ void lease_find_interfaces(time_t now)
|
|||||||
iface_enumerate(AF_INET, &now, find_interface_v4);
|
iface_enumerate(AF_INET, &now, find_interface_v4);
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
iface_enumerate(AF_INET6, &now, find_interface_v6);
|
iface_enumerate(AF_INET6, &now, find_interface_v6);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
|
void lease_make_duid(time_t now)
|
||||||
|
{
|
||||||
/* If we're not doing DHCPv6, and there are not v6 leases, don't add the DUID to the database */
|
/* If we're not doing DHCPv6, and there are not v6 leases, don't add the DUID to the database */
|
||||||
if (!daemon->duid && daemon->dhcp6)
|
if (!daemon->duid && daemon->doing_dhcp6)
|
||||||
{
|
{
|
||||||
file_dirty = 1;
|
file_dirty = 1;
|
||||||
make_duid(now);
|
make_duid(now);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+153
-26
@@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
#include "dnsmasq.h"
|
#include "dnsmasq.h"
|
||||||
|
|
||||||
|
#ifndef IN6_IS_ADDR_ULA
|
||||||
|
#define IN6_IS_ADDR_ULA(a) ((((__const uint32_t *) (a))[0] & htonl (0xfe00000)) == htonl (0xfc000000))
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LINUX_NETWORK
|
#ifdef HAVE_LINUX_NETWORK
|
||||||
|
|
||||||
int indextoname(int fd, int index, char *name)
|
int indextoname(int fd, int index, char *name)
|
||||||
@@ -235,7 +239,7 @@ struct iface_param {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
||||||
union mysockaddr *addr, struct in_addr netmask, int dad)
|
union mysockaddr *addr, struct in_addr netmask, int prefixlen, int dad)
|
||||||
{
|
{
|
||||||
struct irec *iface;
|
struct irec *iface;
|
||||||
int mtu = 0, loopback;
|
int mtu = 0, loopback;
|
||||||
@@ -263,15 +267,67 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
|||||||
label = ifr.ifr_name;
|
label = ifr.ifr_name;
|
||||||
|
|
||||||
|
|
||||||
/* Update addresses from interface_names. These are a set independent
|
|
||||||
of the set we're listening on. */
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
if (addr->sa.sa_family != AF_INET6 || !IN6_IS_ADDR_LINKLOCAL(&addr->in6.sin6_addr))
|
if (addr->sa.sa_family != AF_INET6 || !IN6_IS_ADDR_LINKLOCAL(&addr->in6.sin6_addr))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
struct interface_name *int_name;
|
struct interface_name *int_name;
|
||||||
struct addrlist *al;
|
struct addrlist *al;
|
||||||
|
#ifdef HAVE_AUTH
|
||||||
|
struct auth_zone *zone;
|
||||||
|
struct auth_name_list *name;
|
||||||
|
|
||||||
|
/* Find subnets in auth_zones */
|
||||||
|
for (zone = daemon->auth_zones; zone; zone = zone->next)
|
||||||
|
for (name = zone->interface_names; name; name = name->next)
|
||||||
|
if (wildcard_match(name->name, label))
|
||||||
|
{
|
||||||
|
if (addr->sa.sa_family == AF_INET && (name->flags & AUTH4))
|
||||||
|
{
|
||||||
|
if (param->spare)
|
||||||
|
{
|
||||||
|
al = param->spare;
|
||||||
|
param->spare = al->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
al = whine_malloc(sizeof(struct addrlist));
|
||||||
|
|
||||||
|
if (al)
|
||||||
|
{
|
||||||
|
al->next = zone->subnet;
|
||||||
|
zone->subnet = al;
|
||||||
|
al->prefixlen = prefixlen;
|
||||||
|
al->addr.addr.addr4 = addr->in.sin_addr;
|
||||||
|
al->flags = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
if (addr->sa.sa_family == AF_INET6 && (name->flags & AUTH6))
|
||||||
|
{
|
||||||
|
if (param->spare)
|
||||||
|
{
|
||||||
|
al = param->spare;
|
||||||
|
param->spare = al->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
al = whine_malloc(sizeof(struct addrlist));
|
||||||
|
|
||||||
|
if (al)
|
||||||
|
{
|
||||||
|
al->next = zone->subnet;
|
||||||
|
zone->subnet = al;
|
||||||
|
al->prefixlen = prefixlen;al->addr.addr.addr6 = addr->in6.sin6_addr;
|
||||||
|
al->flags = ADDRLIST_IPV6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Update addresses from interface_names. These are a set independent
|
||||||
|
of the set we're listening on. */
|
||||||
for (int_name = daemon->int_names; int_name; int_name = int_name->next)
|
for (int_name = daemon->int_names; int_name; int_name = int_name->next)
|
||||||
if (strncmp(label, int_name->intr, IF_NAMESIZE) == 0)
|
if (strncmp(label, int_name->intr, IF_NAMESIZE) == 0)
|
||||||
{
|
{
|
||||||
@@ -285,18 +341,19 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
|||||||
|
|
||||||
if (al)
|
if (al)
|
||||||
{
|
{
|
||||||
|
al->next = int_name->addr;
|
||||||
|
int_name->addr = al;
|
||||||
|
|
||||||
if (addr->sa.sa_family == AF_INET)
|
if (addr->sa.sa_family == AF_INET)
|
||||||
{
|
{
|
||||||
al->addr.addr.addr4 = addr->in.sin_addr;
|
al->addr.addr.addr4 = addr->in.sin_addr;
|
||||||
al->next = int_name->addr4;
|
al->flags = 0;
|
||||||
int_name->addr4 = al;
|
|
||||||
}
|
}
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
al->addr.addr.addr6 = addr->in6.sin6_addr;
|
al->addr.addr.addr6 = addr->in6.sin6_addr;
|
||||||
al->next = int_name->addr6;
|
al->flags = ADDRLIST_IPV6;
|
||||||
int_name->addr6 = al;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -383,7 +440,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
|||||||
iface->dns_auth = auth_dns;
|
iface->dns_auth = auth_dns;
|
||||||
iface->mtu = mtu;
|
iface->mtu = mtu;
|
||||||
iface->dad = dad;
|
iface->dad = dad;
|
||||||
iface->done = iface->multicast_done = 0;
|
iface->done = iface->multicast_done = iface->warned = 0;
|
||||||
iface->index = if_index;
|
iface->index = if_index;
|
||||||
if ((iface->name = whine_malloc(strlen(ifr.ifr_name)+1)))
|
if ((iface->name = whine_malloc(strlen(ifr.ifr_name)+1)))
|
||||||
{
|
{
|
||||||
@@ -409,7 +466,6 @@ static int iface_allowed_v6(struct in6_addr *local, int prefix,
|
|||||||
struct in_addr netmask; /* dummy */
|
struct in_addr netmask; /* dummy */
|
||||||
netmask.s_addr = 0;
|
netmask.s_addr = 0;
|
||||||
|
|
||||||
(void)prefix; /* warning */
|
|
||||||
(void)scope; /* warning */
|
(void)scope; /* warning */
|
||||||
(void)preferred;
|
(void)preferred;
|
||||||
(void)valid;
|
(void)valid;
|
||||||
@@ -423,7 +479,7 @@ static int iface_allowed_v6(struct in6_addr *local, int prefix,
|
|||||||
addr.in6.sin6_port = htons(daemon->port);
|
addr.in6.sin6_port = htons(daemon->port);
|
||||||
addr.in6.sin6_scope_id = if_index;
|
addr.in6.sin6_scope_id = if_index;
|
||||||
|
|
||||||
return iface_allowed((struct iface_param *)vparam, if_index, NULL, &addr, netmask, !!(flags & IFACE_TENTATIVE));
|
return iface_allowed((struct iface_param *)vparam, if_index, NULL, &addr, netmask, prefix, !!(flags & IFACE_TENTATIVE));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -431,6 +487,7 @@ static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
|
|||||||
struct in_addr netmask, struct in_addr broadcast, void *vparam)
|
struct in_addr netmask, struct in_addr broadcast, void *vparam)
|
||||||
{
|
{
|
||||||
union mysockaddr addr;
|
union mysockaddr addr;
|
||||||
|
int prefix, bit;
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||||
@@ -441,7 +498,10 @@ static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
|
|||||||
addr.in.sin_addr = local;
|
addr.in.sin_addr = local;
|
||||||
addr.in.sin_port = htons(daemon->port);
|
addr.in.sin_port = htons(daemon->port);
|
||||||
|
|
||||||
return iface_allowed((struct iface_param *)vparam, if_index, label, &addr, netmask, 0);
|
/* determine prefix length from netmask */
|
||||||
|
for (prefix = 32, bit = 1; (bit & ntohl(netmask.s_addr)) == 0 && prefix != 0; bit = bit << 1, prefix--);
|
||||||
|
|
||||||
|
return iface_allowed((struct iface_param *)vparam, if_index, label, &addr, netmask, prefix, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int enumerate_interfaces(int reset)
|
int enumerate_interfaces(int reset)
|
||||||
@@ -452,7 +512,10 @@ int enumerate_interfaces(int reset)
|
|||||||
int errsave, ret = 1;
|
int errsave, ret = 1;
|
||||||
struct addrlist *addr, *tmp;
|
struct addrlist *addr, *tmp;
|
||||||
struct interface_name *intname;
|
struct interface_name *intname;
|
||||||
|
#ifdef HAVE_AUTH
|
||||||
|
struct auth_zone *zone;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Do this max once per select cycle - also inhibits netlink socket use
|
/* Do this max once per select cycle - also inhibits netlink socket use
|
||||||
in TCP child processes. */
|
in TCP child processes. */
|
||||||
|
|
||||||
@@ -476,27 +539,38 @@ int enumerate_interfaces(int reset)
|
|||||||
/* remove addresses stored against interface_names */
|
/* remove addresses stored against interface_names */
|
||||||
for (intname = daemon->int_names; intname; intname = intname->next)
|
for (intname = daemon->int_names; intname; intname = intname->next)
|
||||||
{
|
{
|
||||||
for (addr = intname->addr4; addr; addr = tmp)
|
for (addr = intname->addr; addr; addr = tmp)
|
||||||
{
|
{
|
||||||
tmp = addr->next;
|
tmp = addr->next;
|
||||||
addr->next = spare;
|
addr->next = spare;
|
||||||
spare = addr;
|
spare = addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
intname->addr4 = NULL;
|
intname->addr = NULL;
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
for (addr = intname->addr6; addr; addr = tmp)
|
|
||||||
{
|
|
||||||
tmp = addr->next;
|
|
||||||
addr->next = spare;
|
|
||||||
spare = addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
intname->addr6 = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_AUTH
|
||||||
|
/* remove addresses stored against auth_zone subnets, but not
|
||||||
|
ones configured as address literals */
|
||||||
|
for (zone = daemon->auth_zones; zone; zone = zone->next)
|
||||||
|
if (zone->interface_names)
|
||||||
|
{
|
||||||
|
struct addrlist **up;
|
||||||
|
for (up = &zone->subnet, addr = zone->subnet; addr; addr = tmp)
|
||||||
|
{
|
||||||
|
tmp = addr->next;
|
||||||
|
if (addr->flags & ADDRLIST_LITERAL)
|
||||||
|
up = &addr->next;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*up = addr->next;
|
||||||
|
addr->next = spare;
|
||||||
|
spare = addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
param.spare = spare;
|
param.spare = spare;
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
@@ -824,6 +898,59 @@ void create_bound_listeners(int dienow)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* In --bind-interfaces, the only access control is the addresses we're listening on.
|
||||||
|
There's nothing to avoid a query to the address of an internal interface arriving via
|
||||||
|
an external interface where we don't want to accept queries, except that in the usual
|
||||||
|
case the addresses of internal interfaces are RFC1918. When bind-interfaces in use,
|
||||||
|
and we listen on an address that looks like it's probably globally routeable, shout.
|
||||||
|
|
||||||
|
The fix is to use --bind-dynamic, which actually checks the arrival interface too.
|
||||||
|
Tough if your platform doesn't support this.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void warn_bound_listeners(void)
|
||||||
|
{
|
||||||
|
struct irec *iface;
|
||||||
|
int advice = 0;
|
||||||
|
|
||||||
|
for (iface = daemon->interfaces; iface; iface = iface->next)
|
||||||
|
if (option_bool(OPT_NOWILD) && !iface->dns_auth)
|
||||||
|
{
|
||||||
|
int warn = 0;
|
||||||
|
if (iface->addr.sa.sa_family == AF_INET)
|
||||||
|
{
|
||||||
|
if (!private_net(iface->addr.in.sin_addr, 1))
|
||||||
|
{
|
||||||
|
inet_ntop(AF_INET, &iface->addr.in.sin_addr, daemon->addrbuff, ADDRSTRLEN);
|
||||||
|
warn = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!IN6_IS_ADDR_LINKLOCAL(&iface->addr.in6.sin6_addr) &&
|
||||||
|
!IN6_IS_ADDR_SITELOCAL(&iface->addr.in6.sin6_addr) &&
|
||||||
|
!IN6_IS_ADDR_ULA(&iface->addr.in6.sin6_addr) &&
|
||||||
|
!IN6_IS_ADDR_LOOPBACK(&iface->addr.in6.sin6_addr))
|
||||||
|
{
|
||||||
|
inet_ntop(AF_INET6, &iface->addr.in6.sin6_addr, daemon->addrbuff, ADDRSTRLEN);
|
||||||
|
warn = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (warn)
|
||||||
|
{
|
||||||
|
iface->warned = advice = 1;
|
||||||
|
my_syslog(LOG_WARNING,
|
||||||
|
_("LOUD WARNING: listening on %s may accept requests via interfaces other than %s. "),
|
||||||
|
daemon->addrbuff, iface->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (advice)
|
||||||
|
my_syslog(LOG_WARNING, _("LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)."));
|
||||||
|
}
|
||||||
|
|
||||||
int is_dad_listeners(void)
|
int is_dad_listeners(void)
|
||||||
{
|
{
|
||||||
struct irec *iface;
|
struct irec *iface;
|
||||||
|
|||||||
+169
-92
@@ -64,76 +64,81 @@ struct myoption {
|
|||||||
#define OPTSTRING "951yZDNLERKzowefnbvhdkqr:m:p:c:l:s:i:t:u:g:a:x:S:C:A:T:H:Q:I:B:F:G:O:M:X:V:U:j:P:J:W:Y:2:4:6:7:8:0:3:"
|
#define OPTSTRING "951yZDNLERKzowefnbvhdkqr:m:p:c:l:s:i:t:u:g:a:x:S:C:A:T:H:Q:I:B:F:G:O:M:X:V:U:j:P:J:W:Y:2:4:6:7:8:0:3:"
|
||||||
|
|
||||||
/* options which don't have a one-char version */
|
/* options which don't have a one-char version */
|
||||||
#define LOPT_RELOAD 256
|
#define LOPT_RELOAD 256
|
||||||
#define LOPT_NO_NAMES 257
|
#define LOPT_NO_NAMES 257
|
||||||
#define LOPT_TFTP 258
|
#define LOPT_TFTP 258
|
||||||
#define LOPT_SECURE 259
|
#define LOPT_SECURE 259
|
||||||
#define LOPT_PREFIX 260
|
#define LOPT_PREFIX 260
|
||||||
#define LOPT_PTR 261
|
#define LOPT_PTR 261
|
||||||
#define LOPT_BRIDGE 262
|
#define LOPT_BRIDGE 262
|
||||||
#define LOPT_TFTP_MAX 263
|
#define LOPT_TFTP_MAX 263
|
||||||
#define LOPT_FORCE 264
|
#define LOPT_FORCE 264
|
||||||
#define LOPT_NOBLOCK 265
|
#define LOPT_NOBLOCK 265
|
||||||
#define LOPT_LOG_OPTS 266
|
#define LOPT_LOG_OPTS 266
|
||||||
#define LOPT_MAX_LOGS 267
|
#define LOPT_MAX_LOGS 267
|
||||||
#define LOPT_CIRCUIT 268
|
#define LOPT_CIRCUIT 268
|
||||||
#define LOPT_REMOTE 269
|
#define LOPT_REMOTE 269
|
||||||
#define LOPT_SUBSCR 270
|
#define LOPT_SUBSCR 270
|
||||||
#define LOPT_INTNAME 271
|
#define LOPT_INTNAME 271
|
||||||
#define LOPT_BANK 272
|
#define LOPT_BANK 272
|
||||||
#define LOPT_DHCP_HOST 273
|
#define LOPT_DHCP_HOST 273
|
||||||
#define LOPT_APREF 274
|
#define LOPT_APREF 274
|
||||||
#define LOPT_OVERRIDE 275
|
#define LOPT_OVERRIDE 275
|
||||||
#define LOPT_TFTPPORTS 276
|
#define LOPT_TFTPPORTS 276
|
||||||
#define LOPT_REBIND 277
|
#define LOPT_REBIND 277
|
||||||
#define LOPT_NOLAST 278
|
#define LOPT_NOLAST 278
|
||||||
#define LOPT_OPTS 279
|
#define LOPT_OPTS 279
|
||||||
#define LOPT_DHCP_OPTS 280
|
#define LOPT_DHCP_OPTS 280
|
||||||
#define LOPT_MATCH 281
|
#define LOPT_MATCH 281
|
||||||
#define LOPT_BROADCAST 282
|
#define LOPT_BROADCAST 282
|
||||||
#define LOPT_NEGTTL 283
|
#define LOPT_NEGTTL 283
|
||||||
#define LOPT_ALTPORT 284
|
#define LOPT_ALTPORT 284
|
||||||
#define LOPT_SCRIPTUSR 285
|
#define LOPT_SCRIPTUSR 285
|
||||||
#define LOPT_LOCAL 286
|
#define LOPT_LOCAL 286
|
||||||
#define LOPT_NAPTR 287
|
#define LOPT_NAPTR 287
|
||||||
#define LOPT_MINPORT 288
|
#define LOPT_MINPORT 288
|
||||||
#define LOPT_DHCP_FQDN 289
|
#define LOPT_DHCP_FQDN 289
|
||||||
#define LOPT_CNAME 290
|
#define LOPT_CNAME 290
|
||||||
#define LOPT_PXE_PROMT 291
|
#define LOPT_PXE_PROMT 291
|
||||||
#define LOPT_PXE_SERV 292
|
#define LOPT_PXE_SERV 292
|
||||||
#define LOPT_TEST 293
|
#define LOPT_TEST 293
|
||||||
#define LOPT_TAG_IF 294
|
#define LOPT_TAG_IF 294
|
||||||
#define LOPT_PROXY 295
|
#define LOPT_PROXY 295
|
||||||
#define LOPT_GEN_NAMES 296
|
#define LOPT_GEN_NAMES 296
|
||||||
#define LOPT_MAXTTL 297
|
#define LOPT_MAXTTL 297
|
||||||
#define LOPT_NO_REBIND 298
|
#define LOPT_NO_REBIND 298
|
||||||
#define LOPT_LOC_REBND 299
|
#define LOPT_LOC_REBND 299
|
||||||
#define LOPT_ADD_MAC 300
|
#define LOPT_ADD_MAC 300
|
||||||
#define LOPT_DNSSEC 301
|
#define LOPT_DNSSEC 301
|
||||||
#define LOPT_INCR_ADDR 302
|
#define LOPT_INCR_ADDR 302
|
||||||
#define LOPT_CONNTRACK 303
|
#define LOPT_CONNTRACK 303
|
||||||
#define LOPT_FQDN 304
|
#define LOPT_FQDN 304
|
||||||
#define LOPT_LUASCRIPT 305
|
#define LOPT_LUASCRIPT 305
|
||||||
#define LOPT_RA 306
|
#define LOPT_RA 306
|
||||||
#define LOPT_DUID 307
|
#define LOPT_DUID 307
|
||||||
#define LOPT_HOST_REC 308
|
#define LOPT_HOST_REC 308
|
||||||
#define LOPT_TFTP_LC 309
|
#define LOPT_TFTP_LC 309
|
||||||
#define LOPT_RR 310
|
#define LOPT_RR 310
|
||||||
#define LOPT_CLVERBIND 311
|
#define LOPT_CLVERBIND 311
|
||||||
#define LOPT_MAXCTTL 312
|
#define LOPT_MAXCTTL 312
|
||||||
#define LOPT_AUTHZONE 313
|
#define LOPT_AUTHZONE 313
|
||||||
#define LOPT_AUTHSERV 314
|
#define LOPT_AUTHSERV 314
|
||||||
#define LOPT_AUTHTTL 315
|
#define LOPT_AUTHTTL 315
|
||||||
#define LOPT_AUTHSOA 316
|
#define LOPT_AUTHSOA 316
|
||||||
#define LOPT_AUTHSFS 317
|
#define LOPT_AUTHSFS 317
|
||||||
#define LOPT_AUTHPEER 318
|
#define LOPT_AUTHPEER 318
|
||||||
#define LOPT_IPSET 319
|
#define LOPT_IPSET 319
|
||||||
#define LOPT_SYNTH 320
|
#define LOPT_SYNTH 320
|
||||||
#ifdef OPTION6_PREFIX_CLASS
|
#ifdef OPTION6_PREFIX_CLASS
|
||||||
#define LOPT_PREF_CLSS 321
|
#define LOPT_PREF_CLSS 321
|
||||||
#endif
|
#endif
|
||||||
#define LOPT_FAST_RA 322
|
#define LOPT_RELAY 323
|
||||||
#define LOPT_RELAY 323
|
#define LOPT_RA_PARAM 324
|
||||||
|
#define LOPT_ADD_SBNET 325
|
||||||
|
#define LOPT_QUIET_DHCP 326
|
||||||
|
#define LOPT_QUIET_DHCP6 327
|
||||||
|
#define LOPT_QUIET_RA 328
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_GETOPT_LONG
|
#ifdef HAVE_GETOPT_LONG
|
||||||
static const struct option opts[] =
|
static const struct option opts[] =
|
||||||
@@ -251,6 +256,7 @@ static const struct myoption opts[] =
|
|||||||
{ "dhcp-generate-names", 2, 0, LOPT_GEN_NAMES },
|
{ "dhcp-generate-names", 2, 0, LOPT_GEN_NAMES },
|
||||||
{ "rebind-localhost-ok", 0, 0, LOPT_LOC_REBND },
|
{ "rebind-localhost-ok", 0, 0, LOPT_LOC_REBND },
|
||||||
{ "add-mac", 0, 0, LOPT_ADD_MAC },
|
{ "add-mac", 0, 0, LOPT_ADD_MAC },
|
||||||
|
{ "add-subnet", 2, 0, LOPT_ADD_SBNET },
|
||||||
{ "proxy-dnssec", 0, 0, LOPT_DNSSEC },
|
{ "proxy-dnssec", 0, 0, LOPT_DNSSEC },
|
||||||
{ "dhcp-sequential-ip", 0, 0, LOPT_INCR_ADDR },
|
{ "dhcp-sequential-ip", 0, 0, LOPT_INCR_ADDR },
|
||||||
{ "conntrack", 0, 0, LOPT_CONNTRACK },
|
{ "conntrack", 0, 0, LOPT_CONNTRACK },
|
||||||
@@ -271,8 +277,11 @@ static const struct myoption opts[] =
|
|||||||
#ifdef OPTION6_PREFIX_CLASS
|
#ifdef OPTION6_PREFIX_CLASS
|
||||||
{ "dhcp-prefix-class", 1, 0, LOPT_PREF_CLSS },
|
{ "dhcp-prefix-class", 1, 0, LOPT_PREF_CLSS },
|
||||||
#endif
|
#endif
|
||||||
{ "force-fast-ra", 0, 0, LOPT_FAST_RA },
|
|
||||||
{ "dhcp-relay", 1, 0, LOPT_RELAY },
|
{ "dhcp-relay", 1, 0, LOPT_RELAY },
|
||||||
|
{ "ra-param", 1, 0, LOPT_RA_PARAM },
|
||||||
|
{ "quiet-dhcp", 0, 0, LOPT_QUIET_DHCP },
|
||||||
|
{ "quiet-dhcp6", 0, 0, LOPT_QUIET_DHCP6 },
|
||||||
|
{ "quiet-ra", 0, 0, LOPT_QUIET_RA },
|
||||||
{ NULL, 0, 0, 0 }
|
{ NULL, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -397,12 +406,12 @@ static struct {
|
|||||||
{ LOPT_PXE_SERV, ARG_DUP, "<service>", gettext_noop("Boot service for PXE menu."), NULL },
|
{ LOPT_PXE_SERV, ARG_DUP, "<service>", gettext_noop("Boot service for PXE menu."), NULL },
|
||||||
{ LOPT_TEST, 0, NULL, gettext_noop("Check configuration syntax."), NULL },
|
{ LOPT_TEST, 0, NULL, gettext_noop("Check configuration syntax."), NULL },
|
||||||
{ LOPT_ADD_MAC, OPT_ADD_MAC, NULL, gettext_noop("Add requestor's MAC address to forwarded DNS queries."), NULL },
|
{ LOPT_ADD_MAC, OPT_ADD_MAC, NULL, gettext_noop("Add requestor's MAC address to forwarded DNS queries."), NULL },
|
||||||
|
{ LOPT_ADD_SBNET, ARG_ONE, "<v4 pref>[,<v6 pref>]", gettext_noop("Add requestor's IP subnet to forwarded DNS queries."), NULL },
|
||||||
{ LOPT_DNSSEC, OPT_DNSSEC, NULL, gettext_noop("Proxy DNSSEC validation results from upstream nameservers."), NULL },
|
{ LOPT_DNSSEC, OPT_DNSSEC, NULL, gettext_noop("Proxy DNSSEC validation results from upstream nameservers."), NULL },
|
||||||
{ LOPT_INCR_ADDR, OPT_CONSEC_ADDR, NULL, gettext_noop("Attempt to allocate sequential IP addresses to DHCP clients."), NULL },
|
{ LOPT_INCR_ADDR, OPT_CONSEC_ADDR, NULL, gettext_noop("Attempt to allocate sequential IP addresses to DHCP clients."), NULL },
|
||||||
{ LOPT_CONNTRACK, OPT_CONNTRACK, NULL, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL },
|
{ LOPT_CONNTRACK, OPT_CONNTRACK, NULL, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL },
|
||||||
{ LOPT_FQDN, OPT_FQDN_UPDATE, NULL, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL },
|
{ LOPT_FQDN, OPT_FQDN_UPDATE, NULL, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL },
|
||||||
{ LOPT_RA, OPT_RA, NULL, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL },
|
{ LOPT_RA, OPT_RA, NULL, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL },
|
||||||
{ LOPT_FAST_RA, OPT_FAST_RA, NULL, gettext_noop("Always send frequent router-advertisements"), NULL },
|
|
||||||
{ LOPT_DUID, ARG_ONE, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL },
|
{ LOPT_DUID, ARG_ONE, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL },
|
||||||
{ LOPT_HOST_REC, ARG_DUP, "<name>,<address>", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL },
|
{ LOPT_HOST_REC, ARG_DUP, "<name>,<address>", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL },
|
||||||
{ LOPT_RR, ARG_DUP, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL },
|
{ LOPT_RR, ARG_DUP, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL },
|
||||||
@@ -414,10 +423,14 @@ static struct {
|
|||||||
{ LOPT_AUTHSFS, ARG_DUP, "<NS>[,<NS>...]", gettext_noop("Secondary authoritative nameservers for forward domains"), NULL },
|
{ LOPT_AUTHSFS, ARG_DUP, "<NS>[,<NS>...]", gettext_noop("Secondary authoritative nameservers for forward domains"), NULL },
|
||||||
{ LOPT_AUTHPEER, ARG_DUP, "<ipaddr>[,<ipaddr>...]", gettext_noop("Peers which are allowed to do zone transfer"), NULL },
|
{ LOPT_AUTHPEER, ARG_DUP, "<ipaddr>[,<ipaddr>...]", gettext_noop("Peers which are allowed to do zone transfer"), NULL },
|
||||||
{ LOPT_IPSET, ARG_DUP, "/<domain>/<ipset>[,<ipset>...]", gettext_noop("Specify ipsets to which matching domains should be added"), NULL },
|
{ LOPT_IPSET, ARG_DUP, "/<domain>/<ipset>[,<ipset>...]", gettext_noop("Specify ipsets to which matching domains should be added"), NULL },
|
||||||
{ LOPT_SYNTH, ARG_DUP, "<domain>,<range>,[<prefix>]", gettext_noop("Specify a domain and address range for sythesised names"), NULL },
|
{ LOPT_SYNTH, ARG_DUP, "<domain>,<range>,[<prefix>]", gettext_noop("Specify a domain and address range for synthesised names"), NULL },
|
||||||
#ifdef OPTION6_PREFIX_CLASS
|
#ifdef OPTION6_PREFIX_CLASS
|
||||||
{ LOPT_PREF_CLSS, ARG_DUP, "set:tag,<class>", gettext_noop("Specify DHCPv6 prefix class"), NULL },
|
{ LOPT_PREF_CLSS, ARG_DUP, "set:tag,<class>", gettext_noop("Specify DHCPv6 prefix class"), NULL },
|
||||||
#endif
|
#endif
|
||||||
|
{ LOPT_RA_PARAM, ARG_DUP, "<interface>,[high,|low,]<interval>[,<lifetime>]", gettext_noop("Set priority, resend-interval and router-lifetime"), NULL },
|
||||||
|
{ LOPT_QUIET_DHCP, OPT_QUIET_DHCP, NULL, gettext_noop("Do not log routine DHCP."), NULL },
|
||||||
|
{ LOPT_QUIET_DHCP6, OPT_QUIET_DHCP6, NULL, gettext_noop("Do not log routine DHCPv6."), NULL },
|
||||||
|
{ LOPT_QUIET_RA, OPT_QUIET_RA, NULL, gettext_noop("Do not log RA."), NULL },
|
||||||
{ 0, 0, NULL, NULL, NULL }
|
{ 0, 0, NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1424,6 +1437,17 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case LOPT_ADD_SBNET: /* --add-subnet */
|
||||||
|
set_option_bool(OPT_CLIENT_SUBNET);
|
||||||
|
if (arg)
|
||||||
|
{
|
||||||
|
comma = split(arg);
|
||||||
|
if (!atoi_check(arg, &daemon->addr4_netmask) ||
|
||||||
|
(comma && !atoi_check(comma, &daemon->addr6_netmask)))
|
||||||
|
ret_err(gen_err);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case '1': /* --enable-dbus */
|
case '1': /* --enable-dbus */
|
||||||
set_option_bool(OPT_DBUS);
|
set_option_bool(OPT_DBUS);
|
||||||
if (arg)
|
if (arg)
|
||||||
@@ -1625,6 +1649,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
new = opt_malloc(sizeof(struct auth_zone));
|
new = opt_malloc(sizeof(struct auth_zone));
|
||||||
new->domain = opt_string_alloc(arg);
|
new->domain = opt_string_alloc(arg);
|
||||||
new->subnet = NULL;
|
new->subnet = NULL;
|
||||||
|
new->interface_names = NULL;
|
||||||
new->next = daemon->auth_zones;
|
new->next = daemon->auth_zones;
|
||||||
daemon->auth_zones = new;
|
daemon->auth_zones = new;
|
||||||
|
|
||||||
@@ -1632,10 +1657,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
{
|
{
|
||||||
int prefixlen = 0;
|
int prefixlen = 0;
|
||||||
char *prefix;
|
char *prefix;
|
||||||
struct subnet *subnet = opt_malloc(sizeof(struct subnet));
|
struct addrlist *subnet = NULL;
|
||||||
|
struct all_addr addr;
|
||||||
subnet->next = new->subnet;
|
|
||||||
new->subnet = subnet;
|
|
||||||
|
|
||||||
comma = split(arg);
|
comma = split(arg);
|
||||||
prefix = split_chr(arg, '/');
|
prefix = split_chr(arg, '/');
|
||||||
@@ -1643,24 +1666,50 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
if (prefix && !atoi_check(prefix, &prefixlen))
|
if (prefix && !atoi_check(prefix, &prefixlen))
|
||||||
ret_err(gen_err);
|
ret_err(gen_err);
|
||||||
|
|
||||||
if (inet_pton(AF_INET, arg, &subnet->addr4))
|
if (inet_pton(AF_INET, arg, &addr.addr.addr4))
|
||||||
{
|
{
|
||||||
|
subnet = opt_malloc(sizeof(struct addrlist));
|
||||||
subnet->prefixlen = (prefixlen == 0) ? 24 : prefixlen;
|
subnet->prefixlen = (prefixlen == 0) ? 24 : prefixlen;
|
||||||
subnet->is6 = 0;
|
subnet->flags = ADDRLIST_LITERAL;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
else if (inet_pton(AF_INET6, arg, &subnet->addr6))
|
else if (inet_pton(AF_INET6, arg, &addr.addr.addr6))
|
||||||
{
|
{
|
||||||
|
subnet = opt_malloc(sizeof(struct addrlist));
|
||||||
subnet->prefixlen = (prefixlen == 0) ? 64 : prefixlen;
|
subnet->prefixlen = (prefixlen == 0) ? 64 : prefixlen;
|
||||||
subnet->is6 = 1;
|
subnet->flags = ADDRLIST_LITERAL | ADDRLIST_IPV6;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
ret_err(gen_err);
|
{
|
||||||
|
struct auth_name_list *name = opt_malloc(sizeof(struct auth_name_list));
|
||||||
|
name->name = opt_string_alloc(arg);
|
||||||
|
name->flags = AUTH4 | AUTH6;
|
||||||
|
name->next = new->interface_names;
|
||||||
|
new->interface_names = name;
|
||||||
|
if (prefix)
|
||||||
|
{
|
||||||
|
if (prefixlen == 4)
|
||||||
|
name->flags &= ~AUTH6;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
else if (prefixlen == 6)
|
||||||
|
name->flags &= ~AUTH4;
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
ret_err(gen_err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subnet)
|
||||||
|
{
|
||||||
|
subnet->addr = addr;
|
||||||
|
subnet->next = new->subnet;
|
||||||
|
new->subnet = subnet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case LOPT_AUTHSOA: /* --auth-soa */
|
case LOPT_AUTHSOA: /* --auth-soa */
|
||||||
comma = split(arg);
|
comma = split(arg);
|
||||||
daemon->soa_sn = (u32)atoi(arg);
|
daemon->soa_sn = (u32)atoi(arg);
|
||||||
@@ -1836,9 +1885,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
else
|
else
|
||||||
ret_err(gen_err);
|
ret_err(gen_err);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
char *prefstr;
|
||||||
arg = split(comma);
|
arg = split(comma);
|
||||||
|
prefstr = split(arg);
|
||||||
|
|
||||||
if (inet_pton(AF_INET, comma, &new->start))
|
if (inet_pton(AF_INET, comma, &new->start))
|
||||||
{
|
{
|
||||||
new->is6 = 0;
|
new->is6 = 0;
|
||||||
@@ -1859,6 +1911,13 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
ret_err(gen_err);
|
ret_err(gen_err);
|
||||||
|
|
||||||
|
if (option != 's' && prefstr)
|
||||||
|
{
|
||||||
|
if (!(new->prefix = canonicalise_opt(prefstr)) ||
|
||||||
|
strlen(new->prefix) > MAXLABEL - INET_ADDRSTRLEN)
|
||||||
|
ret_err(_("bad prefix"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new->domain = d;
|
new->domain = d;
|
||||||
@@ -2430,11 +2489,6 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
new->template_interface = opt_string_alloc(a[leasepos] + 12);
|
new->template_interface = opt_string_alloc(a[leasepos] + 12);
|
||||||
new->flags |= CONTEXT_TEMPLATE;
|
new->flags |= CONTEXT_TEMPLATE;
|
||||||
}
|
}
|
||||||
else if (strstr(a[leasepos], "constructor-noauth:") == a[leasepos])
|
|
||||||
{
|
|
||||||
new->template_interface = opt_string_alloc(a[leasepos] + 19);
|
|
||||||
new->flags |= CONTEXT_TEMPLATE | CONTEXT_NOAUTH;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -3215,6 +3269,31 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
|
case LOPT_RA_PARAM: /* --ra-param */
|
||||||
|
if ((comma = split(arg)))
|
||||||
|
{
|
||||||
|
struct ra_interface *new = opt_malloc(sizeof(struct ra_interface));
|
||||||
|
new->lifetime = -1;
|
||||||
|
new->prio = 0;
|
||||||
|
new->name = opt_string_alloc(arg);
|
||||||
|
if (strcasestr(comma, "high") == comma || strcasestr(comma, "low") == comma)
|
||||||
|
{
|
||||||
|
if (*comma == 'l' || *comma == 'L')
|
||||||
|
new->prio = 0x18;
|
||||||
|
else
|
||||||
|
new->prio = 0x08;
|
||||||
|
comma = split(comma);
|
||||||
|
}
|
||||||
|
arg = split(comma);
|
||||||
|
if (!atoi_check(comma, &new->interval) ||
|
||||||
|
(arg && !atoi_check(arg, &new->lifetime)))
|
||||||
|
ret_err(_("bad RA-params"));
|
||||||
|
|
||||||
|
new->next = daemon->ra_interfaces;
|
||||||
|
daemon->ra_interfaces = new;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case LOPT_DUID: /* --dhcp-duid */
|
case LOPT_DUID: /* --dhcp-duid */
|
||||||
if (!(comma = split(arg)) || !atoi_check(arg, (int *)&daemon->duid_enterprise))
|
if (!(comma = split(arg)) || !atoi_check(arg, (int *)&daemon->duid_enterprise))
|
||||||
ret_err(_("bad DUID"));
|
ret_err(_("bad DUID"));
|
||||||
@@ -3276,10 +3355,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
|
|
||||||
new = opt_malloc(sizeof(struct interface_name));
|
new = opt_malloc(sizeof(struct interface_name));
|
||||||
new->next = NULL;
|
new->next = NULL;
|
||||||
new->addr4 = NULL;
|
new->addr = NULL;
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
new->addr6 = NULL;
|
|
||||||
#endif
|
|
||||||
/* Add to the end of the list, so that first name
|
/* Add to the end of the list, so that first name
|
||||||
of an interface is used for PTR lookups. */
|
of an interface is used for PTR lookups. */
|
||||||
for (up = &daemon->int_names; *up; up = &((*up)->next));
|
for (up = &daemon->int_names; *up; up = &((*up)->next));
|
||||||
|
|||||||
+106
-33
@@ -32,11 +32,12 @@ struct ra_param {
|
|||||||
char *if_name;
|
char *if_name;
|
||||||
struct dhcp_netid *tags;
|
struct dhcp_netid *tags;
|
||||||
struct in6_addr link_local, link_global;
|
struct in6_addr link_local, link_global;
|
||||||
unsigned int pref_time;
|
unsigned int pref_time, adv_interval;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct search_param {
|
struct search_param {
|
||||||
time_t now; int iface;
|
time_t now; int iface;
|
||||||
|
char name[IF_NAMESIZE+1];
|
||||||
};
|
};
|
||||||
|
|
||||||
static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *dest);
|
static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *dest);
|
||||||
@@ -47,7 +48,11 @@ static int iface_search(struct in6_addr *local, int prefix,
|
|||||||
int scope, int if_index, int flags,
|
int scope, int if_index, int flags,
|
||||||
int prefered, int valid, void *vparam);
|
int prefered, int valid, void *vparam);
|
||||||
static int add_lla(int index, unsigned int type, char *mac, size_t maclen, void *parm);
|
static int add_lla(int index, unsigned int type, char *mac, size_t maclen, void *parm);
|
||||||
static void new_timeout(struct dhcp_context *context, time_t now);
|
static void new_timeout(struct dhcp_context *context, char *iface_name, time_t now);
|
||||||
|
static unsigned int calc_lifetime(struct ra_interface *ra);
|
||||||
|
static unsigned int calc_interval(struct ra_interface *ra);
|
||||||
|
static unsigned int calc_prio(struct ra_interface *ra);
|
||||||
|
static struct ra_interface *find_iface_param(char *iface);
|
||||||
|
|
||||||
static int hop_limit;
|
static int hop_limit;
|
||||||
|
|
||||||
@@ -184,7 +189,8 @@ void icmp6_packet(time_t now)
|
|||||||
mac = daemon->namebuff;
|
mac = daemon->namebuff;
|
||||||
}
|
}
|
||||||
|
|
||||||
my_syslog(MS_DHCP | LOG_INFO, "RTR-SOLICIT(%s) %s", interface, mac);
|
if (!option_bool(OPT_QUIET_RA))
|
||||||
|
my_syslog(MS_DHCP | LOG_INFO, "RTR-SOLICIT(%s) %s", interface, mac);
|
||||||
/* source address may not be valid in solicit request. */
|
/* source address may not be valid in solicit request. */
|
||||||
send_ra(now, if_index, interface, !IN6_IS_ADDR_UNSPECIFIED(&from.sin6_addr) ? &from.sin6_addr : NULL);
|
send_ra(now, if_index, interface, !IN6_IS_ADDR_UNSPECIFIED(&from.sin6_addr) ? &from.sin6_addr : NULL);
|
||||||
}
|
}
|
||||||
@@ -198,19 +204,20 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
|||||||
struct dhcp_context *context, *tmp, **up;
|
struct dhcp_context *context, *tmp, **up;
|
||||||
struct dhcp_netid iface_id;
|
struct dhcp_netid iface_id;
|
||||||
struct dhcp_opt *opt_cfg;
|
struct dhcp_opt *opt_cfg;
|
||||||
|
struct ra_interface *ra_param = find_iface_param(iface_name);
|
||||||
int done_dns = 0;
|
int done_dns = 0;
|
||||||
#ifdef HAVE_LINUX_NETWORK
|
#ifdef HAVE_LINUX_NETWORK
|
||||||
FILE *f;
|
FILE *f;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
save_counter(0);
|
save_counter(0);
|
||||||
ra = expand(sizeof(struct ra_packet));
|
ra = expand(sizeof(struct ra_packet));
|
||||||
|
|
||||||
ra->type = ND_ROUTER_ADVERT;
|
ra->type = ND_ROUTER_ADVERT;
|
||||||
ra->code = 0;
|
ra->code = 0;
|
||||||
ra->hop_limit = hop_limit;
|
ra->hop_limit = hop_limit;
|
||||||
ra->flags = 0x00;
|
ra->flags = calc_prio(ra_param);
|
||||||
ra->lifetime = htons(RA_INTERVAL * 3); /* AdvDefaultLifetime * 3 */
|
ra->lifetime = htons(calc_lifetime(ra_param));
|
||||||
ra->reachable_time = 0;
|
ra->reachable_time = 0;
|
||||||
ra->retrans_time = 0;
|
ra->retrans_time = 0;
|
||||||
|
|
||||||
@@ -222,6 +229,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
|||||||
parm.first = 1;
|
parm.first = 1;
|
||||||
parm.now = now;
|
parm.now = now;
|
||||||
parm.pref_time = 0;
|
parm.pref_time = 0;
|
||||||
|
parm.adv_interval = calc_interval(ra_param);
|
||||||
|
|
||||||
/* set tag with name == interface */
|
/* set tag with name == interface */
|
||||||
iface_id.net = iface_name;
|
iface_id.net = iface_name;
|
||||||
@@ -281,7 +289,8 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
|||||||
opt->prefix = local;
|
opt->prefix = local;
|
||||||
|
|
||||||
inet_ntop(AF_INET6, &local, daemon->addrbuff, ADDRSTRLEN);
|
inet_ntop(AF_INET6, &local, daemon->addrbuff, ADDRSTRLEN);
|
||||||
my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s old prefix", iface_name, daemon->addrbuff);
|
if (!option_bool(OPT_QUIET_RA))
|
||||||
|
my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s old prefix", iface_name, daemon->addrbuff);
|
||||||
}
|
}
|
||||||
|
|
||||||
up = &context->next;
|
up = &context->next;
|
||||||
@@ -327,15 +336,15 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
|||||||
if (opt_cfg->opt == OPTION6_DNS_SERVER)
|
if (opt_cfg->opt == OPTION6_DNS_SERVER)
|
||||||
{
|
{
|
||||||
struct in6_addr *a = (struct in6_addr *)opt_cfg->val;
|
struct in6_addr *a = (struct in6_addr *)opt_cfg->val;
|
||||||
|
|
||||||
done_dns = 1;
|
done_dns = 1;
|
||||||
if (opt_cfg->len == 0)
|
if (opt_cfg->len == 0 || (IN6_IS_ADDR_UNSPECIFIED(a) && parm.pref_time != 0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
put_opt6_char(ICMP6_OPT_RDNSS);
|
put_opt6_char(ICMP6_OPT_RDNSS);
|
||||||
put_opt6_char((opt_cfg->len/8) + 1);
|
put_opt6_char((opt_cfg->len/8) + 1);
|
||||||
put_opt6_short(0);
|
put_opt6_short(0);
|
||||||
put_opt6_long(RA_INTERVAL * 2); /* lifetime - twice RA retransmit */
|
put_opt6_long(parm.pref_time);
|
||||||
/* zero means "self" */
|
/* zero means "self" */
|
||||||
for (i = 0; i < opt_cfg->len; i += IN6ADDRSZ, a++)
|
for (i = 0; i < opt_cfg->len; i += IN6ADDRSZ, a++)
|
||||||
if (IN6_IS_ADDR_UNSPECIFIED(a))
|
if (IN6_IS_ADDR_UNSPECIFIED(a))
|
||||||
@@ -351,7 +360,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
|||||||
put_opt6_char(ICMP6_OPT_DNSSL);
|
put_opt6_char(ICMP6_OPT_DNSSL);
|
||||||
put_opt6_char(len + 1);
|
put_opt6_char(len + 1);
|
||||||
put_opt6_short(0);
|
put_opt6_short(0);
|
||||||
put_opt6_long(RA_INTERVAL * 2); /* lifetime - twice RA retransmit */
|
put_opt6_long(parm.pref_time);
|
||||||
put_opt6(opt_cfg->val, opt_cfg->len);
|
put_opt6(opt_cfg->val, opt_cfg->len);
|
||||||
|
|
||||||
/* pad */
|
/* pad */
|
||||||
@@ -360,14 +369,14 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (daemon->port == NAMESERVER_PORT && !done_dns)
|
if (daemon->port == NAMESERVER_PORT && !done_dns && parm.pref_time != 0)
|
||||||
{
|
{
|
||||||
/* default == us, as long as we are supplying DNS service. */
|
/* default == us, as long as we are supplying DNS service. */
|
||||||
put_opt6_char(ICMP6_OPT_RDNSS);
|
put_opt6_char(ICMP6_OPT_RDNSS);
|
||||||
put_opt6_char(3);
|
put_opt6_char(3);
|
||||||
put_opt6_short(0);
|
put_opt6_short(0);
|
||||||
put_opt6_long(RA_INTERVAL * 2); /* lifetime - twice RA retransmit */
|
put_opt6_long(parm.pref_time);
|
||||||
put_opt6(&parm.link_global, IN6ADDRSZ);
|
put_opt6(&parm.link_local, IN6ADDRSZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set managed bits unless we're providing only RA on this link */
|
/* set managed bits unless we're providing only RA on this link */
|
||||||
@@ -455,8 +464,8 @@ static int add_prefixes(struct in6_addr *local, int prefix,
|
|||||||
if (time > context->lease_time)
|
if (time > context->lease_time)
|
||||||
{
|
{
|
||||||
time = context->lease_time;
|
time = context->lease_time;
|
||||||
if (time < ((unsigned int)(3 * RA_INTERVAL)))
|
if (time < ((unsigned int)(3 * param->adv_interval)))
|
||||||
time = 3 * RA_INTERVAL;
|
time = 3 * param->adv_interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->flags & CONTEXT_DEPRECATE)
|
if (context->flags & CONTEXT_DEPRECATE)
|
||||||
@@ -529,7 +538,8 @@ static int add_prefixes(struct in6_addr *local, int prefix,
|
|||||||
opt->prefix = *local;
|
opt->prefix = *local;
|
||||||
|
|
||||||
inet_ntop(AF_INET6, local, daemon->addrbuff, ADDRSTRLEN);
|
inet_ntop(AF_INET6, local, daemon->addrbuff, ADDRSTRLEN);
|
||||||
my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s", param->if_name, daemon->addrbuff);
|
if (!option_bool(OPT_QUIET_RA))
|
||||||
|
my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s", param->if_name, daemon->addrbuff);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -564,8 +574,7 @@ time_t periodic_ra(time_t now)
|
|||||||
struct search_param param;
|
struct search_param param;
|
||||||
struct dhcp_context *context;
|
struct dhcp_context *context;
|
||||||
time_t next_event;
|
time_t next_event;
|
||||||
char interface[IF_NAMESIZE+1];
|
|
||||||
|
|
||||||
param.now = now;
|
param.now = now;
|
||||||
param.iface = 0;
|
param.iface = 0;
|
||||||
|
|
||||||
@@ -586,13 +595,15 @@ time_t periodic_ra(time_t now)
|
|||||||
if (!context)
|
if (!context)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ((context->flags & CONTEXT_OLD) && context->if_index != 0)
|
if ((context->flags & CONTEXT_OLD) &&
|
||||||
|
context->if_index != 0 &&
|
||||||
|
indextoname(daemon->icmp6fd, context->if_index, param.name))
|
||||||
{
|
{
|
||||||
/* A context for an old address. We'll not find the interface by
|
/* A context for an old address. We'll not find the interface by
|
||||||
looking for addresses, but we know it anyway, as long as we
|
looking for addresses, but we know it anyway, since the context is
|
||||||
sent at least one RA whilst the address was current. */
|
constructed */
|
||||||
param.iface = context->if_index;
|
param.iface = context->if_index;
|
||||||
new_timeout(context, now);
|
new_timeout(context, param.name, now);
|
||||||
}
|
}
|
||||||
else if (iface_enumerate(AF_INET6, ¶m, iface_search))
|
else if (iface_enumerate(AF_INET6, ¶m, iface_search))
|
||||||
/* There's a context overdue, but we can't find an interface
|
/* There's a context overdue, but we can't find an interface
|
||||||
@@ -603,15 +614,14 @@ time_t periodic_ra(time_t now)
|
|||||||
context->ra_time = 0;
|
context->ra_time = 0;
|
||||||
|
|
||||||
if (param.iface != 0 &&
|
if (param.iface != 0 &&
|
||||||
indextoname(daemon->icmp6fd, param.iface, interface) &&
|
iface_check(AF_LOCAL, NULL, param.name, NULL))
|
||||||
iface_check(AF_LOCAL, NULL, interface, NULL))
|
|
||||||
{
|
{
|
||||||
struct iname *tmp;
|
struct iname *tmp;
|
||||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||||
if (tmp->name && wildcard_match(tmp->name, interface))
|
if (tmp->name && wildcard_match(tmp->name, param.name))
|
||||||
break;
|
break;
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
send_ra(now, param.iface, interface, NULL);
|
send_ra(now, param.iface, param.name, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return next_event;
|
return next_event;
|
||||||
@@ -643,7 +653,14 @@ static int iface_search(struct in6_addr *local, int prefix,
|
|||||||
if (!(flags & IFACE_TENTATIVE))
|
if (!(flags & IFACE_TENTATIVE))
|
||||||
param->iface = if_index;
|
param->iface = if_index;
|
||||||
|
|
||||||
new_timeout(context, param->now);
|
/* should never fail */
|
||||||
|
if (!indextoname(daemon->icmp6fd, if_index, param->name))
|
||||||
|
{
|
||||||
|
param->iface = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_timeout(context, param->name, param->now);
|
||||||
|
|
||||||
/* zero timers for other contexts on the same subnet, so they don't timeout
|
/* zero timers for other contexts on the same subnet, so they don't timeout
|
||||||
independently */
|
independently */
|
||||||
@@ -659,14 +676,70 @@ static int iface_search(struct in6_addr *local, int prefix,
|
|||||||
return 1; /* keep searching */
|
return 1; /* keep searching */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void new_timeout(struct dhcp_context *context, time_t now)
|
static void new_timeout(struct dhcp_context *context, char *iface_name, time_t now)
|
||||||
{
|
{
|
||||||
if (difftime(now, context->ra_short_period_start) < 60.0 || option_bool(OPT_FAST_RA))
|
if (difftime(now, context->ra_short_period_start) < 60.0)
|
||||||
/* range 5 - 20 */
|
/* range 5 - 20 */
|
||||||
context->ra_time = now + 5 + (rand16()/4400);
|
context->ra_time = now + 5 + (rand16()/4400);
|
||||||
else
|
else
|
||||||
/* range 3/4 - 1 times RA_INTERVAL */
|
{
|
||||||
context->ra_time = now + (3 * RA_INTERVAL)/4 + ((RA_INTERVAL * (unsigned int)rand16()) >> 18);
|
/* range 3/4 - 1 times MaxRtrAdvInterval */
|
||||||
|
unsigned int adv_interval = calc_interval(find_iface_param(iface_name));
|
||||||
|
context->ra_time = now + (3 * adv_interval)/4 + ((adv_interval * (unsigned int)rand16()) >> 18);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ra_interface *find_iface_param(char *iface)
|
||||||
|
{
|
||||||
|
struct ra_interface *ra;
|
||||||
|
|
||||||
|
for (ra = daemon->ra_interfaces; ra; ra = ra->next)
|
||||||
|
if (wildcard_match(ra->name, iface))
|
||||||
|
return ra;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int calc_interval(struct ra_interface *ra)
|
||||||
|
{
|
||||||
|
int interval = 600;
|
||||||
|
|
||||||
|
if (ra && ra->interval != 0)
|
||||||
|
{
|
||||||
|
interval = ra->interval;
|
||||||
|
if (interval > 1800)
|
||||||
|
interval = 1800;
|
||||||
|
else if (interval < 4)
|
||||||
|
interval = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (unsigned int)interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int calc_lifetime(struct ra_interface *ra)
|
||||||
|
{
|
||||||
|
int lifetime, interval = (int)calc_interval(ra);
|
||||||
|
|
||||||
|
if (!ra || ra->lifetime == -1) /* not specified */
|
||||||
|
lifetime = 3 * interval;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lifetime = ra->lifetime;
|
||||||
|
if (lifetime < interval && lifetime != 0)
|
||||||
|
lifetime = interval;
|
||||||
|
else if (lifetime > 9000)
|
||||||
|
lifetime = 9000;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (unsigned int)lifetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int calc_prio(struct ra_interface *ra)
|
||||||
|
{
|
||||||
|
if (ra)
|
||||||
|
return ra->prio;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+283
-173
@@ -513,15 +513,81 @@ struct macparm {
|
|||||||
size_t plen;
|
size_t plen;
|
||||||
union mysockaddr *l3;
|
union mysockaddr *l3;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *limit,
|
||||||
|
int optno, unsigned char *opt, size_t optlen)
|
||||||
|
{
|
||||||
|
unsigned char *lenp, *datap, *p;
|
||||||
|
int rdlen;
|
||||||
|
|
||||||
|
if (ntohs(header->arcount) == 0)
|
||||||
|
{
|
||||||
|
/* We are adding the pseudoheader */
|
||||||
|
if (!(p = skip_questions(header, plen)) ||
|
||||||
|
!(p = skip_section(p,
|
||||||
|
ntohs(header->ancount) + ntohs(header->nscount),
|
||||||
|
header, plen)))
|
||||||
|
return plen;
|
||||||
|
*p++ = 0; /* empty name */
|
||||||
|
PUTSHORT(T_OPT, p);
|
||||||
|
PUTSHORT(daemon->edns_pktsz, p); /* max packet length */
|
||||||
|
PUTLONG(0, p); /* extended RCODE */
|
||||||
|
lenp = p;
|
||||||
|
PUTSHORT(0, p); /* RDLEN */
|
||||||
|
rdlen = 0;
|
||||||
|
if (((ssize_t)optlen) > (limit - (p + 4)))
|
||||||
|
return plen; /* Too big */
|
||||||
|
header->arcount = htons(1);
|
||||||
|
datap = p;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i, is_sign;
|
||||||
|
unsigned short code, len;
|
||||||
|
|
||||||
|
if (ntohs(header->arcount) != 1 ||
|
||||||
|
!(p = find_pseudoheader(header, plen, NULL, NULL, &is_sign)) ||
|
||||||
|
is_sign ||
|
||||||
|
(!(p = skip_name(p, header, plen, 10))))
|
||||||
|
return plen;
|
||||||
|
|
||||||
|
p += 8; /* skip UDP length and RCODE */
|
||||||
|
|
||||||
|
lenp = p;
|
||||||
|
GETSHORT(rdlen, p);
|
||||||
|
if (!CHECK_LEN(header, p, plen, rdlen))
|
||||||
|
return plen; /* bad packet */
|
||||||
|
datap = p;
|
||||||
|
|
||||||
|
/* check if option already there */
|
||||||
|
for (i = 0; i + 4 < rdlen; i += len + 4)
|
||||||
|
{
|
||||||
|
GETSHORT(code, p);
|
||||||
|
GETSHORT(len, p);
|
||||||
|
if (code == optno)
|
||||||
|
return plen;
|
||||||
|
p += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((ssize_t)optlen) > (limit - (p + 4)))
|
||||||
|
return plen; /* Too big */
|
||||||
|
}
|
||||||
|
|
||||||
|
PUTSHORT(optno, p);
|
||||||
|
PUTSHORT(optlen, p);
|
||||||
|
memcpy(p, opt, optlen);
|
||||||
|
p += optlen;
|
||||||
|
|
||||||
|
PUTSHORT(p - datap, lenp);
|
||||||
|
return p - (unsigned char *)header;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *parmv)
|
static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *parmv)
|
||||||
{
|
{
|
||||||
struct macparm *parm = parmv;
|
struct macparm *parm = parmv;
|
||||||
int match = 0;
|
int match = 0;
|
||||||
unsigned short rdlen;
|
|
||||||
struct dns_header *header = parm->header;
|
|
||||||
unsigned char *lenp, *datap, *p;
|
|
||||||
|
|
||||||
if (family == parm->l3->sa.sa_family)
|
if (family == parm->l3->sa.sa_family)
|
||||||
{
|
{
|
||||||
if (family == AF_INET && memcmp (&parm->l3->in.sin_addr, addrp, INADDRSZ) == 0)
|
if (family == AF_INET && memcmp (&parm->l3->in.sin_addr, addrp, INADDRSZ) == 0)
|
||||||
@@ -535,72 +601,12 @@ static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *p
|
|||||||
|
|
||||||
if (!match)
|
if (!match)
|
||||||
return 1; /* continue */
|
return 1; /* continue */
|
||||||
|
|
||||||
if (ntohs(header->arcount) == 0)
|
|
||||||
{
|
|
||||||
/* We are adding the pseudoheader */
|
|
||||||
if (!(p = skip_questions(header, parm->plen)) ||
|
|
||||||
!(p = skip_section(p,
|
|
||||||
ntohs(header->ancount) + ntohs(header->nscount),
|
|
||||||
header, parm->plen)))
|
|
||||||
return 0;
|
|
||||||
*p++ = 0; /* empty name */
|
|
||||||
PUTSHORT(T_OPT, p);
|
|
||||||
PUTSHORT(PACKETSZ, p); /* max packet length - is 512 suitable default for non-EDNS0 resolvers? */
|
|
||||||
PUTLONG(0, p); /* extended RCODE */
|
|
||||||
lenp = p;
|
|
||||||
PUTSHORT(0, p); /* RDLEN */
|
|
||||||
rdlen = 0;
|
|
||||||
if (((ssize_t)maclen) > (parm->limit - (p + 4)))
|
|
||||||
return 0; /* Too big */
|
|
||||||
header->arcount = htons(1);
|
|
||||||
datap = p;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int i, is_sign;
|
|
||||||
unsigned short code, len;
|
|
||||||
|
|
||||||
if (ntohs(header->arcount) != 1 ||
|
|
||||||
!(p = find_pseudoheader(header, parm->plen, NULL, NULL, &is_sign)) ||
|
|
||||||
is_sign ||
|
|
||||||
(!(p = skip_name(p, header, parm->plen, 10))))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
p += 8; /* skip UDP length and RCODE */
|
|
||||||
|
|
||||||
lenp = p;
|
|
||||||
GETSHORT(rdlen, p);
|
|
||||||
if (!CHECK_LEN(header, p, parm->plen, rdlen))
|
|
||||||
return 0; /* bad packet */
|
|
||||||
datap = p;
|
|
||||||
|
|
||||||
/* check if option already there */
|
parm->plen = add_pseudoheader(parm->header, parm->plen, parm->limit, EDNS0_OPTION_MAC, (unsigned char *)mac, maclen);
|
||||||
for (i = 0; i + 4 < rdlen; i += len + 4)
|
|
||||||
{
|
|
||||||
GETSHORT(code, p);
|
|
||||||
GETSHORT(len, p);
|
|
||||||
if (code == EDNS0_OPTION_MAC)
|
|
||||||
return 0;
|
|
||||||
p += len;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((ssize_t)maclen) > (parm->limit - (p + 4)))
|
|
||||||
return 0; /* Too big */
|
|
||||||
}
|
|
||||||
|
|
||||||
PUTSHORT(EDNS0_OPTION_MAC, p);
|
|
||||||
PUTSHORT(maclen, p);
|
|
||||||
memcpy(p, mac, maclen);
|
|
||||||
p += maclen;
|
|
||||||
|
|
||||||
PUTSHORT(p - datap, lenp);
|
|
||||||
parm->plen = p - (unsigned char *)header;
|
|
||||||
|
|
||||||
return 0; /* done */
|
return 0; /* done */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t add_mac(struct dns_header *header, size_t plen, char *limit, union mysockaddr *l3)
|
size_t add_mac(struct dns_header *header, size_t plen, char *limit, union mysockaddr *l3)
|
||||||
{
|
{
|
||||||
struct macparm parm;
|
struct macparm parm;
|
||||||
@@ -621,9 +627,104 @@ size_t add_mac(struct dns_header *header, size_t plen, char *limit, union mysock
|
|||||||
return parm.plen;
|
return parm.plen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct subnet_opt {
|
||||||
|
u16 family;
|
||||||
|
u8 source_netmask, scope_netmask;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
u8 addr[IN6ADDRSZ];
|
||||||
|
#else
|
||||||
|
u8 addr[INADDRSZ];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
|
||||||
|
{
|
||||||
|
/* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
|
||||||
|
|
||||||
|
int len;
|
||||||
|
void *addrp;
|
||||||
|
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
if (source->sa.sa_family == AF_INET6)
|
||||||
|
{
|
||||||
|
opt->family = htons(2);
|
||||||
|
opt->source_netmask = daemon->addr6_netmask;
|
||||||
|
addrp = &source->in6.sin6_addr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
opt->family = htons(1);
|
||||||
|
opt->source_netmask = daemon->addr4_netmask;
|
||||||
|
addrp = &source->in.sin_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
opt->scope_netmask = 0;
|
||||||
|
len = 0;
|
||||||
|
|
||||||
|
if (opt->source_netmask != 0)
|
||||||
|
{
|
||||||
|
len = ((opt->source_netmask - 1) >> 3) + 1;
|
||||||
|
memcpy(opt->addr, addrp, len);
|
||||||
|
if (opt->source_netmask & 7)
|
||||||
|
opt->addr[len-1] &= 0xff << (8 - (opt->source_netmask & 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
return len + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t add_source_addr(struct dns_header *header, size_t plen, char *limit, union mysockaddr *source)
|
||||||
|
{
|
||||||
|
/* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
|
||||||
|
|
||||||
|
int len;
|
||||||
|
struct subnet_opt opt;
|
||||||
|
|
||||||
|
len = calc_subnet_opt(&opt, source);
|
||||||
|
return add_pseudoheader(header, plen, (unsigned char *)limit, EDNS0_OPTION_CLIENT_SUBNET, (unsigned char *)&opt, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer)
|
||||||
|
{
|
||||||
|
/* Section 9.2, Check that subnet option in reply matches. */
|
||||||
|
|
||||||
|
|
||||||
|
int len, calc_len;
|
||||||
|
struct subnet_opt opt;
|
||||||
|
unsigned char *p;
|
||||||
|
int code, i, rdlen;
|
||||||
|
|
||||||
|
calc_len = calc_subnet_opt(&opt, peer);
|
||||||
|
|
||||||
|
if (!(p = skip_name(pseudoheader, header, plen, 10)))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
p += 8; /* skip UDP length and RCODE */
|
||||||
|
|
||||||
|
GETSHORT(rdlen, p);
|
||||||
|
if (!CHECK_LEN(header, p, plen, rdlen))
|
||||||
|
return 1; /* bad packet */
|
||||||
|
|
||||||
|
/* check if option there */
|
||||||
|
for (i = 0; i + 4 < rdlen; i += len + 4)
|
||||||
|
{
|
||||||
|
GETSHORT(code, p);
|
||||||
|
GETSHORT(len, p);
|
||||||
|
if (code == EDNS0_OPTION_CLIENT_SUBNET)
|
||||||
|
{
|
||||||
|
/* make sure this doesn't mismatch. */
|
||||||
|
opt.scope_netmask = p[3];
|
||||||
|
if (len != calc_len || memcmp(p, &opt, len) != 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
p += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* is addr in the non-globally-routed IP space? */
|
/* is addr in the non-globally-routed IP space? */
|
||||||
static int private_net(struct in_addr addr, int ban_localhost)
|
int private_net(struct in_addr addr, int ban_localhost)
|
||||||
{
|
{
|
||||||
in_addr_t ip_addr = ntohl(addr.s_addr);
|
in_addr_t ip_addr = ntohl(addr.s_addr);
|
||||||
|
|
||||||
@@ -910,91 +1011,88 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
|
|||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!(flags & F_NXDOMAIN))
|
cname_loop1:
|
||||||
|
if (!(p1 = skip_questions(header, qlen)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (j = ntohs(header->ancount); j != 0; j--)
|
||||||
{
|
{
|
||||||
cname_loop1:
|
if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
|
||||||
if (!(p1 = skip_questions(header, qlen)))
|
return 0; /* bad packet */
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (j = ntohs(header->ancount); j != 0; j--)
|
GETSHORT(aqtype, p1);
|
||||||
|
GETSHORT(aqclass, p1);
|
||||||
|
GETLONG(attl, p1);
|
||||||
|
if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
|
||||||
{
|
{
|
||||||
if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
|
(p1) -= 4;
|
||||||
return 0; /* bad packet */
|
PUTLONG(daemon->max_ttl, p1);
|
||||||
|
}
|
||||||
GETSHORT(aqtype, p1);
|
GETSHORT(ardlen, p1);
|
||||||
GETSHORT(aqclass, p1);
|
endrr = p1+ardlen;
|
||||||
GETLONG(attl, p1);
|
|
||||||
if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
|
if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype))
|
||||||
|
{
|
||||||
|
if (aqtype == T_CNAME)
|
||||||
{
|
{
|
||||||
(p1) -= 4;
|
if (!cname_count--)
|
||||||
PUTLONG(daemon->max_ttl, p1);
|
return 0; /* looped CNAMES */
|
||||||
}
|
newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD);
|
||||||
GETSHORT(ardlen, p1);
|
if (newc)
|
||||||
endrr = p1+ardlen;
|
|
||||||
|
|
||||||
if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype))
|
|
||||||
{
|
|
||||||
if (aqtype == T_CNAME)
|
|
||||||
{
|
{
|
||||||
if (!cname_count--)
|
newc->addr.cname.target.cache = NULL;
|
||||||
return 0; /* looped CNAMES */
|
if (cpp)
|
||||||
newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD);
|
|
||||||
if (newc)
|
|
||||||
{
|
{
|
||||||
newc->addr.cname.cache = NULL;
|
cpp->addr.cname.target.cache = newc;
|
||||||
if (cpp)
|
|
||||||
{
|
|
||||||
cpp->addr.cname.cache = newc;
|
|
||||||
cpp->addr.cname.uid = newc->uid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cpp = newc;
|
|
||||||
if (attl < cttl)
|
|
||||||
cttl = attl;
|
|
||||||
|
|
||||||
if (!extract_name(header, qlen, &p1, name, 1, 0))
|
|
||||||
return 0;
|
|
||||||
goto cname_loop1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
found = 1;
|
|
||||||
|
|
||||||
/* copy address into aligned storage */
|
|
||||||
if (!CHECK_LEN(header, p1, qlen, addrlen))
|
|
||||||
return 0; /* bad packet */
|
|
||||||
memcpy(&addr, p1, addrlen);
|
|
||||||
|
|
||||||
/* check for returned address in private space */
|
|
||||||
if (check_rebind &&
|
|
||||||
(flags & F_IPV4) &&
|
|
||||||
private_net(addr.addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
#ifdef HAVE_IPSET
|
|
||||||
if (ipsets && (flags & (F_IPV4 | F_IPV6)))
|
|
||||||
{
|
|
||||||
ipsets_cur = ipsets;
|
|
||||||
while (*ipsets_cur)
|
|
||||||
add_to_ipset(*ipsets_cur++, &addr, flags, 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD);
|
|
||||||
if (newc && cpp)
|
|
||||||
{
|
|
||||||
cpp->addr.cname.cache = newc;
|
|
||||||
cpp->addr.cname.uid = newc->uid;
|
cpp->addr.cname.uid = newc->uid;
|
||||||
}
|
}
|
||||||
cpp = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cpp = newc;
|
||||||
|
if (attl < cttl)
|
||||||
|
cttl = attl;
|
||||||
|
|
||||||
|
if (!extract_name(header, qlen, &p1, name, 1, 0))
|
||||||
|
return 0;
|
||||||
|
goto cname_loop1;
|
||||||
|
}
|
||||||
|
else if (!(flags & F_NXDOMAIN))
|
||||||
|
{
|
||||||
|
found = 1;
|
||||||
|
|
||||||
|
/* copy address into aligned storage */
|
||||||
|
if (!CHECK_LEN(header, p1, qlen, addrlen))
|
||||||
|
return 0; /* bad packet */
|
||||||
|
memcpy(&addr, p1, addrlen);
|
||||||
|
|
||||||
|
/* check for returned address in private space */
|
||||||
|
if (check_rebind &&
|
||||||
|
(flags & F_IPV4) &&
|
||||||
|
private_net(addr.addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
#ifdef HAVE_IPSET
|
||||||
|
if (ipsets && (flags & (F_IPV4 | F_IPV6)))
|
||||||
|
{
|
||||||
|
ipsets_cur = ipsets;
|
||||||
|
while (*ipsets_cur)
|
||||||
|
add_to_ipset(*ipsets_cur++, &addr, flags, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD);
|
||||||
|
if (newc && cpp)
|
||||||
|
{
|
||||||
|
cpp->addr.cname.target.cache = newc;
|
||||||
|
cpp->addr.cname.uid = newc->uid;
|
||||||
|
}
|
||||||
|
cpp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
p1 = endrr;
|
|
||||||
if (!CHECK_LEN(header, p1, qlen, 0))
|
|
||||||
return 0; /* bad packet */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p1 = endrr;
|
||||||
|
if (!CHECK_LEN(header, p1, qlen, 0))
|
||||||
|
return 0; /* bad packet */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found && !option_bool(OPT_NO_NEG))
|
if (!found && !option_bool(OPT_NO_NEG))
|
||||||
@@ -1011,7 +1109,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
|
|||||||
newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags);
|
newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags);
|
||||||
if (newc && cpp)
|
if (newc && cpp)
|
||||||
{
|
{
|
||||||
cpp->addr.cname.cache = newc;
|
cpp->addr.cname.target.cache = newc;
|
||||||
cpp->addr.cname.uid = newc->uid;
|
cpp->addr.cname.uid = newc->uid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1123,7 +1221,7 @@ int check_for_local_domain(char *name, time_t now)
|
|||||||
struct naptr *naptr;
|
struct naptr *naptr;
|
||||||
|
|
||||||
if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_CNAME)) &&
|
if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_CNAME)) &&
|
||||||
(crecp->flags & (F_HOSTS | F_DHCP)))
|
(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
for (naptr = daemon->naptr; naptr; naptr = naptr->next)
|
for (naptr = daemon->naptr; naptr; naptr = naptr->next)
|
||||||
@@ -1452,8 +1550,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
{
|
{
|
||||||
struct addrlist *addrlist;
|
struct addrlist *addrlist;
|
||||||
|
|
||||||
for (addrlist = intr->addr4; addrlist; addrlist = addrlist->next)
|
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
|
||||||
if (addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr)
|
if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (addrlist)
|
if (addrlist)
|
||||||
@@ -1468,8 +1566,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
{
|
{
|
||||||
struct addrlist *addrlist;
|
struct addrlist *addrlist;
|
||||||
|
|
||||||
for (addrlist = intr->addr6; addrlist; addrlist = addrlist->next)
|
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
|
||||||
if (IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6))
|
if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (addrlist)
|
if (addrlist)
|
||||||
@@ -1619,7 +1717,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* interface name stuff */
|
/* interface name stuff */
|
||||||
|
intname_restart:
|
||||||
for (intr = daemon->int_names; intr; intr = intr->next)
|
for (intr = daemon->int_names; intr; intr = intr->next)
|
||||||
if (hostname_isequal(name, intr->name))
|
if (hostname_isequal(name, intr->name))
|
||||||
break;
|
break;
|
||||||
@@ -1627,29 +1725,35 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
if (intr)
|
if (intr)
|
||||||
{
|
{
|
||||||
struct addrlist *addrlist;
|
struct addrlist *addrlist;
|
||||||
|
int gotit = 0;
|
||||||
|
|
||||||
enumerate_interfaces(0);
|
enumerate_interfaces(0);
|
||||||
|
|
||||||
addrlist = intr->addr4;
|
for (intr = daemon->int_names; intr; intr = intr->next)
|
||||||
#ifdef HAVE_IPV6
|
if (hostname_isequal(name, intr->name))
|
||||||
if (type == T_AAAA)
|
{
|
||||||
addrlist = intr->addr6;
|
ans = 1;
|
||||||
#endif
|
if (!dryrun)
|
||||||
ans = 1;
|
|
||||||
if (!dryrun)
|
|
||||||
{
|
|
||||||
if (!addrlist)
|
|
||||||
log_query(F_FORWARD | F_CONFIG | flag | F_NEG, name, NULL, NULL);
|
|
||||||
else
|
|
||||||
for (; addrlist; addrlist = addrlist->next)
|
|
||||||
{
|
{
|
||||||
log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
|
|
||||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
|
||||||
daemon->local_ttl, NULL, type, C_IN,
|
#ifdef HAVE_IPV6
|
||||||
type == T_A ? "4" : "6", &addrlist->addr))
|
if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == type)
|
||||||
anscount++;
|
#endif
|
||||||
|
{
|
||||||
|
gotit = 1;
|
||||||
|
log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
|
||||||
|
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||||
|
daemon->local_ttl, NULL, type, C_IN,
|
||||||
|
type == T_A ? "4" : "6", &addrlist->addr))
|
||||||
|
anscount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!dryrun && !gotit)
|
||||||
|
log_query(F_FORWARD | F_CONFIG | flag | F_NEG, name, NULL, NULL);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1678,22 +1782,28 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
{
|
{
|
||||||
/* don't answer wildcard queries with data not from /etc/hosts
|
/* don't answer wildcard queries with data not from /etc/hosts
|
||||||
or DHCP leases */
|
or DHCP leases */
|
||||||
if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
|
if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (crecp->flags & F_CNAME)
|
if (crecp->flags & F_CNAME)
|
||||||
{
|
{
|
||||||
|
char *cname_target = cache_get_cname_target(crecp);
|
||||||
|
|
||||||
if (!dryrun)
|
if (!dryrun)
|
||||||
{
|
{
|
||||||
log_query(crecp->flags, name, NULL, record_source(crecp->uid));
|
log_query(crecp->flags, name, NULL, record_source(crecp->uid));
|
||||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||||
crec_ttl(crecp, now), &nameoffset,
|
crec_ttl(crecp, now), &nameoffset,
|
||||||
T_CNAME, C_IN, "d", cache_get_name(crecp->addr.cname.cache)))
|
T_CNAME, C_IN, "d", cname_target))
|
||||||
anscount++;
|
anscount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(name, cache_get_name(crecp->addr.cname.cache));
|
strcpy(name, cname_target);
|
||||||
goto cname_restart;
|
/* check if target interface_name */
|
||||||
|
if (crecp->addr.cname.uid == -1)
|
||||||
|
goto intname_restart;
|
||||||
|
else
|
||||||
|
goto cname_restart;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crecp->flags & F_NEG)
|
if (crecp->flags & F_NEG)
|
||||||
@@ -1747,7 +1857,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
if (qtype == T_CNAME || qtype == T_ANY)
|
if (qtype == T_CNAME || qtype == T_ANY)
|
||||||
{
|
{
|
||||||
if ((crecp = cache_find_by_name(NULL, name, now, F_CNAME)) &&
|
if ((crecp = cache_find_by_name(NULL, name, now, F_CNAME)) &&
|
||||||
(qtype == T_CNAME || (crecp->flags & (F_HOSTS | F_DHCP))))
|
(qtype == T_CNAME || (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))))
|
||||||
{
|
{
|
||||||
ans = 1;
|
ans = 1;
|
||||||
if (!dryrun)
|
if (!dryrun)
|
||||||
@@ -1755,7 +1865,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
log_query(crecp->flags, name, NULL, record_source(crecp->uid));
|
log_query(crecp->flags, name, NULL, record_source(crecp->uid));
|
||||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||||
crec_ttl(crecp, now), &nameoffset,
|
crec_ttl(crecp, now), &nameoffset,
|
||||||
T_CNAME, C_IN, "d", cache_get_name(crecp->addr.cname.cache)))
|
T_CNAME, C_IN, "d", cache_get_cname_target(crecp)))
|
||||||
anscount++;
|
anscount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1928,7 +2038,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
if (trunc)
|
if (trunc)
|
||||||
header->hb3 |= HB3_TC;
|
header->hb3 |= HB3_TC;
|
||||||
|
|
||||||
if (anscount == 0 && nxdomain)
|
if (nxdomain)
|
||||||
SET_RCODE(header, NXDOMAIN);
|
SET_RCODE(header, NXDOMAIN);
|
||||||
else
|
else
|
||||||
SET_RCODE(header, NOERROR); /* no error */
|
SET_RCODE(header, NOERROR); /* no error */
|
||||||
|
|||||||
+23
-18
@@ -34,7 +34,7 @@ static void option_put_string(struct dhcp_packet *mess, unsigned char *end,
|
|||||||
static struct in_addr option_addr(unsigned char *opt);
|
static struct in_addr option_addr(unsigned char *opt);
|
||||||
static unsigned int option_uint(unsigned char *opt, int i, int size);
|
static unsigned int option_uint(unsigned char *opt, int i, int size);
|
||||||
static void log_packet(char *type, void *addr, unsigned char *ext_mac,
|
static void log_packet(char *type, void *addr, unsigned char *ext_mac,
|
||||||
int mac_len, char *interface, char *string, u32 xid);
|
int mac_len, char *interface, char *string, char *err, u32 xid);
|
||||||
static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize);
|
static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize);
|
||||||
static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize);
|
static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize);
|
||||||
static size_t dhcp_packet_size(struct dhcp_packet *mess, unsigned char *agent_id, unsigned char *real_end);
|
static size_t dhcp_packet_size(struct dhcp_packet *mess, unsigned char *agent_id, unsigned char *real_end);
|
||||||
@@ -610,7 +610,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log_packet("BOOTP", logaddr, mess->chaddr, mess->hlen, iface_name, message, mess->xid);
|
log_packet("BOOTP", logaddr, mess->chaddr, mess->hlen, iface_name, NULL, message, mess->xid);
|
||||||
|
|
||||||
return message ? 0 : dhcp_packet_size(mess, agent_id, real_end);
|
return message ? 0 : dhcp_packet_size(mess, agent_id, real_end);
|
||||||
}
|
}
|
||||||
@@ -827,7 +827,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
opt71.next = daemon->dhcp_opts;
|
opt71.next = daemon->dhcp_opts;
|
||||||
do_encap_opts(&opt71, OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
|
do_encap_opts(&opt71, OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
|
||||||
|
|
||||||
log_packet("PXE", &mess->yiaddr, emac, emac_len, iface_name, (char *)mess->file, mess->xid);
|
log_packet("PXE", &mess->yiaddr, emac, emac_len, iface_name, (char *)mess->file, NULL, mess->xid);
|
||||||
log_tags(tagif_netid, ntohl(mess->xid));
|
log_tags(tagif_netid, ntohl(mess->xid));
|
||||||
return dhcp_packet_size(mess, agent_id, real_end);
|
return dhcp_packet_size(mess, agent_id, real_end);
|
||||||
}
|
}
|
||||||
@@ -887,7 +887,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
prune_vendor_opts(tagif_netid);
|
prune_vendor_opts(tagif_netid);
|
||||||
do_encap_opts(pxe_opts(pxearch, tagif_netid, context->local, now), OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
|
do_encap_opts(pxe_opts(pxearch, tagif_netid, context->local, now), OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
|
||||||
|
|
||||||
log_packet("PXE", NULL, emac, emac_len, iface_name, ignore ? "proxy-ignored" : "proxy", mess->xid);
|
log_packet("PXE", NULL, emac, emac_len, iface_name, ignore ? "proxy-ignored" : "proxy", NULL, mess->xid);
|
||||||
log_tags(tagif_netid, ntohl(mess->xid));
|
log_tags(tagif_netid, ntohl(mess->xid));
|
||||||
return ignore ? 0 : dhcp_packet_size(mess, agent_id, real_end);
|
return ignore ? 0 : dhcp_packet_size(mess, agent_id, real_end);
|
||||||
}
|
}
|
||||||
@@ -919,7 +919,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
if (!(opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ)))
|
if (!(opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
log_packet("DHCPDECLINE", option_ptr(opt, 0), emac, emac_len, iface_name, daemon->dhcp_buff, mess->xid);
|
log_packet("DHCPDECLINE", option_ptr(opt, 0), emac, emac_len, iface_name, NULL, daemon->dhcp_buff, mess->xid);
|
||||||
|
|
||||||
if (lease && lease->addr.s_addr == option_addr(opt).s_addr)
|
if (lease && lease->addr.s_addr == option_addr(opt).s_addr)
|
||||||
lease_prune(lease, now);
|
lease_prune(lease, now);
|
||||||
@@ -951,7 +951,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
else
|
else
|
||||||
message = _("unknown lease");
|
message = _("unknown lease");
|
||||||
|
|
||||||
log_packet("DHCPRELEASE", &mess->ciaddr, emac, emac_len, iface_name, message, mess->xid);
|
log_packet("DHCPRELEASE", &mess->ciaddr, emac, emac_len, iface_name, NULL, message, mess->xid);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -1015,7 +1015,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
message = _("no address available");
|
message = _("no address available");
|
||||||
}
|
}
|
||||||
|
|
||||||
log_packet("DHCPDISCOVER", opt ? option_ptr(opt, 0) : NULL, emac, emac_len, iface_name, message, mess->xid);
|
log_packet("DHCPDISCOVER", opt ? option_ptr(opt, 0) : NULL, emac, emac_len, iface_name, NULL, message, mess->xid);
|
||||||
|
|
||||||
if (message || !(context = narrow_context(context, mess->yiaddr, tagif_netid)))
|
if (message || !(context = narrow_context(context, mess->yiaddr, tagif_netid)))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1028,7 +1028,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
|
|
||||||
log_tags(tagif_netid, ntohl(mess->xid));
|
log_tags(tagif_netid, ntohl(mess->xid));
|
||||||
|
|
||||||
log_packet("DHCPOFFER" , &mess->yiaddr, emac, emac_len, iface_name, NULL, mess->xid);
|
log_packet("DHCPOFFER" , &mess->yiaddr, emac, emac_len, iface_name, NULL, NULL, mess->xid);
|
||||||
|
|
||||||
time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4));
|
time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4));
|
||||||
clear_packet(mess, end);
|
clear_packet(mess, end);
|
||||||
@@ -1144,7 +1144,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
mess->yiaddr = mess->ciaddr;
|
mess->yiaddr = mess->ciaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_packet("DHCPREQUEST", &mess->yiaddr, emac, emac_len, iface_name, NULL, mess->xid);
|
log_packet("DHCPREQUEST", &mess->yiaddr, emac, emac_len, iface_name, NULL, NULL, mess->xid);
|
||||||
|
|
||||||
if (!message)
|
if (!message)
|
||||||
{
|
{
|
||||||
@@ -1216,7 +1216,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
|
|
||||||
if (message)
|
if (message)
|
||||||
{
|
{
|
||||||
log_packet("DHCPNAK", &mess->yiaddr, emac, emac_len, iface_name, message, mess->xid);
|
log_packet("DHCPNAK", &mess->yiaddr, emac, emac_len, iface_name, NULL, message, mess->xid);
|
||||||
|
|
||||||
mess->yiaddr.s_addr = 0;
|
mess->yiaddr.s_addr = 0;
|
||||||
clear_packet(mess, end);
|
clear_packet(mess, end);
|
||||||
@@ -1355,7 +1355,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
else
|
else
|
||||||
override = lease->override;
|
override = lease->override;
|
||||||
|
|
||||||
log_packet("DHCPACK", &mess->yiaddr, emac, emac_len, iface_name, hostname, mess->xid);
|
log_packet("DHCPACK", &mess->yiaddr, emac, emac_len, iface_name, hostname, NULL, mess->xid);
|
||||||
|
|
||||||
clear_packet(mess, end);
|
clear_packet(mess, end);
|
||||||
option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
|
option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
|
||||||
@@ -1378,7 +1378,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
if (ignore || have_config(config, CONFIG_DISABLE))
|
if (ignore || have_config(config, CONFIG_DISABLE))
|
||||||
message = _("ignored");
|
message = _("ignored");
|
||||||
|
|
||||||
log_packet("DHCPINFORM", &mess->ciaddr, emac, emac_len, iface_name, message, mess->xid);
|
log_packet("DHCPINFORM", &mess->ciaddr, emac, emac_len, iface_name, message, NULL, mess->xid);
|
||||||
|
|
||||||
if (message || mess->ciaddr.s_addr == 0)
|
if (message || mess->ciaddr.s_addr == 0)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1404,7 +1404,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
|
|
||||||
log_tags(tagif_netid, ntohl(mess->xid));
|
log_tags(tagif_netid, ntohl(mess->xid));
|
||||||
|
|
||||||
log_packet("DHCPACK", &mess->ciaddr, emac, emac_len, iface_name, hostname, mess->xid);
|
log_packet("DHCPACK", &mess->ciaddr, emac, emac_len, iface_name, hostname, NULL, mess->xid);
|
||||||
|
|
||||||
if (lease)
|
if (lease)
|
||||||
{
|
{
|
||||||
@@ -1538,10 +1538,13 @@ static void add_extradata_opt(struct dhcp_lease *lease, unsigned char *opt)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void log_packet(char *type, void *addr, unsigned char *ext_mac,
|
static void log_packet(char *type, void *addr, unsigned char *ext_mac,
|
||||||
int mac_len, char *interface, char *string, u32 xid)
|
int mac_len, char *interface, char *string, char *err, u32 xid)
|
||||||
{
|
{
|
||||||
struct in_addr a;
|
struct in_addr a;
|
||||||
|
|
||||||
|
if (!err && !option_bool(OPT_LOG_OPTS) && option_bool(OPT_QUIET_DHCP))
|
||||||
|
return;
|
||||||
|
|
||||||
/* addr may be misaligned */
|
/* addr may be misaligned */
|
||||||
if (addr)
|
if (addr)
|
||||||
memcpy(&a, addr, sizeof(a));
|
memcpy(&a, addr, sizeof(a));
|
||||||
@@ -1549,22 +1552,24 @@ static void log_packet(char *type, void *addr, unsigned char *ext_mac,
|
|||||||
print_mac(daemon->namebuff, ext_mac, mac_len);
|
print_mac(daemon->namebuff, ext_mac, mac_len);
|
||||||
|
|
||||||
if(option_bool(OPT_LOG_OPTS))
|
if(option_bool(OPT_LOG_OPTS))
|
||||||
my_syslog(MS_DHCP | LOG_INFO, "%u %s(%s) %s%s%s %s",
|
my_syslog(MS_DHCP | LOG_INFO, "%u %s(%s) %s%s%s %s%s",
|
||||||
ntohl(xid),
|
ntohl(xid),
|
||||||
type,
|
type,
|
||||||
interface,
|
interface,
|
||||||
addr ? inet_ntoa(a) : "",
|
addr ? inet_ntoa(a) : "",
|
||||||
addr ? " " : "",
|
addr ? " " : "",
|
||||||
daemon->namebuff,
|
daemon->namebuff,
|
||||||
string ? string : "");
|
string ? string : "",
|
||||||
|
err ? err : "");
|
||||||
else
|
else
|
||||||
my_syslog(MS_DHCP | LOG_INFO, "%s(%s) %s%s%s %s",
|
my_syslog(MS_DHCP | LOG_INFO, "%s(%s) %s%s%s %s%s",
|
||||||
type,
|
type,
|
||||||
interface,
|
interface,
|
||||||
addr ? inet_ntoa(a) : "",
|
addr ? inet_ntoa(a) : "",
|
||||||
addr ? " " : "",
|
addr ? " " : "",
|
||||||
daemon->namebuff,
|
daemon->namebuff,
|
||||||
string ? string : "");
|
string ? string : "",
|
||||||
|
err ? err : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_options(unsigned char *start, u32 xid)
|
static void log_options(unsigned char *start, u32 xid)
|
||||||
|
|||||||
+31
-15
@@ -41,6 +41,7 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
|
|||||||
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, void *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_opts(int nest, unsigned int xid, void *start_opts, void *end_opts);
|
||||||
static void log6_packet(struct state *state, char *type, struct in6_addr *addr, char *string);
|
static void log6_packet(struct state *state, char *type, struct in6_addr *addr, char *string);
|
||||||
|
static void log6_quiet(struct state *state, char *type, struct in6_addr *addr, char *string);
|
||||||
static void *opt6_find (void *opts, void *end, unsigned int search, unsigned int minsize);
|
static void *opt6_find (void *opts, void *end, unsigned int search, unsigned int minsize);
|
||||||
static void *opt6_next(void *opts, void *end);
|
static void *opt6_next(void *opts, void *end);
|
||||||
static unsigned int opt6_uint(unsigned char *opt, int offset, int size);
|
static unsigned int opt6_uint(unsigned char *opt, int offset, int size);
|
||||||
@@ -66,6 +67,10 @@ static void calculate_times(struct dhcp_context *context, unsigned int *min_time
|
|||||||
#define opt6_type(opt) (opt6_uint(opt, -4, 2))
|
#define opt6_type(opt) (opt6_uint(opt, -4, 2))
|
||||||
#define opt6_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[4+(i)]))
|
#define opt6_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[4+(i)]))
|
||||||
|
|
||||||
|
#define opt6_user_vendor_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[2+(i)]))
|
||||||
|
#define opt6_user_vendor_len(opt) ((int)(opt6_uint(opt, -4, 2)))
|
||||||
|
#define opt6_user_vendor_next(opt, end) (opt6_next(((void *) opt) - 2, end))
|
||||||
|
|
||||||
|
|
||||||
unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name,
|
unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name,
|
||||||
struct in6_addr *fallback, size_t sz, struct in6_addr *client_addr, time_t now)
|
struct in6_addr *fallback, size_t sz, struct in6_addr *client_addr, time_t now)
|
||||||
@@ -355,9 +360,10 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
|||||||
offset = 4;
|
offset = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (enc_opt = opt6_ptr(opt, offset); enc_opt; enc_opt = opt6_next(enc_opt, enc_end))
|
/* Note that format if user/vendor classes is different to DHCP options - no option types. */
|
||||||
for (i = 0; i <= (opt6_len(enc_opt) - vendor->len); i++)
|
for (enc_opt = opt6_ptr(opt, offset); enc_opt; enc_opt = opt6_user_vendor_next(enc_opt, enc_end))
|
||||||
if (memcmp(vendor->data, opt6_ptr(enc_opt, i), vendor->len) == 0)
|
for (i = 0; i <= (opt6_user_vendor_len(enc_opt) - vendor->len); i++)
|
||||||
|
if (memcmp(vendor->data, opt6_user_vendor_ptr(enc_opt, i), vendor->len) == 0)
|
||||||
{
|
{
|
||||||
vendor->netid.next = state->tags;
|
vendor->netid.next = state->tags;
|
||||||
state->tags = &vendor->netid;
|
state->tags = &vendor->netid;
|
||||||
@@ -590,7 +596,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
|||||||
end_opt6(o);
|
end_opt6(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
log6_packet(state, "DHCPSOLICIT", NULL, ignore ? _("ignored") : NULL);
|
log6_quiet(state, "DHCPSOLICIT", NULL, ignore ? _("ignored") : NULL);
|
||||||
|
|
||||||
request_no_address:
|
request_no_address:
|
||||||
solicit_tags = tagif;
|
solicit_tags = tagif;
|
||||||
@@ -758,7 +764,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Return addresses for all valid contexts which don't yet have one */
|
/* Return addresses for all valid contexts which don't yet have one */
|
||||||
while ((c = address6_allocate(state->context, state->clid, state->clid_len, state->iaid, ia_counter, solicit_tags, plain_range, &addr)))
|
while ((c = address6_allocate(state->context, state->clid, state->clid_len, state->ia_type == OPTION6_IA_TA,
|
||||||
|
state->iaid, ia_counter, solicit_tags, plain_range, &addr)))
|
||||||
{
|
{
|
||||||
#ifdef OPTION6_PREFIX_CLASS
|
#ifdef OPTION6_PREFIX_CLASS
|
||||||
if (dump_all_prefix_classes && state->ia_type == OPTION6_IA_NA)
|
if (dump_all_prefix_classes && state->ia_type == OPTION6_IA_NA)
|
||||||
@@ -810,7 +817,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
|||||||
*outmsgtypep = DHCP6REPLY;
|
*outmsgtypep = DHCP6REPLY;
|
||||||
state->lease_allocate = 1;
|
state->lease_allocate = 1;
|
||||||
|
|
||||||
log6_packet(state, "DHCPREQUEST", NULL, ignore ? _("ignored") : NULL);
|
log6_quiet(state, "DHCPREQUEST", NULL, ignore ? _("ignored") : NULL);
|
||||||
|
|
||||||
if (ignore)
|
if (ignore)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -923,7 +930,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
|||||||
/* set reply message type */
|
/* set reply message type */
|
||||||
*outmsgtypep = DHCP6REPLY;
|
*outmsgtypep = DHCP6REPLY;
|
||||||
|
|
||||||
log6_packet(state, "DHCPRENEW", NULL, NULL);
|
log6_quiet(state, "DHCPRENEW", NULL, NULL);
|
||||||
|
|
||||||
for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
|
for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
|
||||||
{
|
{
|
||||||
@@ -1006,8 +1013,11 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
|||||||
message = _("address invalid");
|
message = _("address invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
log6_packet(state, "DHCPREPLY", req_addr, message);
|
if (message)
|
||||||
|
log6_packet(state, "DHCPREPLY", req_addr, message);
|
||||||
|
else
|
||||||
|
log6_quiet(state, "DHCPREPLY", req_addr, message);
|
||||||
|
|
||||||
o1 = new_opt6(OPTION6_IAADDR);
|
o1 = new_opt6(OPTION6_IAADDR);
|
||||||
put_opt6(req_addr, sizeof(*req_addr));
|
put_opt6(req_addr, sizeof(*req_addr));
|
||||||
put_opt6_long(preferred_time);
|
put_opt6_long(preferred_time);
|
||||||
@@ -1029,7 +1039,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
|||||||
/* set reply message type */
|
/* set reply message type */
|
||||||
*outmsgtypep = DHCP6REPLY;
|
*outmsgtypep = DHCP6REPLY;
|
||||||
|
|
||||||
log6_packet(state, "DHCPCONFIRM", NULL, NULL);
|
log6_quiet(state, "DHCPCONFIRM", NULL, NULL);
|
||||||
|
|
||||||
for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
|
for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
|
||||||
{
|
{
|
||||||
@@ -1050,7 +1060,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
log6_packet(state, "DHCPREPLY", req_addr, state->hostname);
|
log6_quiet(state, "DHCPREPLY", req_addr, state->hostname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1079,7 +1089,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
|||||||
else
|
else
|
||||||
state->send_domain = get_domain6(NULL);
|
state->send_domain = get_domain6(NULL);
|
||||||
|
|
||||||
log6_packet(state, "DHCPINFORMATION-REQUEST", NULL, ignore ? _("ignored") : state->hostname);
|
log6_quiet(state, "DHCPINFORMATION-REQUEST", NULL, ignore ? _("ignored") : state->hostname);
|
||||||
if (ignore)
|
if (ignore)
|
||||||
return 0;
|
return 0;
|
||||||
*outmsgtypep = DHCP6REPLY;
|
*outmsgtypep = DHCP6REPLY;
|
||||||
@@ -1093,7 +1103,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
|||||||
/* set reply message type */
|
/* set reply message type */
|
||||||
*outmsgtypep = DHCP6REPLY;
|
*outmsgtypep = DHCP6REPLY;
|
||||||
|
|
||||||
log6_packet(state, "DHCPRELEASE", NULL, NULL);
|
log6_quiet(state, "DHCPRELEASE", NULL, NULL);
|
||||||
|
|
||||||
for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
|
for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
|
||||||
{
|
{
|
||||||
@@ -1155,7 +1165,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
|||||||
/* set reply message type */
|
/* set reply message type */
|
||||||
*outmsgtypep = DHCP6REPLY;
|
*outmsgtypep = DHCP6REPLY;
|
||||||
|
|
||||||
log6_packet(state, "DHCPDECLINE", NULL, NULL);
|
log6_quiet(state, "DHCPDECLINE", NULL, NULL);
|
||||||
|
|
||||||
for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
|
for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
|
||||||
{
|
{
|
||||||
@@ -1605,7 +1615,7 @@ static void add_address(struct state *state, struct dhcp_context *context, unsig
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log6_packet(state, state->lease_allocate ? "DHCPREPLY" : "DHCPADVERTISE", addr, state->hostname);
|
log6_quiet(state, state->lease_allocate ? "DHCPREPLY" : "DHCPADVERTISE", addr, state->hostname);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1875,6 +1885,12 @@ static void log6_opts(int nest, unsigned int xid, void *start_opts, void *end_op
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void log6_quiet(struct state *state, char *type, struct in6_addr *addr, char *string)
|
||||||
|
{
|
||||||
|
if (option_bool(OPT_LOG_OPTS) || !option_bool(OPT_QUIET_DHCP6))
|
||||||
|
log6_packet(state, type, addr, string);
|
||||||
|
}
|
||||||
|
|
||||||
static void log6_packet(struct state *state, char *type, struct in6_addr *addr, char *string)
|
static void log6_packet(struct state *state, char *type, struct in6_addr *addr, char *string)
|
||||||
{
|
{
|
||||||
int clid_len = state->clid_len;
|
int clid_len = state->clid_len;
|
||||||
|
|||||||
+2
-1
@@ -200,7 +200,8 @@ void slaac_ping_reply(struct in6_addr *sender, unsigned char *packet, char *inte
|
|||||||
slaac->backoff = 0;
|
slaac->backoff = 0;
|
||||||
gotone = 1;
|
gotone = 1;
|
||||||
inet_ntop(AF_INET6, sender, daemon->addrbuff, ADDRSTRLEN);
|
inet_ntop(AF_INET6, sender, daemon->addrbuff, ADDRSTRLEN);
|
||||||
my_syslog(MS_DHCP | LOG_INFO, "SLAAC-CONFIRM(%s) %s %s", interface, daemon->addrbuff, lease->hostname);
|
if (!option_bool(OPT_QUIET_DHCP6))
|
||||||
|
my_syslog(MS_DHCP | LOG_INFO, "SLAAC-CONFIRM(%s) %s %s", interface, daemon->addrbuff, lease->hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
lease_update_dns(gotone);
|
lease_update_dns(gotone);
|
||||||
|
|||||||
+31
-6
@@ -39,6 +39,15 @@ unsigned short rand16(void)
|
|||||||
return (unsigned short) (arc4random() >> 15);
|
return (unsigned short) (arc4random() >> 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 rand64(void)
|
||||||
|
{
|
||||||
|
u64 ret;
|
||||||
|
|
||||||
|
arc4random_buf(&ret, sizeof(ret));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* SURF random number generator */
|
/* SURF random number generator */
|
||||||
@@ -46,6 +55,7 @@ unsigned short rand16(void)
|
|||||||
static u32 seed[32];
|
static u32 seed[32];
|
||||||
static u32 in[12];
|
static u32 in[12];
|
||||||
static u32 out[8];
|
static u32 out[8];
|
||||||
|
static int outleft = 0;
|
||||||
|
|
||||||
void rand_init()
|
void rand_init()
|
||||||
{
|
{
|
||||||
@@ -82,16 +92,31 @@ static void surf(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned short rand16(void)
|
unsigned short rand16(void)
|
||||||
|
{
|
||||||
|
if (!outleft)
|
||||||
|
{
|
||||||
|
if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3];
|
||||||
|
surf();
|
||||||
|
outleft = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (unsigned short) out[--outleft];
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 rand64(void)
|
||||||
{
|
{
|
||||||
static int outleft = 0;
|
static int outleft = 0;
|
||||||
|
|
||||||
if (!outleft) {
|
if (outleft < 2)
|
||||||
if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3];
|
{
|
||||||
surf();
|
if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3];
|
||||||
outleft = 8;
|
surf();
|
||||||
}
|
outleft = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
outleft -= 2;
|
||||||
|
|
||||||
return (unsigned short) out[--outleft];
|
return (u64)out[outleft+1] + (((u64)out[outleft]) << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in new issue
Block a user