Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2621c7ff0 | ||
|
|
6b01084f8e |
113
CHANGELOG
113
CHANGELOG
@@ -2119,7 +2119,118 @@ version 2.37
|
||||
Added a LIMITS section to the man-page, with guidance on
|
||||
maximum numbers of clients, file sizes and tuning.
|
||||
|
||||
release 2.38
|
||||
Fix compilation on *BSD. Thanks to Tom Hensel.
|
||||
|
||||
Don't send length zero DHCP option 43 and cope with
|
||||
encapsulated options whose total length exceeds 255 octets
|
||||
by splitting them into multiple option 43 pieces.
|
||||
|
||||
|
||||
Avoid queries being retried forever when --strict-order is
|
||||
set and an upstream server returns a SERVFAIL
|
||||
error. Thanks to Johannes Stezenbach for spotting this.
|
||||
|
||||
Fix BOOTP support, broken in version 2.37.
|
||||
|
||||
Add example dhcp-options for Etherboot.
|
||||
|
||||
Add \e (for ASCII ESCape) to the set of valid escapes
|
||||
in config-file strings.
|
||||
|
||||
Added --dhcp-option-force flag and examples in the
|
||||
configuration file which use this to control PXELinux.
|
||||
|
||||
Added --tftp-no-blocksize option.
|
||||
|
||||
Set netid tag "bootp" when BOOTP (rather than DHCP) is in
|
||||
use. This makes it easy to customise which options are
|
||||
sent to BOOTP clients. (BOOTP allows only 64 octets for
|
||||
options, so it can be necessary to trim things.)
|
||||
|
||||
Fix rare hang in cache code, a 2.37 regression. This
|
||||
probably needs an infinite DHCP lease and some bad luck to
|
||||
trigger. Thanks to Detlef Reichelt for bug reports and testing.
|
||||
|
||||
release 2.39
|
||||
Apply patch from Mike Baker/OpenWRT to ensure that names
|
||||
like "localhost." in /etc/hosts with trailing period
|
||||
are treated as fully-qualified.
|
||||
|
||||
Tolerate and ignore spaces around commas in the
|
||||
configuration file in all circumstances. Note that this
|
||||
may change the meaning of a few existing config files, for
|
||||
instance
|
||||
txt-record=mydomain.com, string
|
||||
would have a leading space in the string before, and now
|
||||
will not. To get the old behaviour back, use quotes:
|
||||
txt-record=mydomain.com," string"
|
||||
|
||||
/a is no longer a valid escape in quoted strings.
|
||||
|
||||
Added symbolic DHCP option names. Instead of
|
||||
dhcp-option = 3, 1.2.3.4
|
||||
it is now possible to do
|
||||
dhcp-option = option:router, 1.2.3.4
|
||||
To see the list of known DHCP options, use the
|
||||
command "dnsmasq --help dhcp"
|
||||
Thanks to Luigi Rizzo for a patch and good work on this.
|
||||
|
||||
Overhauled the log code so that logging can be asynchronous;
|
||||
dnsmasq then no longer blocks waiting for the syslog() library
|
||||
call. This is important on systems where syslog
|
||||
is being used to log over the network (and therefore doing
|
||||
DNS lookups) and syslog is using dnsmasq as its DNS
|
||||
server. Having dnsmasq block awaiting syslog under
|
||||
such circumstances can lead to syslog and dnsmasq
|
||||
deadlocking. The new behaviour is enabled with a new
|
||||
--log-async flag, which can also be used to tune the
|
||||
queue length. Paul Chambers found and diagnosed
|
||||
this trap for the unwary. He also did much testing of
|
||||
the solution along with Carlos Carvalho.
|
||||
|
||||
--log-facility can now take a file-name instead of a
|
||||
facility name. When this is done, dnsmasq logs to the
|
||||
file and not via syslog. (Failures early in startup,
|
||||
whilst reading configuration, will still go to syslog,
|
||||
and syslog is used as a log-of-last-resort if the file
|
||||
cannot be written.)
|
||||
|
||||
Added --log-dhcp flag. Suggestion from Carlos Carvalho.
|
||||
|
||||
Made BINDIR, MANDIR and LOCALEDIR independently
|
||||
over-rideable in the makefile. Suggestion from Thomas
|
||||
Klausner.
|
||||
|
||||
Added 127.0.0.0/8 and 169.254.0.0/16 to the address
|
||||
ranges affected by --bogus-priv. Thanks to Paul
|
||||
Chambers for the patch.
|
||||
|
||||
Fixed failure of TFTP server with --listen-address. Thanks
|
||||
to William Dinkel for the bug report.
|
||||
|
||||
Added --dhcp-circuitid and --dhcp-remoteid for RFC3046
|
||||
relay agent data matching.
|
||||
|
||||
Added --dhcp-subscrid for RFC3993 subscriber-id relay
|
||||
agent data matching.
|
||||
|
||||
Correctly garbage-collect connections when upstream
|
||||
servers go away as a result of DBus transactions.
|
||||
|
||||
Allow absolute paths for TFTP transfers even when
|
||||
--tftp-root is set, as long as the path matches the root,
|
||||
so /var/ftp/myfile is OK with tftp-root=/var/ftp.
|
||||
Thanks for Thomas Mizzi for the patch.
|
||||
|
||||
Updated Spanish translation - thanks to Chris Chatham.
|
||||
|
||||
Updated French translation - thanks to Gildas Le Nadan.
|
||||
|
||||
Added to example conf file example of routing PTR queries
|
||||
for a subnet to a different nameserver. Suggestion from
|
||||
Jon Nicholson.
|
||||
|
||||
Added --interface-name option. This provides a facility
|
||||
to add a domain name with a dynamic IP address taken from
|
||||
the address of a local network interface. Useful for
|
||||
networks with dynamic IPs.
|
||||
|
||||
21
FAQ
21
FAQ
@@ -409,6 +409,27 @@ A: Yes, as a DNS server, dnsmasq will just work in a vserver.
|
||||
refer to the vserver documentation for more information).
|
||||
|
||||
|
||||
Q: What's the problem with syslog and dnsmasq?
|
||||
|
||||
A: In almost all cases: none. If you have the normal arrangement with
|
||||
local daemons logging to a local syslog, which then writes to disk,
|
||||
then there's never a problem. If you use network logging, then
|
||||
there's a potential problem with deadlock: the syslog daemon will
|
||||
do DNS lookups so that it can log the source of log messages,
|
||||
these lookups will (depending on exact configuration) go through
|
||||
dnsmasq, which also sends log messages. With bad timing, you can
|
||||
arrive at a situation where syslog is waiting for dnsmasq, and
|
||||
dnsmasq is waiting for syslog; they will both wait forever. This
|
||||
problem is fixed from dnsmasq-2.39, which introduces asynchronous
|
||||
logging: dnsmasq no longer waits for syslog and the deadlock is
|
||||
broken. There is a remaining problem in 2.39, where "log-queries"
|
||||
is in use. In this case most DNS queries generate two log lines, if
|
||||
these go to a syslog which is doing a DNS lookup for each log line,
|
||||
then those queries will in turn generate two more log lines, and a
|
||||
chain reaction runaway will occur. To avoid this, use syslog-ng
|
||||
and turn on syslog-ng's dns-cache function.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
8
Makefile
8
Makefile
@@ -1,7 +1,7 @@
|
||||
PREFIX?=/usr/local
|
||||
BINDIR = ${PREFIX}/sbin
|
||||
MANDIR = ${PREFIX}/share/man
|
||||
LOCALEDIR = ${PREFIX}/share/locale
|
||||
PREFIX ?= /usr/local
|
||||
BINDIR ?= ${PREFIX}/sbin
|
||||
MANDIR ?= ${PREFIX}/share/man
|
||||
LOCALEDIR ?= ${PREFIX}/share/locale
|
||||
|
||||
SRC = src
|
||||
PO = po
|
||||
|
||||
@@ -3,7 +3,8 @@ PKG_CONFIG ?= pkg-config
|
||||
|
||||
|
||||
OBJS = cache.o rfc1035.o util.o option.o forward.o isc.o network.o \
|
||||
dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o helper.o tftp.o
|
||||
dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \
|
||||
helper.o tftp.o log.o
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) $(COPTS) $(I18N) `echo $(COPTS) | ../bld/pkg-wrapper $(PKG_CONFIG) --cflags dbus-1` $(RPM_OPT_FLAGS) -Wall -W -c $<
|
||||
|
||||
@@ -48,6 +48,10 @@
|
||||
# non-public domains.
|
||||
#server=/localnet/192.168.0.1
|
||||
|
||||
# Example of routing PTR queries to nameservers: this will send all
|
||||
# address->name queries for 192.168.3/24 to nameserver 10.1.2.3
|
||||
#server=/3.168.192.in-addr.arpa/10.1.2.3
|
||||
|
||||
# Add local-only domains here, queries in these domains are answered
|
||||
# from /etc/hosts or DHCP only.
|
||||
#local=/localnet/
|
||||
@@ -196,23 +200,22 @@
|
||||
|
||||
# Send options to hosts which ask for a DHCP lease.
|
||||
# See RFC 2132 for details of available options.
|
||||
# Common options can be given to dnsmasq by name:
|
||||
# run "dnsmasq --help dhcp" to get a list.
|
||||
# Note that all the common settings, such as netmask and
|
||||
# broadcast address, DNS server and default route, are given
|
||||
# sane defaults by dnsmasq. You very likely will not need any
|
||||
# any dhcp-options. If you use Windows clients and Samba, there
|
||||
# are some options which are recommended, they are detailed at the
|
||||
# end of this section.
|
||||
# For reference, the common options are:
|
||||
# subnet mask - 1
|
||||
# default router - 3
|
||||
# DNS server - 6
|
||||
# hostname - 12
|
||||
# broadcast address - 28
|
||||
|
||||
# Override the default route supplied by dnsmasq, which assumes the
|
||||
# router is the same machine as the one running dnsmasq.
|
||||
#dhcp-option=3,1.2.3.4
|
||||
|
||||
# Do the same thing, but using the option name
|
||||
#dhcp-option=option:router,1.2.3.4
|
||||
|
||||
# Override the default route supplied by dnsmasq and send no default
|
||||
# route at all. Note that this only works for the options sent by
|
||||
# default (1, 3, 6, 12, 28) the same line will send a zero-length option
|
||||
@@ -220,7 +223,7 @@
|
||||
#dhcp-option=3
|
||||
|
||||
# Set the NTP time server addresses to 192.168.0.4 and 10.10.0.5
|
||||
#dhcp-option=42,192.168.0.4,10.10.0.5
|
||||
#dhcp-option=option:ntp-server,192.168.0.4,10.10.0.5
|
||||
|
||||
# Set the NTP time server address to be the same machine as
|
||||
# is running dnsmasq
|
||||
@@ -241,7 +244,8 @@
|
||||
|
||||
# Specify an option which will only be sent to the "red" network
|
||||
# (see dhcp-range for the declaration of the "red" network)
|
||||
#dhcp-option=red,42,192.168.1.1
|
||||
# Note that the net: part must precede the option: part.
|
||||
#dhcp-option = net:red, option:ntp-server, 192.168.1.1
|
||||
|
||||
# The following DHCP options set up dnsmasq in the same way as is specified
|
||||
# for the ISC dhcpcd in
|
||||
@@ -257,7 +261,7 @@
|
||||
|
||||
# Send RFC-3397 DNS domain search DHCP option. WARNING: Your DHCP client
|
||||
# probably doesn't support this......
|
||||
#dhcp-option=119,eng.apple.com,marketing.apple.com
|
||||
#dhcp-option=option:domain-search,eng.apple.com,marketing.apple.com
|
||||
|
||||
# Send RFC-3442 classless static routes (note the netmask encoding)
|
||||
#dhcp-option=121,192.168.1.0/24,1.2.3.4,10.0.0.0/8,5.6.7.8
|
||||
@@ -276,6 +280,23 @@
|
||||
# http://technet2.microsoft.com/WindowsServer/en/library/a70f1bb7-d2d4-49f0-96d6-4b7414ecfaae1033.mspx?mfr=true
|
||||
#dhcp-option=vendor:MSFT,2,1i
|
||||
|
||||
# Send the Encapsulated-vendor-class ID needed by some configurations of
|
||||
# Etherboot to allow is to recognise the DHCP server.
|
||||
#dhcp-option=vendor:Etherboot,60,"Etherboot"
|
||||
|
||||
# Send options to PXELinux. Note that we need to send the options even
|
||||
# though they don't appear in the parameter request list, so we need
|
||||
# to use dhcp-option-force here.
|
||||
# See http://syslinux.zytor.com/pxe.php#special for details.
|
||||
# Magic number - needed before anything else is recognised
|
||||
#dhcp-option-force=208,f1:00:74:7e
|
||||
# Configuration file name
|
||||
#dhcp-option-force=209,configs/common
|
||||
# Path prefix
|
||||
#dhcp-option-force=210,/tftpboot/pxelinux/files/
|
||||
# Reboot time. (Note 'i' to send 32-bit value)
|
||||
#dhcp-option-force=211,30i
|
||||
|
||||
# Set the boot filename for BOOTP. You will only need
|
||||
# this is you want to boot machines over the network and you will need
|
||||
# a TFTP server; either dnsmasq's built in TFTP server or an
|
||||
@@ -417,6 +438,9 @@
|
||||
# dnsmasq.
|
||||
#log-queries
|
||||
|
||||
# Log lots of extra information about DHCP transactions.
|
||||
#log-dhcp
|
||||
|
||||
# Include a another lot of configuration options.
|
||||
#conf-file=/etc/dnsmasq.more.conf
|
||||
#conf-dir=/etc/dnsmasq.d
|
||||
|
||||
105
man/dnsmasq.8
105
man/dnsmasq.8
@@ -18,7 +18,7 @@ DNS queries for DHCP configured hosts.
|
||||
The dnsmasq DHCP server supports static address assignments, multiple
|
||||
networks, DHCP-relay and RFC3011 subnet specifiers. It automatically
|
||||
sends a sensible default set of DHCP options, and can be configured to
|
||||
send any desired set of DHCP options, inlcuding vendor-encapsulated
|
||||
send any desired set of DHCP options, including vendor-encapsulated
|
||||
options. It includes a secure, read-only,
|
||||
TFTP server to allow net/PXE boot of DHCP hosts and also supports BOOTP.
|
||||
.PP
|
||||
@@ -68,7 +68,23 @@ Log the results of DNS queries handled by dnsmasq. Enable a full cache dump on r
|
||||
.TP
|
||||
.B \-8, --log-facility=<facility>
|
||||
Set the facility to which dnsmasq will send syslog entries, this
|
||||
defaults to DAEMON, and to LOCAL0 when debug mode is in operation.
|
||||
defaults to DAEMON, and to LOCAL0 when debug mode is in operation. If
|
||||
the facilty given contains at least one '/' character, it is taken to
|
||||
be a filename, and dnsmasq logs to the given file, instead of
|
||||
syslog. (Errors whilst reading configuration will still go to syslog,
|
||||
but all output from a successful startup, and all output whilst
|
||||
running, will go exclusively to the file.)
|
||||
.TP
|
||||
.B --log-async[=<lines>]
|
||||
Enable asynchronous logging and optionally set the limit on the
|
||||
number of lines
|
||||
which will be queued by dnsmasq when writing to the syslog is slow.
|
||||
Dnsmasq can log asynchronously: this
|
||||
allows it to continue functioning without being blocked by syslog, and
|
||||
allows syslog to use dnsmasq for DNS queries without risking deadlock.
|
||||
If the queue of log-lines becomes full, dnsmasq will log the
|
||||
overflow, and the number of messages lost. The default queue length is
|
||||
5, a sane value would be 5-25, and a maximum limit of 100 is imposed.
|
||||
.TP
|
||||
.B \-x, --pid-file=<path>
|
||||
Specify an alternate path for dnsmasq to record its process-id in. Normally /var/run/dnsmasq.pid.
|
||||
@@ -331,6 +347,17 @@ so any number may be included, split by commas.
|
||||
.B --ptr-record=<name>[,<target>]
|
||||
Return a PTR DNS record.
|
||||
.TP
|
||||
.B --interface-name=<name>,<interface>
|
||||
Return a DNS record associating the name with the primary address on
|
||||
the given interface. This flag specifies an A record for the given
|
||||
name in the same way as an /etc/hosts line, except that the address is
|
||||
not constant, but taken from the given interface. If the interface is
|
||||
down, not configured or non-existant, an empty record is returned. The
|
||||
matching PTR record is also created, mapping the interface address to
|
||||
the name. More than one name may be associated with an interface
|
||||
address by repeating the flag; in that case the first instance is used
|
||||
for the reverse address-to-name mapping.
|
||||
.TP
|
||||
.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.
|
||||
.TP
|
||||
@@ -438,19 +465,26 @@ have exactly the same effect as
|
||||
.B --dhcp-host
|
||||
options containing the same information.
|
||||
.TP
|
||||
.B \-O, --dhcp-option=[<network-id>,[<network-id>,]][vendor:[<vendor-class>],]<opt>,[<value>[,<value>]]
|
||||
.B \-O, --dhcp-option=[<network-id>,[<network-id>,]][vendor:[<vendor-class>],][<opt>|option:<opt-name>],[<value>[,<value>]]
|
||||
Specify different or extra options to DHCP clients. By default,
|
||||
dnsmasq sends some standard options to DHCP clients, the netmask and
|
||||
broadcast address are set to the same as the host running dnsmasq, and
|
||||
the DNS server and default route are set to the address of the machine
|
||||
running dnsmasq. If the domain name option has been set, that is sent.
|
||||
This option allows these defaults to be overridden,
|
||||
or other options specified. The <opt> is the number of the option, as
|
||||
specified in RFC2132. For example, to set the default route option to
|
||||
This configuration allows these defaults to be overridden,
|
||||
or other options specified. The option, to be sent may be given as a
|
||||
decimal number or as "option:<option-name>" The option numbers are
|
||||
specified in RFC2132 and subsequent RFCs. The set of option-names
|
||||
known by dnsmasq can be discovered by running "dnsmasq --help dhcp".
|
||||
For example, to set the default route option to
|
||||
192.168.4.4, do
|
||||
.B --dhcp-option=3,192.168.4.4
|
||||
.B --dhcp-option=3,192.168.4.4
|
||||
or
|
||||
.B --dhcp-option = option:router, 192.168.4.4
|
||||
and to set the time-server address to 192.168.0.4, do
|
||||
.B --dhcp-option=42,192.168.0.4
|
||||
.B --dhcp-option = 42,192.168.0.4
|
||||
or
|
||||
.B --dhcp-option = option:ntp-server, 192.168.0.4
|
||||
The special address 0.0.0.0 is taken to mean "the address of the
|
||||
machine running dnsmasq". Data types allowed are comma separated
|
||||
dotted-quad IP addresses, a decimal number, colon-separated hex digits
|
||||
@@ -484,17 +518,27 @@ Encapsulated Vendor-class options may also be specified using
|
||||
sends the encapsulated vendor
|
||||
class-specific option "mftp-address=0.0.0.0" to any client whose
|
||||
vendor-class matches "PXEClient". The vendor-class matching is
|
||||
substring based (see --dhcp-vendorclass for details) and it is
|
||||
substring based (see --dhcp-vendorclass for details). If a
|
||||
vendor-class option (number 60) is sent by dnsmasq, then that is used
|
||||
for selecting encapsulated options in preference to any sent by the
|
||||
client. It is
|
||||
possible to omit the vendorclass completely;
|
||||
.B --dhcp-option=vendor:,1,0.0.0.0
|
||||
in which case the encapsulated option is always sent.
|
||||
The address 0.0.0.0 is not treated specially in
|
||||
encapsulated vendor class options.
|
||||
.TP
|
||||
.B --dhcp-option-force=[<network-id>,[<network-id>,]][vendor:[<vendor-class>],]<opt>,[<value>[,<value>]]
|
||||
This works in exactly the same way as
|
||||
.B --dhcp-option
|
||||
except that the option will always be sent, even if the client does
|
||||
not ask for it in the parameter request list. This is sometimes
|
||||
needed, for example when sending options to PXELinux.
|
||||
.TP
|
||||
.B \-U, --dhcp-vendorclass=<network-id>,<vendor-class>
|
||||
Map from a vendor-class string to a network id. Most DHCP clients provide a
|
||||
Map from a vendor-class string to a network id tag. Most DHCP clients provide a
|
||||
"vendor class" which represents, in some sense, the type of host. This option
|
||||
maps vendor classes to network ids, so that DHCP options may be selectively delivered
|
||||
maps vendor classes to tags, so that DHCP options may be selectively delivered
|
||||
to different classes of hosts. For example
|
||||
.B dhcp-vendorclass=printers,Hewlett-Packard JetDirect
|
||||
will allow options to be set only for HP printers like so:
|
||||
@@ -504,20 +548,30 @@ substring matched against the vendor-class supplied by the client, to
|
||||
allow fuzzy matching.
|
||||
.TP
|
||||
.B \-j, --dhcp-userclass=<network-id>,<user-class>
|
||||
Map from a user-class string to a network id (with substring
|
||||
Map from a user-class string to a network id tag (with substring
|
||||
matching, like vendor classes). Most DHCP clients provide a
|
||||
"user class" which is configurable. This option
|
||||
maps user classes to network ids, so that DHCP options may be selectively delivered
|
||||
maps user classes to tags, so that DHCP options may be selectively delivered
|
||||
to different classes of hosts. It is possible, for instance to use
|
||||
this to set a different printer server for hosts in the class
|
||||
"accounts" than for hosts in the class "engineering".
|
||||
.TP
|
||||
.B \-4, --dhcp-mac=<network-id>,<MAC address>
|
||||
Map from a MAC address to a network-id. The MAC address may include
|
||||
Map from a MAC address to a network-id tag. The MAC address may include
|
||||
wildcards. For example
|
||||
.B --dhcp-mac=3com,01:34:23:*:*:*
|
||||
will set the tag "3com" for any host whose MAC address matches the pattern.
|
||||
.TP
|
||||
.B --dhcp-circuitid=<network-id>,<circuit-id>, --dhcp-remoteid=<network-id>,<remote-id>
|
||||
Map from RFC3046 relay agent options to network-id tags. This data may
|
||||
be provided by DHCP relay agents. The circuit-id or remote-id is
|
||||
normally given as colon-separated hex, but is also allowed to be a
|
||||
simple string. If an exact match is achieved between the circuit or
|
||||
agent ID and one provided by a relay agent, the network-id tag is set.
|
||||
.TP
|
||||
.B --dhcp-subscrid=<network-id>,<subscriber-id>
|
||||
Map from RFC3993 subscriber-d relay agent options to network-id tags.
|
||||
.TP
|
||||
.B \-J, --dhcp-ignore=<network-id>[,<network-id>]
|
||||
When all the given network-ids match the set of network-ids derived
|
||||
from the net, host, vendor and user classes, ignore the host and do
|
||||
@@ -550,7 +604,7 @@ create thousands of leases and use lots of memory in the dnsmasq
|
||||
process.
|
||||
.TP
|
||||
.B \-K, --dhcp-authoritative
|
||||
Should be set when dnsmasq is definately the only DHCP server on a network.
|
||||
Should be set when dnsmasq is definitely the only DHCP server on a network.
|
||||
It changes the behaviour from strict RFC compliance so that DHCP requests on
|
||||
unknown leases from unknown hosts are not ignored. This allows new hosts
|
||||
to get a lease without a tedious timeout under all circumstances. It also
|
||||
@@ -570,6 +624,10 @@ ICMP echo request (aka "ping") to the address in question. If it gets
|
||||
a reply, then the address must already be in use, and another is
|
||||
tried. This flag disables this check. Use with caution.
|
||||
.TP
|
||||
.B --log-dhcp
|
||||
Extra logging for DHCP: log all the options sent to DHCP clients and
|
||||
the netid tags used to determine them.
|
||||
.TP
|
||||
.B \-l, --dhcp-leasefile=<path>
|
||||
Use the specified file to store DHCP lease information. If this option
|
||||
is given but no dhcp-range option is given then dnsmasq version 1
|
||||
@@ -611,7 +669,7 @@ closed except stdin, stdout and stderr which are open to /dev/null
|
||||
(except in debug mode).
|
||||
The script is not invoked concurrently: if subsequent lease
|
||||
changes occur, the script is not invoked again until any existing
|
||||
invokation exits. At dnsmasq startup, the script will be invoked for
|
||||
invocation exits. At dnsmasq startup, the script will be invoked for
|
||||
all existing leases as they are read from the lease file. Expired
|
||||
leases will be called with "del" and others with "old". <path>
|
||||
must be an absolute pathname, no PATH search occurs.
|
||||
@@ -621,7 +679,7 @@ Completely suppress use of the lease database file. The file will not
|
||||
be created, read, or written. Change the way the lease-change
|
||||
script (if one is provided) is called, so that the lease database may
|
||||
be maintained in external storage by the script. In addition to the
|
||||
invokations given in
|
||||
invocations given in
|
||||
.B --dhcp-script
|
||||
the lease-change script is called once, at dnsmasq startup, with the
|
||||
single argument "init". When called like this the script should write
|
||||
@@ -665,6 +723,8 @@ binary/octet mode. The tsize and blksize extensions are supported.
|
||||
Look for files to transfer using TFTP relative to the given
|
||||
directory. When this is set, TFTP paths which include ".." are
|
||||
rejected, to stop clients getting outside the specified root.
|
||||
Absolute paths (starting with /) are allowed, but they must be within
|
||||
the tftp-root.
|
||||
.TP
|
||||
.B --tftp-secure
|
||||
Enable TFTP secure mode: without this, any file which is readble by
|
||||
@@ -686,6 +746,11 @@ file descriptor per unique file (plus a few others). So serving the
|
||||
same file simultaneously to n clients will use require about n + 10 file
|
||||
descriptors, serving different files simultaneously to n clients will
|
||||
require about (2*n) + 10 descriptors.
|
||||
.TP
|
||||
.B --tftp-no-blocksize
|
||||
Stop the TFTP server from negotiating the "blocksize" option with a
|
||||
client. Some buggy clients request this option but then behave badly
|
||||
when it is granted.
|
||||
.TP
|
||||
.B \-C, --conf-file=<file>
|
||||
Specify a different configuration file. The conf-file option is also allowed in
|
||||
@@ -718,7 +783,7 @@ corresponding to tab, bell, backspace, return and newline.
|
||||
When it receives a SIGHUP,
|
||||
.B dnsmasq
|
||||
clears its cache and then re-loads
|
||||
.I /etc/hosts.
|
||||
.I /etc/hosts and /etc/ethers.
|
||||
If
|
||||
.B
|
||||
--no-poll
|
||||
@@ -835,7 +900,7 @@ on a particular network. (Setting --bootp-dynamic removes the need for
|
||||
static address mappings.) The filename
|
||||
parameter in a BOOTP request is matched against netids in
|
||||
.B dhcp-option
|
||||
configurations, allowing some control over the options returned to
|
||||
configurations, as is the tag "bootp", allowing some control over the options returned to
|
||||
different classes of hosts.
|
||||
|
||||
.SH LIMITS
|
||||
@@ -848,7 +913,7 @@ following applies to dnsmasq-2.37: earlier versions did not scale as well.
|
||||
.PP
|
||||
Dnsmasq is capable of handling DNS and DHCP for at least a thousand
|
||||
clients. Clearly to do this the value of
|
||||
.B --dhcp-max
|
||||
.B --dhcp-lease-max
|
||||
must be increased,
|
||||
and lease times should not be very short (less than one hour). The
|
||||
value of
|
||||
|
||||
473
man/es/dnsmasq.8
473
man/es/dnsmasq.8
@@ -6,7 +6,7 @@ dnsmasq \- Un ligero servidor DHCP y DNS con cach
|
||||
.I [OPCION]...
|
||||
.SH "DESCRIPCION"
|
||||
.BR dnsmasq
|
||||
es un ligero servidor DNS y DHCP. Su propósito es proveer servicios DNS
|
||||
es un ligero servidor DNS, TFTP y DHCP. Su propósito es proveer servicios DNS
|
||||
y DHCP a una red de área local.
|
||||
.PP
|
||||
Dnsmasq acepta búsquedas DNS y las responde desde un pequeño
|
||||
@@ -19,11 +19,12 @@ v
|
||||
El servidor DHCP dnsmasq incluye soporte para assignación de direcciones
|
||||
estáticas, redes múltiples, DHCP-relay y especificadores de subredes
|
||||
RFC3011. Automáticamente envía un predeterminado sensible de opciones
|
||||
DHCP, y puede ser configurado para enviar cualquier opciones DHCP
|
||||
deseadas. Tambíen incluye soporte para BOOTP.
|
||||
DHCP, y puede ser configurado para enviar cualquier opciones DHCP deseadas,
|
||||
incluyendo opciones encapsuladas por vendedores. Incluye un servidor seguro
|
||||
TFTP solo-lectura para permitir el inicio vía red/PXE de hosts DHCP. Tambíen
|
||||
incluye soporte para BOOTP.
|
||||
.PP
|
||||
Dnsmasq
|
||||
incluye soporte para IPv6.
|
||||
Dnsmasq incluye soporte IPv6 para DNS, pero no para DHCP.
|
||||
.SH OPCIONES
|
||||
Nótese que en general parámetros ausentes son permitidos y deshabilitan
|
||||
funciones, por ejemplo "--pid-file=" deshabilita la escritura de un
|
||||
@@ -39,9 +40,13 @@ Archivo de hosts adicional. Leer el archivo especificado adicionalmente
|
||||
a /etc/hosts. Si se brinda -h, leer solo el archivo especificado. Esta
|
||||
opción puede ser repetida para más de un archivo de hosts adicional.
|
||||
.TP
|
||||
.B \-E, --expand-hosts
|
||||
Agregar el dominio a nombres sencillos (sin punto) en /etc/hosts de la
|
||||
misma manera que con nombres derivados de DHCP.
|
||||
.TP
|
||||
.B \-T, --local-ttl=<tiempo>
|
||||
Al responder con información desde /etc/hosts o desde el archivo
|
||||
de arriendos DHCP, dnsmasq fija el tiempo de vida a cero por
|
||||
de arriendos DHCP, dnsmasq fija el tiempo de vida (TTL) a cero por
|
||||
predeterminado, significando que el remitente no debrá cachear
|
||||
la información por sí mismo. Esto es lo correcto a hacer en casi
|
||||
todas las situaciones. Esta opción permite que se especifique
|
||||
@@ -50,15 +55,15 @@ reduce la carga sobre el servidor al costo de que los clientes
|
||||
usaran datos añejos bajo algunas circunstancias.
|
||||
.TP
|
||||
.B \-k, --keep-in-foreground
|
||||
No ir hacia el fondo al iniciar, pero aparte de eso correr como
|
||||
normal. La intención de esto es para cuando dnsmasq es corrido
|
||||
No ir hacia el fondo al iniciar, pero aparte de eso ejecutar como
|
||||
normal. La intención de esto es para cuando dnsmasq es ejecutado
|
||||
bajo daemontools o launchd.
|
||||
.TP
|
||||
.B \-d, --no-daemon
|
||||
Modo debug: no hacer un fork hacia el fondo, no crear un archivo PID,
|
||||
no cambiar el ID del usuario, generar un cache dump completo al
|
||||
recibir un SIGUSR1, bitacorear a stderr al igual que a syslog, no
|
||||
hacerle fork a procesos nuevos para manejar búsquedas TCP.
|
||||
forkear procesos nuevos para manejar búsquedas TCP.
|
||||
.TP
|
||||
.B \-q, --log-queries
|
||||
Bitacorear los resultados de búsquedas DNS manejadas por dnsmasq.
|
||||
@@ -66,7 +71,22 @@ Habilitar un dump de cach
|
||||
.TP
|
||||
.B \-8, --log-facility=<facilidad>
|
||||
Fijar la facilidad a la cual dnsmasq deberá enviar mensajes syslog,
|
||||
esto es DAEMON por predeterminado, y LOCAL0 cuando en modo debug.
|
||||
esto es DAEMON por predeterminado, y LOCAL0 cuando el modo debug está
|
||||
en operación. Si la facilidad brindada contiene por lo menos un carácter
|
||||
"/", se trata como un nombre de archivo, y dnsmasq bitacoreará a dicho
|
||||
archivo, en vez de syslog. (Errores durante la lectura de la configuración
|
||||
irán a syslog todavía, pero todo output desde un inicio exitoso, y todo
|
||||
output mientras en ejecución, irá a este archivo exclusivamente.)
|
||||
.TP
|
||||
.B --log-async[=<líneas>]
|
||||
Habilitar bitacoréo asincrónico y opcionalmente fijar el límite de número
|
||||
de líneas que serán enviadas a la coleta por dnsmasq cuando syslog está
|
||||
lento. Dnsmasq puede bitacorear asincrónicamente: esto le permite continuar
|
||||
funcionando sin ser bloqueado por syslog, y permite a syslog usar dnsmasq
|
||||
para búsquedas DNS sin riesgo de tranque. Si la coleta de líneas de bitácora
|
||||
se llena, dnsmasq bitacoreará el desbordamiento, y el número de mensajes
|
||||
perdidos. El tamaño predeterminado de coleta es 5, un valor sano sería 5-25,
|
||||
y el valor máximo de 100 es impuesto.
|
||||
.TP
|
||||
.B \-x, --pid-file=<path>
|
||||
Especificar un path alterno donde dnsmasq debe guardar su PID.
|
||||
@@ -82,7 +102,7 @@ con esta opci
|
||||
.B \-g, --group=<grupo>
|
||||
Especificar el grupo como el cual dnsmasq correrá. El predeterminado
|
||||
es "dip", si está disponible, para facilitar el acceso a
|
||||
/etc/ppp/resolv.conf el cuál normalmente no es globalmente leíble.
|
||||
/etc/ppp/resolv.conf el cuál normálmente no es globalmente leíble.
|
||||
.TP
|
||||
.B \-v, --version
|
||||
Mostrar el número de versión.
|
||||
@@ -105,37 +125,37 @@ servidores DNS for
|
||||
adaptarse dinámicamente al puerto siendo usado por la actual
|
||||
instancia de dnsmasq.
|
||||
.TP
|
||||
.B \-i, --interface=<interface>
|
||||
Escuchar solo en las interfaces especificadas. Dnsmasq automaticamente
|
||||
.B \-i, --interface=<nombre de interface>
|
||||
Escuchar solo en las interfaces especificadas. Dnsmasq automáticamente
|
||||
agrega la interface loopback a la lista de interfaces para usar cuando
|
||||
la opción
|
||||
.B \--interface
|
||||
es usada. Si ninguna opcion
|
||||
es usada. Si ninguna opción
|
||||
.B \--interface
|
||||
o
|
||||
.B \--listen-address
|
||||
es brindada, dnsmasq escucha en todas las interfaces disponibles excepto
|
||||
cualquiera fijada con la opcion
|
||||
cualquiera fijada con la opción
|
||||
.B \--except-interface
|
||||
Interfaces IP alias (eg "eth1:0") no pueden ser utilizadas con
|
||||
Interfaces IP alias (por ejemplo, "eth1:0") no pueden ser utilizadas con
|
||||
.B --interface
|
||||
o
|
||||
.B --except-interface
|
||||
, usar --listen-address en vez.
|
||||
.TP
|
||||
.B \-I, --except-interface=<interface>
|
||||
.B \-I, --except-interface=<nombre de interface>
|
||||
No escuchar en la interface especificada. Nótese que el orden de
|
||||
las opciones
|
||||
.B \--listen-address
|
||||
.B --interface
|
||||
y
|
||||
.B --except-interface
|
||||
no importa y la opcion
|
||||
no importa y la opción
|
||||
.B --except-interface
|
||||
siempre invalida a las otras.
|
||||
siempre invalida las otras.
|
||||
.TP
|
||||
.B \-2, --no-dhcp-interface=<interface>
|
||||
No proveer DHCP en la interface especificada, pero sí
|
||||
.B \-2, --no-dhcp-interface=<nombre de interface>
|
||||
No proveer DHCP ni TFTP en la interface especificada, pero sí
|
||||
proveer servicio DNS.
|
||||
.TP
|
||||
.B \-a, --listen-address=<dirección IP>
|
||||
@@ -149,8 +169,8 @@ direcciones IP y interfaces es usada. N
|
||||
es brindada, pero sí se brinda la opción
|
||||
.B \--listen-address
|
||||
entonces dnsmasq no escuchará automáticamente en la interface
|
||||
loopback. Para obtener esto, la dirección IP 127.0.0.1 debe ser
|
||||
explícitamente dada como una opción
|
||||
loopback. Para obtener esto, su dirección IP, 127.0.0.1, debe ser
|
||||
explícitamente brindada como una opción
|
||||
.B \--listen-address
|
||||
.TP
|
||||
.B \-z, --bind-interfaces
|
||||
@@ -178,18 +198,18 @@ dependiendo de cual red tengan adjunta. Por el momento, esta facilidad
|
||||
está limitada a IPv4.
|
||||
.TP
|
||||
.B \-b, --bogus-priv
|
||||
Búsquedas privadas reversas raras. Toda búsqueda para rangos de IP
|
||||
Búsquedas privadas reversas raras. Toda búsqueda reversa para rangos de IP
|
||||
privados (192.168.x.x, etc.) los cuales no se encuentren en
|
||||
/etc/hosts o en el archivo de arriendos DHCP es respondida con
|
||||
"dominio no existente" en vez de ser reenviada upstream.
|
||||
.TP
|
||||
.B \-V, --alias=<IP vieja>,<IP nueva>[,<máscara>]
|
||||
.B \-V, --alias=<IP viejo>,<IP nuevo>[,<máscara>]
|
||||
Modificar direcciones IPv4 retornadas desde servidores DNS upstream;
|
||||
<IP vieja> es remplazada con <IP nueva>. Si la máscara opcional
|
||||
es brindada, entonces cualquier dirección que coincida con la
|
||||
<IP vieja> enmascarada será re-escrita. Así que, por ejemplo,
|
||||
.B --alias=1.2.3.0,6.7.8.0,255.255.255.0
|
||||
mapeará 1.2.3.56 a 6.7.8.56 y 1.2.3.67 a 6.7.8.67. Esto es lo que
|
||||
<IP viejo> es remplazado con <IP nuevo>. Si la máscara opcional
|
||||
es brindada, entonces cualquier dirección que coincida con el
|
||||
<IP viejo> enmascarado será re-escrita. Así que, por ejemplo,
|
||||
.B --alias=1.2.3.0,6.7.8.0,255.255.255.0 trazará 1.2.3.56 a 6.7.8.56
|
||||
y 1.2.3.67 a 6.7.8.67. Esto es lo que
|
||||
ruteadores Cisco PIX llaman "DNS doctoring".
|
||||
.TP
|
||||
.B \-B, --bogus-nxdomain=<dirección IP>
|
||||
@@ -200,7 +220,7 @@ del 2003, cuando comenzaron a retornar la direcci
|
||||
de publicidad en respuesta a búsquedas por nombres no registrados,
|
||||
en vez de la correcta respuesta NXDOMAIN. Esta opción le dice a dnsmasq
|
||||
que debe forjear la respuesta correcta cuando ve este comportamiento.
|
||||
Desde septiembre 2003 la dirección IP siendo retornada por Verisign
|
||||
Para septiembre 2003 la dirección IP siendo retornada por Verisign
|
||||
es 64.94.110.11
|
||||
.TP
|
||||
.B \-f, --filterwin2k
|
||||
@@ -217,9 +237,9 @@ en vez de /etc/resolv.conf. Para el formato de este archivo, ver
|
||||
Las únicas líneas relevantes a dnsmasq son las de servidores DNS. A
|
||||
dnsmasq se le puede decir que revise más de un archivo resolv.conf,
|
||||
el primer archivo especificado remplaza al predeterminado, y los
|
||||
subsiguientes archivos son agregados a la lista. Esto es solo
|
||||
permitido cuando haciendo polling; el archivo con la actual fecha
|
||||
de modificación más nueva es el que es usado.
|
||||
subsiguientes son agregados a la lista. Esto es solo
|
||||
permitido al hacer polling; el archivo con la actual fecha
|
||||
de modificación más nueva es el que será usado.
|
||||
.TP
|
||||
.B \-R, --no-resolv
|
||||
No leer /etc/resolv.conf. Obtener los servidores DNS upstream solo
|
||||
@@ -242,13 +262,18 @@ que aparecen en /etc/resolv.conf
|
||||
.B \-n, --no-poll
|
||||
No revisar periodicamente a /etc/resolv.conf en busca de cambios.
|
||||
.TP
|
||||
.B --clear-on-reload
|
||||
Cuando sea que /etc/resolv.conf es re-leida, liberar el caché DNS.
|
||||
Esto es útil cuando servidores DNS nuevos puedan tener datos diferentes
|
||||
a los contenidos en el caché.
|
||||
.TP
|
||||
.B \-D, --domain-needed
|
||||
Le dice a dnsmasq que no debe reenviar búsquedas para nombres sencillos,
|
||||
sin puntos o partes de dominios, a servidores upstream. Si el nombre
|
||||
no se conoce desde /etc/hosts o desde DHCP entonces una respuesta
|
||||
"no encontrado" es devuelta.
|
||||
.TP
|
||||
.B \-S, --server=[/[<domain>]/[domain/]][<ipaddr>[#<port>][@<source>[#<port>]]]
|
||||
.B \-S, --local, --server=[/[<dominio>]/[dominio/]][<dirección IP>[#<puerto>][@<remitente>[#<puerto>]]]
|
||||
Especificar la dirección IP de servidores upstream directamente. Fijar
|
||||
esta opción no suprime la lectura de /etc/resolv.conf, use -R para
|
||||
hacer eso. Si uno a más dominios opcionales son brindados, ese servidor
|
||||
@@ -261,10 +286,10 @@ opci
|
||||
.B -S /internal.thekelleys.org.uk/192.168.1.1
|
||||
enviará todas las búsquedas de máquinas internas a ese servidor DNS,
|
||||
todas las demás búsquedas serán enviadas a los servidores en
|
||||
/etc/resolv.conf. Una especificación de dominio en blanco
|
||||
/etc/resolv.conf. Una especificación de dominio en blanco,
|
||||
.B //
|
||||
tiene el significado especial de "solo nombres no calificados", o
|
||||
sea nombres sin ningun punto en ellos. Un puerto no-estándar puede
|
||||
sea nombres sin ningún punto en ellos. Un puerto no-estándar puede
|
||||
ser especificado como parte de la dirección IP usando el caracter
|
||||
#. Más de una opción -S es permitida, con partes de dominio o
|
||||
dirección IP repetidas como sea necesario.
|
||||
@@ -303,8 +328,8 @@ retornar
|
||||
/etc/hosts o DHCP y que no haya sido enviada a un servidor DNS
|
||||
upstream por una directiva --server mas especifica.
|
||||
.TP
|
||||
.B \-m, --mx-host=<mx name>[[,<hostname>],<preference>]
|
||||
Retornar un record llamado <nombre MX> apuntando hacia un nombre de
|
||||
.B \-m, --mx-host=<nombre mx>[[,<nombre de host>],<preferencia>]
|
||||
Retornar un record llamado <mx name> apuntando hacia el nombre de
|
||||
host brindado (opcionalmente), o el host especificado en la opción
|
||||
--mx-target, o si esa opción no es brindada, el host en el cual
|
||||
dnsmasq está corriendo. El predeterminado es útil para redireccionar
|
||||
@@ -312,11 +337,11 @@ correo de sistemas en la red local hacia un servidor central. La
|
||||
opción de preferencia es opcional, y su predeterminado es 1 si no
|
||||
es brindada. Más de un record MX puede ser brindado para un host.
|
||||
.TP
|
||||
.B \-t, --mx-target=<hostname>
|
||||
.B \-t, --mx-target=<nombre de host>
|
||||
Especificar el target predeterminado para el record MX devuelto
|
||||
por dnsmasq. Ver --mx-host. Si --mx-target es brindado, pero no
|
||||
--mx-host, entonces dnsmasq devuelve un record MX conteniendo
|
||||
el target MX para búsquedas MX en el hostname de la máquina donde
|
||||
el target MX para búsquedas MX en el nombre de host de la máquina donde
|
||||
dnsmasq está corriendo.
|
||||
.TP
|
||||
.B \-e, --selfmx
|
||||
@@ -328,23 +353,26 @@ Retornar un record MX apuntando al host brindado por mx-target (o
|
||||
la máquina donde dnsmasq está corriendo) para cada máquina local.
|
||||
Máquinas locales son aquellas en /etc/hosts o con arriendos DHCP.
|
||||
.TP
|
||||
.B \-W, --srv-host=<_service>.<_prot>.[<domain>],[<target>[,<port>[,<priority>[,<weight>]]]]
|
||||
.B \-W, --srv-host=<_servicio>.<_prot>.[<dominio>],[<target>[,<puerto>[,<prioridad>[,<peso>]]]]
|
||||
Retornar un record SRV DNS. Ver RFC2782 para detalles. Si no es
|
||||
brindada, el dominio se predetermina a el brindado por
|
||||
.B --domain.
|
||||
El predeterminado para el dominio target está vacío, y el predeterminado
|
||||
para puerto es uno y los predeterminados para peso y prioridad son cero.
|
||||
El predeterminado para el dominio target está vacío, el predeterminado
|
||||
para puerto es uno, y los predeterminados para peso y prioridad son cero.
|
||||
Tener cuidado al transponer data desde archivos de zona BIND: los
|
||||
números de puerto, peso, y prioridad están en un orden diferente. Más
|
||||
de un record SRV para un servicio/dominio es permitido, todos los que
|
||||
coincidan son retornados.
|
||||
.TP
|
||||
.B \-Y, --txt-record=<name>[[,<text>],<text>]
|
||||
.B \-Y, --txt-record=<nombre>[[,<texto>],<texto>]
|
||||
Retornar un récord DNS TXT. El valor del récord TXT es una serie de
|
||||
strings, así que cualquier número puede ser incluido, dividido por
|
||||
comas.
|
||||
.TP
|
||||
.B \-c, --cache-size=<cachesize>
|
||||
.B --ptr-record=<nombre>[,<target>]
|
||||
Retornar un récord DNS PTR.
|
||||
.TP
|
||||
.B \-c, --cache-size=<tamaño de caché>
|
||||
Fijar el tamaño del caché de dnsmasq. El predeterminado es 150 nombres.
|
||||
Fijar el tamaño a cero deshabilita el caché.
|
||||
.TP
|
||||
@@ -354,32 +382,40 @@ recordar resultados tipo "dominio no existe" desde servidores DNS
|
||||
upstream y responder búsquedas idénticas sin reenviarlas nuevamente.
|
||||
Esta opción deshabilita el caché negativo.
|
||||
.TP
|
||||
.B \-F, --dhcp-range=[[net:]network-id,]<start-addr>,<end-addr>[[,<netmask>],<broadcast>][,<default lease time>]
|
||||
.B \-0, --dns-forward-max=<búsquedas>
|
||||
Fijar el número máximo de búsquedas DNS simultáneas. El valor
|
||||
predeterminado es 150, lo cuál debería estar bien para la mayoría
|
||||
de casos. La única situación conocida donde esto debe ser incrementado
|
||||
es al usar resolvedores de bitácoras de servidores web, los cuales pueden
|
||||
generar un número inmenso de búsquedas simultáneas.
|
||||
.TP
|
||||
.B \-F, --dhcp-range=[[net:]network-id,]<dirección-inicio>,<dirección-final>[[,<máscara>],<broadcast>][,<tiempo de arriendo predeterminado>]
|
||||
Habilitar el servidor DHCP. Direcciones serán distribuidas desde el
|
||||
rango <start-addr> hasta <end-addr> y desde direcciones definidas
|
||||
estáticamente en opciones
|
||||
.B dhcp-host
|
||||
Si el tiempo de arriendo es brindado, entonces arriendos serán
|
||||
dados por esa cantidad de tiempo. El tiempo de arriendo es en
|
||||
segundos, o minutos (ej. 45m), o horas (ej. 1h), o el literal
|
||||
"infinite". Esta opción puede ser repetida, con diferentes
|
||||
segundos, o minutos (por ejemplo, 45m), o horas (por ejemplo, 1h), o el
|
||||
literal "infinite". Esta opción puede ser repetida, con diferentes
|
||||
direcciones para habilitar servicio DHCP en más de una red. Para
|
||||
redes conectadas diréctamente (en otras palabras, redes en las
|
||||
cuales la máquina corriendo dnsmasq tiene una interface) la
|
||||
máscara de subred es opcional. Es requerida para redes que
|
||||
máscara de subred es opcional. Pero, es requerida para redes que
|
||||
reciben servicio DHCP vía un agente de relay. La dirección de
|
||||
broadcast siempre es opcional. En algunos sistemas rotos, dnsmasq
|
||||
solo puede escuchar en una interface cuando se usa DHCP, y el
|
||||
nombre de esa interface debe ser brindado usando la opcion
|
||||
nombre de esa interface debe ser brindado usando la opción
|
||||
.B interface
|
||||
Esta limitación actualmente afecta a OpenBSD. Siempre se permite
|
||||
tener más de un rango dhcp (dhcp-range) en una subred. El
|
||||
parametro opcional network-id es una etiqueta alfanumerica la
|
||||
cual marca esta red de tal forma que opciones dhcp puedan ser
|
||||
Esta limitación actualmente afecta a OpenBSD antes de versión 4.0.
|
||||
Siempre se permite tener más de un rango dhcp (dhcp-range) en una
|
||||
subred. El parámetro opcional network-id es una etiqueta alfanumérica
|
||||
la cual marca esta red de tal forma que opciones dhcp puedan ser
|
||||
especificadas en base a cada red.
|
||||
Cuando es prefijada con 'net:' entonces el significado cambia
|
||||
de "fijar etiqueta" a "coincidir con etiqueta".
|
||||
La dirección final puede ser remplazada por la palabra
|
||||
de "fijar etiqueta" a "coincidir con etiqueta". Solo una etiqueta puede
|
||||
ser fijada, pero más de una puede ser revisada por coincidencias. La
|
||||
dirección final puede ser remplazada por la palabra clave
|
||||
.B static
|
||||
la cual le dice a dnsmasq que debe habilitar DHCP para la red
|
||||
especificada, pero no alocar dinámicamente direcciones IP.
|
||||
@@ -387,7 +423,7 @@ Solo hosts que tienen direcciones est
|
||||
.B dhcp-host
|
||||
o desde /etc/ethers serán servidas.
|
||||
.TP
|
||||
.B \-G, --dhcp-host=[[<hwaddr>]|[id:[<client_id>][*]]][net:<netid>][,<ipaddr>][,<hostname>][,<lease_time>][,ignore]
|
||||
.B \-G, --dhcp-host=[<dirección de hardware>][,id:<client_id>|*][,net:<netid>][,<dirección IP>][,<nombre de host>][,<tiempo de arriendo>][,ignore]
|
||||
Especificar parámetros por host para el servidor DHCP. Esto permite
|
||||
que una máquina con una dirección de hardware particular sea siempre
|
||||
alocada el mismo nombre de host, dirección IP, y tiempo de arriendo.
|
||||
@@ -410,7 +446,7 @@ hardware para identificar hosts prefijando 'id:'. O sea que:
|
||||
.B --dhcp-host=id:01:02:03:04,.....
|
||||
se refiere al host con identificador de cliente 01:02:03:04.
|
||||
También se permite especificar el ID de cliente como texto, así:
|
||||
.B --dhcp-host=id:clientidastext,.....
|
||||
.B --dhcp-host=id:iddeclientecomotexto,.....
|
||||
La opción especial id:* significa "ignorar cualquier ID de cliente
|
||||
y usar solamente direcciones MAC." Esto es útil cuando un cliente
|
||||
presenta un ID de cliente algunas veces pero otras no.
|
||||
@@ -423,7 +459,7 @@ una m
|
||||
hardware, ID de cliente, o nombre de host, por ejemplo:
|
||||
.B --dhcp-host=00:20:e0:3b:13:af,ignore
|
||||
Esto es útil cuando hay otro servidor DHCP en la red para ser
|
||||
usado por algúnas máquinas. net:<network-id> fija la etiqueta
|
||||
usado por algúnas máquinas. El net:<network-id> fija la etiqueta
|
||||
network-id cuando sea que esta directiva dhcp-host está en uso.
|
||||
Esto puede ser usado para enviar selectivamente opciones DHCP
|
||||
a este host.
|
||||
@@ -448,7 +484,7 @@ dnsmasq, estas l
|
||||
.B --dhcp-host
|
||||
que contienen la misma información.
|
||||
.TP
|
||||
.B \-O, --dhcp-option=[<network-id>,[<network-id>,]][vendor:<vendor-class>]<opt>,[<value>[,<value>]]
|
||||
.B \-O, --dhcp-option=[<network-id>,[<network-id>,]][vendor:[<vendor-class>],][<opt>|option:<opt-name>],[<value>[,<value>]]
|
||||
Especificar opciones diferentes o extra a clientes DHCP. Por
|
||||
predeterminado, dnsmasq envía algunas opciones estándar a clientes
|
||||
DHCP. La máscara de subred y dirección broadcast son fijadas igual
|
||||
@@ -456,20 +492,33 @@ a las del host que corre dnsmasq, y el servidor DNS y ruteador
|
||||
a la dirección de la máquina que corre dnsmasq. Si la opción de
|
||||
nombre de dominio ha sido fijada, es enviada. Esta opción permite
|
||||
que esos predeterminados sean sobrescritos, o que sean especificadas
|
||||
otras opciones. <opt> es el numero de la opción, como especificado
|
||||
en RFC2132. Por ejemplo, para fijar a ruta predeterminada a
|
||||
otras opciones. La opción a ser enviada puede ser brindada como un
|
||||
número decimal o como "option:<option-name>". Los números de opción
|
||||
están especificados en RFC2132 y RFCs subsiguientes. El juego de
|
||||
option-names conocido por dnsmasq puede ser descubierto ejecutando
|
||||
"dnsmasq --help dhcp". Por ejemplo, para fijar a ruta predeterminada a
|
||||
192.168.4.4, hágase un
|
||||
.B --dhcp-option=3,192.168.4.4
|
||||
o
|
||||
.B --dhcp-option = option:router, 192.168.4.4
|
||||
y para fijar la dirección de servidor de tiempo a 192.168.0.4,
|
||||
hágase un
|
||||
.B --dhcp-option=42,192.168.0.4
|
||||
o
|
||||
.B --dhcp-option = option:ntp-server, 192.168.0.4
|
||||
La dirección especial 0.0.0.0 es entendida que significa "la
|
||||
dirección de la máquina que corre dnsmasq". Tipos de data permitidos
|
||||
son direcciones IP de cuatro puntos, un número decimal, dígitos hex
|
||||
son direcciones IP de cuatro segmentos, un número decimal, dígitos hex
|
||||
separados por colones, y un string de texto. Si las network-ids
|
||||
opcionales son brindadas, entonces esta opcion es solo enviada cuando
|
||||
todas las network-ids coinciden.
|
||||
|
||||
Procesamiento especial es llevado a cabo en un argumento de texto para
|
||||
la opción 119, en conforme con RFC3397. Direcciones IP textuales o de
|
||||
cuatro segmentos como argumentos a la opción 120 son manejados mediante
|
||||
RFC3361. Direcciones IP de cuatro segmentos que son seguidas por un diagonal
|
||||
(slash) y después una máscara son codificados mediante RFC3442.
|
||||
|
||||
Tener cuidado: niguna verificación es hecha sobre si el número de tipo
|
||||
correcto es enviado, y es muy posible persuadir a dnsmasq para que
|
||||
genere paquetes DHCP ilegales mediante uso inadecuado de esta opción.
|
||||
@@ -486,20 +535,33 @@ Para forzar un string literal, usar comillas. Por ejemplo, cuando se
|
||||
usa la opción 66 para enviar una IP literal como un nombre de servidor
|
||||
TFTP, es necesario hacer:
|
||||
.B --dhcp-option=66,"1.2.3.4"
|
||||
Opciones encapsuladas vendor-class también pueden ser especificadas
|
||||
usando
|
||||
|
||||
Opciones encapsuladas vendor-class también pueden ser especificadas usando
|
||||
--dhcp-option: por ejemplo
|
||||
.B --dhcp-option=vendor:PXEClient,1,0.0.0.0
|
||||
envía la clase de vendedor "PXEClient" y la clase encapsulada de vendedor
|
||||
especifica "mftp-address=0.0.0.0". Solo se permite una clase para cualquier
|
||||
host, pero opciones múltiples son permitidas, con tal que tengan la misma
|
||||
clase de vendedor. La dirección 0.0.0.0 no es tratada de forma especial
|
||||
en opciones de clase encapsuladas.
|
||||
envía la opción específica de clase de vendedor "mftp-address=0.0.0.0" a
|
||||
cualquier cliente cuyo vendor-class
|
||||
coincida con "PXEClient". El revisado de coincidencias vendor-class está
|
||||
basado en substrings (ver --dhcp-vendorclass para detalles). Si una opción
|
||||
vendor-class (número 60) es enviada por dnsmasq, entonces es usada para
|
||||
seleccionar opciones encapsuladas en preferencia sobre cualquiera enviada
|
||||
por el cliente. Es posible omitir el vendorclass completamente;
|
||||
.B --dhcp-option=vendor:,1,0.0.0.0
|
||||
caso en el cuál la opción encapsulada siempre es enviada. La dirección
|
||||
0.0.0.0 no es tratada de forma especial en opciones de clase de vendedor
|
||||
encapsuladas.
|
||||
.TP
|
||||
.B --dhcp-option-force=[<network-id>,[<network-id>,]][vendor:[<vendor-class>],]<opt>,[<value>[,<value>]]
|
||||
Esto funciona exáctamente de la misma forma que
|
||||
.B --dhcp-option
|
||||
excepto que la opción siempre será enviada, aún si el cliente no lo pide en
|
||||
la lista de pedido de parámetros. Esto se necesita aveces, por ejemplo cuando
|
||||
enviando opciones a PXELinux.
|
||||
.TP
|
||||
.B \-U, --dhcp-vendorclass=<network-id>,<vendor-class>
|
||||
Mapear desde un string vendor-class a un network id. La mayoría de los
|
||||
Trazar desde un string vendor-class a un network id. La mayoría de los
|
||||
clientes DHCP proveen una "vendor class" la cual representa, en cierto
|
||||
sentido, el tipo de host. Esta opción mapea clases de vendedor a network
|
||||
sentido, el tipo de host. Esta opción traza clases de vendedor a network
|
||||
ids, de tal forma que opciones DHCP pueden ser selectivamente entregadas
|
||||
a diferentes clases de hosts. Por ejemplo
|
||||
.B dhcp-vendorclass=printers,Hewlett-Packard JetDirect
|
||||
@@ -509,35 +571,58 @@ El string vendor-class es coordinado con el vendor-class proveido por
|
||||
el cliente, para permitir coincidencias borrosas.
|
||||
.TP
|
||||
.B \-j, --dhcp-userclass=<network-id>,<user-class>
|
||||
Mapear desde un string user-class a un network id (con coordinación
|
||||
Trazar desde un string user-class a un network id (con coordinación
|
||||
substring, como con vendor-class). La mayoría de los clientes DHCP
|
||||
proveen un "user class" el cual es configurable. Esta opción mapea
|
||||
proveen un "user class" el cual es configurable. Esta opción traza
|
||||
clases user a network ids, de tal manera que opciones DHCP puedan
|
||||
ser selectivamente enviadas a diferentes tipos de hosts. Es posible,
|
||||
por ejemplo, usar esto para especificar una impresora diferente para
|
||||
hosts en la clase "accounts" que para los de la clase "engineering".
|
||||
hosts en la clase "cuentas" que para los de la clase "ingenieria".
|
||||
.TP
|
||||
.B \-4, --dhcp-mac=<network-id>,<MAC address>
|
||||
.B \-4, --dhcp-mac=<network-id>,<dirección MAC>
|
||||
Mapear desde una dirección MAC a una network id. La dirección MAC
|
||||
puede incluir comodínes. Por ejemplo:
|
||||
.B --dhcp-mac=3com,01:34:23:*:*:*
|
||||
fijaría el tag "3com" a cualquier host el cual su MAC coincida con
|
||||
el patrón.
|
||||
.TP
|
||||
.B --dhcp-circuitid=<network-id>,<circuit-id>, --dhcp-remoteid=<network-id>,<remote-id>
|
||||
Trazar de opciones agente de relay RFC3046 a opciones network-id. Estos
|
||||
datos pueden ser proveídos por agentes de relay DHCP. El circuit-id o
|
||||
remote-id es normlamente brindado como hex separado por doblepuntos, pero
|
||||
también se permite un string simple. Si se obtiene una coincidencia exacta
|
||||
entre el circuit o agent ID y uno proveído por un agente de relay,
|
||||
network-id es fijado.
|
||||
.TP
|
||||
.B --dhcp-subscrid=<network-id>,<subscriber-id>
|
||||
Trazar de opciones relay subscriber-id RFC3993 a opciones network-id.
|
||||
.TP
|
||||
.B \-J, --dhcp-ignore=<network-id>[,<network-id>]
|
||||
Cuando todos los network ids brindados coincidan con el juego de
|
||||
network ids derivados de las clases net, host, y vendor, ignorar
|
||||
el host y no brindarle un arriendo DHCP.
|
||||
.TP
|
||||
.B --dhcp-ignore-name[=<network-id>[,<network-id>]]
|
||||
Cuando todos los network-ids brindados coinciden con el juego de
|
||||
network-ids derivado de la red, host, classes de vendedor y usuario,
|
||||
ignorar cualquier nombre de host proveido por el host. Nótese que,
|
||||
a diferencia de dhcp-ignore, es permisible no brindar ningún tag netid,
|
||||
y en tal caso nombres de host proveidos por clientes DHCP siempre son
|
||||
ignorados, y hosts DHCP son agregados al DNS usando solo la configuración
|
||||
dhcp-host en dnsmasq y el contenido de /etc/hosts y /etc/ethers.
|
||||
.TP
|
||||
.B \-M, --dhcp-boot=[net:<network-id>,]<filename>,[<servername>[,<server address>]]
|
||||
Fijar opciones BOOTP que han de ser devueltas por el servidor DHCP.
|
||||
Estas se necesitan para máquinas que bootean desde la red, y decirle
|
||||
a la máquina donde conseguir su configuración inicial. Si las network
|
||||
id opcionales son brindadas, deben coincidir con esta opción para ser
|
||||
enviadas. Nótese que network ids son prefijadas con "net:" para
|
||||
distinguirlas.
|
||||
Fijar opciones BOOTP que han de ser devueltas por el servidor DHCP. Nombre
|
||||
y dirección de servidor son opcionales: si no son brindadas, el nombre es
|
||||
dejado en blanco, y la dirección es fijada a la de la máquina que corre
|
||||
dnsmasq. Si dnsmasq está brindando servicio TFTP (ver
|
||||
.B --enable-tftp
|
||||
) entonces solo el nombre de archivo es requirido aquí para habilitar
|
||||
el inicio atravéz de una red. Si las opcionales network-ids son brindadas,
|
||||
ellas deberán coincidir para que esta configuración sea enviada. Nótese
|
||||
que network-ids están prefijadas con "net:" para distinguirlas.
|
||||
.TP
|
||||
.B \-X, --dhcp-lease-max=<number>
|
||||
.B \-X, --dhcp-lease-max=<número>
|
||||
Limita a dnsmasq a el número especificado de arriendos DHCP. El
|
||||
predeterminado es 150. El limite es para prevenir ataques DoS desde
|
||||
hosts que crean cientos de arriendos y usan mucha de la memoria del
|
||||
@@ -554,55 +639,92 @@ es perdida.
|
||||
.TP
|
||||
.B \-3, --bootp-dynamic
|
||||
Habilitar alocación dinámica de direcciones IP a clientes BOOTP. Usar
|
||||
esto con cuidado, ya que cada cirección alocada a un cliente BOOTP
|
||||
esto con cuidado, ya que cada dirección alocada a un cliente BOOTP
|
||||
es arrendada para siempre, y consecuentemente queda no-disponible
|
||||
para uso por otros hosts.
|
||||
para re-uso por otros hosts.
|
||||
.TP
|
||||
.B \-5, --no-ping
|
||||
Por predetermindado, el servidor DHCP tratará de asegurarse que una
|
||||
dirección no esté en uso antes de alocarsela a un host. Hace esto
|
||||
enviando un echo ICMP (ping) a la dirección referente. Si recibe una
|
||||
respuesta, entonces la dirección debe estar siendo usada, y se repite
|
||||
la prueba con otra. Esta opcion deshabilita esta prueba. Usar con
|
||||
la prueba con otra. Esta opción deshabilita esta prueba. Usar con
|
||||
cuidado.
|
||||
.TP
|
||||
.B --log-dhcp
|
||||
Bitacoréo extra para DHCP: Bitacorear todas las opciones enviadas a
|
||||
clientes DHCP y los tags netid usados para determinarlos.
|
||||
.TP
|
||||
.B \-l, --dhcp-leasefile=<path>
|
||||
Usar el archivo especificado para almacenar informacion de arriendos
|
||||
DHCP. Si esta opcion es brindada, pero ninguna opcion dhcp-range es
|
||||
Usar el archivo especificado para almacenar información de arriendos
|
||||
DHCP. Si esta opción es brindada, pero ninguna opcion dhcp-range es
|
||||
brindada, entonces se activa comportamiento tipo dnsmasq versión 1.
|
||||
El archivo brindado se asume es un archivo de arriendos dhcpd ISC y
|
||||
es analizado en busca de arriendos los cuales son agregados al sistema
|
||||
DNS si tienen un nombre de host. Esta funcionalidad pudo haber sido
|
||||
excluida de dnsmasq a la hora de compilación, y en tal caso ocurrirá
|
||||
un error. En todo caso, nótese que la integración de archivos de
|
||||
un error. Nótese que la integración de archivos de
|
||||
arriendo ISC es una caracterísctica depreciada. No debería ser usada
|
||||
en instalaciones nuevas, y será eliminada en versiones futuras.
|
||||
.TP
|
||||
.B \-6 --dhcp-script=<path>
|
||||
Cuando sea que un arriendo DHCP nuevo es creado, o uno viejo es
|
||||
Cuando un arriendo DHCP nuevo es creado, o uno viejo es
|
||||
destruido, el binario especificado por esta opción es ejecutado.
|
||||
Los argumentos para el binario son "add", "old", o "del", la dirección
|
||||
MAC del host (o "<null>"), la dirección IP, y el hostname, si es
|
||||
conocido. "add" significa que un arriendo ha sido creado, "del" que
|
||||
ha sido destruido, y "old" es una notificación de un arriendo existente
|
||||
cuando dnsmasq inicia o un cambio a una MAC o nombre host de un arriendo
|
||||
existente. Este proceso es ejecutado como el usuario sin privilegios
|
||||
como corre dnsmasq, así que puede ser necesario inhibir el dejar el
|
||||
usuario root, usando la directiva
|
||||
.B -u
|
||||
si el ejecutable necesita privilegios root.
|
||||
El ambiente es heredado del usuario que ha invocado a dnsmasq, y todos
|
||||
los descriptores están cerrados excepto stdin, stdout y stderr los cuales
|
||||
están abiertos a /dev/null (excepto en modo debug).
|
||||
existente (también, tiempo de arriendo o vencimiento y client-id, si
|
||||
leasefile-ro está fijado). El proceso es ejecutado como root (asumiendo
|
||||
que dnsmasq fue originalmente ejecutado como root) aún si dnsmasq está
|
||||
configurado para cambiar su UID a un usuario sin privilegios.
|
||||
El ambiente es heredado del usuario que ha invocado a dnsmasq, y si el
|
||||
host brindó un client-id, es almacenado en la variable de ambiente
|
||||
DNSMASQ_CLIENT_ID. Si el cliente brinda información de clase de vendedor
|
||||
o usuario, estos son brindados en las variables DNSMASQ_VENDOR_CLASS y
|
||||
DNSMASQ_USER_CLASS0..DNSMASQ_USER_CLASSn, pero solo para acciones "add"
|
||||
y "old" cuando un host resume un arriendo existente, dado a que estos
|
||||
datos no son almacenados en la base de datos de arriendos de dnsmasq.
|
||||
Si dnsmasq fue compilado con HAVE_BROKEN_RTC, entonces la duración del
|
||||
arriendo (en segundos) es almacenada en DNSMASQ_LEASE_LENGTH, de otra
|
||||
manera el tiempo de vencimiento es almacenado en DNSMASQ_LEASE_EXPIRES.
|
||||
Si un arriendo solía tener un nombre de host, el cual es removido, un
|
||||
evento "old" es generado con el nuevo estado del arriendo, (por ejemplo, sin
|
||||
nombre), y el nombre anterior es brindado en la variable de ambiente
|
||||
DNSMASQ_OLD_HOSTNAME. Todos los descriptores de archivo están cerrados
|
||||
excepto stdin, stdout, y stderr los cuales están abiertos a /dev/null
|
||||
(excepto en modo debug).
|
||||
Este guión no es invocado concurrentemente: si cambios de arriendos
|
||||
subsiguientes ocurren, el guión no es invocado otra vez hasta que
|
||||
cualquier invocación existennte haga exit. Al inicio de dnsmasq, el guión
|
||||
cualquier invocación existente haga exit. Al inicio de dnsmasq, el guión
|
||||
será invocado para todos los arriendos existenetes mientras van siendo
|
||||
leidos desde el archivo de arriendos. Arriendos vencidos serán llamados
|
||||
leídos desde el archivo de arriendos. Arriendos vencidos serán llamados
|
||||
con "del" y otros con "old". <path> debe ser un path absoluto, ninguna
|
||||
búsqueda PATH ocurre.
|
||||
.TP
|
||||
.B \-s, --domain=<domain>
|
||||
.B \-9, --leasefile-ro
|
||||
Suprimir completamente el uso del archivo de arriendos. El archivo no será
|
||||
creado, leído, o escrito. Cambiar la manera en la cuál el archivo guión de
|
||||
cambio de arriendo es llamado, de tal forma que la base de datos de arriendos
|
||||
pueda ser mantenida en almacenaje externo por el archivo guión. Adicionálmente
|
||||
a las invocaciones brindadas en
|
||||
.B --dhcp-script
|
||||
el archivo de cambio de arriendos es llamado una vez, al inicio de dnsmasq,
|
||||
con el único argumento "init". Cuando invocado de esta forma, el guión debería
|
||||
escribir el estado guardado de la base de datos de arriendos, en formato de
|
||||
archivo de arriendos dnsmasq, a stdout y hacer exit con código exit cero. Fijar
|
||||
esta opción también forza que el archivo de cambio de arriendos sea llamado
|
||||
cuando hay cambios hechos a el client-id y tiempos de arriendo y vencimiento.
|
||||
.TP
|
||||
.B --bridge-interface=<nombre de interface>,<alias>[,<alias>]
|
||||
Tratar paquetes de pedidos DHCP que llegan a cualquiera de las interfaces <alias>
|
||||
como si hubieran llegado a la interface <nombre de interface>. Esta opción solo
|
||||
está disponible en FreeBSD y Dragonfly BSD, y es necesaria cuando se usan
|
||||
puentes "estilo viejo", ya que los paquetes llegan a interfaces tap que no
|
||||
tienen una dirección IP.
|
||||
.TP
|
||||
.B \-s, --domain=<dominio>
|
||||
Especifica el dominio para el servidor DHCP. Esto tiene dos efectos:
|
||||
Primeramente, causa que el servidor DHCP le devuelva el dominio a
|
||||
cualquier host que lo pida. Segundamente, fija el dominio para el cual
|
||||
@@ -611,7 +733,7 @@ restringir nombres de host para que un host no-confiado en la LAN no
|
||||
pueda proclamar su nombre vía DHCP, como por ejemplo "microsoft.com" y
|
||||
capturar tráfico no destinado a ella. Si ningún sufijo de dominio es
|
||||
especificado, entonces cualquier nombre de host con una parte de dominio
|
||||
(o sea con un punto) será negada y logeada. Si un sufijo es especificado,
|
||||
(o sea con un punto) será negada y bitacorada. Si un sufijo es especificado,
|
||||
entonces nombres de host con una parte de dominio son permitidos, con tal
|
||||
que la parte de dominio coincida con el sufijo. Adicionalmente, cuando
|
||||
un sufijo es fijado, entonces nombres de host sin parte de dominio tienen
|
||||
@@ -622,12 +744,47 @@ y tener una maquina cuyo nombre host DHCP es "laptop". La direcci
|
||||
de esa máquina es disponible desde
|
||||
.B dnsmasq
|
||||
como "laptop" y "laptop.thekelleys.org.uk". Si el dominio es brindado
|
||||
como "#" entonces el dominio es leido desde la primera directiva de
|
||||
búsqueda en /etc/resolv.conf (o equivalente).
|
||||
como "#" entonces el dominio es leido desde la primera directiva search
|
||||
en /etc/resolv.conf (o equivalente).
|
||||
.TP
|
||||
.B \-E, --expand-hosts
|
||||
Agregar el dominio a nombres simples (sin un punto) en /etc/hosts de
|
||||
la misma manera que con nombres derivados de DHCP.
|
||||
.B --enable-tftp
|
||||
Habilitar la función de servidor TFTP. Esto está deliberadamente limitado
|
||||
a lo necesario para hacerle a un cliente un inicio vía red: solo lectura es
|
||||
permitida, y solo en modo binario/octeto. Las extensiones "tsize" y "blksize"
|
||||
están soportadas.
|
||||
.TP
|
||||
.B --tftp-root=<directorio>
|
||||
Buscar, relativo al directorio brindado, archivos para transferir mediante el
|
||||
uso de TFTP. Cuando esta opción está fijada, paths TFTP que incluyen ".." son
|
||||
rechazados, para prevenir que clientes salgan de la raíz especificada. Paths
|
||||
absolutos (los que comienzan con "/") están permitidos, pero deben estar
|
||||
dentro del tftp-root.
|
||||
.TP
|
||||
.B --tftp-secure
|
||||
Habilitar modo TFTP seguro: sin esto, cualquier archivo que es leíble por el
|
||||
proceso dnsmasq bajo reglas normales de control de acceso UNIX, está disponible
|
||||
vía TFTP. Cuando la opción --tftp-secure es fijada, solo archivos
|
||||
pertenecientes al usuario que corre el proceso dnsmasq están accesibles. Si
|
||||
dnsmasq está corriendo como root, reglas diferentes aplican: --tftp-secure no
|
||||
tiene ningún efecto, pero solo archivos que tienen el bit de lectura global
|
||||
fijados están accesibles. No se recomienda correr dnsmasq como root con TFTP
|
||||
habilitado, y mucho menos sin especificar --tftp-root, ya que se puede exponer
|
||||
cualquier archivo de lectura global en el servidor a cualquier host de la red.
|
||||
.TP
|
||||
.B --tftp-max=<conecciones>
|
||||
Fijar el número máximo permitido de conecciones TFTP simultáneas. Esto es 50
|
||||
por predeterminado. Al servir un número grande de conecciones TFTP, límites
|
||||
de descriptor de archivo por proceso pueden ser encontrados. Dnsmasq necesita
|
||||
un descriptor de archivo por cada coneccion TFTP concurrente, y por archivo
|
||||
único (mas algunos otros). De tal manera que servirle el mismo archivo
|
||||
simultáneo a n clientes requerirá el uso de n + 10 descriptores de archivo,
|
||||
y servirles archivos diferentes simultáneamente requerirá (2*n) + 10
|
||||
descriptores.
|
||||
.TP
|
||||
.B --tftp-no-blocksize
|
||||
No permitir que el servidor negocie la opción "blocksize" con un cliente.
|
||||
Algunos clientes con errores piden esta opción pero se portán mal cuando se
|
||||
les brinda.
|
||||
.TP
|
||||
.B \-C, --conf-file=<archivo>
|
||||
Especificar un archivo de configuración diferente. La opción conf-file
|
||||
@@ -644,7 +801,7 @@ Al inicio, dnsmasq lee
|
||||
.I /etc/dnsmasq.conf,
|
||||
si existe. (En FreeBSD, el archivo es
|
||||
.I /usr/local/etc/dnsmasq.conf
|
||||
) (ver las opciónes
|
||||
) (pero ver las opciónes
|
||||
.B \-C
|
||||
y
|
||||
.B \-7
|
||||
@@ -652,8 +809,8 @@ porfavor.) El formato de este archivo consiste de una opci
|
||||
exáctamente como las opciones largas detalladas en la sección OPCIONES
|
||||
pero sin el "--" al frente. Líneas que comienzan con # son comentarios
|
||||
y son ignoradas. Para opciones que solo pueden ser especificadas una
|
||||
sola vez, la línea de comandos invalida el archivo de configuración.
|
||||
La comillas son permitidas en el archivo de configuración: entre comillas
|
||||
sola vez, el archivo de configuración invalida la línea de comandos.
|
||||
Las comillas son permitidas en el archivo de configuración: entre comillas
|
||||
tipo " los significados especiales de ,:. y # son eliminados y los
|
||||
siguientes escapes son permitidos: \\\\ \\" \\t \\a \\b \\r y \\n. El
|
||||
último corresponde a tab, bell, backspace, return y newline.
|
||||
@@ -661,24 +818,23 @@ siguientes escapes son permitidos: \\\\ \\" \\t \\a \\b \\r y \\n. El
|
||||
Al recibir un SIGHUP
|
||||
.B dnsmasq
|
||||
libera su cache y entonces recarga
|
||||
.I /etc/hosts.
|
||||
.I /etc/hosts y /etc/ethers.
|
||||
Si
|
||||
.B
|
||||
--no-poll
|
||||
está fijado entnces SIGHUP también re-lee
|
||||
está fijado entonces SIGHUP también re-lee
|
||||
.I /etc/resolv.conf.
|
||||
SIGHUP
|
||||
NO re-lee el archivo de configuración.
|
||||
.PP
|
||||
Al recibir un SIGUSR1,
|
||||
.B dnsmasq
|
||||
escribe estadisticas de caché al log del sistema. Escribe el tamaño
|
||||
escribe estadisticas de caché a la biácora del sistema. Escribe el tamaño
|
||||
del caché, el numero de nombres que han tenido que ser removidos del
|
||||
caché antes de que vencieran para hacer espacio para nombres nuevos
|
||||
y el número total de nombres que han sido insertados en el caché. En
|
||||
modo
|
||||
caché antes de que vencieran para hacer espacio para nombres nuevos, y el
|
||||
número total de nombres que han sido insertados en el caché. En modo
|
||||
.B --no-daemon
|
||||
o cuando logeo completo está habilitado (-q), una descarga completa de
|
||||
o cuando bitacoréo completo está habilitado (-q), una descarga completa de
|
||||
el contenido del caché es hecha.
|
||||
.PP
|
||||
Dnsmasq es un reenviador de búsquedas DNS: no puede responder búsquedas
|
||||
@@ -696,7 +852,7 @@ revisa el tiempo de modificaci
|
||||
.I /etc/resolv.conf
|
||||
(o equivalente si
|
||||
.B \--resolv-file
|
||||
es usado) y lo re-lee si ha cambiado. Esto permite que servidores DNS séan
|
||||
es usado) y lo re-lee si ha cambiado. Esto permite que servidores DNS séan
|
||||
fijados dinámicamente vía PPP o DHCP ya que ambos protocolos brindan esta
|
||||
información.
|
||||
La ausencia de
|
||||
@@ -705,36 +861,34 @@ no es un error ya que pudo haber sido creada antes de que una conexi
|
||||
haya existido. Dnsmasq simplemente sigue revisando en caso de que
|
||||
.I /etc/resolv.conf
|
||||
sea creado en algún momento. A dnsmasq se le puede decir que revise más
|
||||
de un archivo resolv.conf. Esto es útil en una laptp, donde ambos PPP y
|
||||
DHCP podrían estar siendo usados: dnsmasq puede ser fijado para revisar
|
||||
ambos:
|
||||
de un archivo resolv.conf. Esto es útil en una laptop, donde ambos PPP y
|
||||
DHCP podrían estar siendo usados: dnsmasq puede ser fijado para revisar ambos:
|
||||
.I /etc/ppp/resolv.conf
|
||||
y
|
||||
.I /etc/dhcpc/resolv.conf
|
||||
y usará el contenido de cualquiera que haya cambiado mas recientemente,
|
||||
y usará el contenido del que haya cambiado mas recientemente,
|
||||
brindando así la habilidad de cambio automático entre servidores DNS.
|
||||
.PP
|
||||
Servidores upstream también pueden ser especificados en la línea de
|
||||
comandos o en el archivo de configuración. Estas especificaciones de
|
||||
servidor ocpionalmente llevan un nombre de dominio el cual le dice a
|
||||
servidor opcionalmente llevan un nombre de dominio el cual le dice a
|
||||
dnsmasq que debe usar ese servidor solo para encontrar nombres en ese
|
||||
dominio en particular.
|
||||
.PP
|
||||
Para configurar dnsmasq para que actúe como caché para el host donde está
|
||||
Para configurar dnsmasq como caché para el host donde está
|
||||
corriendo, poner un "nameserver 127.0.0.1" en
|
||||
.I /etc/resolv.conf
|
||||
para así forzar procesos locales a enviar búsquedas a dnsmasq. Entonces
|
||||
o espesificar los servidores upstream diréctamente a dnsmasq usando
|
||||
opciones
|
||||
para así forzar procesos locales a enviar búsquedas a dnsmasq. Entonces,
|
||||
o especificar los servidores upstream diréctamente a dnsmasq usando opciones
|
||||
.B \--server
|
||||
o poniendo sus direcciones reales en otro archivo, digamos
|
||||
.I /etc/resolv.dnsmasq
|
||||
y correr dnsmasq con la opcion
|
||||
.B \-r /etc/resolv.dnsmasq
|
||||
Esta segunda técnica permite la actualización dinámica de las direcciones
|
||||
de servidores mediante PPP o DHCP.
|
||||
de servidor mediante PPP o DHCP.
|
||||
.PP
|
||||
Direcciones en /etc/hosts harán "sombra" a diferentes direcciones para
|
||||
Direcciones en /etc/hosts "harán sombra" a diferentes direcciones para
|
||||
los mismos nombres en servidores DNS upstream, así que
|
||||
"miempresa.com 1.2.3.4" en /etc/hosts se asegurará que las búsquedas
|
||||
por "miempresa.com" siempre retornarán 1.2.3.4 aún si búsquedas en el
|
||||
@@ -742,7 +896,7 @@ servidor DNS upstream devolver
|
||||
excepción a esto: si el servidor DNS upstream contiene un CNAME que
|
||||
apunta a un nombre sombreado, entonces buscando el CNAME a travéz de
|
||||
dnsmasq resultará en que la dirección no-sombreada será asociada con
|
||||
el destino del CNAME. Para circumventar esto, agregar en CNAME a
|
||||
el destino del CNAME. Para circumventar esto, agregar el CNAME a
|
||||
/etc/hosts de tal manera que el CNAME es sombreado también.
|
||||
.PP
|
||||
El sistema network-id funciona de la siguiente manera: Para cada pedido
|
||||
@@ -753,7 +907,7 @@ usado para alocar la direcci
|
||||
.B dhcp-host
|
||||
que coincida, y posiblemente muchas de clases de vendedor y usuario
|
||||
que coinicdan que hayan sido enviadas por el cliente DHCP.
|
||||
Cualquier opcion
|
||||
Cualquier opción
|
||||
.B dhcp-option
|
||||
que tenga etiquetas network-id será usada en preferencia de una opción
|
||||
.B dhcp-option,
|
||||
@@ -767,8 +921,8 @@ Si el network-id en un
|
||||
.B dhcp-range
|
||||
es prefijado con "net:", entonces su significado cambia de "fijar
|
||||
etiqueta" a "coincidir con etiqueta". O sea que si hay más de un
|
||||
dhcp-range en enu subred, y una tiene una etiqueta network-id la
|
||||
cual está fijada (por ejemplo una opcion de clase de vendedor) entonces
|
||||
dhcp-range en en una subred, y uno tiene una etiqueta network-id la
|
||||
cual está fijada (por ejemplo una opción de clase de vendedor) entonces
|
||||
hosts que fijen la etiqueta network-id serán alocados direcciones en
|
||||
el rango etiquetado.
|
||||
.PP
|
||||
@@ -781,12 +935,55 @@ o en
|
||||
, y una configuración
|
||||
.B dhcp-range
|
||||
esté presente para activar el servidor DHCP en una red particular.
|
||||
(Fijar --bootp-dynamic elimina la necesidad de mapeos estáticos.) El
|
||||
Parámetro de nombre de archivos en un pedido BOOTP es revisado para
|
||||
(Fijar --bootp-dynamic elimina la necesidad de trazados estáticos.) El
|
||||
parámetro de nombre de archivos en un pedido BOOTP es revisado para
|
||||
ver si coincide con algún network-id en configuraciónes
|
||||
.B dhcp-option
|
||||
permitiendo algún control sobre las opciones devueltas a diferentes
|
||||
clases de hosts.
|
||||
al igual que la etiqueta "bootp", permitiendo así algún control sobre
|
||||
las opciones devueltas a diferentes clases de hosts.
|
||||
|
||||
.SH LIMITES
|
||||
Los valores predeterminados para limites de recursos son generálmente
|
||||
conservadores, y apropiados para uso en dispositivos tipo enrutador
|
||||
encrustrado con procesadores lentos y poca memoria. En hardware más
|
||||
capáz, es posible incrementar los límites, y soportar muchos mas
|
||||
clientes. Lo siguiente se aplica a dnsmasq-2.37: versiones previas
|
||||
no escalaban tan bien.
|
||||
|
||||
.PP
|
||||
Dnsmasq es capaz de soportar con DNS y DHCP a por lo menos mil (1,000)
|
||||
clientes. Por supuesto que para lograr esto debe ser aumentadoo el valor de
|
||||
.B --dhcp-lease-max
|
||||
debe ser incrementado, y tiempos de arriendo no deben ser muy cortos
|
||||
(menos de una hora). El valor de
|
||||
.B --dns-forward-max
|
||||
puede ser aumentado: comienze con el equivalente a el número de clientes y
|
||||
auméntelo si parece lento el DNS. Nótese que el rendimiento DNS depende
|
||||
también de los servidores DNS upstream. El tamaño del caché DNS puede ser
|
||||
incrementado: el límite obligatorio es 10,000 nombres y el predeterminado
|
||||
(150) es muy bajo. Enviarle un SIGUSR1 a dnsmasq hace que bitacorée
|
||||
información que es útil para afinar el tamaño de caché. Ver la sección
|
||||
.B NOTAS
|
||||
para detalles.
|
||||
.PP
|
||||
El servidor TFTP incorporado es capáz de soportar varias transferencias
|
||||
simultáneas de archivos: el límite absoluto está relacionado con el número
|
||||
de file-handles permitidos a un proceso y la habilidad del system call
|
||||
select() a soportar números grandes de file-handles. Si el límite es fijado
|
||||
demasiado alto con
|
||||
.B --tftp-max
|
||||
será de-escalado y el límite real será bitacoreado al inicio. Nótese que más
|
||||
transferencias son posibles cuando el mismo archivo es enviado qué cuando
|
||||
cada transferencia envía un archivo diferente.
|
||||
.PP
|
||||
Es posible usar dnsmasq para negar publicidad Web usando una lista de
|
||||
servidores de banners bien conocidos, todos resolviendose a 127.0.0.1 o
|
||||
0.0.0.0 en
|
||||
.B /etc/hosts
|
||||
o en un archivo hosts adicional. La lista puede ser muy larga. Dnsmasq ha sido
|
||||
probado exitósamente con un millón de nombres. Ese tamaño de archivo necesita
|
||||
un CPU de 1GHz y aproximadamente 60MB de RAM.
|
||||
|
||||
.SH ARCHIVOS
|
||||
.IR /etc/dnsmasq.conf
|
||||
|
||||
|
||||
676
po/pt_BR.po
676
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
@@ -73,8 +73,8 @@ void send_via_bpf(struct daemon *daemon, struct dhcp_packet *mess, size_t len,
|
||||
/* Only know how to do ethernet on *BSD */
|
||||
if (mess->htype != ARPHRD_ETHER || mess->hlen != ETHER_ADDR_LEN)
|
||||
{
|
||||
syslog(LOG_WARNING, _("DHCP request for unsupported hardware type (%d) received on %s"),
|
||||
mess->htype, ifr->ifr_name);
|
||||
my_syslog(LOG_WARNING, _("DHCP request for unsupported hardware type (%d) received on %s"),
|
||||
mess->htype, ifr->ifr_name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
133
src/cache.c
133
src/cache.c
@@ -13,7 +13,7 @@
|
||||
#include "dnsmasq.h"
|
||||
|
||||
static struct crec *cache_head, *cache_tail, **hash_table;
|
||||
static struct crec *dhcp_inuse, *dhcp_spare, *new_chain;
|
||||
static struct crec *dhcp_spare, *new_chain;
|
||||
static int cache_inserted, cache_live_freed, insert_error;
|
||||
static union bigname *big_free;
|
||||
static int bignames_left, log_queries, cache_size, hash_size;
|
||||
@@ -74,7 +74,7 @@ void cache_init(int size, int logq)
|
||||
addrbuff = NULL;
|
||||
|
||||
cache_head = cache_tail = NULL;
|
||||
dhcp_inuse = dhcp_spare = NULL;
|
||||
dhcp_spare = NULL;
|
||||
new_chain = NULL;
|
||||
hash_table = NULL;
|
||||
cache_size = size;
|
||||
@@ -170,7 +170,7 @@ static void cache_hash(struct crec *crecp)
|
||||
up = &((*up)->hash_next);
|
||||
|
||||
if (crecp->flags & F_IMMORTAL)
|
||||
while (*up && (!(*up)->flags & F_IMMORTAL))
|
||||
while (*up && !((*up)->flags & F_IMMORTAL))
|
||||
up = &((*up)->hash_next);
|
||||
}
|
||||
crecp->hash_next = *up;
|
||||
@@ -282,9 +282,7 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
|
||||
|
||||
if (flags & F_FORWARD)
|
||||
{
|
||||
for (up = hash_bucket(name), crecp = *up;
|
||||
crecp && ((crecp->flags & F_REVERSE) || !(crecp->flags & F_IMMORTAL));
|
||||
crecp = crecp->hash_next)
|
||||
for (up = hash_bucket(name), crecp = *up; crecp; crecp = crecp->hash_next)
|
||||
if (is_expired(now, crecp) || is_outdated_cname_pointer(crecp))
|
||||
{
|
||||
*up = crecp->hash_next;
|
||||
@@ -601,8 +599,7 @@ struct crec *cache_find_by_addr(struct crec *crecp, struct all_addr *addr,
|
||||
crecp = crecp->hash_next)
|
||||
if (!is_expired(now, crecp))
|
||||
{
|
||||
if ((crecp->flags & F_REVERSE) &&
|
||||
(crecp->flags & prot) &&
|
||||
if ((crecp->flags & prot) &&
|
||||
memcmp(&crecp->addr.addr, addr, addrlen) == 0)
|
||||
{
|
||||
if (crecp->flags & (F_HOSTS | F_DHCP))
|
||||
@@ -694,7 +691,7 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf
|
||||
|
||||
if (!f)
|
||||
{
|
||||
syslog(LOG_ERR, _("failed to load names from %s: %m"), filename);
|
||||
my_syslog(LOG_ERR, _("failed to load names from %s: %s"), filename, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -728,7 +725,7 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf
|
||||
#endif
|
||||
else
|
||||
{
|
||||
syslog(LOG_ERR, _("bad address at %s line %d"), filename, lineno);
|
||||
my_syslog(LOG_ERR, _("bad address at %s line %d"), filename, lineno);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -752,10 +749,11 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf
|
||||
while ((token = strtok(NULL, " \t\n\r")) && (*token != '#'))
|
||||
{
|
||||
struct crec *cache;
|
||||
int fqdn = !!strchr(token, '.');
|
||||
if (canonicalise(token))
|
||||
{
|
||||
/* If set, add a version of the name with a default domain appended */
|
||||
if ((opts & OPT_EXPAND) && domain_suffix && !strchr(token, '.') &&
|
||||
if ((opts & OPT_EXPAND) && domain_suffix && !fqdn &&
|
||||
(cache = malloc(sizeof(struct crec) +
|
||||
strlen(token)+2+strlen(domain_suffix)-SMALLDNAME)))
|
||||
{
|
||||
@@ -774,14 +772,14 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf
|
||||
}
|
||||
}
|
||||
else
|
||||
syslog(LOG_ERR, _("bad name at %s line %d"), filename, lineno);
|
||||
my_syslog(LOG_ERR, _("bad name at %s line %d"), filename, lineno);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
rehash(name_count);
|
||||
|
||||
syslog(LOG_INFO, _("read %s - %d addresses"), filename, addr_count);
|
||||
my_syslog(LOG_INFO, _("read %s - %d addresses"), filename, addr_count);
|
||||
|
||||
return name_count;
|
||||
}
|
||||
@@ -819,7 +817,7 @@ void cache_reload(int opts, char *buff, char *domain_suffix, struct hostsfile *a
|
||||
if ((opts & OPT_NO_HOSTS) && !addn_hosts)
|
||||
{
|
||||
if (cache_size > 0)
|
||||
syslog(LOG_INFO, _("cleared cache"));
|
||||
my_syslog(LOG_INFO, _("cleared cache"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -834,25 +832,19 @@ void cache_reload(int opts, char *buff, char *domain_suffix, struct hostsfile *a
|
||||
|
||||
void cache_unhash_dhcp(void)
|
||||
{
|
||||
struct crec *tmp, *cache, **up;
|
||||
struct crec *cache, **up;
|
||||
int i;
|
||||
|
||||
for (i=0; i<hash_size; i++)
|
||||
for (cache = hash_table[i], up = &hash_table[i]; cache; cache = cache->hash_next)
|
||||
if (cache->flags & F_DHCP)
|
||||
*up = cache->hash_next;
|
||||
{
|
||||
*up = cache->hash_next;
|
||||
cache->next = dhcp_spare;
|
||||
dhcp_spare = cache;
|
||||
}
|
||||
else
|
||||
up = &cache->hash_next;
|
||||
|
||||
/* prev field links all dhcp entries */
|
||||
for (cache = dhcp_inuse; cache; cache = tmp)
|
||||
{
|
||||
tmp = cache->prev;
|
||||
cache->prev = dhcp_spare;
|
||||
dhcp_spare = cache;
|
||||
}
|
||||
|
||||
dhcp_inuse = NULL;
|
||||
}
|
||||
|
||||
void cache_add_dhcp_entry(struct daemon *daemon, char *host_name,
|
||||
@@ -871,11 +863,11 @@ void cache_add_dhcp_entry(struct daemon *daemon, char *host_name,
|
||||
if (crec->addr.addr.addr.addr4.s_addr != host_address->s_addr)
|
||||
{
|
||||
strcpy(daemon->namebuff, inet_ntoa(crec->addr.addr.addr.addr4));
|
||||
syslog(LOG_WARNING,
|
||||
_("not giving name %s to the DHCP lease of %s because "
|
||||
"the name exists in %s with address %s"),
|
||||
host_name, inet_ntoa(*host_address),
|
||||
record_source(daemon->addn_hosts, crec->uid), daemon->namebuff);
|
||||
my_syslog(LOG_WARNING,
|
||||
_("not giving name %s to the DHCP lease of %s because "
|
||||
"the name exists in %s with address %s"),
|
||||
host_name, inet_ntoa(*host_address),
|
||||
record_source(daemon->addn_hosts, crec->uid), daemon->namebuff);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -893,7 +885,7 @@ void cache_add_dhcp_entry(struct daemon *daemon, char *host_name,
|
||||
}
|
||||
|
||||
if ((crec = dhcp_spare))
|
||||
dhcp_spare = dhcp_spare->prev;
|
||||
dhcp_spare = dhcp_spare->next;
|
||||
else /* need new one */
|
||||
crec = malloc(sizeof(struct crec));
|
||||
|
||||
@@ -906,72 +898,69 @@ void cache_add_dhcp_entry(struct daemon *daemon, char *host_name,
|
||||
crec->ttd = ttd;
|
||||
crec->addr.addr.addr.addr4 = *host_address;
|
||||
crec->name.namep = host_name;
|
||||
crec->prev = dhcp_inuse;
|
||||
dhcp_inuse = crec;
|
||||
cache_hash(crec);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void dump_cache(struct daemon *daemon, time_t now)
|
||||
{
|
||||
syslog(LOG_INFO, _("time %lu, cache size %d, %d/%d cache insertions re-used unexpired cache entries."),
|
||||
(unsigned long)now, daemon->cachesize, cache_live_freed, cache_inserted);
|
||||
my_syslog(LOG_INFO, _("time %lu, cache size %d, %d/%d cache insertions re-used unexpired cache entries."),
|
||||
(unsigned long)now, daemon->cachesize, cache_live_freed, cache_inserted);
|
||||
|
||||
if ((daemon->options & (OPT_DEBUG | OPT_LOG)) &&
|
||||
(addrbuff || (addrbuff = malloc(ADDRSTRLEN))))
|
||||
{
|
||||
struct crec *cache ;
|
||||
int i;
|
||||
syslog(LOG_DEBUG, "Host Address Flags Expires");
|
||||
my_syslog(LOG_DEBUG, "Host Address Flags Expires");
|
||||
|
||||
for (i=0; i<hash_size; i++)
|
||||
for (cache = hash_table[i]; cache; cache = cache->hash_next)
|
||||
{
|
||||
char *a, *p = daemon->namebuff;
|
||||
p += sprintf(p, "%-40.40s ", cache_get_name(cache));
|
||||
if ((cache->flags & F_NEG) && (cache->flags & F_FORWARD))
|
||||
addrbuff[0] = 0;
|
||||
a = "";
|
||||
else if (cache->flags & F_CNAME)
|
||||
{
|
||||
addrbuff[0] = 0;
|
||||
addrbuff[ADDRSTRLEN-1] = 0;
|
||||
a = "";
|
||||
if (!is_outdated_cname_pointer(cache))
|
||||
strncpy(addrbuff, cache_get_name(cache->addr.cname.cache), ADDRSTRLEN);
|
||||
a = cache_get_name(cache->addr.cname.cache);
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else if (cache->flags & F_IPV4)
|
||||
inet_ntop(AF_INET, &cache->addr.addr, addrbuff, ADDRSTRLEN);
|
||||
else if (cache->flags & F_IPV6)
|
||||
inet_ntop(AF_INET6, &cache->addr.addr, addrbuff, ADDRSTRLEN);
|
||||
else
|
||||
{
|
||||
a = addrbuff;
|
||||
if (cache->flags & F_IPV4)
|
||||
inet_ntop(AF_INET, &cache->addr.addr, addrbuff, ADDRSTRLEN);
|
||||
else if (cache->flags & F_IPV6)
|
||||
inet_ntop(AF_INET6, &cache->addr.addr, addrbuff, ADDRSTRLEN);
|
||||
}
|
||||
#else
|
||||
else
|
||||
strcpy(addrbuff, inet_ntoa(cache->addr.addr.addr.addr4));
|
||||
a = inet_ntoa(cache->addr.addr.addr.addr4);
|
||||
#endif
|
||||
syslog(LOG_DEBUG,
|
||||
p += sprintf(p, "%-30.30s %s%s%s%s%s%s%s%s%s%s ", a,
|
||||
cache->flags & F_IPV4 ? "4" : "",
|
||||
cache->flags & F_IPV6 ? "6" : "",
|
||||
cache->flags & F_CNAME ? "C" : "",
|
||||
cache->flags & F_FORWARD ? "F" : " ",
|
||||
cache->flags & F_REVERSE ? "R" : " ",
|
||||
cache->flags & F_IMMORTAL ? "I" : " ",
|
||||
cache->flags & F_DHCP ? "D" : " ",
|
||||
cache->flags & F_NEG ? "N" : " ",
|
||||
cache->flags & F_NXDOMAIN ? "X" : " ",
|
||||
cache->flags & F_HOSTS ? "H" : " ");
|
||||
#ifdef HAVE_BROKEN_RTC
|
||||
"%-40.40s %-30.30s %s%s%s%s%s%s%s%s%s%s %lu",
|
||||
p += sprintf(p, "%lu", cache->flags & F_IMMORTAL ? 0: (unsigned long)(cache->ttd - now));
|
||||
#else
|
||||
"%-40.40s %-30.30s %s%s%s%s%s%s%s%s%s%s %s",
|
||||
p += sprintf(p, "%s", cache->flags & F_IMMORTAL ? "\n" : ctime(&(cache->ttd)));
|
||||
/* ctime includes trailing \n - eat it */
|
||||
*(p-1) = 0;
|
||||
#endif
|
||||
cache_get_name(cache), addrbuff,
|
||||
cache->flags & F_IPV4 ? "4" : "",
|
||||
cache->flags & F_IPV6 ? "6" : "",
|
||||
cache->flags & F_CNAME ? "C" : "",
|
||||
cache->flags & F_FORWARD ? "F" : " ",
|
||||
cache->flags & F_REVERSE ? "R" : " ",
|
||||
cache->flags & F_IMMORTAL ? "I" : " ",
|
||||
cache->flags & F_DHCP ? "D" : " ",
|
||||
cache->flags & F_NEG ? "N" : " ",
|
||||
cache->flags & F_NXDOMAIN ? "X" : " ",
|
||||
cache->flags & F_HOSTS ? "H" : " ",
|
||||
#ifdef HAVE_BROKEN_RTC
|
||||
cache->flags & F_IMMORTAL ? 0: (unsigned long)(cache->ttd - now)
|
||||
#else
|
||||
cache->flags & F_IMMORTAL ? "\n" : ctime(&(cache->ttd))
|
||||
#endif
|
||||
);
|
||||
}
|
||||
}
|
||||
my_syslog(LOG_DEBUG, daemon->namebuff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *record_source(struct hostsfile *addn_hosts, int index)
|
||||
@@ -1076,8 +1065,8 @@ void log_query(unsigned short flags, char *name, struct all_addr *addr,
|
||||
name = ".";
|
||||
|
||||
if ((flags & F_FORWARD) | (flags & F_NEG))
|
||||
syslog(LOG_DEBUG, "%s %s %s %s", source, name, verb, addrbuff);
|
||||
my_syslog(LOG_DEBUG, "%s %s %s %s", source, name, verb, addrbuff);
|
||||
else if (flags & F_REVERSE)
|
||||
syslog(LOG_DEBUG, "%s %s is %s", source, addrbuff, name);
|
||||
my_syslog(LOG_DEBUG, "%s %s is %s", source, addrbuff, name);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2006 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2007 Simon Kelley
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -10,7 +10,7 @@
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#define VERSION "2.37"
|
||||
#define VERSION "2.39"
|
||||
|
||||
#define FTABSIZ 150 /* max number of outstanding requests (default) */
|
||||
#define MAX_PROCS 20 /* max no children for TCP requests */
|
||||
@@ -50,6 +50,7 @@
|
||||
#define DHCP_CLIENT_PORT 68
|
||||
#define TFTP_PORT 69
|
||||
#define TFTP_MAX_CONNECTIONS 50 /* max simultaneous connections */
|
||||
#define LOG_MAX 5 /* log-queue length */
|
||||
|
||||
/* DBUS interface specifics */
|
||||
#define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq"
|
||||
@@ -180,7 +181,7 @@ NOTES:
|
||||
# error HAVE_ISC_READER is not compatible with HAVE_BROKEN_RTC
|
||||
#endif
|
||||
|
||||
/* Allow TFTP to be disabled with CFLAGS=-DNO_TFTP */
|
||||
/* Allow TFTP to be disabled with COPT=-DNO_TFTP */
|
||||
#ifdef NO_TFTP
|
||||
#undef HAVE_TFTP
|
||||
#endif
|
||||
@@ -276,6 +277,7 @@ typedef unsigned long in_addr_t;
|
||||
|
||||
#endif
|
||||
/* Decide if we're going to support IPv6 */
|
||||
/* IPv6 can be forced off with "make COPTS=-DNO_IPV6" */
|
||||
/* We assume that systems which don't have IPv6
|
||||
headers don't have ntop and pton either */
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ static void dbus_read_servers(struct daemon *daemon, DBusMessage *message)
|
||||
}
|
||||
|
||||
#ifndef HAVE_IPV6
|
||||
syslog(LOG_WARNING, _("attempt to set an IPv6 server address via DBus - no IPv6 support"));
|
||||
my_syslog(LOG_WARNING, _("attempt to set an IPv6 server address via DBus - no IPv6 support"));
|
||||
#else
|
||||
if (i == sizeof(struct in6_addr)-1)
|
||||
{
|
||||
@@ -208,6 +208,7 @@ static void dbus_read_servers(struct daemon *daemon, DBusMessage *message)
|
||||
tmp = serv->next;
|
||||
if (serv->flags & SERV_MARK)
|
||||
{
|
||||
server_gone(daemon, serv);
|
||||
*up = serv->next;
|
||||
free(serv);
|
||||
}
|
||||
@@ -235,7 +236,7 @@ DBusHandlerResult message_handler(DBusConnection *connection,
|
||||
}
|
||||
else if (strcmp(method, "SetServers") == 0)
|
||||
{
|
||||
syslog(LOG_INFO, _("setting upstream servers from DBus"));
|
||||
my_syslog(LOG_INFO, _("setting upstream servers from DBus"));
|
||||
dbus_read_servers(daemon, message);
|
||||
check_servers(daemon);
|
||||
}
|
||||
|
||||
22
src/dhcp.c
22
src/dhcp.c
@@ -216,7 +216,7 @@ void dhcp_packet(struct daemon *daemon, time_t now)
|
||||
{
|
||||
if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) != -1)
|
||||
{
|
||||
syslog(LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
|
||||
my_syslog(LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -347,8 +347,8 @@ static int complete_context(struct daemon *daemon, struct in_addr local, int if_
|
||||
{
|
||||
strcpy(daemon->dhcp_buff, inet_ntoa(context->start));
|
||||
strcpy(daemon->dhcp_buff2, inet_ntoa(context->end));
|
||||
syslog(LOG_WARNING, _("DHCP range %s -- %s is not consistent with netmask %s"),
|
||||
daemon->dhcp_buff, daemon->dhcp_buff2, inet_ntoa(netmask));
|
||||
my_syslog(LOG_WARNING, _("DHCP range %s -- %s is not consistent with netmask %s"),
|
||||
daemon->dhcp_buff, daemon->dhcp_buff2, inet_ntoa(netmask));
|
||||
}
|
||||
context->netmask = netmask;
|
||||
}
|
||||
@@ -664,7 +664,7 @@ void dhcp_read_ethers(struct daemon *daemon)
|
||||
|
||||
if (!f)
|
||||
{
|
||||
syslog(LOG_ERR, _("failed to read %s:%m"), ETHERSFILE);
|
||||
my_syslog(LOG_ERR, _("failed to read %s:%s"), ETHERSFILE, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -699,7 +699,7 @@ void dhcp_read_ethers(struct daemon *daemon)
|
||||
*ip = 0;
|
||||
if (!*ip || parse_hex(buff, hwaddr, ETHER_ADDR_LEN, NULL, NULL) != ETHER_ADDR_LEN)
|
||||
{
|
||||
syslog(LOG_ERR, _("bad line at %s line %d"), ETHERSFILE, lineno);
|
||||
my_syslog(LOG_ERR, _("bad line at %s line %d"), ETHERSFILE, lineno);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -712,7 +712,7 @@ void dhcp_read_ethers(struct daemon *daemon)
|
||||
{
|
||||
if ((addr.s_addr = inet_addr(ip)) == (in_addr_t)-1)
|
||||
{
|
||||
syslog(LOG_ERR, _("bad address at %s line %d"), ETHERSFILE, lineno);
|
||||
my_syslog(LOG_ERR, _("bad address at %s line %d"), ETHERSFILE, lineno);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -726,7 +726,7 @@ void dhcp_read_ethers(struct daemon *daemon)
|
||||
{
|
||||
if (!canonicalise(ip))
|
||||
{
|
||||
syslog(LOG_ERR, _("bad name at %s line %d"), ETHERSFILE, lineno);
|
||||
my_syslog(LOG_ERR, _("bad name at %s line %d"), ETHERSFILE, lineno);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -780,7 +780,7 @@ void dhcp_read_ethers(struct daemon *daemon)
|
||||
|
||||
fclose(f);
|
||||
|
||||
syslog(LOG_INFO, _("read %s - %d addresses"), ETHERSFILE, count);
|
||||
my_syslog(LOG_INFO, _("read %s - %d addresses"), ETHERSFILE, count);
|
||||
}
|
||||
|
||||
void dhcp_update_configs(struct dhcp_config *configs)
|
||||
@@ -806,8 +806,8 @@ void dhcp_update_configs(struct dhcp_config *configs)
|
||||
(crec->flags & F_HOSTS))
|
||||
{
|
||||
if (config_find_by_address(configs, crec->addr.addr.addr.addr4))
|
||||
syslog(LOG_WARNING, _("duplicate IP address %s (%s) in dhcp-config directive"),
|
||||
inet_ntoa(crec->addr.addr.addr.addr4), config->hostname);
|
||||
my_syslog(LOG_WARNING, _("duplicate IP address %s (%s) in dhcp-config directive"),
|
||||
inet_ntoa(crec->addr.addr.addr.addr4), config->hostname);
|
||||
else
|
||||
{
|
||||
config->addr = crec->addr.addr.addr.addr4;
|
||||
@@ -842,7 +842,7 @@ char *strip_hostname(struct daemon *daemon, char *hostname)
|
||||
{
|
||||
if (!daemon->domain_suffix || !hostname_isequal(dot+1, daemon->domain_suffix))
|
||||
{
|
||||
syslog(LOG_WARNING, _("Ignoring DHCP host name %s because it has an illegal domain part"), hostname);
|
||||
my_syslog(LOG_WARNING, _("Ignoring DHCP host name %s because it has an illegal domain part"), hostname);
|
||||
hostname = NULL;
|
||||
}
|
||||
else
|
||||
|
||||
105
src/dnsmasq.c
105
src/dnsmasq.c
@@ -59,7 +59,7 @@ int main (int argc, char **argv)
|
||||
time_t now, last = 0;
|
||||
struct sigaction sigact;
|
||||
struct iname *if_tmp;
|
||||
int piperead, pipefd[2];
|
||||
int piperead, pipefd[2], log_fd;
|
||||
unsigned char sig;
|
||||
|
||||
#ifndef NO_GETTEXT
|
||||
@@ -84,6 +84,7 @@ int main (int argc, char **argv)
|
||||
sigaction(SIGPIPE, &sigact, NULL);
|
||||
|
||||
daemon = read_opts(argc, argv, compile_opts);
|
||||
log_fd = log_start(daemon);
|
||||
|
||||
if (daemon->edns_pktsz < PACKETSZ)
|
||||
daemon->edns_pktsz = PACKETSZ;
|
||||
@@ -250,7 +251,7 @@ int main (int argc, char **argv)
|
||||
#endif
|
||||
for (i=0; i<64; i++)
|
||||
{
|
||||
if (i == piperead || i == pipewrite)
|
||||
if (i == piperead || i == pipewrite || i == log_fd)
|
||||
continue;
|
||||
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
@@ -279,8 +280,8 @@ int main (int argc, char **argv)
|
||||
}
|
||||
|
||||
/* if we are to run scripts, we need to fork a helper before dropping root. */
|
||||
daemon->helperfd = create_helper(daemon);
|
||||
|
||||
daemon->helperfd = create_helper(daemon, log_fd);
|
||||
|
||||
if (!(daemon->options & OPT_DEBUG))
|
||||
{
|
||||
/* UID changing, etc */
|
||||
@@ -335,47 +336,48 @@ int main (int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
log_start(daemon);
|
||||
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
if (daemon->options & OPT_DEBUG)
|
||||
prctl(PR_SET_DUMPABLE, 1);
|
||||
#endif
|
||||
|
||||
if (daemon->cachesize != 0)
|
||||
syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize);
|
||||
my_syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize);
|
||||
else
|
||||
syslog(LOG_INFO, _("started, version %s cache disabled"), VERSION);
|
||||
my_syslog(LOG_INFO, _("started, version %s cache disabled"), VERSION);
|
||||
|
||||
syslog(LOG_INFO, _("compile time options: %s"), compile_opts);
|
||||
my_syslog(LOG_INFO, _("compile time options: %s"), compile_opts);
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
if (daemon->options & OPT_DBUS)
|
||||
{
|
||||
if (daemon->dbus)
|
||||
syslog(LOG_INFO, _("DBus support enabled: connected to system bus"));
|
||||
my_syslog(LOG_INFO, _("DBus support enabled: connected to system bus"));
|
||||
else
|
||||
syslog(LOG_INFO, _("DBus support enabled: bus connection pending"));
|
||||
my_syslog(LOG_INFO, _("DBus support enabled: bus connection pending"));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (bind_fallback)
|
||||
syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
|
||||
my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
|
||||
|
||||
if (!(daemon->options & OPT_NOWILD))
|
||||
for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
|
||||
if (if_tmp->name && !if_tmp->used)
|
||||
syslog(LOG_WARNING, _("warning: interface %s does not currently exist"), if_tmp->name);
|
||||
my_syslog(LOG_WARNING, _("warning: interface %s does not currently exist"), if_tmp->name);
|
||||
|
||||
if (daemon->options & OPT_NO_RESOLV)
|
||||
{
|
||||
if (daemon->resolv_files && !daemon->resolv_files->is_default)
|
||||
syslog(LOG_WARNING, _("warning: ignoring resolv-file flag because no-resolv is set"));
|
||||
my_syslog(LOG_WARNING, _("warning: ignoring resolv-file flag because no-resolv is set"));
|
||||
daemon->resolv_files = NULL;
|
||||
if (!daemon->servers)
|
||||
syslog(LOG_WARNING, _("warning: no upstream servers configured"));
|
||||
my_syslog(LOG_WARNING, _("warning: no upstream servers configured"));
|
||||
}
|
||||
|
||||
if (daemon->max_logs != 0)
|
||||
my_syslog(LOG_INFO, _("asynchronous logging enabled, queue limit is %d messages"), daemon->max_logs);
|
||||
|
||||
if (daemon->dhcp)
|
||||
{
|
||||
struct dhcp_context *dhcp_tmp;
|
||||
@@ -384,11 +386,11 @@ int main (int argc, char **argv)
|
||||
{
|
||||
prettyprint_time(daemon->dhcp_buff2, dhcp_tmp->lease_time);
|
||||
strcpy(daemon->dhcp_buff, inet_ntoa(dhcp_tmp->start));
|
||||
syslog(LOG_INFO,
|
||||
(dhcp_tmp->flags & CONTEXT_STATIC) ?
|
||||
_("DHCP, static leases only on %.0s%s, lease time %s") :
|
||||
_("DHCP, IP range %s -- %s, lease time %s"),
|
||||
daemon->dhcp_buff, inet_ntoa(dhcp_tmp->end), daemon->dhcp_buff2);
|
||||
my_syslog(LOG_INFO,
|
||||
(dhcp_tmp->flags & CONTEXT_STATIC) ?
|
||||
_("DHCP, static leases only on %.0s%s, lease time %s") :
|
||||
_("DHCP, IP range %s -- %s, lease time %s"),
|
||||
daemon->dhcp_buff, inet_ntoa(dhcp_tmp->end), daemon->dhcp_buff2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,13 +404,13 @@ int main (int argc, char **argv)
|
||||
max_fd = FD_SETSIZE;
|
||||
#endif
|
||||
|
||||
syslog(LOG_INFO, "TFTP %s%s %s",
|
||||
daemon->tftp_prefix ? _("root is ") : _("enabled"),
|
||||
daemon->tftp_prefix ? daemon->tftp_prefix: "",
|
||||
daemon->options & OPT_TFTP_SECURE ? _("secure mode") : "");
|
||||
|
||||
my_syslog(LOG_INFO, "TFTP %s%s %s",
|
||||
daemon->tftp_prefix ? _("root is ") : _("enabled"),
|
||||
daemon->tftp_prefix ? daemon->tftp_prefix: "",
|
||||
daemon->options & OPT_TFTP_SECURE ? _("secure mode") : "");
|
||||
|
||||
/* This is a guess, it assumes that for small limits,
|
||||
disjoint files might be servered, but for large limits,
|
||||
disjoint files might be served, but for large limits,
|
||||
a single file will be sent to may clients (the file only needs
|
||||
one fd). */
|
||||
|
||||
@@ -424,9 +426,9 @@ int main (int argc, char **argv)
|
||||
if (daemon->tftp_max > max_fd)
|
||||
{
|
||||
daemon->tftp_max = max_fd;
|
||||
syslog(LOG_WARNING,
|
||||
_("restricting maximum simultaneous TFTP transfers to %d"),
|
||||
daemon->tftp_max);
|
||||
my_syslog(LOG_WARNING,
|
||||
_("restricting maximum simultaneous TFTP transfers to %d"),
|
||||
daemon->tftp_max);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -434,11 +436,9 @@ int main (int argc, char **argv)
|
||||
if (!(daemon->options & OPT_DEBUG) && (getuid() == 0 || geteuid() == 0))
|
||||
{
|
||||
if (bad_capabilities)
|
||||
{
|
||||
errno = bad_capabilities;
|
||||
syslog(LOG_WARNING, _("warning: setting capabilities failed: %m"));
|
||||
}
|
||||
syslog(LOG_WARNING, _("running as root"));
|
||||
my_syslog(LOG_WARNING, _("warning: setting capabilities failed: %s"), strerror(bad_capabilities));
|
||||
|
||||
my_syslog(LOG_WARNING, _("running as root"));
|
||||
}
|
||||
|
||||
check_servers(daemon);
|
||||
@@ -498,7 +498,11 @@ int main (int argc, char **argv)
|
||||
FD_SET(daemon->helperfd, &wset);
|
||||
bump_maxfd(daemon->helperfd, &maxfd);
|
||||
}
|
||||
|
||||
|
||||
/* must do this just before select(), when we know no
|
||||
more calls to my_syslog() can occur */
|
||||
set_log_writer(&wset, &maxfd);
|
||||
|
||||
if (select(maxfd+1, &rset, &wset, &eset, tp) < 0)
|
||||
{
|
||||
/* otherwise undefined after error */
|
||||
@@ -507,6 +511,8 @@ int main (int argc, char **argv)
|
||||
|
||||
now = dnsmasq_time();
|
||||
|
||||
check_log_writer(&wset);
|
||||
|
||||
/* Check for changes to resolv files once per second max. */
|
||||
/* Don't go silent for long periods if the clock goes backwards. */
|
||||
if (last == 0 || difftime(now, last) > 1.0 || difftime(now, last) < -1.0)
|
||||
@@ -530,7 +536,7 @@ int main (int argc, char **argv)
|
||||
if (stat(res->name, &statbuf) == -1)
|
||||
{
|
||||
if (!res->logged)
|
||||
syslog(LOG_WARNING, _("failed to access %s: %m"), res->name);
|
||||
my_syslog(LOG_WARNING, _("failed to access %s: %s"), res->name, strerror(errno));
|
||||
res->logged = 1;
|
||||
}
|
||||
else
|
||||
@@ -552,7 +558,7 @@ int main (int argc, char **argv)
|
||||
static int warned = 0;
|
||||
if (reload_servers(latest->name, daemon))
|
||||
{
|
||||
syslog(LOG_INFO, _("reading %s"), latest->name);
|
||||
my_syslog(LOG_INFO, _("reading %s"), latest->name);
|
||||
warned = 0;
|
||||
check_servers(daemon);
|
||||
if (daemon->options & OPT_RELOAD)
|
||||
@@ -563,7 +569,7 @@ int main (int argc, char **argv)
|
||||
latest->mtime = 0;
|
||||
if (!warned)
|
||||
{
|
||||
syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
|
||||
my_syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
|
||||
warned = 1;
|
||||
}
|
||||
}
|
||||
@@ -622,7 +628,7 @@ int main (int argc, char **argv)
|
||||
if (daemon->lease_stream)
|
||||
fclose(daemon->lease_stream);
|
||||
|
||||
syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
|
||||
my_syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@@ -657,9 +663,9 @@ int main (int argc, char **argv)
|
||||
{
|
||||
char *err;
|
||||
if ((err = dbus_init(daemon)))
|
||||
syslog(LOG_WARNING, _("DBus error: %s"), err);
|
||||
my_syslog(LOG_WARNING, _("DBus error: %s"), err);
|
||||
if (daemon->dbus)
|
||||
syslog(LOG_INFO, _("connected to system DBus"));
|
||||
my_syslog(LOG_INFO, _("connected to system DBus"));
|
||||
}
|
||||
check_dbus_listeners(daemon, &rset, &wset, &eset);
|
||||
#endif
|
||||
@@ -969,7 +975,7 @@ int icmp_ping(struct daemon *daemon, struct in_addr addr)
|
||||
difftime(now, start) < (float)PING_WAIT;)
|
||||
{
|
||||
struct timeval tv;
|
||||
fd_set rset;
|
||||
fd_set rset, wset;
|
||||
struct sockaddr_in faddr;
|
||||
int maxfd = fd;
|
||||
socklen_t len = sizeof(faddr);
|
||||
@@ -978,13 +984,20 @@ int icmp_ping(struct daemon *daemon, struct in_addr addr)
|
||||
tv.tv_sec = 0;
|
||||
|
||||
FD_ZERO(&rset);
|
||||
FD_ZERO(&wset);
|
||||
FD_SET(fd, &rset);
|
||||
set_dns_listeners(daemon, now, &rset, &maxfd);
|
||||
|
||||
if (select(maxfd+1, &rset, NULL, NULL, &tv) < 0)
|
||||
FD_ZERO(&rset);
|
||||
|
||||
set_log_writer(&wset, &maxfd);
|
||||
|
||||
if (select(maxfd+1, &rset, &wset, NULL, &tv) < 0)
|
||||
{
|
||||
FD_ZERO(&rset);
|
||||
FD_ZERO(&wset);
|
||||
}
|
||||
|
||||
now = dnsmasq_time();
|
||||
|
||||
check_log_writer(&wset);
|
||||
check_dns_listeners(daemon, &rset, now);
|
||||
|
||||
#ifdef HAVE_TFTP
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <sys/select.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/un.h>
|
||||
#include <limits.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
@@ -114,6 +115,8 @@ extern int capset(cap_user_header_t header, cap_user_data_t data);
|
||||
#define OPT_RELOAD (1<<24)
|
||||
#define OPT_TFTP (1<<25)
|
||||
#define OPT_TFTP_SECURE (1<<26)
|
||||
#define OPT_TFTP_NOBLOCK (1<<27)
|
||||
#define OPT_LOG_OPTS (1<<28)
|
||||
|
||||
struct all_addr {
|
||||
union {
|
||||
@@ -153,6 +156,12 @@ struct ptr_record {
|
||||
struct ptr_record *next;
|
||||
};
|
||||
|
||||
struct interface_name {
|
||||
char *name; /* domain name */
|
||||
char *intr; /* interface name */
|
||||
struct interface_name *next;
|
||||
};
|
||||
|
||||
union bigname {
|
||||
char name[MAXDNAME];
|
||||
union bigname *next; /* freelist */
|
||||
@@ -365,7 +374,9 @@ struct dhcp_opt {
|
||||
|
||||
#define DHOPT_ADDR 1
|
||||
#define DHOPT_STRING 2
|
||||
#define DHOPT_VENDOR_MATCH 4
|
||||
#define DHOPT_ENCAPSULATE 4
|
||||
#define DHOPT_VENDOR_MATCH 8
|
||||
#define DHOPT_FORCE 16
|
||||
|
||||
struct dhcp_boot {
|
||||
char *file, *sname;
|
||||
@@ -374,8 +385,15 @@ struct dhcp_boot {
|
||||
struct dhcp_boot *next;
|
||||
};
|
||||
|
||||
#define MATCH_VENDOR 1
|
||||
#define MATCH_USER 2
|
||||
#define MATCH_CIRCUIT 3
|
||||
#define MATCH_REMOTE 4
|
||||
#define MATCH_SUBSCRIBER 5
|
||||
|
||||
/* vendorclass, userclass, remote-id or cicuit-id */
|
||||
struct dhcp_vendor {
|
||||
int len, is_vendor;
|
||||
int len, match_type;
|
||||
char *data;
|
||||
struct dhcp_netid netid;
|
||||
struct dhcp_vendor *next;
|
||||
@@ -458,6 +476,7 @@ struct daemon {
|
||||
struct mx_srv_record *mxnames;
|
||||
struct txt_record *txt;
|
||||
struct ptr_record *ptr;
|
||||
struct interface_name *int_names;
|
||||
char *mxtarget;
|
||||
char *lease_file;
|
||||
char *username, *groupname;
|
||||
@@ -468,13 +487,15 @@ struct daemon {
|
||||
struct bogus_addr *bogus_addr;
|
||||
struct server *servers;
|
||||
int log_fac; /* log facility */
|
||||
char *log_file; /* optional log file */
|
||||
int max_logs; /* queue limit */
|
||||
int cachesize, ftabsize;
|
||||
int port, query_port;
|
||||
unsigned long local_ttl;
|
||||
struct hostsfile *addn_hosts;
|
||||
struct dhcp_context *dhcp;
|
||||
struct dhcp_config *dhcp_conf;
|
||||
struct dhcp_opt *dhcp_opts, *vendor_opts;
|
||||
struct dhcp_opt *dhcp_opts;
|
||||
struct dhcp_vendor *dhcp_vendors;
|
||||
struct dhcp_mac *dhcp_macs;
|
||||
struct dhcp_boot *boot_config;
|
||||
@@ -566,8 +587,6 @@ unsigned short rand16(void);
|
||||
int legal_char(char c);
|
||||
int canonicalise(char *s);
|
||||
unsigned char *do_rfc1035_name(unsigned char *p, char *sval);
|
||||
void die(char *message, char *arg1);
|
||||
void complain(char *message, int lineno, char *file);
|
||||
void *safe_malloc(size_t size);
|
||||
int sa_len(union mysockaddr *addr);
|
||||
int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2);
|
||||
@@ -584,11 +603,18 @@ int memcmp_masked(unsigned char *a, unsigned char *b, int len,
|
||||
int expand_buf(struct iovec *iov, size_t size);
|
||||
char *print_mac(struct daemon *daemon, unsigned char *mac, int len);
|
||||
void bump_maxfd(int fd, int *max);
|
||||
void log_start(struct daemon *daemon);
|
||||
int read_write(int fd, unsigned char *packet, int size, int rw);
|
||||
|
||||
/* log.c */
|
||||
void die(char *message, char *arg1);
|
||||
int log_start(struct daemon *daemon);
|
||||
void my_syslog(int priority, const char *format, ...);
|
||||
void set_log_writer(fd_set *set, int *maxfdp);
|
||||
void check_log_writer(fd_set *set);
|
||||
|
||||
/* option.c */
|
||||
struct daemon *read_opts (int argc, char **argv, char *compile_opts);
|
||||
char *option_string(unsigned char opt);
|
||||
|
||||
/* forward.c */
|
||||
void reply_query(struct serverfd *sfd, struct daemon *daemon, time_t now);
|
||||
@@ -608,6 +634,7 @@ struct listener *create_bound_listeners(struct daemon *daemon);
|
||||
int iface_check(struct daemon *daemon, int family, struct all_addr *addr,
|
||||
struct ifreq *ifr, int *indexp);
|
||||
int fix_fd(int fd);
|
||||
struct in_addr get_ifaddr(struct daemon* daemon, char *intr);
|
||||
|
||||
/* dhcp.c */
|
||||
void dhcp_init(struct daemon *daemon);
|
||||
@@ -687,7 +714,7 @@ void set_dbus_listeners(struct daemon *daemon, int *maxfdp,
|
||||
#endif
|
||||
|
||||
/* helper.c */
|
||||
int create_helper(struct daemon *daemon);
|
||||
int create_helper(struct daemon *daemon, int log_fd);
|
||||
void helper_write(struct daemon *daemon);
|
||||
void queue_script(struct daemon *daemon, int action,
|
||||
struct dhcp_lease *lease, char *hostname);
|
||||
|
||||
@@ -373,7 +373,7 @@ static size_t process_reply(struct daemon *daemon, HEADER *header, time_t now,
|
||||
server && !(server->flags & SERV_WARNED_RECURSIVE))
|
||||
{
|
||||
prettyprint_addr(&server->addr, daemon->namebuff);
|
||||
syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff);
|
||||
my_syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff);
|
||||
if (!(daemon->options & OPT_LOG))
|
||||
server->flags |= SERV_WARNED_RECURSIVE;
|
||||
}
|
||||
@@ -447,7 +447,9 @@ void reply_query(struct serverfd *sfd, struct daemon *daemon, time_t now)
|
||||
{
|
||||
struct server *server = forward->sentto;
|
||||
|
||||
if ((header->rcode == SERVFAIL || header->rcode == REFUSED) && forward->forwardall == 0)
|
||||
if ((header->rcode == SERVFAIL || header->rcode == REFUSED) &&
|
||||
!(daemon->options & OPT_ORDER) &&
|
||||
forward->forwardall == 0)
|
||||
/* for broken servers, attempt to send to another one. */
|
||||
{
|
||||
unsigned char *pheader;
|
||||
|
||||
15
src/helper.c
15
src/helper.c
@@ -40,7 +40,7 @@ struct script_data
|
||||
static struct script_data *buf;
|
||||
static size_t bytes_in_buf, buf_size;
|
||||
|
||||
int create_helper(struct daemon *daemon)
|
||||
int create_helper(struct daemon *daemon, int log_fd)
|
||||
{
|
||||
pid_t pid;
|
||||
int i, pipefd[2];
|
||||
@@ -72,11 +72,8 @@ int create_helper(struct daemon *daemon)
|
||||
/* close all the sockets etc, we don't need them here */
|
||||
for (i = 0; i < 64; i++)
|
||||
if (i != STDOUT_FILENO && i != STDERR_FILENO &&
|
||||
i != STDIN_FILENO && i != pipefd[0])
|
||||
i != STDIN_FILENO && i != pipefd[0] && i != log_fd)
|
||||
close(i);
|
||||
|
||||
/* we open our own log connection. */
|
||||
log_start(daemon);
|
||||
|
||||
/* don't give our end of the pipe to our children */
|
||||
if ((i = fcntl(pipefd[0], F_GETFD)) != -1)
|
||||
@@ -142,9 +139,9 @@ int create_helper(struct daemon *daemon)
|
||||
int status;
|
||||
waitpid(pid, &status, 0);
|
||||
if (WIFSIGNALED(status))
|
||||
syslog(LOG_WARNING, _("child process killed by signal %d"), WTERMSIG(status));
|
||||
my_syslog(LOG_WARNING, _("child process killed by signal %d"), WTERMSIG(status));
|
||||
else if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
|
||||
syslog(LOG_WARNING, _("child process exited with status %d"), WEXITSTATUS(status));
|
||||
my_syslog(LOG_WARNING, _("child process exited with status %d"), WEXITSTATUS(status));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -213,8 +210,8 @@ int create_helper(struct daemon *daemon)
|
||||
action_str, daemon->dhcp_buff, inet_ntoa(data.addr), hostname, (char*)NULL);
|
||||
|
||||
/* log socket should still be open, right? */
|
||||
syslog(LOG_ERR, _("failed to execute %s: %m"),
|
||||
daemon->lease_change_command);
|
||||
my_syslog(LOG_ERR, _("failed to execute %s: %s"),
|
||||
daemon->lease_change_command, strerror(errno));
|
||||
_exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
14
src/isc.c
14
src/isc.c
@@ -70,7 +70,7 @@ void load_dhcp(struct daemon *daemon, time_t now)
|
||||
if (stat(daemon->lease_file, &statbuf) == -1)
|
||||
{
|
||||
if (!logged_lease)
|
||||
syslog(LOG_WARNING, _("failed to access %s: %m"), daemon->lease_file);
|
||||
my_syslog(LOG_WARNING, _("failed to access %s: %s"), daemon->lease_file, strerror(errno));
|
||||
logged_lease = 1;
|
||||
return;
|
||||
}
|
||||
@@ -86,11 +86,11 @@ void load_dhcp(struct daemon *daemon, time_t now)
|
||||
|
||||
if (!(fp = fopen (daemon->lease_file, "r")))
|
||||
{
|
||||
syslog (LOG_ERR, _("failed to load %s: %m"), daemon->lease_file);
|
||||
my_syslog (LOG_ERR, _("failed to load %s: %s"), daemon->lease_file, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
syslog (LOG_INFO, _("reading %s"), daemon->lease_file);
|
||||
my_syslog (LOG_INFO, _("reading %s"), daemon->lease_file);
|
||||
|
||||
while ((next_token(token, MAXTOK, fp)))
|
||||
{
|
||||
@@ -112,7 +112,7 @@ void load_dhcp(struct daemon *daemon, time_t now)
|
||||
if (!canonicalise(hostname))
|
||||
{
|
||||
*hostname = 0;
|
||||
syslog(LOG_ERR, _("bad name in %s"), daemon->lease_file);
|
||||
my_syslog(LOG_ERR, _("bad name in %s"), daemon->lease_file);
|
||||
}
|
||||
}
|
||||
else if ((strcmp(token, "ends") == 0) ||
|
||||
@@ -173,9 +173,9 @@ void load_dhcp(struct daemon *daemon, time_t now)
|
||||
{
|
||||
if (!daemon->domain_suffix || hostname_isequal(dot+1, daemon->domain_suffix))
|
||||
{
|
||||
syslog(LOG_WARNING,
|
||||
_("Ignoring DHCP lease for %s because it has an illegal domain part"),
|
||||
hostname);
|
||||
my_syslog(LOG_WARNING,
|
||||
_("Ignoring DHCP lease for %s because it has an illegal domain part"),
|
||||
hostname);
|
||||
continue;
|
||||
}
|
||||
*dot = 0;
|
||||
|
||||
@@ -214,9 +214,9 @@ void lease_update_file(struct daemon *daemon, time_t now)
|
||||
if (next_event == 0 || difftime(next_event, LEASE_RETRY + now) > 0.0)
|
||||
next_event = LEASE_RETRY + now;
|
||||
|
||||
syslog(LOG_ERR, _("failed to write %s: %s (retry in %us)"),
|
||||
daemon->lease_file, strerror(err),
|
||||
(unsigned int)difftime(next_event, now));
|
||||
my_syslog(LOG_ERR, _("failed to write %s: %s (retry in %us)"),
|
||||
daemon->lease_file, strerror(err),
|
||||
(unsigned int)difftime(next_event, now));
|
||||
}
|
||||
|
||||
if (next_event != 0)
|
||||
|
||||
342
src/log.c
Normal file
342
src/log.c
Normal file
@@ -0,0 +1,342 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2007 Simon Kelley
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 dated June, 1991.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "dnsmasq.h"
|
||||
|
||||
/* Implement logging to /dev/log asynchronously. If syslogd is
|
||||
making DNS lookups through dnsmasq, and dnsmasq blocks awaiting
|
||||
syslogd, then the two daemons can deadlock. We get around this
|
||||
by not blocking when talking to syslog, instead we queue up to
|
||||
MAX_LOGS messages. If more are queued, they will be dropped,
|
||||
and the drop event itself logged. */
|
||||
|
||||
/* The "wire" protocol for logging is defined in RFC 3164 */
|
||||
|
||||
/* From RFC 3164 */
|
||||
#define MAX_MESSAGE 1024
|
||||
|
||||
/* defaults in case we die() before we log_start() */
|
||||
static int log_fac = LOG_DAEMON;
|
||||
static int log_stderr = 0;
|
||||
static int log_fd = -1;
|
||||
static int log_to_file = 0;
|
||||
static int entries_alloced = 0;
|
||||
static int entries_lost = 0;
|
||||
static int connection_good = 1;
|
||||
static int max_logs = 0;
|
||||
|
||||
struct log_entry {
|
||||
int offset, length;
|
||||
struct log_entry *next;
|
||||
char payload[MAX_MESSAGE];
|
||||
};
|
||||
|
||||
static struct log_entry *entries = NULL;
|
||||
static struct log_entry *free_entries = NULL;
|
||||
|
||||
|
||||
int log_start(struct daemon *daemon)
|
||||
{
|
||||
int flags;
|
||||
|
||||
log_stderr = !!(daemon->options & OPT_DEBUG);
|
||||
|
||||
if (daemon->log_fac != -1)
|
||||
log_fac = daemon->log_fac;
|
||||
#ifdef LOG_LOCAL0
|
||||
else if (daemon->options & OPT_DEBUG)
|
||||
log_fac = LOG_LOCAL0;
|
||||
#endif
|
||||
|
||||
if (daemon->log_file)
|
||||
{
|
||||
log_fd = open(daemon->log_file, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP);
|
||||
log_to_file = 1;
|
||||
daemon->max_logs = 0;
|
||||
}
|
||||
else
|
||||
log_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
|
||||
|
||||
if (log_fd == -1)
|
||||
die(_("cannot open %s: %s"), daemon->log_file ? daemon->log_file : "log");
|
||||
|
||||
/* if queuing is inhibited, make sure we allocate
|
||||
the one required buffer now. */
|
||||
if ((max_logs = daemon->max_logs) == 0)
|
||||
{
|
||||
free_entries = safe_malloc(sizeof(struct log_entry));
|
||||
free_entries->next = NULL;
|
||||
entries_alloced = 1;
|
||||
}
|
||||
|
||||
if ((flags = fcntl(log_fd, F_GETFD)) != -1)
|
||||
fcntl(log_fd, F_SETFD, flags | FD_CLOEXEC);
|
||||
|
||||
/* if max_log is zero, leave the socket blocking */
|
||||
if (max_logs != 0 && (flags = fcntl(log_fd, F_GETFL)) != -1)
|
||||
fcntl(log_fd, F_SETFL, flags | O_NONBLOCK);
|
||||
|
||||
return log_fd;
|
||||
}
|
||||
|
||||
static void log_write(void)
|
||||
{
|
||||
ssize_t rc;
|
||||
int tried_stream = 0;
|
||||
|
||||
while (entries)
|
||||
{
|
||||
connection_good = 1;
|
||||
|
||||
if ((rc = write(log_fd, entries->payload + entries->offset, entries->length)) != -1)
|
||||
{
|
||||
entries->length -= rc;
|
||||
entries->offset += rc;
|
||||
if (entries->length == 0)
|
||||
{
|
||||
struct log_entry *tmp = entries;
|
||||
entries = tmp->next;
|
||||
tmp->next = free_entries;
|
||||
free_entries = tmp;
|
||||
|
||||
if (entries_lost != 0)
|
||||
{
|
||||
int e = entries_lost;
|
||||
entries_lost = 0; /* avoid wild recursion */
|
||||
my_syslog(LOG_WARNING, _("overflow: %d log entries lost"), e);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
if (errno == EAGAIN)
|
||||
return; /* syslogd busy, go again when select() or poll() says so */
|
||||
|
||||
if (errno == ENOBUFS)
|
||||
{
|
||||
connection_good = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Once a stream socket hits EPIPE, we have to close and re-open */
|
||||
if (errno == EPIPE)
|
||||
goto reopen_stream;
|
||||
|
||||
if (!log_to_file &&
|
||||
(errno == ECONNREFUSED ||
|
||||
errno == ENOTCONN ||
|
||||
errno == EDESTADDRREQ ||
|
||||
errno == ECONNRESET))
|
||||
{
|
||||
/* socket went (syslogd down?), try and reconnect. If we fail,
|
||||
stop trying until the next call to my_syslog()
|
||||
ECONNREFUSED -> connection went down
|
||||
ENOTCONN -> nobody listening
|
||||
(ECONNRESET, EDESTADDRREQ are *BSD equivalents)
|
||||
EPIPE comes from broken stream socket (we ignore SIGPIPE) */
|
||||
|
||||
struct sockaddr_un logaddr;
|
||||
|
||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||
logaddr.sun_len = sizeof(logaddr) - sizeof(logaddr.sun_path) + strlen(_PATH_LOG) + 1;
|
||||
#endif
|
||||
logaddr.sun_family = AF_LOCAL;
|
||||
strncpy(logaddr.sun_path, _PATH_LOG, sizeof(logaddr.sun_path));
|
||||
|
||||
/* Got connection back? try again. */
|
||||
if (connect(log_fd, (struct sockaddr *)&logaddr, sizeof(logaddr)) != -1)
|
||||
continue;
|
||||
|
||||
/* errors from connect which mean we should keep trying */
|
||||
if (errno == ENOENT ||
|
||||
errno == EALREADY ||
|
||||
errno == ECONNREFUSED ||
|
||||
errno == EISCONN ||
|
||||
errno == EINTR ||
|
||||
errno == EAGAIN)
|
||||
{
|
||||
/* try again on next syslog() call */
|
||||
connection_good = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* we start with a SOCK_DGRAM socket, but syslog may want SOCK_STREAM */
|
||||
if (!tried_stream && errno == EPROTOTYPE)
|
||||
{
|
||||
reopen_stream:
|
||||
tried_stream = 1;
|
||||
close(log_fd);
|
||||
if ((log_fd = socket(AF_UNIX, SOCK_STREAM, 0)) != -1)
|
||||
{
|
||||
int flags;
|
||||
|
||||
if ((flags = fcntl(log_fd, F_GETFD)) != -1)
|
||||
fcntl(log_fd, F_SETFD, flags | FD_CLOEXEC);
|
||||
|
||||
/* if max_log is zero, leave the socket blocking */
|
||||
if (max_logs != 0 && (flags = fcntl(log_fd, F_GETFL)) != -1)
|
||||
fcntl(log_fd, F_SETFL, flags | O_NONBLOCK);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* give up - fall back to syslog() - this handles out-of-space
|
||||
when logging to a file, for instance. */
|
||||
log_fd = -1;
|
||||
my_syslog(LOG_CRIT, _("log failed: %s"), strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void my_syslog(int priority, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
struct log_entry *entry;
|
||||
time_t time_now;
|
||||
char *p;
|
||||
size_t len;
|
||||
|
||||
va_start(ap, format);
|
||||
|
||||
if (log_stderr)
|
||||
{
|
||||
fprintf(stderr, "dnsmasq: ");
|
||||
vfprintf(stderr, format, ap);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
if (log_fd == -1)
|
||||
{
|
||||
/* fall-back to syslog if we die during startup or fail during running. */
|
||||
static int isopen = 0;
|
||||
if (!isopen)
|
||||
{
|
||||
openlog("dnsmasq", LOG_PID, log_fac);
|
||||
isopen = 1;
|
||||
}
|
||||
vsyslog(priority, format, ap);
|
||||
va_end(ap);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((entry = free_entries))
|
||||
free_entries = entry->next;
|
||||
else if (entries_alloced < max_logs && (entry = malloc(sizeof(struct log_entry))))
|
||||
entries_alloced++;
|
||||
|
||||
if (!entry)
|
||||
entries_lost++;
|
||||
else
|
||||
{
|
||||
/* add to end of list, consumed from the start */
|
||||
entry->next = NULL;
|
||||
if (!entries)
|
||||
entries = entry;
|
||||
else
|
||||
{
|
||||
struct log_entry *tmp;
|
||||
for (tmp = entries; tmp->next; tmp = tmp->next);
|
||||
tmp->next = entry;
|
||||
}
|
||||
|
||||
time(&time_now);
|
||||
p = entry->payload;
|
||||
if (!log_to_file)
|
||||
p += sprintf(p, "<%d>", priority | log_fac);
|
||||
|
||||
p += sprintf(p, "%.15s dnsmasq[%d]: ", ctime(&time_now) + 4, getpid());
|
||||
len = p - entry->payload;
|
||||
len += vsnprintf(p, MAX_MESSAGE - len, format, ap) + 1; /* include zero-terminator */
|
||||
entry->length = len > MAX_MESSAGE ? MAX_MESSAGE : len;
|
||||
entry->offset = 0;
|
||||
|
||||
/* replace terminator with \n */
|
||||
if (log_to_file)
|
||||
entry->payload[entry->length - 1] = '\n';
|
||||
}
|
||||
|
||||
/* almost always, logging won't block, so try and write this now,
|
||||
to save collecting too many log messages during a select loop. */
|
||||
log_write();
|
||||
|
||||
/* Since we're doing things asynchronously, a cache-dump, for instance,
|
||||
can now generate log lines very fast. With a small buffer (desirable),
|
||||
that means it can overflow the log-buffer very quickly,
|
||||
so that the cache dump becomes mainly a count of how many lines
|
||||
overflowed. To avoid this, we delay here, the delay is controlled
|
||||
by queue-occupancy, and grows exponentially. The delay is limited to (2^8)ms.
|
||||
The scaling stuff ensures that when the queue is bigger than 8, the delay
|
||||
only occurs for the last 8 entries. Once the queue is full, we stop delaying
|
||||
to preserve performance.
|
||||
*/
|
||||
|
||||
if (entries && max_logs != 0)
|
||||
{
|
||||
int d;
|
||||
|
||||
for (d = 0,entry = entries; entry; entry = entry->next, d++);
|
||||
|
||||
if (d == max_logs)
|
||||
d = 0;
|
||||
else if (max_logs > 8)
|
||||
d -= max_logs - 8;
|
||||
|
||||
if (d > 0)
|
||||
{
|
||||
struct timespec waiter;
|
||||
waiter.tv_sec = 0;
|
||||
waiter.tv_nsec = 1000000 << (d - 1); /* 1 ms */
|
||||
nanosleep(&waiter, NULL);
|
||||
|
||||
/* Have another go now */
|
||||
log_write();
|
||||
}
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void set_log_writer(fd_set *set, int *maxfdp)
|
||||
{
|
||||
if (entries && log_fd != -1 && connection_good)
|
||||
{
|
||||
FD_SET(log_fd, set);
|
||||
bump_maxfd(log_fd, maxfdp);
|
||||
}
|
||||
}
|
||||
|
||||
void check_log_writer(fd_set *set)
|
||||
{
|
||||
if (log_fd != -1 && FD_ISSET(log_fd, set))
|
||||
log_write();
|
||||
}
|
||||
|
||||
void die(char *message, char *arg1)
|
||||
{
|
||||
char *errmess = strerror(errno);
|
||||
|
||||
if (!arg1)
|
||||
arg1 = errmess;
|
||||
|
||||
log_stderr = 1; /* print as well as log when we die.... */
|
||||
my_syslog(LOG_CRIT, message, arg1, errmess);
|
||||
|
||||
log_stderr = 0;
|
||||
my_syslog(LOG_CRIT, _("FAILED to start up"));
|
||||
|
||||
exit(1);
|
||||
}
|
||||
@@ -229,7 +229,7 @@ static void nl_err(struct nlmsghdr *h)
|
||||
{
|
||||
struct nlmsgerr *err = NLMSG_DATA(h);
|
||||
if (err->error != 0)
|
||||
syslog(LOG_ERR, _("netlink returns error: %s"), strerror(-(err->error)));
|
||||
my_syslog(LOG_ERR, _("netlink returns error: %s"), strerror(-(err->error)));
|
||||
}
|
||||
|
||||
/* We arrange to receive netlink multicast messages whenever the network route is added.
|
||||
|
||||
@@ -38,7 +38,7 @@ int iface_check(struct daemon *daemon, int family, struct all_addr *addr,
|
||||
|
||||
if (!(newindex = if_nametoindex(bridge->iface)))
|
||||
{
|
||||
syslog(LOG_WARNING, _("unknown interface %s in bridge-interface"), ifr->ifr_name);
|
||||
my_syslog(LOG_WARNING, _("unknown interface %s in bridge-interface"), ifr->ifr_name);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
@@ -492,7 +492,7 @@ void check_servers(struct daemon *daemon)
|
||||
break;
|
||||
if (iface)
|
||||
{
|
||||
syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
|
||||
my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
|
||||
free(new);
|
||||
continue;
|
||||
}
|
||||
@@ -500,8 +500,9 @@ void check_servers(struct daemon *daemon)
|
||||
/* Do we need a socket set? */
|
||||
if (!new->sfd && !(new->sfd = allocate_sfd(&new->source_addr, &daemon->sfds)))
|
||||
{
|
||||
syslog(LOG_WARNING,
|
||||
_("ignoring nameserver %s - cannot make/bind socket: %m"), daemon->namebuff);
|
||||
my_syslog(LOG_WARNING,
|
||||
_("ignoring nameserver %s - cannot make/bind socket: %s"),
|
||||
daemon->namebuff, strerror(errno));
|
||||
free(new);
|
||||
continue;
|
||||
}
|
||||
@@ -520,12 +521,12 @@ void check_servers(struct daemon *daemon)
|
||||
s1 = _("unqualified"), s2 = _("domains");
|
||||
|
||||
if (new->flags & SERV_NO_ADDR)
|
||||
syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
|
||||
my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
|
||||
else if (!(new->flags & SERV_LITERAL_ADDRESS))
|
||||
syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port, s1, s2);
|
||||
my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port, s1, s2);
|
||||
}
|
||||
else
|
||||
syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
|
||||
my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
|
||||
}
|
||||
|
||||
daemon->servers = ret;
|
||||
@@ -545,7 +546,7 @@ int reload_servers(char *fname, struct daemon *daemon)
|
||||
/* buff happens to be MAXDNAME long... */
|
||||
if (!(f = fopen(fname, "r")))
|
||||
{
|
||||
syslog(LOG_ERR, _("failed to read %s: %m"), fname);
|
||||
my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -644,8 +645,22 @@ int reload_servers(char *fname, struct daemon *daemon)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Use an IPv4 listener socket for ioctling */
|
||||
struct in_addr get_ifaddr(struct daemon* daemon, char *intr)
|
||||
{
|
||||
struct listener *l;
|
||||
struct ifreq ifr;
|
||||
|
||||
for (l = daemon->listeners; l && l->family != AF_INET; l = l->next);
|
||||
|
||||
strncpy(ifr.ifr_name, intr, IF_NAMESIZE);
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
|
||||
if (!l || ioctl(l->fd, SIOCGIFADDR, &ifr) == -1)
|
||||
((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = -1;
|
||||
|
||||
return ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
753
src/option.c
753
src/option.c
File diff suppressed because it is too large
Load Diff
189
src/rfc1035.c
189
src/rfc1035.c
@@ -485,15 +485,16 @@ unsigned char *find_pseudoheader(HEADER *header, size_t plen, size_t *len, unsi
|
||||
|
||||
|
||||
/* is addr in the non-globally-routed IP space? */
|
||||
static int private_net(struct all_addr *addrp)
|
||||
static int private_net(struct in_addr addr)
|
||||
{
|
||||
struct in_addr addr = *(struct in_addr *)addrp;
|
||||
if (inet_netof(addr) == 0xA ||
|
||||
(inet_netof(addr) >= 0xAC10 && inet_netof(addr) < 0xAC20) ||
|
||||
(inet_netof(addr) >> 8) == 0xC0A8)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
in_addr_t ip_addr = ntohl(addr.s_addr);
|
||||
|
||||
return
|
||||
((ip_addr & 0xFF000000) == 0x7F000000) /* 127.0.0.0/8 (loopback) */ ||
|
||||
((ip_addr & 0xFFFF0000) == 0xC0A80000) /* 192.168.0.0/16 (private) */ ||
|
||||
((ip_addr & 0xFF000000) == 0x0A000000) /* 10.0.0.0/8 (private) */ ||
|
||||
((ip_addr & 0xFFF00000) == 0xAC100000) /* 172.16.0.0/12 (private) */ ||
|
||||
((ip_addr & 0xFFFF0000) == 0xA9FE0000) /* 169.254.0.0/16 (zeroconf) */ ;
|
||||
}
|
||||
|
||||
static void dns_doctor(HEADER *header, struct doctor *doctor, struct in_addr *addr)
|
||||
@@ -864,7 +865,9 @@ int check_for_local_domain(char *name, time_t now, struct daemon *daemon)
|
||||
struct crec *crecp;
|
||||
struct mx_srv_record *mx;
|
||||
struct txt_record *txt;
|
||||
|
||||
struct interface_name *intr;
|
||||
struct ptr_record *ptr;
|
||||
|
||||
if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)) &&
|
||||
(crecp->flags & (F_HOSTS | F_DHCP)))
|
||||
return 1;
|
||||
@@ -876,7 +879,15 @@ int check_for_local_domain(char *name, time_t now, struct daemon *daemon)
|
||||
for (txt = daemon->txt; txt; txt = txt->next)
|
||||
if (hostname_isequal(name, txt->name))
|
||||
return 1;
|
||||
|
||||
|
||||
for (intr = daemon->int_names; intr; intr = intr->next)
|
||||
if (hostname_isequal(name, intr->name))
|
||||
return 1;
|
||||
|
||||
for (ptr = daemon->ptr; ptr; ptr = ptr->next)
|
||||
if (hostname_isequal(name, ptr->name))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1108,21 +1119,27 @@ size_t answer_request(HEADER *header, char *limit, size_t qlen, struct daemon *d
|
||||
/* see if it's w.z.y.z.in-addr.arpa format */
|
||||
int is_arpa = in_arpa_name_2_addr(name, &addr);
|
||||
struct ptr_record *ptr;
|
||||
struct interface_name* intr = NULL;
|
||||
|
||||
for (ptr = daemon->ptr; ptr; ptr = ptr->next)
|
||||
if (hostname_isequal(name, ptr->name))
|
||||
break;
|
||||
|
||||
if (!ptr &&
|
||||
!(crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
|
||||
{
|
||||
if (is_arpa == F_IPV4 && (daemon->options & OPT_BOGUSPRIV) && private_net(&addr))
|
||||
if (is_arpa == F_IPV4)
|
||||
for (intr = daemon->int_names; intr; intr = intr->next)
|
||||
if (addr.addr.addr4.s_addr == get_ifaddr(daemon, intr->intr).s_addr)
|
||||
break;
|
||||
|
||||
if (intr)
|
||||
{
|
||||
ans = 1;
|
||||
if (!dryrun)
|
||||
{
|
||||
/* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
|
||||
ans = 1;
|
||||
nxdomain = 1;
|
||||
if (!dryrun)
|
||||
log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN, name, &addr, 0, NULL, 0);
|
||||
log_query(F_IPV4 | F_REVERSE | F_CONFIG, intr->name, &addr, 0, NULL, 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->local_ttl, NULL,
|
||||
T_PTR, C_IN, "d", intr->name))
|
||||
anscount++;
|
||||
}
|
||||
}
|
||||
else if (ptr)
|
||||
@@ -1132,59 +1149,71 @@ size_t answer_request(HEADER *header, char *limit, size_t qlen, struct daemon *d
|
||||
{
|
||||
log_query(F_CNAME | F_FORWARD | F_CONFIG | F_BIGNAME, name, NULL, 0, NULL, 0);
|
||||
for (ptr = daemon->ptr; ptr; ptr = ptr->next)
|
||||
if (hostname_isequal(name, ptr->name))
|
||||
{
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL,
|
||||
T_PTR, C_IN, "d", ptr->ptr))
|
||||
anscount++;
|
||||
}
|
||||
if (hostname_isequal(name, ptr->name) &&
|
||||
add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->local_ttl, NULL,
|
||||
T_PTR, C_IN, "d", ptr->ptr))
|
||||
anscount++;
|
||||
|
||||
}
|
||||
}
|
||||
else do
|
||||
{
|
||||
/* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
|
||||
if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
|
||||
continue;
|
||||
|
||||
if (crecp->flags & F_NEG)
|
||||
{
|
||||
ans = 1;
|
||||
auth = 0;
|
||||
if (crecp->flags & F_NXDOMAIN)
|
||||
nxdomain = 1;
|
||||
if (!dryrun)
|
||||
log_query(crecp->flags & ~F_FORWARD, name, &addr, 0, NULL, 0);
|
||||
}
|
||||
else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd)
|
||||
{
|
||||
ans = 1;
|
||||
if (!(crecp->flags & (F_HOSTS | F_DHCP)))
|
||||
else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
|
||||
do
|
||||
{
|
||||
/* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
|
||||
if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
|
||||
continue;
|
||||
|
||||
if (crecp->flags & F_NEG)
|
||||
{
|
||||
ans = 1;
|
||||
auth = 0;
|
||||
if (!dryrun)
|
||||
{
|
||||
unsigned long ttl;
|
||||
/* Return 0 ttl for DHCP entries, which might change
|
||||
before the lease expires. */
|
||||
if (crecp->flags & (F_IMMORTAL | F_DHCP))
|
||||
ttl = daemon->local_ttl;
|
||||
else
|
||||
ttl = crecp->ttd - now;
|
||||
|
||||
log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr,
|
||||
0, daemon->addn_hosts, crecp->uid);
|
||||
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, ttl, NULL,
|
||||
T_PTR, C_IN, "d", cache_get_name(crecp)))
|
||||
anscount++;
|
||||
}
|
||||
}
|
||||
} while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
|
||||
if (crecp->flags & F_NXDOMAIN)
|
||||
nxdomain = 1;
|
||||
if (!dryrun)
|
||||
log_query(crecp->flags & ~F_FORWARD, name, &addr, 0, NULL, 0);
|
||||
}
|
||||
else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd)
|
||||
{
|
||||
ans = 1;
|
||||
if (!(crecp->flags & (F_HOSTS | F_DHCP)))
|
||||
auth = 0;
|
||||
if (!dryrun)
|
||||
{
|
||||
unsigned long ttl;
|
||||
/* Return 0 ttl for DHCP entries, which might change
|
||||
before the lease expires. */
|
||||
if (crecp->flags & (F_IMMORTAL | F_DHCP))
|
||||
ttl = daemon->local_ttl;
|
||||
else
|
||||
ttl = crecp->ttd - now;
|
||||
|
||||
log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr,
|
||||
0, daemon->addn_hosts, crecp->uid);
|
||||
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, ttl, NULL,
|
||||
T_PTR, C_IN, "d", cache_get_name(crecp)))
|
||||
anscount++;
|
||||
}
|
||||
}
|
||||
} while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
|
||||
else if (is_arpa == F_IPV4 &&
|
||||
(daemon->options & OPT_BOGUSPRIV) &&
|
||||
private_net(addr.addr.addr4))
|
||||
{
|
||||
/* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
|
||||
ans = 1;
|
||||
nxdomain = 1;
|
||||
if (!dryrun)
|
||||
log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN,
|
||||
name, &addr, 0, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0)
|
||||
{
|
||||
unsigned short type = T_A;
|
||||
|
||||
|
||||
if (flag == F_IPV6)
|
||||
#ifdef HAVE_IPV6
|
||||
type = T_AAAA;
|
||||
@@ -1195,7 +1224,7 @@ size_t answer_request(HEADER *header, char *limit, size_t qlen, struct daemon *d
|
||||
if (qtype != type && qtype != T_ANY)
|
||||
continue;
|
||||
|
||||
/* Check for "A for A" queries. */
|
||||
/* Check for "A for A" queries */
|
||||
if (qtype == T_A && (addr.addr.addr4.s_addr = inet_addr(name)) != (in_addr_t) -1)
|
||||
{
|
||||
ans = 1;
|
||||
@@ -1209,6 +1238,34 @@ size_t answer_request(HEADER *header, char *limit, size_t qlen, struct daemon *d
|
||||
continue;
|
||||
}
|
||||
|
||||
/* interface name stuff */
|
||||
if (qtype == T_A)
|
||||
{
|
||||
struct interface_name *intr;
|
||||
|
||||
for (intr = daemon->int_names; intr; intr = intr->next)
|
||||
if (hostname_isequal(name, intr->name))
|
||||
break;
|
||||
|
||||
if (intr)
|
||||
{
|
||||
ans = 1;
|
||||
if (!dryrun)
|
||||
{
|
||||
if ((addr.addr.addr4 = get_ifaddr(daemon, intr->intr)).s_addr == (in_addr_t) -1)
|
||||
log_query(F_FORWARD | F_CONFIG | F_IPV4 | F_NEG, name, NULL, 0, NULL, 0);
|
||||
else
|
||||
{
|
||||
log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, 0, NULL, 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->local_ttl, NULL, type, C_IN, "4", &addr))
|
||||
anscount++;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
cname_restart:
|
||||
if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME)))
|
||||
{
|
||||
|
||||
465
src/rfc2131.c
465
src/rfc2131.c
@@ -48,7 +48,10 @@
|
||||
#define OPTION_SUBNET_SELECT 118
|
||||
#define OPTION_END 255
|
||||
|
||||
#define SUBOPT_CIRCUIT_ID 1
|
||||
#define SUBOPT_REMOTE_ID 2
|
||||
#define SUBOPT_SUBNET_SELECT 5 /* RFC 3527 */
|
||||
#define SUBOPT_SUBSCR_ID 6 /* RFC 3393 */
|
||||
|
||||
#define DHCPDISCOVER 1
|
||||
#define DHCPOFFER 2
|
||||
@@ -63,6 +66,7 @@
|
||||
#define option_len(opt) ((int)(((unsigned char *)(opt))[1]))
|
||||
#define option_ptr(opt) ((void *)&(((unsigned char *)(opt))[2]))
|
||||
|
||||
static int sanitise(unsigned char *opt, char *buf);
|
||||
static unsigned int calc_time(struct dhcp_context *context, struct dhcp_config *config,
|
||||
struct dhcp_lease *lease, unsigned char *opt, time_t now);
|
||||
static void option_put(struct dhcp_packet *mess, unsigned char *end, int opt, int len, unsigned int val);
|
||||
@@ -74,7 +78,7 @@ static void log_packet(struct daemon *daemon, char *type, void *addr,
|
||||
unsigned char *ext_mac, int mac_len, char *interface, char *string);
|
||||
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 size_t dhcp_packet_size(struct dhcp_packet *mess);
|
||||
static size_t dhcp_packet_size(struct daemon *daemon, struct dhcp_packet *mess, struct dhcp_netid *netid);
|
||||
static void clear_packet(struct dhcp_packet *mess, unsigned char *end);
|
||||
static void do_options(struct dhcp_context *context,
|
||||
struct dhcp_packet *mess,
|
||||
@@ -87,35 +91,10 @@ static void do_options(struct dhcp_context *context,
|
||||
unsigned char fqdn_flags,
|
||||
int null_term,
|
||||
unsigned char *agent_id);
|
||||
|
||||
/* find a good value to use as MAC address for logging and address-allocation hashing.
|
||||
This is normally just the chaddr field from the DHCP packet,
|
||||
but eg Firewire will have hlen == 0 and use the client-id instead.
|
||||
This could be anything, but will normally be EUI64 for Firewire.
|
||||
We assume that if the first byte of the client-id equals the htype byte
|
||||
then the client-id is using the usual encoding and use the rest of the
|
||||
client-id: if not we can use the whole client-id. This should give
|
||||
sane MAC address logs. */
|
||||
static unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr,
|
||||
int clid_len, unsigned char *clid, int *len_out)
|
||||
{
|
||||
if (hwlen == 0 && clid && clid_len > 3)
|
||||
{
|
||||
if ((clid[0] == ARPHRD_EUI64 && hwtype == ARPHRD_IEEE1394) || clid[0] == hwtype)
|
||||
{
|
||||
*len_out = clid_len - 1 ;
|
||||
return clid + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*len_out = clid_len;
|
||||
return clid;
|
||||
}
|
||||
}
|
||||
|
||||
*len_out = hwlen;
|
||||
return hwaddr;
|
||||
}
|
||||
int clid_len, unsigned char *clid, int *len_out);
|
||||
static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt);
|
||||
|
||||
|
||||
size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *iface_name,
|
||||
size_t sz, time_t now, int unicast_dest)
|
||||
@@ -123,7 +102,6 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
|
||||
unsigned char *opt, *clid = NULL;
|
||||
struct dhcp_lease *ltmp, *lease = NULL;
|
||||
struct dhcp_vendor *vendor;
|
||||
struct dhcp_opt *dopt;
|
||||
struct dhcp_mac *mac;
|
||||
struct dhcp_netid_list *id_list;
|
||||
int clid_len = 0, ignore = 0, do_classes = 0, selecting = 0;
|
||||
@@ -192,6 +170,7 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
|
||||
get overwritten, then it will be shuffled back at the end of processing.
|
||||
Note that the incoming options must not be overwritten here, so there has to
|
||||
be enough free space at the end of the packet to copy the option. */
|
||||
unsigned char *sopt;
|
||||
unsigned int total = option_len(opt) + 2;
|
||||
unsigned char *last_opt = option_find(mess, sz, OPTION_END, 0);
|
||||
if (last_opt && last_opt < end - total)
|
||||
@@ -201,10 +180,34 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
|
||||
}
|
||||
|
||||
/* look for RFC3527 Link selection sub-option */
|
||||
if ((opt = option_find1(option_ptr(opt), option_ptr(opt) + option_len(opt), SUBOPT_SUBNET_SELECT, INADDRSZ)))
|
||||
subnet_addr = option_addr(opt);
|
||||
if ((sopt = option_find1(option_ptr(opt), option_ptr(opt) + option_len(opt), SUBOPT_SUBNET_SELECT, INADDRSZ)))
|
||||
subnet_addr = option_addr(sopt);
|
||||
|
||||
/* if a circuit-id or remote-is option is provided, exact-match to options. */
|
||||
for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
|
||||
{
|
||||
int search;
|
||||
|
||||
if (vendor->match_type == MATCH_CIRCUIT)
|
||||
search = SUBOPT_CIRCUIT_ID;
|
||||
else if (vendor->match_type == MATCH_REMOTE)
|
||||
search = SUBOPT_REMOTE_ID;
|
||||
else if (vendor->match_type == MATCH_SUBSCRIBER)
|
||||
search = SUBOPT_SUBSCR_ID;
|
||||
else
|
||||
continue;
|
||||
|
||||
if ((sopt = option_find1(option_ptr(opt), option_ptr(opt) + option_len(opt), search, 1)) &&
|
||||
vendor->len == option_len(sopt) &&
|
||||
memcmp(option_ptr(sopt), vendor->data, vendor->len) == 0)
|
||||
{
|
||||
vendor->netid.next = netid;
|
||||
netid = &vendor->netid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Check for RFC3011 subnet selector - only if RFC3527 one not present */
|
||||
if (subnet_addr.s_addr == 0 && (opt = option_find(mess, sz, OPTION_SUBNET_SELECT, INADDRSZ)))
|
||||
subnet_addr = option_addr(opt);
|
||||
@@ -294,15 +297,29 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
|
||||
|
||||
if (!context)
|
||||
{
|
||||
syslog(LOG_WARNING, _("no address range available for DHCP request %s %s"),
|
||||
subnet_addr.s_addr ? _("with subnet selector") : _("via"),
|
||||
subnet_addr.s_addr ? inet_ntoa(subnet_addr) : (mess->giaddr.s_addr ? inet_ntoa(mess->giaddr) : iface_name));
|
||||
my_syslog(LOG_WARNING, _("no address range available for DHCP request %s %s"),
|
||||
subnet_addr.s_addr ? _("with subnet selector") : _("via"),
|
||||
subnet_addr.s_addr ? inet_ntoa(subnet_addr) : (mess->giaddr.s_addr ? inet_ntoa(mess->giaddr) : iface_name));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* keep _a_ local address available. */
|
||||
fallback = context->local;
|
||||
|
||||
if (daemon->options & OPT_LOG_OPTS)
|
||||
{
|
||||
struct dhcp_context *context_tmp;
|
||||
my_syslog(LOG_INFO, _("DHCP packet: transaction-id is %u"), mess->xid);
|
||||
for (context_tmp = context; context_tmp; context_tmp = context_tmp->current)
|
||||
{
|
||||
strcpy(daemon->namebuff, inet_ntoa(context_tmp->start));
|
||||
if (context_tmp->flags & CONTEXT_STATIC)
|
||||
my_syslog(LOG_INFO, _("Available DHCP subnet: %s/%s"), daemon->namebuff, inet_ntoa(context_tmp->netmask));
|
||||
else
|
||||
my_syslog(LOG_INFO, _("Available DHCP range: %s -- %s"), daemon->namebuff, inet_ntoa(context_tmp->end));
|
||||
}
|
||||
}
|
||||
|
||||
mess->op = BOOTREPLY;
|
||||
|
||||
config = find_config(daemon->dhcp_conf, context, clid, clid_len,
|
||||
@@ -311,7 +328,7 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
|
||||
if (mess_type == 0)
|
||||
{
|
||||
/* BOOTP request */
|
||||
struct dhcp_netid id;
|
||||
struct dhcp_netid id, bootp_id;
|
||||
struct in_addr *logaddr = NULL;
|
||||
|
||||
/* must have a MAC addr for bootp */
|
||||
@@ -341,6 +358,12 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
|
||||
id.next = netid;
|
||||
netid = &id;
|
||||
}
|
||||
|
||||
/* Add "bootp" as a tag to allow different options, address ranges etc
|
||||
for BOOTP clients */
|
||||
bootp_id.net = "bootp";
|
||||
bootp_id.next = netid;
|
||||
netid = &bootp_id;
|
||||
|
||||
for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
|
||||
if (match_netid(id_list->list, netid, 0))
|
||||
@@ -381,7 +404,10 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
|
||||
if (!message &&
|
||||
!lease &&
|
||||
(!(lease = lease_allocate(mess->yiaddr))))
|
||||
message = _("no leases left");
|
||||
{
|
||||
my_syslog(LOG_WARNING, _("Limit of %d leases exceeded."), daemon->dhcp_max);
|
||||
message = _("no leases left");
|
||||
}
|
||||
|
||||
if (!message && !(context = narrow_context(context, mess->yiaddr)))
|
||||
message = _("wrong network");
|
||||
@@ -409,7 +435,7 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
|
||||
|
||||
log_packet(daemon, NULL, logaddr, mess->chaddr, mess->hlen, iface_name, message);
|
||||
|
||||
return message ? dhcp_packet_size(mess) : 0;
|
||||
return message ? 0 : dhcp_packet_size(daemon, mess, netid);
|
||||
}
|
||||
|
||||
if ((opt = option_find(mess, sz, OPTION_CLIENT_FQDN, 4)))
|
||||
@@ -521,37 +547,40 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
|
||||
}
|
||||
|
||||
for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
|
||||
if ((opt = option_find(mess, sz, vendor->is_vendor ? OPTION_VENDOR_ID : OPTION_USER_CLASS, 1)))
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i <= (option_len(opt) - vendor->len); i++)
|
||||
if (memcmp(vendor->data, option_ptr(opt)+i, vendor->len) == 0)
|
||||
{
|
||||
vendor->netid.next = netid;
|
||||
netid = &vendor->netid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* mark vendor-encapsulated options which match the client-supplied vendor class */
|
||||
opt = option_find(mess, sz, OPTION_VENDOR_ID, 1);
|
||||
for (dopt = daemon->vendor_opts; dopt; dopt = dopt->next)
|
||||
{
|
||||
int i, len = 0;
|
||||
dopt->flags &= ~DHOPT_VENDOR_MATCH;
|
||||
if (opt)
|
||||
int mopt;
|
||||
|
||||
if (vendor->match_type == MATCH_VENDOR)
|
||||
mopt = OPTION_VENDOR_ID;
|
||||
else if (vendor->match_type == MATCH_USER)
|
||||
mopt = OPTION_USER_CLASS;
|
||||
else
|
||||
continue;
|
||||
|
||||
if ((opt = option_find(mess, sz, mopt, 1)))
|
||||
{
|
||||
if (dopt->vendor_class)
|
||||
len = strlen((char *)dopt->vendor_class);
|
||||
for (i = 0; i <= (option_len(opt) - len); i++)
|
||||
if (len == 0 || memcmp(dopt->vendor_class, option_ptr(opt)+i, len) == 0)
|
||||
int i;
|
||||
for (i = 0; i <= (option_len(opt) - vendor->len); i++)
|
||||
if (memcmp(vendor->data, option_ptr(opt)+i, vendor->len) == 0)
|
||||
{
|
||||
dopt->flags |= DHOPT_VENDOR_MATCH;
|
||||
vendor->netid.next = netid;
|
||||
netid = &vendor->netid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* mark vendor-encapsulated options which match the client-supplied vendor class */
|
||||
match_vendor_opts(option_find(mess, sz, OPTION_VENDOR_ID, 1), daemon->dhcp_opts);
|
||||
|
||||
if (daemon->options & OPT_LOG_OPTS)
|
||||
{
|
||||
if (sanitise(option_find(mess, sz, OPTION_VENDOR_ID, 1), daemon->namebuff))
|
||||
my_syslog(LOG_INFO, _("Vendor class: %s"), daemon->namebuff);
|
||||
if (sanitise(option_find(mess, sz, OPTION_USER_CLASS, 1), daemon->namebuff))
|
||||
my_syslog(LOG_INFO, _("User class: %s"), daemon->namebuff);
|
||||
}
|
||||
|
||||
/* if all the netids in the ignore list are present, ignore this client */
|
||||
for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
|
||||
if (match_netid(id_list->list, netid, 0))
|
||||
@@ -576,19 +605,7 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
|
||||
return 0;
|
||||
|
||||
/* sanitise any message. Paranoid? Moi? */
|
||||
if ((opt = option_find(mess, sz, OPTION_MESSAGE, 1)))
|
||||
{
|
||||
char *p = option_ptr(opt), *q = daemon->dhcp_buff;
|
||||
int i;
|
||||
|
||||
for (i = option_len(opt); i > 0; i--)
|
||||
{
|
||||
char c = *p++;
|
||||
if (isprint(c))
|
||||
*q++ = c;
|
||||
}
|
||||
*q++ = 0; /* add terminator */
|
||||
}
|
||||
sanitise(option_find(mess, sz, OPTION_MESSAGE, 1), daemon->dhcp_buff);
|
||||
|
||||
if (!(opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ)))
|
||||
return 0;
|
||||
@@ -602,8 +619,8 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
|
||||
config->addr.s_addr == option_addr(opt).s_addr)
|
||||
{
|
||||
prettyprint_time(daemon->dhcp_buff, DECLINE_BACKOFF);
|
||||
syslog(LOG_WARNING, _("disabling DHCP static address %s for %s"),
|
||||
inet_ntoa(config->addr), daemon->dhcp_buff);
|
||||
my_syslog(LOG_WARNING, _("disabling DHCP static address %s for %s"),
|
||||
inet_ntoa(config->addr), daemon->dhcp_buff);
|
||||
config->flags |= CONFIG_DECLINED;
|
||||
config->decline_time = now;
|
||||
}
|
||||
@@ -652,8 +669,8 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
|
||||
int len;
|
||||
unsigned char *mac = extended_hwaddr(ltmp->hwaddr_type, ltmp->hwaddr_len,
|
||||
ltmp->hwaddr, ltmp->clid_len, ltmp->clid, &len);
|
||||
syslog(LOG_WARNING, _("not using configured address %s because it is leased to %s"),
|
||||
addrs, print_mac(daemon, mac, len));
|
||||
my_syslog(LOG_WARNING, _("not using configured address %s because it is leased to %s"),
|
||||
addrs, print_mac(daemon, mac, len));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -662,10 +679,10 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
|
||||
if (context->router.s_addr == config->addr.s_addr)
|
||||
break;
|
||||
if (tmp)
|
||||
syslog(LOG_WARNING, _("not using configured address %s because it is in use by the server or relay"), addrs);
|
||||
my_syslog(LOG_WARNING, _("not using configured address %s because it is in use by the server or relay"), addrs);
|
||||
else if (have_config(config, CONFIG_DECLINED) &&
|
||||
difftime(now, config->decline_time) < (float)DECLINE_BACKOFF)
|
||||
syslog(LOG_WARNING, _("not using configured address %s because it was previously declined"), addrs);
|
||||
my_syslog(LOG_WARNING, _("not using configured address %s because it was previously declined"), addrs);
|
||||
else
|
||||
conf = config->addr;
|
||||
}
|
||||
@@ -709,7 +726,7 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
|
||||
do_options(context, mess, end, req_options, daemon, offer_hostname,
|
||||
netid, subnet_addr, fqdn_flags, borken_opt, agent_id);
|
||||
|
||||
return dhcp_packet_size(mess);
|
||||
return dhcp_packet_size(daemon, mess, netid);
|
||||
|
||||
case DHCPREQUEST:
|
||||
if (ignore || have_config(config, CONFIG_DISABLE))
|
||||
@@ -927,7 +944,7 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
|
||||
netid, subnet_addr, fqdn_flags, borken_opt, agent_id);
|
||||
}
|
||||
|
||||
return dhcp_packet_size(mess);
|
||||
return dhcp_packet_size(daemon, mess, netid);
|
||||
|
||||
case DHCPINFORM:
|
||||
if (ignore || have_config(config, CONFIG_DISABLE))
|
||||
@@ -955,12 +972,47 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
|
||||
do_options(context, mess, end, req_options, daemon, hostname,
|
||||
netid, subnet_addr, fqdn_flags, borken_opt, agent_id);
|
||||
|
||||
return dhcp_packet_size(mess);
|
||||
return dhcp_packet_size(daemon, mess, netid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* find a good value to use as MAC address for logging and address-allocation hashing.
|
||||
This is normally just the chaddr field from the DHCP packet,
|
||||
but eg Firewire will have hlen == 0 and use the client-id instead.
|
||||
This could be anything, but will normally be EUI64 for Firewire.
|
||||
We assume that if the first byte of the client-id equals the htype byte
|
||||
then the client-id is using the usual encoding and use the rest of the
|
||||
client-id: if not we can use the whole client-id. This should give
|
||||
sane MAC address logs. */
|
||||
static unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr,
|
||||
int clid_len, unsigned char *clid, int *len_out)
|
||||
{
|
||||
if (hwlen == 0 && clid && clid_len > 3)
|
||||
{
|
||||
if (clid[0] == hwtype)
|
||||
{
|
||||
*len_out = clid_len - 1 ;
|
||||
return clid + 1;
|
||||
}
|
||||
|
||||
#if defined(ARPHRD_EUI64) && defined(ARPHRD_IEEE1394)
|
||||
if (clid[0] == ARPHRD_EUI64 && hwtype == ARPHRD_IEEE1394)
|
||||
{
|
||||
*len_out = clid_len - 1 ;
|
||||
return clid + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
*len_out = clid_len;
|
||||
return clid;
|
||||
}
|
||||
|
||||
*len_out = hwlen;
|
||||
return hwaddr;
|
||||
}
|
||||
|
||||
static unsigned int calc_time(struct dhcp_context *context, struct dhcp_config *config,
|
||||
struct dhcp_lease *lease, unsigned char *opt, time_t now)
|
||||
{
|
||||
@@ -989,6 +1041,29 @@ static unsigned int calc_time(struct dhcp_context *context, struct dhcp_config *
|
||||
return time;
|
||||
}
|
||||
|
||||
static int sanitise(unsigned char *opt, char *buf)
|
||||
{
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
*buf = 0;
|
||||
|
||||
if (!opt)
|
||||
return 0;
|
||||
|
||||
p = option_ptr(opt);
|
||||
|
||||
for (i = option_len(opt); i > 0; i--)
|
||||
{
|
||||
char c = *p++;
|
||||
if (isprint(c))
|
||||
*buf++ = c;
|
||||
}
|
||||
*buf = 0; /* add terminator */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void log_packet(struct daemon *daemon, char *type, void *addr,
|
||||
unsigned char *ext_mac, int mac_len, char *interface, char *string)
|
||||
{
|
||||
@@ -998,14 +1073,30 @@ static void log_packet(struct daemon *daemon, char *type, void *addr,
|
||||
if (addr)
|
||||
memcpy(&a, addr, sizeof(a));
|
||||
|
||||
syslog(LOG_INFO, "%s%s(%s) %s%s%s %s",
|
||||
type ? "DHCP" : "BOOTP",
|
||||
type ? type : "",
|
||||
interface,
|
||||
addr ? inet_ntoa(a) : "",
|
||||
addr ? " " : "",
|
||||
print_mac(daemon, ext_mac, mac_len),
|
||||
string ? string : "");
|
||||
my_syslog(LOG_INFO, "%s%s(%s) %s%s%s %s",
|
||||
type ? "DHCP" : "BOOTP",
|
||||
type ? type : "",
|
||||
interface,
|
||||
addr ? inet_ntoa(a) : "",
|
||||
addr ? " " : "",
|
||||
print_mac(daemon, ext_mac, mac_len),
|
||||
string ? string : "");
|
||||
}
|
||||
|
||||
static void log_options(struct daemon *daemon, unsigned char *start)
|
||||
{
|
||||
while (*start != OPTION_END)
|
||||
{
|
||||
char *text = option_string(start[0]);
|
||||
unsigned char trunc = start[1] < 13 ? start[1] : 13;
|
||||
my_syslog(LOG_INFO, "sent size:%3d option:%3d%s%s%s%s%s",
|
||||
start[1], start[0],
|
||||
text ? ":" : "", text ? text : "",
|
||||
start[1] == 0 ? "" : " ",
|
||||
start[1] == 0 ? "" : print_mac(daemon, &start[2], trunc),
|
||||
trunc == start[1] ? "" : "...");
|
||||
start += start[1] + 2;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize)
|
||||
@@ -1103,28 +1194,53 @@ static unsigned char *find_overload(struct dhcp_packet *mess)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static size_t dhcp_packet_size(struct dhcp_packet *mess)
|
||||
static size_t dhcp_packet_size(struct daemon *daemon, struct dhcp_packet *mess, struct dhcp_netid *netid)
|
||||
{
|
||||
unsigned char *p = dhcp_skip_opts(&mess->options[0] + sizeof(u32));
|
||||
unsigned char *overload;
|
||||
size_t ret;
|
||||
|
||||
/* We do logging too */
|
||||
if (netid && (daemon->options & OPT_LOG_OPTS))
|
||||
{
|
||||
char *p = daemon->namebuff;
|
||||
*p = 0;
|
||||
for (; netid; netid = netid->next)
|
||||
{
|
||||
strncat (p, netid->net, MAXDNAME);
|
||||
if (netid->next)
|
||||
strncat (p, ", ", MAXDNAME);
|
||||
}
|
||||
p[MAXDNAME - 1] = 0;
|
||||
my_syslog(LOG_INFO, _("tags: %s"), p);
|
||||
}
|
||||
|
||||
/* add END options to the regions. */
|
||||
if ((overload = find_overload(mess)))
|
||||
{
|
||||
if (option_uint(overload, 1) & 1)
|
||||
*dhcp_skip_opts(mess->file) = OPTION_END;
|
||||
{
|
||||
*dhcp_skip_opts(mess->file) = OPTION_END;
|
||||
if (daemon->options & OPT_LOG_OPTS)
|
||||
log_options(daemon, mess->file);
|
||||
}
|
||||
if (option_uint(overload, 1) & 2)
|
||||
*dhcp_skip_opts(mess->sname) = OPTION_END;
|
||||
{
|
||||
*dhcp_skip_opts(mess->sname) = OPTION_END;
|
||||
if (daemon->options & OPT_LOG_OPTS)
|
||||
log_options(daemon, mess->sname);
|
||||
}
|
||||
}
|
||||
|
||||
*p++ = OPTION_END;
|
||||
if (daemon->options & OPT_LOG_OPTS)
|
||||
log_options(daemon, &mess->options[0] + sizeof(u32));
|
||||
|
||||
ret = (size_t)(p - (unsigned char *)mess);
|
||||
|
||||
if (ret < MIN_PACKETSZ)
|
||||
ret = MIN_PACKETSZ;
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1178,7 +1294,7 @@ static unsigned char *free_space(struct dhcp_packet *mess, unsigned char *end, i
|
||||
}
|
||||
|
||||
if (!p)
|
||||
syslog(LOG_WARNING, _("cannot send DHCP option %d: no space left in packet"), opt);
|
||||
my_syslog(LOG_WARNING, _("cannot send DHCP/BOOTP option %d: no space left in packet"), opt);
|
||||
}
|
||||
|
||||
if (p)
|
||||
@@ -1223,7 +1339,7 @@ static int do_opt(struct dhcp_opt *opt, unsigned char *p, struct in_addr local,
|
||||
|
||||
if (p && len != 0)
|
||||
{
|
||||
if (opt->flags & DHOPT_ADDR)
|
||||
if ((opt->flags & DHOPT_ADDR) && !(opt->flags & DHOPT_ENCAPSULATE))
|
||||
{
|
||||
int j;
|
||||
struct in_addr *a = (struct in_addr *)opt->val;
|
||||
@@ -1246,8 +1362,8 @@ static int do_opt(struct dhcp_opt *opt, unsigned char *p, struct in_addr local,
|
||||
static int in_list(unsigned char *list, int opt)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* If no requested options, send everything, not nothing. */
|
||||
|
||||
/* If no requested options, send everything, not nothing. */
|
||||
if (!list)
|
||||
return 1;
|
||||
|
||||
@@ -1262,13 +1378,35 @@ static struct dhcp_opt *option_find2(struct dhcp_netid *netid, struct dhcp_opt *
|
||||
{
|
||||
struct dhcp_opt *tmp;
|
||||
for (tmp = opts; tmp; tmp = tmp->next)
|
||||
if (tmp->opt == opt)
|
||||
if (tmp->opt == opt && !(tmp->flags & DHOPT_ENCAPSULATE))
|
||||
if (match_netid(tmp->netid, netid, 1) || match_netid(tmp->netid, netid, 0))
|
||||
return tmp;
|
||||
|
||||
return netid ? option_find2(NULL, opts, opt) : NULL;
|
||||
}
|
||||
|
||||
/* mark vendor-encapsulated options which match the client-supplied or
|
||||
config-supplied vendor class */
|
||||
static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt)
|
||||
{
|
||||
for (; dopt; dopt = dopt->next)
|
||||
{
|
||||
dopt->flags &= ~DHOPT_VENDOR_MATCH;
|
||||
if (opt && (dopt->flags & DHOPT_ENCAPSULATE))
|
||||
{
|
||||
int i, len = 0;
|
||||
if (dopt->vendor_class)
|
||||
len = strlen((char *)dopt->vendor_class);
|
||||
for (i = 0; i <= (option_len(opt) - len); i++)
|
||||
if (len == 0 || memcmp(dopt->vendor_class, option_ptr(opt)+i, len) == 0)
|
||||
{
|
||||
dopt->flags |= DHOPT_VENDOR_MATCH;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void clear_packet(struct dhcp_packet *mess, unsigned char *end)
|
||||
{
|
||||
memset(mess->sname, 0, sizeof(mess->sname));
|
||||
@@ -1292,9 +1430,30 @@ static void do_options(struct dhcp_context *context,
|
||||
struct dhcp_opt *opt, *config_opts = daemon->dhcp_opts;
|
||||
struct dhcp_boot *boot;
|
||||
unsigned char *p, *end = agent_id ? agent_id : real_end;
|
||||
int len;
|
||||
int i, len, force_encap = 0;
|
||||
unsigned char f0 = 0, s0 = 0;
|
||||
|
||||
/* logging */
|
||||
if ((daemon->options & OPT_LOG_OPTS) && req_options)
|
||||
{
|
||||
char *q = daemon->namebuff;
|
||||
for (i = 0; req_options[i] != OPTION_END; i++)
|
||||
{
|
||||
char *s = option_string(req_options[i]);
|
||||
q +=snprintf(q, MAXDNAME - (q - daemon->namebuff),
|
||||
"%d%s%s%s",
|
||||
req_options[i],
|
||||
s ? ":" : "",
|
||||
s ? s : "",
|
||||
req_options[i+1] == OPTION_END ? "" : ", ");
|
||||
if (req_options[i+1] == OPTION_END || (q - daemon->namebuff) > 40)
|
||||
{
|
||||
q = daemon->namebuff;
|
||||
my_syslog(LOG_INFO, _("requested options: %s"), daemon->namebuff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* decide which dhcp-boot option we're using */
|
||||
for (boot = daemon->boot_config; boot; boot = boot->next)
|
||||
if (match_netid(boot->netid, netid, 0))
|
||||
@@ -1319,7 +1478,11 @@ static void do_options(struct dhcp_context *context,
|
||||
if (req_options && in_list(req_options, OPTION_SNAME))
|
||||
option_put_string(mess, end, OPTION_SNAME, boot->sname, 1);
|
||||
else
|
||||
strncpy((char *)mess->sname, boot->sname, sizeof(mess->sname)-1);
|
||||
{
|
||||
if (daemon->options & OPT_LOG_OPTS)
|
||||
my_syslog(LOG_INFO, _("server name: %s"), boot->sname);
|
||||
strncpy((char *)mess->sname, boot->sname, sizeof(mess->sname)-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (boot->file)
|
||||
@@ -1327,13 +1490,20 @@ static void do_options(struct dhcp_context *context,
|
||||
if (req_options && in_list(req_options, OPTION_FILENAME))
|
||||
option_put_string(mess, end, OPTION_FILENAME, boot->file, 1);
|
||||
else
|
||||
strncpy((char *)mess->file, boot->file, sizeof(mess->file)-1);
|
||||
{
|
||||
if (daemon->options & OPT_LOG_OPTS)
|
||||
my_syslog(LOG_INFO, _("bootfile name: %s"), boot->file);
|
||||
strncpy((char *)mess->file, boot->file, sizeof(mess->file)-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (boot->next_server.s_addr)
|
||||
mess->siaddr = boot->next_server;
|
||||
|
||||
if (daemon->options & OPT_LOG_OPTS)
|
||||
my_syslog(LOG_INFO, _("next server: %s"), inet_ntoa(mess->siaddr));
|
||||
}
|
||||
|
||||
|
||||
/* We don't want to do option-overload for BOOTP, so make the file and sname
|
||||
fields look like they are in use, even when they aren't. This gets restored
|
||||
at the end of this function. */
|
||||
@@ -1428,17 +1598,23 @@ static void do_options(struct dhcp_context *context,
|
||||
}
|
||||
}
|
||||
|
||||
for (opt=config_opts; opt; opt = opt->next)
|
||||
for (opt = config_opts; opt; opt = opt->next)
|
||||
{
|
||||
/* was it asked for, or are we sending it anyway? */
|
||||
if (!(opt->flags & DHOPT_FORCE) && !in_list(req_options, opt->opt))
|
||||
continue;
|
||||
|
||||
/* prohibit some used-internally options */
|
||||
if (opt->opt == OPTION_HOSTNAME ||
|
||||
opt->opt == OPTION_CLIENT_FQDN ||
|
||||
opt->opt == OPTION_MAXMESSAGE ||
|
||||
opt->opt == OPTION_VENDOR_CLASS_OPT ||
|
||||
opt->opt == OPTION_OVERLOAD ||
|
||||
opt->opt == OPTION_PAD ||
|
||||
opt->opt == OPTION_END ||
|
||||
!in_list(req_options, opt->opt) ||
|
||||
opt != option_find2(netid, config_opts, opt->opt))
|
||||
opt->opt == OPTION_END)
|
||||
continue;
|
||||
|
||||
/* netids match and not encapsulated? */
|
||||
if (opt != option_find2(netid, config_opts, opt->opt))
|
||||
continue;
|
||||
|
||||
/* For the options we have default values on
|
||||
@@ -1453,41 +1629,66 @@ static void do_options(struct dhcp_context *context,
|
||||
|
||||
len = do_opt(opt, NULL, context->local, null_term);
|
||||
if ((p = free_space(mess, end, opt->opt, len)))
|
||||
do_opt(opt, p, context->local, null_term);
|
||||
}
|
||||
{
|
||||
do_opt(opt, p, context->local, null_term);
|
||||
|
||||
if (in_list(req_options, OPTION_VENDOR_CLASS_OPT))
|
||||
/* If we send a vendor-id, revisit which vendor-ops we consider
|
||||
it appropriate to send. */
|
||||
if (opt->opt == OPTION_VENDOR_ID)
|
||||
match_vendor_opts(p - 2, config_opts);
|
||||
}
|
||||
}
|
||||
|
||||
/* prune encapsulated options based on netid, and look if we're forcing them to be sent */
|
||||
for (opt = config_opts; opt; opt = opt->next)
|
||||
if (opt->flags & DHOPT_VENDOR_MATCH)
|
||||
{
|
||||
if (!match_netid(opt->netid, netid, 1) && !match_netid(opt->netid, netid, 0))
|
||||
opt->flags &= ~DHOPT_VENDOR_MATCH;
|
||||
else if (opt->flags & DHOPT_FORCE)
|
||||
force_encap = 1;
|
||||
}
|
||||
|
||||
if (force_encap || in_list(req_options, OPTION_VENDOR_CLASS_OPT))
|
||||
{
|
||||
int enc_len = 0;
|
||||
|
||||
struct dhcp_opt *start;
|
||||
|
||||
/* find size in advance */
|
||||
for (opt = daemon->vendor_opts; opt; opt = opt->next)
|
||||
for (start = opt = config_opts; opt; opt = opt->next)
|
||||
if (opt->flags & DHOPT_VENDOR_MATCH)
|
||||
{
|
||||
if (!match_netid(opt->netid, netid, 1) && !match_netid(opt->netid, netid, 0))
|
||||
opt->flags &= ~DHOPT_VENDOR_MATCH;
|
||||
int new = do_opt(opt, NULL, context->local, null_term) + 2;
|
||||
if (enc_len + new <= 255)
|
||||
enc_len += new;
|
||||
else
|
||||
{
|
||||
int new = enc_len + do_opt(opt, NULL, context->local, null_term) + 2;
|
||||
if (new <= 255)
|
||||
enc_len = new;
|
||||
else
|
||||
{
|
||||
syslog(LOG_WARNING, _("cannot send encapsulated option %d: no space left in wrapper"), opt->opt);
|
||||
opt->flags &= ~DHOPT_VENDOR_MATCH;
|
||||
}
|
||||
p = free_space(mess, end, OPTION_VENDOR_CLASS_OPT, enc_len);
|
||||
for (; start && start != opt; start = start->next)
|
||||
if (p && (start->flags & DHOPT_VENDOR_MATCH))
|
||||
{
|
||||
len = do_opt(start, p + 2, context->local, null_term);
|
||||
*(p++) = start->opt;
|
||||
*(p++) = len;
|
||||
p += len;
|
||||
}
|
||||
enc_len = new;
|
||||
start = opt;
|
||||
}
|
||||
}
|
||||
|
||||
if ((p = free_space(mess, end, OPTION_VENDOR_CLASS_OPT, enc_len)))
|
||||
|
||||
if (enc_len != 0 &&
|
||||
(p = free_space(mess, end, OPTION_VENDOR_CLASS_OPT, enc_len + 1)))
|
||||
{
|
||||
for (opt = daemon->vendor_opts; opt; opt = opt->next)
|
||||
if (opt->flags & DHOPT_VENDOR_MATCH)
|
||||
for (; start; start = start->next)
|
||||
if (start->flags & DHOPT_VENDOR_MATCH)
|
||||
{
|
||||
len = do_opt(opt, p + 2, context->local, null_term);
|
||||
*(p++) = opt->opt;
|
||||
len = do_opt(start, p + 2, context->local, null_term);
|
||||
*(p++) = start->opt;
|
||||
*(p++) = len;
|
||||
p += len;
|
||||
}
|
||||
*p = OPTION_END;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
42
src/tftp.c
42
src/tftp.c
@@ -106,7 +106,8 @@ void tftp_request(struct listener *listen, struct daemon *daemon, time_t now)
|
||||
if (addr.sin_addr.s_addr == 0)
|
||||
return;
|
||||
|
||||
if (!iface_check(daemon, AF_INET, (struct all_addr *)&addr, &ifr, &if_index))
|
||||
if (!iface_check(daemon, AF_INET, (struct all_addr *)&addr.sin_addr,
|
||||
&ifr, &if_index))
|
||||
return;
|
||||
|
||||
/* allowed interfaces are the same as for DHCP */
|
||||
@@ -160,7 +161,8 @@ void tftp_request(struct listener *listen, struct daemon *daemon, time_t now)
|
||||
while ((opt = next(&p, end)))
|
||||
{
|
||||
if (strcasecmp(opt, "blksize") == 0 &&
|
||||
(opt = next(&p, end)))
|
||||
(opt = next(&p, end)) &&
|
||||
!(daemon->options & OPT_TFTP_NOBLOCK))
|
||||
{
|
||||
transfer->blocksize = atoi(opt);
|
||||
if (transfer->blocksize < 1)
|
||||
@@ -178,18 +180,26 @@ void tftp_request(struct listener *listen, struct daemon *daemon, time_t now)
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(daemon->namebuff, "/");
|
||||
if (daemon->tftp_prefix)
|
||||
{
|
||||
strncpy(daemon->namebuff, daemon->tftp_prefix, MAXDNAME);
|
||||
if (daemon->tftp_prefix[strlen(daemon->tftp_prefix)-1] != '/' &&
|
||||
filename[0] != '/')
|
||||
if (daemon->tftp_prefix[0] == '/')
|
||||
daemon->namebuff[0] = 0;
|
||||
strncat(daemon->namebuff, daemon->tftp_prefix, MAXDNAME);
|
||||
if (daemon->tftp_prefix[strlen(daemon->tftp_prefix)-1] != '/')
|
||||
strncat(daemon->namebuff, "/", MAXDNAME);
|
||||
|
||||
/* Absolute pathnames OK if they match prefix */
|
||||
if (filename[0] == '/')
|
||||
{
|
||||
if (strstr(filename, daemon->namebuff) == filename)
|
||||
daemon->namebuff[0] = 0;
|
||||
else
|
||||
filename++;
|
||||
}
|
||||
}
|
||||
else if (filename[0] != '/')
|
||||
strncpy(daemon->namebuff, "/", MAXDNAME);
|
||||
else
|
||||
else if (filename[0] == '/')
|
||||
daemon->namebuff[0] = 0;
|
||||
|
||||
strncat(daemon->namebuff, filename, MAXDNAME);
|
||||
daemon->namebuff[MAXDNAME-1] = 0;
|
||||
|
||||
@@ -226,7 +236,7 @@ void tftp_request(struct listener *listen, struct daemon *daemon, time_t now)
|
||||
free_transfer(transfer);
|
||||
else
|
||||
{
|
||||
syslog(LOG_INFO, _("TFTP sent %s to %s"), daemon->namebuff, inet_ntoa(peer.sin_addr));
|
||||
my_syslog(LOG_INFO, _("TFTP sent %s to %s"), daemon->namebuff, inet_ntoa(peer.sin_addr));
|
||||
transfer->next = daemon->tftp_trans;
|
||||
daemon->tftp_trans = transfer;
|
||||
}
|
||||
@@ -349,9 +359,9 @@ void check_tftp_listeners(struct daemon *daemon, fd_set *rset, time_t now)
|
||||
*(q++) = *r;
|
||||
*q = 0;
|
||||
}
|
||||
syslog(LOG_ERR, _("TFTP error %d %s received from %s"),
|
||||
(int)ntohs(mess->block), err,
|
||||
inet_ntoa(transfer->peer.sin_addr));
|
||||
my_syslog(LOG_ERR, _("TFTP error %d %s received from %s"),
|
||||
(int)ntohs(mess->block), err,
|
||||
inet_ntoa(transfer->peer.sin_addr));
|
||||
|
||||
/* Got err, ensure we take abort */
|
||||
transfer->timeout = now;
|
||||
@@ -380,8 +390,8 @@ void check_tftp_listeners(struct daemon *daemon, fd_set *rset, time_t now)
|
||||
/* don't complain about timeout when we're awaiting the last
|
||||
ACK, some clients never send it */
|
||||
if (len != 0)
|
||||
syslog(LOG_ERR, _("TFTP failed sending %s to %s"),
|
||||
transfer->file->filename, inet_ntoa(transfer->peer.sin_addr));
|
||||
my_syslog(LOG_ERR, _("TFTP failed sending %s to %s"),
|
||||
transfer->file->filename, inet_ntoa(transfer->peer.sin_addr));
|
||||
len = 0;
|
||||
}
|
||||
|
||||
@@ -440,7 +450,7 @@ static ssize_t tftp_err(int err, char *packet, char *message, char *file)
|
||||
mess->err = htons(err);
|
||||
ret += (snprintf(mess->message, 500, message, file, errstr) + 1);
|
||||
if (err != ERR_FNF)
|
||||
syslog(LOG_ERR, "TFTP %s", mess->message);
|
||||
my_syslog(LOG_ERR, "TFTP %s", mess->message);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
43
src/util.c
43
src/util.c
@@ -156,35 +156,6 @@ void *safe_malloc(size_t size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void log_err(char *message, char *arg1)
|
||||
{
|
||||
char *errmess = strerror(errno);
|
||||
|
||||
if (!arg1)
|
||||
arg1 = errmess;
|
||||
|
||||
fprintf(stderr, "dnsmasq: ");
|
||||
fprintf(stderr, message, arg1, errmess);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
syslog(LOG_CRIT, message, arg1, errmess);
|
||||
}
|
||||
|
||||
void complain(char *message, int lineno, char *file)
|
||||
{
|
||||
char buff[256];
|
||||
|
||||
sprintf(buff, _("%s at line %d of %%s"), message, lineno);
|
||||
log_err(buff, file);
|
||||
}
|
||||
|
||||
void die(char *message, char *arg1)
|
||||
{
|
||||
log_err(message, arg1);
|
||||
syslog(LOG_CRIT, _("FAILED to start up"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2)
|
||||
{
|
||||
if (s1->sa.sa_family == s2->sa.sa_family)
|
||||
@@ -418,20 +389,6 @@ void bump_maxfd(int fd, int *max)
|
||||
*max = fd;
|
||||
}
|
||||
|
||||
void log_start(struct daemon *daemon)
|
||||
{
|
||||
if (daemon->options & OPT_DEBUG)
|
||||
{
|
||||
#ifdef LOG_PERROR
|
||||
openlog("dnsmasq", LOG_PERROR, daemon->log_fac);
|
||||
#else
|
||||
openlog("dnsmasq", 0, daemon->log_fac);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
openlog("dnsmasq", LOG_PID, daemon->log_fac);
|
||||
}
|
||||
|
||||
int read_write(int fd, unsigned char *packet, int size, int rw)
|
||||
{
|
||||
ssize_t n, done;
|
||||
|
||||
Reference in New Issue
Block a user