Compare commits

...

2 Commits
v2.30 ... v2.32

Author SHA1 Message Date
Simon Kelley
849a8357ba import of dnsmasq-2.32.tar.gz 2012-01-05 17:31:12 +00:00
Simon Kelley
7cebd20fe7 import of dnsmasq-2.31.tar.gz 2012-01-05 17:31:12 +00:00
35 changed files with 7049 additions and 4704 deletions

View File

@@ -1803,10 +1803,87 @@ version 2.29
version 2.30
Fixed crash when a DHCP client requested a broadcast
reply. This problem was introduced in version 2.29.
reply. This problem was introduced in version 2.28.
Thanks to Sandra Dekkers for the bug report.
version 2.31
Added --dhcp-script option. There have been calls for this
for a long time from many good people. Fabio Muzzi gets
the prize for finally convincing me.
Added example dbus config file and moved dbus stuff into
its own directory.
Removed horribly outdated Redhat RPM build files. These
are obsolete now that dnsmasq in in Fedora extras. Thanks
to Patrick "Jima" Laughton, the Fedora package
maintainer.
Added workaround for Linux kernel bug. This manifests
itself as failure of DHCP on kernels with "support for
classical IP over ATM" configured. That includes most
Debian kernel packages. Many thanks to A. Costa and
Benjamin Kudria for their huge efforts in chasing this
down.
Force-kill child processes when dnsmasq is sent a sigterm,
otherwise an unclosed TCP connection could keep dnsmasq
hanging round for a few minutes.
Tweaked config.h logic for uclibc build. It will now pick
up MMU and IPV6 status correctly on every system I tested.
version 2.32
Attempt a better job of replacing previous configuration
when re-reading /etc/hosts and /etc/ethers. SIGHUP is
still not identical to a restart under all circumstances,
but it is for the common case of name->MAC address in
/etc/ethers and name->IP address in /etc/hosts.
Fall back to broadcast for DHCP to an unconfigured client
when the MAC address size is greater than 14 bytes.
Fix problem in 2.28-onwards releases which breaks DNS on
Mac OS X. Thanks to Doug Fields for the bug report and
testing.
Added fix to allow compilation on c89-only compilers.
Thanks to John Mastwijk for the patch.
Tweak resolv file polling code to work better if there is
a race between updating the mtime and file contents. This
is not normally a problem, but it can be on systems which
replace nameservers whilst active. The code now continues
to read resolv.conf until it gets at least one usable
server. Thanks to Holger Mauermann for help with this.
If a client DECLINEs an address which is allocated to it
via dhcp-host or /etc/hosts, lock that address out of use
for ten minutes, instead of forever, and log when it's not
being used because of the lock-out. This should provide
less surprising behaviour when a configured address can't be
used. Thanks to Peter Surda and Heinz Deinhart for input
on this.
Fixed *BSD DHCP breakage with only some
arches/compilers, depending on structure padding rules.
Thanks to Jeb Campbell and Tom Hensel for help with this.
Added --conf-dir option. Suggestion from Aaron Tygart.
Applied patch from Brent Cook which allows netids in
dhcp-option configuration lines to be prefixed by
"net:". This is not required by the syntax, but it is
consistent with other configuration items.
Added --log-facility option. Suggestion from Fabio Muzzi.
Major update to Spanish translation. Many thanks to Chris
Chatham.
Fixed gcc-4.1 strict-alias compilation warning.

View File

@@ -6,10 +6,10 @@ 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
.c.o:
$(CC) $(CFLAGS) $(I18N) `../bld/pkg-wrapper $(PKG_CONFIG) --cflags dbus-1` $(RPM_OPT_FLAGS) -Wall -W -c $<
$(CC) $(CFLAGS) $(COPTS) $(I18N) `echo $(COPTS) | ../bld/pkg-wrapper $(PKG_CONFIG) --cflags dbus-1` $(RPM_OPT_FLAGS) -Wall -W -c $<
dnsmasq : $(OBJS)
$(CC) -o $@ $(OBJS) `../bld/pkg-wrapper $(PKG_CONFIG) --libs dbus-1` $(LIBS)
$(CC) -o $@ $(OBJS) `echo $(COPTS) | ../bld/pkg-wrapper $(PKG_CONFIG) --libs dbus-1` $(LIBS)
dnsmasq.pot : $(OBJS:.o=.c) dnsmasq.h config.h
xgettext -d dnsmasq --foreign-user --keyword=_ -o dnsmasq.pot -i $(OBJS:.o=.c)

View File

@@ -1,6 +1,6 @@
#!/bin/sh
if grep -q "^\#.*define.*HAVE_DBUS" config.h ; then
if grep -q "^\#.*define.*HAVE_DBUS" config.h || grep -q HAVE_DBUS ; then
exec $*
fi

16
dbus/dnsmasq.conf Normal file
View File

@@ -0,0 +1,16 @@
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<policy user="root">
<allow own="uk.org.thekelleys.dnsmasq"/>
<allow send_destination="uk.org.thekelleys.dnsmasq"/>
<allow send_interface="uk.org.thekelleys.dnsmasq"/>
</policy>
<policy context="default">
<deny own="uk.org.thekelleys.dnsmasq"/>
<deny send_destination="uk.org.thekelleys.dnsmasq"/>
<deny send_interface="uk.org.thekelleys.dnsmasq"/>
</policy>
</busconfig>

View File

@@ -1,133 +0,0 @@
###############################################################################
#
# General mumbojumbo
#
###############################################################################
Name: dnsmasq
Version: 2.30
Release: 1
License: GPL
Group: System Environment/Daemons
Vendor: Simon Kelley
Packager: Simon Kelley
Distribution: Red Hat Linux
URL: http://www.thekelleys.org.uk/dnsmasq
Source0: %{name}-%{version}.tar.gz
Requires: chkconfig
BuildRoot: /var/tmp/%{name}-%{version}
Summary: A lightweight caching nameserver
%description
Dnsmasq is lightweight, easy to configure DNS forwarder and DHCP server. It
is designed to provide DNS and, optionally, DHCP, to a small network. It can
serve the names of local machines which are not in the global DNS. The DHCP
server integrates with the DNS server and allows machines with DHCP-allocated
addresses to appear in the DNS with names configured either in each host or
in a central configuration file. Dnsmasq supports static and dynamic DHCP
leases and BOOTP for network booting of diskless machines.
###############################################################################
#
# Build
#
###############################################################################
%prep
%setup -q
%build
make all-i18n PREFIX=/usr
###############################################################################
#
# Install
#
###############################################################################
%install
rm -rf $RPM_BUILD_ROOT
mkdir -p -m 755 $RPM_BUILD_ROOT/usr/sbin
mkdir -p -m 755 $RPM_BUILD_ROOT/etc/rc.d/init.d
mkdir -p -m 755 $RPM_BUILD_ROOT/usr/share/man/man8
cp rpm/dnsmasq.rh $RPM_BUILD_ROOT/etc/rc.d/init.d/dnsmasq
make install-i18n DESTDIR=$RPM_BUILD_ROOT PREFIX=/usr
strip $RPM_BUILD_ROOT/usr/sbin/dnsmasq
cp src/dnsmasq $RPM_BUILD_ROOT/usr/sbin
cp dnsmasq.conf.example $RPM_BUILD_ROOT/etc/dnsmasq.conf
###############################################################################
#
# Clean up
#
###############################################################################
%clean
rm -rf $RPM_BUILD_ROOT
###############################################################################
#
# Post-install scriptlet
#
###############################################################################
%post
/sbin/chkconfig --add dnsmasq
###############################################################################
#
# Pre-uninstall scriptlet
#
# If there's a time when your package needs to have one last look around before
# the user erases it, the place to do it is in the %preun script. Anything that
# a package needs to do immediately prior to RPM taking any action to erase the
# package, can be done here.
#
###############################################################################
%preun
if [ $1 = 0 ]; then # execute this only if we are NOT doing an upgrade
service dnsmasq stop >/dev/null 2>&1
/sbin/chkconfig --del dnsmasq
fi
###############################################################################
#
# Post-uninstall scriptlet
#
# The %postun script executes after the package has been removed. It is the
# last chance for a package to clean up after itself.
#
###############################################################################
%postun
if [ "$1" -ge "1" ]; then
service dnsmasq restart >/dev/null 2>&1
fi
###############################################################################
#
# File list
#
###############################################################################
%files
%defattr(-,root,root)
%doc CHANGELOG COPYING FAQ doc.html setup.html UPGRADING_to_2.0
%config /etc/rc.d/init.d/dnsmasq
%config /etc/dnsmasq.conf
%attr(0755,root,root) /etc/rc.d/init.d/dnsmasq
%attr(0664,root,root) /etc/dnsmasq.conf
%attr(0755,root,root) /usr/sbin/dnsmasq
#%attr(0644,root,root) /usr/share/man/*/man8/dnsmasq*
%attr(0644,root,root) /usr/share/man/man8/dnsmasq*
%attr(0644,root,root) /usr/share/locale/*/LC_MESSAGES/*

View File

@@ -5,7 +5,7 @@
###############################################################################
Name: dnsmasq
Version: 2.30
Version: 2.32
Release: 1
Copyright: GPL
Group: Productivity/Networking/DNS/Servers

View File

@@ -285,6 +285,12 @@ bogus-priv
# http://www.isc.org/index.pl?/sw/dhcp/authoritative.php
#dhcp-authoritative
# Run an executable when a DHCP lease is created or destroyed.
# The arguments sent to the script are "add" or "del",
# then the MAC address, the IP address and finally the hostname
# if there is one.
#dhcp-script=/bin/echo
# Set the cachesize here.
#cache-size=150

View File

@@ -22,7 +22,8 @@ Supported platforms include Linux (with glibc and uclibc), *BSD and
Mac OS X.
Dnsmasq is included in at least the following Linux distributions:
Gentoo, Debian, Slackware, Suse,
Smoothwall, IP-Cop, floppyfw, Firebox, LEAF, Freesco, fli4l, CoyoteLinux and
Smoothwall, IP-Cop, floppyfw, Firebox, LEAF, Freesco, fli4l,
CoyoteLinux, Endian Firewall and
Clarkconnect. It is also available as a FreeBSD port and is used in
Linksys wireless routers and the m0n0wall project.
<P>

View File

@@ -60,6 +60,10 @@ to handle TCP queries.
.B \-q, --log-queries
Log the results of DNS queries handled by dnsmasq. Enable a full cache dump on receipt of SIGUSR1.
.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.
.TP
.B \-x, --pid-file=<path>
Specify an alternate path for dnsmasq to record its process-id in. Normally /var/run/dnsmasq.pid.
.TP
@@ -533,7 +537,34 @@ is given but no dhcp-range option is given then dnsmasq version 1
behaviour is activated. The file given is assumed to be an ISC dhcpd
lease file and parsed for leases which are then added to the DNS
system if they have a hostname. This functionality may have been
excluded from dnsmasq at compile time, in which case an error will occur.
excluded from dnsmasq at compile time, in which case an error will
occur. In any case note that ISC leasefile integration is a deprecated
feature. It should not be used in new installations, and will be
removed in a future release.
.TP
.B \-6 --dhcp-script=<path>
Whenever a new DHCP lease is created, or an old one destroyed, the
binary specified by this option is run. The arguments to the binary
are "add", "old" or "del", the MAC
address of the host (or "<null>"), the IP address, and the hostname,
if known. "add" means a lease has been created, "del" means it has
been destroyed, "old" is a notification of an existing lease when
dnsmasq starts or a change to MAC address or hostname of an existing lease.
The process is run as any unprivileged user which dnsmasq
runs as, so it may be necessary to inhibit dropping of the root user,
using the
.B -u
directive, if the script needs root privs.
The environment is inherited from the invoker of dnsmasq,
and all file decriptors are
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
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.
.TP
.B \-s, --domain=<domain>
Specifies the domain for the DHCP server. This has two effects;
@@ -553,8 +584,13 @@ in the same way as for DHCP-derived names.
.TP
.B \-C, --conf-file=<file>
Specify a different configuration file. The conf-file option is also allowed in
configuration files, to include multiple configuration files. Only one
level of nesting is allowed.
configuration files, to include multiple configuration files.
.TP
.B \-7, --conf-dir=<directory>
Read all the files in the given directory as configuration
files. Files whose names end in ~ or start with . or start and end
with # are skipped. This flag may be given on the command
line or in a configuration file.
.SH CONFIG FILE
At startup, dnsmasq reads
.I /etc/dnsmasq.conf,
@@ -563,7 +599,9 @@ FreeBSD, the file is
.I /usr/local/etc/dnsmasq.conf
) (but see the
.B \-C
option.) The format of this
and
.B \-7
options.) The format of this
file consists of one option per line, exactly as the long options detailed
in the OPTIONS section but without the leading "--". Lines starting with # are comments and ignored. For
options which may only be specified once, the configuration file overrides

812
man/es/dnsmasq.8 Normal file
View File

@@ -0,0 +1,812 @@
.TH DNSMASQ 8
.SH NOMBRE
dnsmasq \- Un ligero servidor DHCP y DNS con caché.
.SH SINOPSIS
.B dnsmasq
.I [OPCION]...
.SH "DESCRIPCION"
.BR dnsmasq
es un ligero servidor DNS 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
caché local, o las reenvía hacia un servidor DNS real recursivo.
Carga el contenido de /etc/hosts, de tal forma que nombres de
hosts locales los cuales no aparecen en el DNS mundial puedan ser
resueltos. También responde a búsquedas DNS para hosts configurados
vía DHCP.
.PP
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.
.PP
Dnsmasq
incluye soporte para IPv6.
.SH OPCIONES
Nótese que en general parámetros ausentes son permitidos y deshabilitan
funciones, por ejemplo "--pid-file=" deshabilita la escritura de un
archivo PID. En BSD, a menos que la librería GNU getopt esté enlazada,
la forma larga de las opciones no funciona en la línea de comandos,
pero todavía es reconocida en el archivo de configuración.
.TP
.B \-h, --no-hosts
No leer los nombres de hosts en /etc/hosts.
.TP
.B \-H, --addn-hosts=<archivo>
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 \-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
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
cierto tiempo de vida (en segundos) para estas respuestas. Esto
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
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.
.TP
.B \-q, --log-queries
Bitacorear los resultados de búsquedas DNS manejadas por dnsmasq.
Habilitar un dump de caché completo al recibir un SIGUSR1.
.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.
.TP
.B \-x, --pid-file=<path>
Especificar un path alterno donde dnsmasq debe guardar su PID.
Normalmente es /var/run/dnsmasq.pid.
.TP
.B \-u, --user=<usuario>
Especificar el userid al cual dnsmasq debe cambiarse despues de iniciar.
Dnsmasq normalmente debe ser iniciado como root, pero soltará los
privilegios root despues del inicio, cambiando a otro usuario.
Normalmente este usuario es "nobody", pero eso se puede cambiar
con esta opción.
.TP
.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.
.TP
.B \-v, --version
Mostrar el número de versión.
.TP
.B \-p, --port=<puerto>
Escuchar en el puerto <puerto> en vez del puerto estándar DNS (53).
Principalmente útil para debugging.
.TP
.B \-P, --edns-packet-max=<tamaño>
Especificar el paquete UDP EDNS.0 más grande que es soportado por
el reenviador DNS. Por predeterminado es 1280, lo cual es el
máximo recomendado en RFC2671 para ethernet.
.TP
.B \-Q, --query-port=<puerto>
Enviar búsquedas outbound desde, y escuchar por respuestas en,
el puerto UDP <puerto> en vez de usar uno escojido a la hora
de inicio. Esto es útil para simplificar las reglas del firewall;
sin esto, su firewall tendría que permitir conecciones desde
servidores DNS foráneos hacia un rango de puertos UDP, o
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
agrega la interface loopback a la lista de interfaces para usar cuando
la opción
.B \--interface
es usada. Si ninguna opcion
.B \--interface
o
.B \--listen-address
es brindada, dnsmasq escucha en todas las interfaces disponibles excepto
cualquiera fijada con la opcion
.B \--except-interface
Interfaces IP alias (eg "eth1:0") no pueden ser utilizadas con
.B --interface
o
.B --except-interface
, usar --listen-address en vez.
.TP
.B \-I, --except-interface=<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
.B --except-interface
siempre invalida a las otras.
.TP
.B \-2, --no-dhcp-interface=<interface>
No proveer DHCP en la interface especificada, pero sí
proveer servicio DNS.
.TP
.B \-a, --listen-address=<dirección IP>
Escuchar en la(s) dirección(es) IP especificada(s). Las opciones
.B \--interface
y
.B \--listen-address
ambas pueden ser brindadas, y en tal caso el juego de ambas
direcciones IP y interfaces es usada. Nótese que si ninguna opción
.B \--interface
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
.B \--listen-address
.TP
.B \-z, --bind-interfaces
En sistemas que inluyen el soporte, dnsmasq acopla la dirección
de comodín, aún cuando está escuchando solamente en algunas
interfaces. Entonces descarta búsquedas a las cuales no debe
responder. Esto tiene la ventaja de funcionar aún cuando
interfaces van y vienen y cambian direcciones. Esta opción forza
a dnsmasq a acoplarse realmente solo a las interfaces en
las cuales está escuchando. Casi la única vez que esto es útil
es cuando se está corriendo otro servidor DNS (o otra instancia
de dnsmasq) en la misma máquina. Fijar esta opción tambien
habilita multiples instancias de dnsmasq, las cuales proveen
servicio DHCP en la misma máquina.
.TP
.B \-y, --localise-queries
Retornar respuestas a búsquedas DNS desde /etc/hosts las cuales dependen
de la interface donde entró la búsqueda. Si un nombre en /etc/hosts tiene
mas de una dirección asociada con el, y por lo menos una de esas direcciones
está en la misma subred de la interface donde fue enviada, entónces
retornar solo las direcciones en esa subred. Esto permite a un servidor
tener direcciones múltiples en /etc/hosts correspondientes a cada una de
sus interfaces y cada host recibirá la respuesta adecuada
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
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>]
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
ruteadores Cisco PIX llaman "DNS doctoring".
.TP
.B \-B, --bogus-nxdomain=<dirección IP>
Transformar respuestas que contienen la dirección IP brindada en
respuestas tipo "Dominio no existe". La intención de esto es actuar
en contra de una movida desviada hecha por Verisign en septiembre
del 2003, cuando comenzaron a retornar la dirección de un servidor
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
es 64.94.110.11
.TP
.B \-f, --filterwin2k
Algunas versiones de Windows hacen búsquedas DNS periódicas las cuales no
reciben respuestas sensibles desde el DNS público y pueden causar problemas
activando enlaces marcación-en-demanda. Esta opción filtra dichas búsquedas.
Las búsquedas filtradas son para registros tipo SOA y SRV, al igual que
tipo ANY donde el nombre pedido contiene _, para atrapar búsquedas LDAP.
.TP
.B \-r, --resolv-file=<archivo>
Leer las direcciones IP de servidores DNS upstream desde <archivo>,
en vez de /etc/resolv.conf. Para el formato de este archivo, ver
.BR resolv.conf (5)
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.
.TP
.B \-R, --no-resolv
No leer /etc/resolv.conf. Obtener los servidores DNS upstream solo
desde la línea de comandos o desde el archivo de configuración de
dnsmasq.
.TP
.B \-1, --enable-dbus
Permitir que la configuración de dnsmasq sea actualizada vía llamadas
de método DBus. La configuración que puede ser cambiada es servidores
DNS upstream (y dominios correspondientes) y limpieza de caché. Esta
opción requiere que dnsmasq haya sido compilado con soporte para DBus.
.TP
.B \-o, --strict-order
Por predeterminado, dnsmasq enviará búsquedas a cualquiera de los
servidores upstream que conoce, y trata de favorecer servidores los
cuales sabe que están activos. Fijar esta opcion forza a dnsmasq a
probar cada búsqueda con cada servidor estrictamente en el orden
que aparecen en /etc/resolv.conf
.TP
.B \-n, --no-poll
No revisar periodicamente a /etc/resolv.conf en busca de cambios.
.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>]]]
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
es usado solo para esos dominios y las búsquedas son hechas usando
el servidor especificado solamente. La intención de esto es para el
uso con servidores DNS privados: si usted tiene un servidor DNS en su
red el cual lidea con nombres de la forma
xxx.internal.thekelleys.org.uk en 192.168.1.1 entonces brindar la
opción
.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
.B //
tiene el significado especial de "solo nombres no calificados", o
sea nombres sin ningun 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.
También se permite una opción -S la cual brinda un dominio pero
ninguna dirección IP; esto le dice a dnsmasq que un dominio es local
y puede responder a búsquedas desde /etc/hosts o DHCP pero nunca
deberá reenviar búsquedas en ese dominio a ningún servidor upstream.
.B local
es un sinónimo de
.B server
para hacer los archivos de configuración mas claros en este caso.
La segunda dirección IP opcional después del carácter @ le dice
a dnsmasq como fijar la dirección de remitente de las búsquedas
hacia este servidor DNS. Debe ser una dirección perteneciente a
la máquina en la cual corre dnsmasq, o de forma contraria esta
línea de servidor será bitacoreada y después ignorada. La opción
query-port es ignorada para cualquier servidores que tengan una
dirección remitente especificada, pero el puerto puede ser
especificado directamente como parte de la dirección remitente.
.TP
.B \-A, --address=/<domain>/[domain/]<ipaddr>
Especificar una dirección IP para retornar por cualquier host en
los dominios brindados. Búsquedas en estos dominios nunca son
reenviadas, y siempre son respondidas con la dirección IP
especificada, la cual puede ser IPv4 o IPv6. Para brindar ambas
direcciones IPv4 y IPv6 para un dominio, usar opciones -A repetidas.
Nótese que /etc/hosts y arriendos DHCP invalidan esto para nombres
individuales. Un uso común para esto es redireccionar el dominio
doubleclick.net entero a algún servidor web local amigable para
evitar banners de publicidad. La especificación funciona de la misma
forma que con --server, con la facilidad adicional que /#/ coincide
con cualquier dominio. De tal forma, --address=/#/1.2.3.4 siempre
retornará 1.2.3.4 para cualquier búsqueda no respondida desde
/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
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
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>
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
dnsmasq está corriendo.
.TP
.B \-e, --selfmx
Retornar un record MX apuntándose a sí mismo para cada máquina local.
Máquinas locales son aquellas en /etc/hosts o con arriendos DHCP.
.TP
.B \-L, --localmx
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>]]]]
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.
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>]
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>
Fijar el tamaño del caché de dnsmasq. El predeterminado es 150 nombres.
Fijar el tamaño a cero deshabilita el caché.
.TP
.B \-N, --no-negcache
Deshabilitar caché negativo. El caché negativo le permite a dnsmasq
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>]
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
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
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
.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
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
.B static
la cual le dice a dnsmasq que debe habilitar DHCP para la red
especificada, pero no alocar dinámicamente direcciones IP.
Solo hosts que tienen direcciones estáticas brindadas vía
.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]
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.
Un nombre de host especificado de esta manera toma presedencia
sobre cualquiera suministrado por el cliente DHCP en la máquina.
También se permite omitir la direccion de hardware y incluir el
nombre host; en tal caso la dirección IP y los tiempos de arriendo
serán aplicables a cualquier máquina que reclame ese nombre.
Por ejemplo:
.B --dhcp-host=00:20:e0:3b:13:af,wap,infinite
le dice a dnsmasq que debe darle a la máquina con dirección
ethernet 00:20:e0:3b:13:af el nombre wap, y un arriendo DHCP infinito.
.B --dhcp-host=lap,192.168.0.199
le dice a dnsmasq que siempre debe alocarle a la maquina lap
la dirección IP 192.168.0.199. Direcciones alocadas de esta manera
no tienen que estar dentro del rango dado con la opción --dhcp-range,
pero deben estar en la red siendo servida por el servidor DHCP. Se
permite usar identificadores de clientes en vez de direcciones de
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,.....
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.
Si un nombre aparece en /etc/hosts, la dirección asociada puede
ser alocada a un arriendo DHCP, pero solo si existe una opción
.B --dhcp-host
la cual especifica el nombre también. La palabra clave "ignore"
le dice a dnsmasq que no debe ofrecer jamás un arriendo DHCP a
una máquina. La máquina puede ser especificada por dirección de
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
network-id cuando sea que esta directiva dhcp-host está en uso.
Esto puede ser usado para enviar selectivamente opciones DHCP
a este host.
Direcciones ethernet (pero no client-ids) pueden tener bytes
comodínes, así que por ejemplo
.B --dhcp-host=00:20:e0:3b:13:*,ignore
causará que dnsmasq ignore un rango de direcciones ethernet. Nótese
que el "*" necesitará ser escapado o escrito entre comillas en la
línea de comandos, pero no en el archivo de configuración.
Direcciones de hardware normalmente coinciden con cualquier
tipo de red (ARP), pero es posible restringirlas a un tipo ARP
singular precediendolo con el tipo ARP (en HEX) y "-". Así que
.B --dhcp-host=06-00:20:e0:3b:13:af,1.2.3.4
solo coincidaría una dirección de hardware Token-Ring, dado que
el tipo ARP para Token-Ring es 6.
.TP
.B \-Z, --read-ethers
Leer /etc/ethers en busca de información sobre hosts para el servidor
DHCP. El formato de /etc/ethers es una dirección de hardware, seguida
por ya sea un nombre de host o una dirección IP. Al ser leidas por
dnsmasq, estas líneas tienen exáctamente el mismo efecto que opciones
.B --dhcp-host
que contienen la misma información.
.TP
.B \-O, --dhcp-option=[<network-id>,[<network-id>,]][vendor:<vendor-class>]<opt>,[<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
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
192.168.4.4, hágase un
.B --dhcp-option=3,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
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
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.
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.
Cuando el valor es un número decimal, dnsmasq debe determinar qué tan
grande es el objeto de data. Esto es hecho mediante una examinación del
número de opción, y/o el valor, pero puede ser invalidado agregándole
una opción de una sola letra de esta forma: b = un byte, s = dos bytes,
i = cuatro bytes. Esto es principalmente útil con opciones encapsuladas
tipo vendedor (ver abajo) donde dnsmasq no puede determinar el tamaño
de data usando el número de opción. Data de opción la cual consiste
solo de puntos y dígitos será interpretada por dnsmasq como una
dirección IP, y será insertada dentro de una opción de esa manera.
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
--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.
.TP
.B \-U, --dhcp-vendorclass=<network-id>,<vendor-class>
Mapear 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
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
peritiría que opciones sean fijadas solo para impresoras HP así:
.B --dhcp-option=printers,3,192.168.4.4
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
substring, como con vendor-class). La mayoría de los clientes DHCP
proveen un "user class" el cual es configurable. Esta opción mapea
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".
.TP
.B \-4, --dhcp-mac=<network-id>,<MAC address>
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 \-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 \-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.
.TP
.B \-X, --dhcp-lease-max=<number>
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
proceso dnsmasq.
.TP
.B \-K, --dhcp-authoritative
Esta opción debe ser fijada cuando dnsmasq es definitivamente el único
servidor DHCP en la red. Cambia el comportamiento de RFC de tal manera
que pedidos desde hosts no conocidos no serán ignorados. Esto permite que
hosts nuevos puedan conseguir un arriendo sin sin un timeout bajo toda
circunstancia. También permite que dnsmasq reconstruya su base de datos
de arriendos sin que cada cliente requiera un arriendo, si la base de datos
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
es arrendada para siempre, y consecuentemente queda no-disponible
para 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
cuidado.
.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
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
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
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).
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
será invocado para todos los arriendos existenetes mientras van siendo
leidos 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>
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
es legal para hosts configurados mediante DHCP reclamar. La intención es
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,
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
el sufijo agregado como una parte de dominio opcional. Por ejemplo, en
mi red puedo fijar
.B --domain=thekelleys.org.uk
y tener una maquina cuyo nombre host DHCP es "laptop". La dirección IP
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).
.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.
.TP
.B \-C, --conf-file=<archivo>
Especificar un archivo de configuración diferente. La opción conf-file
también es permitida en archivos de configuración, para incluir múltiples
archivos de configuración.
.TP
.B \-7, --conf-dir=<directorio>
Leer todos los archivos dentro del directorio brindado como archivos
de configuración. Archivos cuyos nombres terminen con ~ o comienzen
con . o comienzen y terminen con # son ignorados. Esta opción puede
ser brindada en la línea de comandos o en un archivo de configuración.
.SH ARCHIVO DE CONFIGURACION
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
.B \-C
y
.B \-7
porfavor.) El formato de este archivo consiste de una opción por línea,
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
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.
.SH NOTAS
Al recibir un SIGHUP
.B dnsmasq
libera su cache y entonces recarga
.I /etc/hosts.
Si
.B
--no-poll
está fijado entnces 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
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
.B --no-daemon
o cuando logeo 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
arbitrarias comenzando desde los servidores root pero reenvía dichas
búsquedas a un servidor DNS recursivo, el cual es típicamente proveído
por el proveedor de Internet. Por predeterminado, dnsmasq lee
.I /etc/resolv.conf
para descubir las direcciones IP de los servidores DNS upstream que
debe usar, dado a que esta información es normalmente almacenada allí.
Amenos que
.B --no-poll
sea usado,
.B dnsmasq
revisa el tiempo de modificación de
.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
fijados dinámicamente vía PPP o DHCP ya que ambos protocolos brindan esta
información.
La ausencia de
.I /etc/resolv.conf
no es un error ya que pudo haber sido creada antes de que una conexión PPP
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:
.I /etc/ppp/resolv.conf
y
.I /etc/dhcpc/resolv.conf
y usará el contenido de cualquiera 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
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á
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
.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.
.PP
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
servidor DNS upstream devolverían una dirección diferente. Hay una
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
/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
DHCP, dnsmasq colecciona un juego de etiquetas network-id válidas,
una del
.B dhcp-range
usado para alocar la dirección, una de cualquier
.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
.B dhcp-option
que tenga etiquetas network-id será usada en preferencia de una opción
.B dhcp-option,
sin etiqueta, con tal que _todas_ las etiquetas coincidan en alguna
parte del juego coleccionado describido arriba. El prefijo "#" en una
etiqueta significa "no" así que --dhcp=option=#purple,3,1.2.3.4 envía
la opción cuando la etiqueta network-id "purple" no está en el juego
de etiquetas válidas.
.PP
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
hosts que fijen la etiqueta network-id serán alocados direcciones en
el rango etiquetado.
.PP
El servidor DHCP de dnsmasq funcionará como servidor BOOTP tambien,
con tal que las direcciones MAC y IP de los clientes sean brindadas,
ya sea usando configuraciones
.B dhcp-host
o en
.I /etc/ethers
, 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
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.
.SH ARCHIVOS
.IR /etc/dnsmasq.conf
.IR /usr/local/etc/dnsmasq.conf
.IR /etc/resolv.conf
.IR /etc/hosts
.IR /etc/ethers
.IR /var/lib/misc/dnsmasq.leases
.IR /var/db/dnsmasq.leases
.IR /var/run/dnsmasq.pid
.SH VER TAMBIEN
.BR hosts (5),
.BR resolver (5)
.SH AUTOR
Este manual fue escrito por Simon Kelley <simon@thekelleys.org.uk>.
Traducido a español por Christopher Chatham <chrislinux@gmail.com>.

607
po/de.po

File diff suppressed because it is too large Load Diff

636
po/es.po

File diff suppressed because it is too large Load Diff

607
po/fi.po

File diff suppressed because it is too large Load Diff

536
po/fr.po

File diff suppressed because it is too large Load Diff

595
po/id.po

File diff suppressed because it is too large Load Diff

925
po/it.po Normal file
View File

@@ -0,0 +1,925 @@
# Italian translations for dnsmasq package.
# This file is put in the public domain.
# Simon Kelley <simon@thekelleys.org.uk>, 2006.
#
msgid ""
msgstr ""
"Project-Id-Version: dnsmasq 2.32\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2006-06-09 20:59+0100\n"
"PO-Revision-Date: 2006-05-22 11:09+0100\n"
"Last-Translator: Simon Kelley <simon@thekelleys.org.uk>\n"
"Language-Team: Italian <tp@lists.linux.it>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ASCII\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: cache.c:570
#, c-format
msgid "failed to load names from %s: %m"
msgstr ""
#: cache.c:606 dhcp.c:679
#, c-format
msgid "bad address at %s line %d"
msgstr ""
#: cache.c:633 dhcp.c:693
#, c-format
msgid "bad name at %s line %d"
msgstr ""
#: cache.c:639 dhcp.c:747
#, c-format
msgid "read %s - %d addresses"
msgstr ""
#: cache.c:675
msgid "cleared cache"
msgstr ""
#: cache.c:728
#, c-format
msgid ""
"not giving name %s to the DHCP lease of %s because the name exists in %s "
"with address %s"
msgstr ""
#: cache.c:772
#, c-format
msgid ""
"time %lu, cache size %d, %d/%d cache insertions re-used unexpired cache "
"entries."
msgstr ""
#: util.c:153 option.c:1202
msgid "could not get memory"
msgstr ""
#: util.c:176
#, c-format
msgid "%s at line %d of %%s"
msgstr ""
#: util.c:183
msgid "FAILED to start up"
msgstr ""
#: util.c:304
#, c-format
msgid "infinite"
msgstr ""
#: option.c:138
msgid "Specify local address(es) to listen on."
msgstr ""
#: option.c:139
msgid "Return ipaddr for all hosts in specified domains."
msgstr ""
#: option.c:140
msgid "Fake reverse lookups for RFC1918 private address ranges."
msgstr ""
#: option.c:141
msgid "Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."
msgstr ""
#: option.c:142
#, c-format
msgid "Specify the size of the cache in entries (defaults to %s)."
msgstr ""
#: option.c:143
#, c-format
msgid "Specify configuration file (defaults to %s)."
msgstr ""
#: option.c:144
msgid "Do NOT fork into the background: run in debug mode."
msgstr ""
#: option.c:145
msgid "Do NOT forward queries with no domain part."
msgstr ""
#: option.c:146
msgid "Return self-pointing MX records for local hosts."
msgstr ""
#: option.c:147
msgid "Expand simple names in /etc/hosts with domain-suffix."
msgstr ""
#: option.c:148
msgid "Don't forward spurious DNS requests from Windows hosts."
msgstr ""
#: option.c:149
msgid "Enable DHCP in the range given with lease duration."
msgstr ""
#: option.c:150
#, c-format
msgid "Change to this group after startup (defaults to %s)."
msgstr ""
#: option.c:151
msgid "Set address or hostname for a specified machine."
msgstr ""
#: option.c:152
#, c-format
msgid "Do NOT load %s file."
msgstr ""
#: option.c:153
#, c-format
msgid "Specify a hosts file to be read in addition to %s."
msgstr ""
#: option.c:154
msgid "Specify interface(s) to listen on."
msgstr ""
#: option.c:155
msgid "Specify interface(s) NOT to listen on."
msgstr ""
#: option.c:156
msgid "Map DHCP user class to option set."
msgstr ""
#: option.c:157
msgid "Don't do DHCP for hosts in option set."
msgstr ""
#: option.c:158
msgid "Do NOT fork into the background, do NOT run in debug mode."
msgstr ""
#: option.c:159
msgid "Assume we are the only DHCP server on the local network."
msgstr ""
#: option.c:160
#, c-format
msgid "Specify where to store DHCP leases (defaults to %s)."
msgstr ""
#: option.c:161
msgid "Return MX records for local hosts."
msgstr ""
#: option.c:162
msgid "Specify an MX record."
msgstr ""
#: option.c:163
msgid "Specify BOOTP options to DHCP server."
msgstr ""
#: option.c:164
#, c-format
msgid "Do NOT poll %s file, reload only on SIGHUP."
msgstr ""
#: option.c:165
msgid "Do NOT cache failed search results."
msgstr ""
#: option.c:166
#, c-format
msgid "Use nameservers strictly in the order given in %s."
msgstr ""
#: option.c:167
msgid "Set extra options to be set to DHCP clients."
msgstr ""
#: option.c:168
msgid "Specify port to listen for DNS requests on (defaults to 53)."
msgstr ""
#: option.c:169
#, c-format
msgid "Maximum supported UDP packet size for EDNS.0 (defaults to %s)."
msgstr ""
#: option.c:170
msgid "Log queries."
msgstr ""
#: option.c:171
msgid "Force the originating port for upstream queries."
msgstr ""
#: option.c:172
msgid "Do NOT read resolv.conf."
msgstr ""
#: option.c:173
#, c-format
msgid "Specify path to resolv.conf (defaults to %s)."
msgstr ""
#: option.c:174
msgid "Specify address(es) of upstream servers with optional domains."
msgstr ""
#: option.c:175
msgid "Never forward queries to specified domains."
msgstr ""
#: option.c:176
msgid "Specify the domain to be assigned in DHCP leases."
msgstr ""
#: option.c:177
msgid "Specify default target in an MX record."
msgstr ""
#: option.c:178
msgid "Specify time-to-live in seconds for replies from /etc/hosts."
msgstr ""
#: option.c:179
#, c-format
msgid "Change to this user after startup. (defaults to %s)."
msgstr ""
#: option.c:180
msgid "Map DHCP vendor class to option set."
msgstr ""
#: option.c:181
msgid "Display dnsmasq version and copyright information."
msgstr ""
#: option.c:182
msgid "Translate IPv4 addresses from upstream servers."
msgstr ""
#: option.c:183
msgid "Specify a SRV record."
msgstr ""
#: option.c:184
msgid "Display this message."
msgstr ""
#: option.c:185
#, c-format
msgid "Specify path of PID file. (defaults to %s)."
msgstr ""
#: option.c:186
#, c-format
msgid "Specify maximum number of DHCP leases (defaults to %s)."
msgstr ""
#: option.c:187
msgid "Answer DNS queries based on the interface a query was sent to."
msgstr ""
#: option.c:188
msgid "Specify TXT DNS record."
msgstr ""
#: option.c:189
msgid "Bind only to interfaces in use."
msgstr ""
#: option.c:190
#, c-format
msgid "Read DHCP static host information from %s."
msgstr ""
#: option.c:191
msgid "Enable the DBus interface for setting upstream servers, etc."
msgstr ""
#: option.c:192
msgid "Do not provide DHCP on this interface, only provide DNS."
msgstr ""
#: option.c:193
msgid "Enable dynamic address allocation for bootp."
msgstr ""
#: option.c:194
msgid "Map MAC address (with wildcards) to option set."
msgstr ""
#: option.c:195
msgid "Disable ICMP echo address checking in the DHCP server."
msgstr ""
#: option.c:196
msgid "Script to run on DHCP lease creation and destruction."
msgstr ""
#: option.c:197
msgid "Read configuration from all the files in this directory."
msgstr ""
#: option.c:198
msgid "Log to this syslog facility."
msgstr ""
#: option.c:311
#, c-format
msgid ""
"Usage: dnsmasq [options]\n"
"\n"
msgstr ""
#: option.c:313
#, c-format
msgid "Use short options only on the command line.\n"
msgstr ""
#: option.c:315
#, c-format
msgid "Valid options are :\n"
msgstr ""
#: option.c:348
msgid "extraneous parameter"
msgstr ""
#: option.c:352
msgid "missing parameter"
msgstr ""
#: option.c:374
#, c-format
msgid "cannot access directory %s: %s"
msgstr ""
#: option.c:393
#, c-format
msgid "cannot access %s: %s"
msgstr ""
#: option.c:470
msgid "bad MX preference"
msgstr ""
#: option.c:479
msgid "bad MX name"
msgstr ""
#: option.c:497
msgid "bad MX target"
msgstr ""
#: option.c:509
msgid "cannot run scripts under uClinux"
msgstr ""
#: option.c:708 option.c:719
msgid "bad port"
msgstr ""
#: option.c:859
msgid "bad dhcp-range"
msgstr ""
#: option.c:888
msgid "only one netid tag allowed"
msgstr ""
#: option.c:933
msgid "inconsistent DHCP range"
msgstr ""
#: option.c:1118
msgid "bad dhcp-host"
msgstr ""
#: option.c:1179
msgid "bad dhcp-option"
msgstr ""
#: option.c:1197
msgid "bad domain in dhcp-option"
msgstr ""
#: option.c:1367
msgid "dhcp-option too long"
msgstr ""
#: option.c:1564
msgid "bad TXT record"
msgstr ""
#: option.c:1596
msgid "TXT record string too long"
msgstr ""
#: option.c:1635
msgid "bad SRV record"
msgstr ""
#: option.c:1648
msgid "bad SRV target"
msgstr ""
#: option.c:1660
msgid "invalid port number"
msgstr ""
#: option.c:1671
msgid "invalid priority"
msgstr ""
#: option.c:1682
msgid "invalid weight"
msgstr ""
#: option.c:1713
#, c-format
msgid "files nested too deep in %s"
msgstr ""
#: option.c:1720
#, c-format
msgid "cannot read %s: %s"
msgstr ""
#: option.c:1762
msgid "missing \""
msgstr ""
#: option.c:1797
msgid "error"
msgstr ""
#: option.c:1801
msgid "bad option"
msgstr ""
#: option.c:1864
#, c-format
msgid "Dnsmasq version %s %s\n"
msgstr ""
#: option.c:1865
#, c-format
msgid ""
"Compile time options %s\n"
"\n"
msgstr ""
#: option.c:1866
#, c-format
msgid "This software comes with ABSOLUTELY NO WARRANTY.\n"
msgstr ""
#: option.c:1867
#, c-format
msgid "Dnsmasq is free software, and you are welcome to redistribute it\n"
msgstr ""
#: option.c:1868
#, c-format
msgid "under the terms of the GNU General Public License, version 2.\n"
msgstr ""
#: option.c:1879
msgid "try --help"
msgstr ""
#: option.c:1881
msgid "try -w"
msgstr ""
#: option.c:1884
#, c-format
msgid "bad command line options: %s"
msgstr ""
#: option.c:1935
#, c-format
msgid "cannot get host-name: %s"
msgstr ""
#: option.c:1964
msgid "only one resolv.conf file allowed in no-poll mode."
msgstr ""
#: option.c:1972
msgid "must have exactly one resolv.conf to read domain from."
msgstr ""
#: option.c:1975 network.c:464
#, c-format
msgid "failed to read %s: %m"
msgstr ""
#: option.c:1993
#, c-format
msgid "no search directive found in %s"
msgstr ""
#: forward.c:371
#, c-format
msgid "nameserver %s refused to do a recursive query"
msgstr ""
#: forward.c:878
msgid "forwarding table overflow: check for server loops."
msgstr ""
#: isc.c:73 dnsmasq.c:474
#, c-format
msgid "failed to access %s: %m"
msgstr ""
#: isc.c:89
#, c-format
msgid "failed to load %s: %m"
msgstr ""
#: isc.c:93 dnsmasq.c:495
#, c-format
msgid "reading %s"
msgstr ""
#: isc.c:115
#, c-format
msgid "bad name in %s"
msgstr ""
#: isc.c:177
#, c-format
msgid "Ignoring DHCP lease for %s because it has an illegal domain part"
msgstr ""
#: network.c:315 dnsmasq.c:129
#, c-format
msgid "failed to create listening socket: %s"
msgstr ""
#: network.c:322
#, c-format
msgid "failed to set IPV6 options on listening socket: %s"
msgstr ""
#: network.c:340
#, c-format
msgid "failed to bind listening socket for %s: %s"
msgstr ""
#: network.c:348
#, c-format
msgid "failed to listen on socket: %s"
msgstr ""
#: network.c:411
#, c-format
msgid "ignoring nameserver %s - local interface"
msgstr ""
#: network.c:420
#, c-format
msgid "ignoring nameserver %s - cannot make/bind socket: %m"
msgstr ""
#: network.c:434
msgid "domain"
msgstr ""
#: network.c:436
msgid "unqualified"
msgstr ""
#: network.c:436
msgid "domains"
msgstr ""
#: network.c:439
#, c-format
msgid "using local addresses only for %s %s"
msgstr ""
#: network.c:441
#, c-format
msgid "using nameserver %s#%d for %s %s"
msgstr ""
#: network.c:444
#, c-format
msgid "using nameserver %s#%d"
msgstr ""
#: dnsmasq.c:94
msgid ""
"ISC dhcpd integration not available: set HAVE_ISC_READER in src/config.h"
msgstr ""
#: dnsmasq.c:111
#, c-format
msgid "failed to find list of interfaces: %s"
msgstr ""
#: dnsmasq.c:119
#, c-format
msgid "unknown interface %s"
msgstr ""
#: dnsmasq.c:125
#, c-format
msgid "no interface with address %s"
msgstr ""
#: dnsmasq.c:144
msgid "must set exactly one interface on broken systems without IP_RECVIF"
msgstr ""
#: dnsmasq.c:157 dnsmasq.c:593
#, c-format
msgid "DBus error: %s"
msgstr ""
#: dnsmasq.c:160
msgid "DBus not available: set HAVE_DBUS in src/config.h"
msgstr ""
#: dnsmasq.c:191
#, c-format
msgid "cannot create pipe: %s"
msgstr ""
#: dnsmasq.c:341
#, c-format
msgid "started, version %s cachesize %d"
msgstr ""
#: dnsmasq.c:343
#, c-format
msgid "started, version %s cache disabled"
msgstr ""
#: dnsmasq.c:345
#, c-format
msgid "compile time options: %s"
msgstr ""
#: dnsmasq.c:351
msgid "DBus support enabled: connected to system bus"
msgstr ""
#: dnsmasq.c:353
msgid "DBus support enabled: bus connection pending"
msgstr ""
#: dnsmasq.c:358
msgid "setting --bind-interfaces option because of OS limitations"
msgstr ""
#: dnsmasq.c:363
#, c-format
msgid "warning: interface %s does not currently exist"
msgstr ""
#: dnsmasq.c:375
#, c-format
msgid "DHCP, static leases only on %.0s%s, lease time %s"
msgstr ""
#: dnsmasq.c:376
#, c-format
msgid "DHCP, IP range %s -- %s, lease time %s"
msgstr ""
#: dnsmasq.c:386
#, c-format
msgid "warning: setting capabilities failed: %m"
msgstr ""
#: dnsmasq.c:388
msgid "running as root"
msgstr ""
#: dnsmasq.c:502
#, c-format
msgid "no servers found in %s, will retry"
msgstr ""
#: dnsmasq.c:541
msgid "exiting on receipt of SIGTERM"
msgstr ""
#: dnsmasq.c:595
msgid "connected to system DBus"
msgstr ""
#: dhcp.c:32
#, c-format
msgid "cannot create DHCP socket : %s"
msgstr ""
#: dhcp.c:41
#, c-format
msgid "failed to set options on DHCP socket: %s"
msgstr ""
#: dhcp.c:48
#, c-format
msgid "failed to set SO_REUSEADDR on DHCP socket: %s"
msgstr ""
#: dhcp.c:59
#, c-format
msgid "failed to bind DHCP server socket: %s"
msgstr ""
#: dhcp.c:72
#, c-format
msgid "cannot create ICMP raw socket: %s."
msgstr ""
#: dhcp.c:84
#, c-format
msgid "duplicate IP address %s in dhcp-config directive."
msgstr ""
#: dhcp.c:314
#, c-format
msgid "DHCP range %s -- %s is not consistent with netmask %s"
msgstr ""
#: dhcp.c:631
#, c-format
msgid "failed to read %s:%m"
msgstr ""
#: dhcp.c:666
#, c-format
msgid "bad line at %s line %d"
msgstr ""
#: dhcp.c:775
#, c-format
msgid "duplicate IP address %s (%s) in dhcp-config directive"
msgstr ""
#: dhcp.c:811
#, c-format
msgid "Ignoring DHCP host name %s because it has an illegal domain part"
msgstr ""
#: lease.c:30
#, c-format
msgid "cannot open or create leases file: %s"
msgstr ""
#: lease.c:58
msgid "too many stored leases"
msgstr ""
#: lease.c:174
#, c-format
msgid "failed to write %s: %s (retry in %us)"
msgstr ""
#: lease.c:435
#, c-format
msgid "failed to execute %s: %m"
msgstr ""
#: rfc2131.c:247
#, c-format
msgid "no address range available for DHCP request %s %s"
msgstr ""
#: rfc2131.c:248
msgid "with subnet selector"
msgstr ""
#: rfc2131.c:248
msgid "via"
msgstr ""
#: rfc2131.c:274 rfc2131.c:298
msgid "disabled"
msgstr ""
#: rfc2131.c:310 rfc2131.c:741
msgid "address in use"
msgstr ""
#: rfc2131.c:313
msgid "no address configured"
msgstr ""
#: rfc2131.c:326 rfc2131.c:613
msgid "no address available"
msgstr ""
#: rfc2131.c:335 rfc2131.c:748
msgid "no leases left"
msgstr ""
#: rfc2131.c:338 rfc2131.c:715
msgid "wrong network"
msgstr ""
#: rfc2131.c:542
#, c-format
msgid "disabling DHCP static address %s for %s"
msgstr ""
#: rfc2131.c:562
msgid "unknown lease"
msgstr ""
#: rfc2131.c:571 rfc2131.c:813
msgid "ignored"
msgstr ""
#: rfc2131.c:587
#, c-format
msgid "not using configured address %s because it is leased to %s"
msgstr ""
#: rfc2131.c:596
#, c-format
msgid ""
"not using configured address %s because it is in use by the server or relay"
msgstr ""
#: rfc2131.c:599
#, c-format
msgid "not using configured address %s because it was previously declined"
msgstr ""
#: rfc2131.c:678
msgid "wrong address"
msgstr ""
#: rfc2131.c:691
msgid "lease not found"
msgstr ""
#: rfc2131.c:723
msgid "address not available"
msgstr ""
#: rfc2131.c:734
msgid "static lease available"
msgstr ""
#: rfc2131.c:738
msgid "address reserved"
msgstr ""
#: rfc2131.c:744
msgid "no unique-id"
msgstr ""
#: rfc2131.c:945
#, c-format
msgid "cannot send DHCP option %d: no space left in packet"
msgstr ""
#: rfc2131.c:1246
#, c-format
msgid "More than one vendor class matches, using %s"
msgstr ""
#: netlink.c:51
#, c-format
msgid "cannot create netlink socket: %s"
msgstr ""
#: netlink.c:224
#, c-format
msgid "netlink returns error: %s"
msgstr ""
#: dbus.c:112
msgid "attempt to set an IPv6 server address via DBus - no IPv6 support"
msgstr ""
#: dbus.c:238
msgid "setting upstream servers from DBus"
msgstr ""
#: dbus.c:274
msgid "could not register a DBus message handler"
msgstr ""
#: bpf.c:48
#, c-format
msgid "cannot create DHCP BPF socket: %s"
msgstr ""
#: bpf.c:76
#, c-format
msgid "DHCP request for unsupported hardware type (%d) received on %s"
msgstr ""

536
po/no.po

File diff suppressed because it is too large Load Diff

536
po/pl.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

536
po/ro.po

File diff suppressed because it is too large Load Diff

View File

@@ -1,93 +0,0 @@
#!/bin/sh
#
# Startup script for the DNS caching server
#
# chkconfig: 2345 99 01
# description: This script starts your DNS caching server
# processname: dnsmasq
# pidfile: /var/run/dnsmasq.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0
dnsmasq=/usr/sbin/dnsmasq
[ -f $dnsmasq ] || exit 0
# change this line if you want dnsmasq to serve an MX record for
# the host it is running on.
MAILHOSTNAME=""
# change this line if you want dns to get its upstream servers from
# somewhere other that /etc/resolv.conf
RESOLV_CONF=""
# change this if you want dnsmasq to cache any "hostname" or "client-hostname" from
# a dhcpd's lease file
DHCP_LEASE="/var/lib/dhcp/dhcpd.leases"
DOMAIN_SUFFIX=`dnsdomainname`
OPTIONS=""
if [ ! -z "${MAILHOSTNAME}" ]; then
OPTIONS="$OPTIONS -m $MAILHOSTNAME"
fi
if [ ! -z "${RESOLV_CONF}" ]; then
OPTIONS="$OPTIONS -r $RESOLV_CONF"
fi
if [ ! -z "${DHCP_LEASE}" ]; then
OPTIONS="$OPTIONS -l $DHCP_LEASE"
fi
if [ ! -z "${DOMAIN_SUFFIX}" ]; then
OPTIONS="$OPTIONS -s $DOMAIN_SUFFIX"
fi
RETVAL=0
# See how we were called.
case "$1" in
start)
echo -n "Starting dnsmasq: "
daemon $dnsmasq $OPTIONS
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/dnsmasq
;;
stop)
if test "x`pidof dnsmasq`" != x; then
echo -n "Shutting down dnsmasq: "
killproc dnsmasq
fi
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/dnsmasq /var/run/dnsmasq.pid
;;
status)
status dnsmasq
RETVAL=$?
;;
restart|reload)
$0 stop
$0 start
RETVAL=$?
;;
condrestart)
if test "x`/sbin/pidof dnsmasq`" != x; then
$0 stop
$0 start
RETVAL=$?
fi
;;
*)
echo "Usage: $0 {start|stop|restart|reload|condrestart|status}"
exit 1
esac
exit $RETVAL

143
src/bpf.c
View File

@@ -26,17 +26,6 @@ static struct iovec ifreq = {
.iov_len = 0
};
struct header {
struct ether_header ether;
struct ip ip;
struct udphdr {
u16 uh_sport; /* source port */
u16 uh_dport; /* destination port */
u16 uh_ulen; /* udp length */
u16 uh_sum; /* udp checksum */
} udp;
};
void init_bpf(struct daemon *daemon)
{
int i = 0;
@@ -48,7 +37,12 @@ void init_bpf(struct daemon *daemon)
{
sprintf(ifreq.iov_base, "/dev/bpf%d", i++);
if ((daemon->dhcp_raw_fd = open(ifreq.iov_base, O_RDWR, 0)) != -1)
return;
{
int flags = fcntl(daemon->dhcp_raw_fd, F_GETFD);
if (flags != -1)
fcntl(daemon->dhcp_raw_fd, F_SETFD, flags | FD_CLOEXEC);
return;
}
}
if (errno != EBUSY)
die(_("cannot create DHCP BPF socket: %s"), NULL);
@@ -64,9 +58,17 @@ void send_via_bpf(struct daemon *daemon, struct dhcp_packet *mess, size_t len,
Build the packet by steam, and send directly, bypassing
the kernel IP stack */
struct header header;
struct ether_header ether;
struct ip ip;
struct udphdr {
u16 uh_sport; /* source port */
u16 uh_dport; /* destination port */
u16 uh_ulen; /* udp length */
u16 uh_sum; /* udp checksum */
} udp;
u32 i, sum;
struct iovec iov[2];
struct iovec iov[4];
/* Only know how to do ethernet on *BSD */
if (mess->htype != ARPHRD_ETHER || mess->hlen != ETHER_ADDR_LEN)
@@ -80,62 +82,67 @@ void send_via_bpf(struct daemon *daemon, struct dhcp_packet *mess, size_t len,
if (ioctl(daemon->dhcpfd, SIOCGIFADDR, ifr) < 0)
return;
memcpy(header.ether.ether_shost, LLADDR((struct sockaddr_dl *)&ifr->ifr_addr), ETHER_ADDR_LEN);
header.ether.ether_type = htons(ETHERTYPE_IP);
memcpy(ether.ether_shost, LLADDR((struct sockaddr_dl *)&ifr->ifr_addr), ETHER_ADDR_LEN);
ether.ether_type = htons(ETHERTYPE_IP);
if (ntohs(mess->flags) & 0x8000)
{
memset(header.ether.ether_dhost, 255, ETHER_ADDR_LEN);
header.ip.ip_dst.s_addr = INADDR_BROADCAST;
memset(ether.ether_dhost, 255, ETHER_ADDR_LEN);
ip.ip_dst.s_addr = INADDR_BROADCAST;
}
else
{
memcpy(header.ether.ether_dhost, mess->chaddr, ETHER_ADDR_LEN);
header.ip.ip_dst.s_addr = mess->yiaddr.s_addr;
memcpy(ether.ether_dhost, mess->chaddr, ETHER_ADDR_LEN);
ip.ip_dst.s_addr = mess->yiaddr.s_addr;
}
header.ip.ip_p = IPPROTO_UDP;
header.ip.ip_src.s_addr = iface_addr.s_addr;
header.ip.ip_len = htons(sizeof(struct ip) +
sizeof(struct udphdr) +
len) ;
header.ip.ip_hl = sizeof(struct ip) / 4;
header.ip.ip_v = IPVERSION;
header.ip.ip_tos = 0;
header.ip.ip_id = htons(0);
header.ip.ip_off = htons(0x4000); /* don't fragment */
header.ip.ip_ttl = IPDEFTTL;
header.ip.ip_sum = 0;
ip.ip_p = IPPROTO_UDP;
ip.ip_src.s_addr = iface_addr.s_addr;
ip.ip_len = htons(sizeof(struct ip) +
sizeof(struct udphdr) +
len) ;
ip.ip_hl = sizeof(struct ip) / 4;
ip.ip_v = IPVERSION;
ip.ip_tos = 0;
ip.ip_id = htons(0);
ip.ip_off = htons(0x4000); /* don't fragment */
ip.ip_ttl = IPDEFTTL;
ip.ip_sum = 0;
for (sum = 0, i = 0; i < sizeof(struct ip) / 2; i++)
sum += ((u16 *)&header.ip)[i];
sum += ((u16 *)&ip)[i];
while (sum>>16)
sum = (sum & 0xffff) + (sum >> 16);
header.ip.ip_sum = (sum == 0xffff) ? sum : ~sum;
ip.ip_sum = (sum == 0xffff) ? sum : ~sum;
header.udp.uh_sport = htons(DHCP_SERVER_PORT);
header.udp.uh_dport = htons(DHCP_CLIENT_PORT);
udp.uh_sport = htons(DHCP_SERVER_PORT);
udp.uh_dport = htons(DHCP_CLIENT_PORT);
if (len & 1)
((char *)mess)[len] = 0; /* for checksum, in case length is odd. */
header.udp.uh_sum = 0;
header.udp.uh_ulen = sum = htons(sizeof(struct udphdr) + len);
udp.uh_sum = 0;
udp.uh_ulen = sum = htons(sizeof(struct udphdr) + len);
sum += htons(IPPROTO_UDP);
for (i = 0; i < 4; i++)
sum += ((u16 *)&header.ip.ip_src)[i];
sum += ((u16 *)&ip.ip_src)[i];
for (i = 0; i < sizeof(struct udphdr)/2; i++)
sum += ((u16 *)&header.udp)[i];
sum += ((u16 *)&udp)[i];
for (i = 0; i < (len + 1) / 2; i++)
sum += ((u16 *)mess)[i];
while (sum>>16)
sum = (sum & 0xffff) + (sum >> 16);
header.udp.uh_sum = (sum == 0xffff) ? sum : ~sum;
udp.uh_sum = (sum == 0xffff) ? sum : ~sum;
ioctl(daemon->dhcp_raw_fd, BIOCSETIF, ifr);
iov[0].iov_base = &header;
iov[0].iov_len = sizeof(struct header);
iov[1].iov_base = mess;
iov[1].iov_len = len;
while (writev(daemon->dhcp_raw_fd, iov, 2) == -1 && retry_send());
iov[0].iov_base = &ether;
iov[0].iov_len = sizeof(ether);
iov[1].iov_base = &ip;
iov[1].iov_len = sizeof(ip);
iov[2].iov_base = &udp;
iov[2].iov_len = sizeof(udp);
iov[3].iov_base = mess;
iov[3].iov_len = len;
while (writev(daemon->dhcp_raw_fd, iov, 4) == -1 && retry_send());
}
int iface_enumerate(struct daemon *daemon, void *parm, int (*ipv4_callback)(), int (*ipv6_callback)())
@@ -145,31 +152,33 @@ int iface_enumerate(struct daemon *daemon, void *parm, int (*ipv4_callback)(), i
struct ifconf ifc;
int fd, errsav, ret = 0;
int lastlen = 0;
size_t len;
size_t len = 0;
if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
return 0;
for (len = 0; ; len += 10*sizeof(struct ifreq))
while(1)
{
if (!expand_buf(&ifconf, len))
goto err;
ifc.ifc_len = len;
ifc.ifc_buf = ifconf.iov_base;
if (ioctl(fd, SIOCGIFCONF, &ifc) == -1)
{
if (errno != EINVAL || lastlen != 0)
goto err;
}
else
{
if (ifc.ifc_len == lastlen)
break; /* got a big enough buffer now */
lastlen = ifc.ifc_len;
}
}
len += 10*sizeof(struct ifreq);
if (!expand_buf(&ifconf, len))
goto err;
ifc.ifc_len = len;
ifc.ifc_buf = ifconf.iov_base;
if (ioctl(fd, SIOCGIFCONF, &ifc) == -1)
{
if (errno != EINVAL || lastlen != 0)
goto err;
}
else
{
if (ifc.ifc_len == lastlen)
break; /* got a big enough buffer now */
lastlen = ifc.ifc_len;
}
}
for (ptr = ifc.ifc_buf; ptr < ifc.ifc_buf + ifc.ifc_len; ptr += len )
{

View File

@@ -10,7 +10,7 @@
GNU General Public License for more details.
*/
#define VERSION "2.30"
#define VERSION "2.32"
#define FTABSIZ 150 /* max number of outstanding requests */
#define MAX_PROCS 20 /* max no children for TCP requests */
@@ -23,6 +23,7 @@
#define MAXLEASES 150 /* maximum number of DHCP leases */
#define PING_WAIT 3 /* wait for ping address-in-use test */
#define PING_CACHE_TIME 30 /* Ping test assumed to be valid this long. */
#define DECLINE_BACKOFF 600 /* disable DECLINEd static addresses for this long */
#define DHCP_PACKET_MAX 16384 /* hard limit on DHCP packet size */
#define SMALLDNAME 40 /* most domain names are smaller than this */
#define HOSTSFILE "/etc/hosts"
@@ -53,20 +54,6 @@
#define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq"
#define DNSMASQ_PATH "/uk/org/thekelleys/dnsmasq"
/* Logfile stuff - change this to change the options and facility */
/* debug is true if the --no-daemon flag is given */
#ifdef LOG_PERROR
# define DNSMASQ_LOG_OPT(debug) (debug) ? LOG_PERROR : LOG_PID
#else
# define DNSMASQ_LOG_OPT(debug) (debug) ? 0 : LOG_PID
#endif
#ifdef LOG_LOCAL0
# define DNSMASQ_LOG_FAC(debug) (debug) ? LOG_LOCAL0 : LOG_DAEMON
#else
# define DNSMASQ_LOG_FAC(debug) LOG_DAEMON
#endif
/* A small collection of RR-types which are missing on some platforms */
#ifndef T_SRV
@@ -79,7 +66,8 @@
/* Get linux C library versions. */
#if defined(__linux__) && !defined(__UCLIBC__) && !defined(__uClinux__)
# include <libio.h>
/*# include <libio.h> */
# include <features.h>
#endif
@@ -203,11 +191,13 @@ NOTES:
#define HAVE_DEV_URANDOM
#define HAVE_DEV_RANDOM
#undef HAVE_SOCKADDR_SA_LEN
#if !defined(__UCLIBC_HAS_MMU__)
#if !defined(__ARCH_HAS_MMU__) && !defined(__UCLIBC_HAS_MMU__)
# define NO_FORK
#endif
#if !defined(__UCLIBC_HAS_IPV6__)
# define NO_IPV6
#if defined(__UCLIBC_HAS_IPV6__)
# ifndef IPV6_V6ONLY
# define IPV6_V6ONLY 26
# endif
#endif
/* This is for glibc 2.x */
@@ -282,4 +272,3 @@ typedef unsigned long in_addr_t;
# define ADDRSTRLEN 16 /* 4*3 + 3 dots + NULL */
#endif

View File

@@ -240,7 +240,7 @@ DBusHandlerResult message_handler(DBusConnection *connection,
check_servers(daemon);
}
else if (strcmp(method, "ClearCache") == 0)
clear_cache_and_reload(daemon);
clear_cache_and_reload(daemon, dnsmasq_time());
else
return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
@@ -260,7 +260,7 @@ char *dbus_init(struct daemon *daemon)
dbus_error_init (&dbus_error);
if (!(connection = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_error)))
return NULL;
dbus_connection_set_exit_on_disconnect(connection, FALSE);
dbus_connection_set_watch_functions(connection, add_watch, remove_watch,
NULL, (void *)daemon, NULL);

View File

@@ -25,14 +25,13 @@ void dhcp_init(struct daemon *daemon)
{
int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
struct sockaddr_in saddr;
int flags, oneopt = 1;
int oneopt = 1;
struct dhcp_config *configs, *cp;
if (fd == -1)
die (_("cannot create DHCP socket : %s"), NULL);
if ((flags = fcntl(fd, F_GETFL, 0)) == -1 ||
fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1 ||
if (!fix_fd(fd) ||
#if defined(HAVE_LINUX_NETWORK)
setsockopt(fd, SOL_IP, IP_PKTINFO, &oneopt, sizeof(oneopt)) == -1 ||
#elif defined(IP_RECVIF)
@@ -48,6 +47,7 @@ void dhcp_init(struct daemon *daemon)
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt)) == -1)
die(_("failed to set SO_REUSEADDR on DHCP socket: %s"), NULL);
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(DHCP_SERVER_PORT);
saddr.sin_addr.s_addr = INADDR_ANY;
@@ -203,8 +203,9 @@ void dhcp_packet(struct daemon *daemon, time_t now)
return;
lease_prune(NULL, now); /* lose any expired leases */
iov.iov_len = dhcp_reply(daemon, parm.current, ifr.ifr_name, (size_t)sz, now, unicast_dest);
lease_update_file(daemon);
lease_update_file(daemon, now);
lease_update_dns(daemon);
lease_collect(daemon);
if (iov.iov_len == 0)
return;
@@ -237,9 +238,10 @@ void dhcp_packet(struct daemon *daemon, time_t now)
dest.sin_port = htons(DHCP_CLIENT_PORT);
}
#ifdef HAVE_LINUX_NETWORK
else if (ntohs(mess->flags) & 0x8000)
else if ((ntohs(mess->flags) & 0x8000) || mess->hlen == 0 ||
mess->hlen > sizeof(ifr.ifr_addr.sa_data) || mess->htype == 0)
{
/* broadcast to 255.255.255.255 */
/* broadcast to 255.255.255.255 (or mac address invalid) */
struct in_pktinfo *pkt;
msg.msg_control = control_u.control;
msg.msg_controllen = sizeof(control_u);
@@ -255,12 +257,17 @@ void dhcp_packet(struct daemon *daemon, time_t now)
}
else
{
/* unicast to unconfigured client */
/* unicast to unconfigured client. Inject mac address direct into ARP cache.
struct sockaddr limits size to 14 bytes. */
struct arpreq req;
dest.sin_addr = mess->yiaddr;
dest.sin_port = htons(DHCP_CLIENT_PORT);
if (mess->hlen != 0 && mess->htype != 0)
arp_inject(daemon->netlinkfd, mess->yiaddr, iface_index,
mess->chaddr, mess->hlen);
*((struct sockaddr_in *)&req.arp_pa) = dest;
req.arp_ha.sa_family = mess->htype;
memcpy(req.arp_ha.sa_data, mess->chaddr, mess->hlen);
strncpy(req.arp_dev, ifr.ifr_name, 16);
req.arp_flags = ATF_COM;
ioctl(daemon->dhcpfd, SIOCSARP, &req);
}
#else
else
@@ -357,7 +364,7 @@ struct dhcp_context *address_available(struct dhcp_context *context, struct in_a
struct dhcp_context *tmp;
for (tmp = context; tmp; tmp = tmp->current)
if (taddr.s_addr == context->local.s_addr)
if (taddr.s_addr == context->router.s_addr)
return NULL;
for (tmp = context; tmp; tmp = tmp->current)
@@ -472,7 +479,7 @@ int address_allocate(struct dhcp_context *context, struct daemon *daemon,
do {
/* eliminate addresses in use by the server. */
for (d = context; d; d = d->current)
if (addr.s_addr == d->local.s_addr)
if (addr.s_addr == d->router.s_addr)
break;
if (!d &&
@@ -613,6 +620,7 @@ void dhcp_read_ethers(struct daemon *daemon)
char *ip, *cp;
struct in_addr addr;
unsigned char hwaddr[ETHER_ADDR_LEN];
struct dhcp_config **up, *tmp;
struct dhcp_config *config, *configs = daemon->dhcp_conf;
int count = 0, lineno = 0;
@@ -624,6 +632,22 @@ void dhcp_read_ethers(struct daemon *daemon)
return;
}
/* This can be called again on SIGHUP, so remove entries created last time round. */
for (up = &daemon->dhcp_conf, config = configs; config; config = tmp)
{
tmp = config->next;
if (config->flags & CONFIG_FROM_ETHERS)
{
*up = tmp;
/* cannot have a clid */
if (config->flags & CONFIG_NAME)
free(config->hostname);
free(config);
}
else
up = &config->next;
}
while (fgets(buff, MAXDNAME, f))
{
lineno++;
@@ -691,7 +715,7 @@ void dhcp_read_ethers(struct daemon *daemon)
{
if (!(config = malloc(sizeof(struct dhcp_config))))
continue;
config->flags = 0;
config->flags = CONFIG_FROM_ETHERS;
config->wildcard_mask = 0;
config->next = configs;
configs = config;
@@ -731,10 +755,15 @@ void dhcp_update_configs(struct dhcp_config *configs)
This goes through /etc/hosts and sets static addresses for any DHCP config
records which don't have an address and whose name matches.
We take care to maintain the invariant that any IP address can appear
in at most one dhcp-host. */
in at most one dhcp-host. Since /etc/hosts can be re-read by SIGHUP,
restore the status-quo ante first. */
struct dhcp_config *config;
struct crec *crec;
for (config = configs; config; config = config->next)
if (config->flags & CONFIG_ADDR_HOSTS)
config->flags &= ~(CONFIG_ADDR | CONFIG_ADDR_HOSTS);
for (config = configs; config; config = config->next)
if (!(config->flags & CONFIG_ADDR) &&
@@ -748,7 +777,7 @@ void dhcp_update_configs(struct dhcp_config *configs)
else
{
config->addr = crec->addr.addr.addr.addr4;
config->flags |= CONFIG_ADDR;
config->flags |= CONFIG_ADDR | CONFIG_ADDR_HOSTS;
}
}
}

View File

@@ -52,9 +52,9 @@ int main (int argc, char **argv)
time_t now, last = 0;
struct sigaction sigact;
struct iname *if_tmp;
int flags, piperead, pipefd[2];
int piperead, pipefd[2];
unsigned char sig;
#ifndef NO_GETTEXT
setlocale(LC_ALL, "");
bindtextdomain("dnsmasq", LOCALEDIR);
@@ -128,7 +128,6 @@ int main (int argc, char **argv)
else if (!(daemon->listeners = create_wildcard_listeners(daemon->port)))
die(_("failed to create listening socket: %s"), NULL);
forward_init(1);
cache_init(daemon->cachesize, daemon->options & OPT_LOG);
now = dnsmasq_time();
@@ -167,6 +166,7 @@ int main (int argc, char **argv)
if (daemon->query_port)
{
union mysockaddr addr;
memset(&addr, 0, sizeof(addr));
addr.in.sin_family = AF_INET;
addr.in.sin_addr.s_addr = INADDR_ANY;
addr.in.sin_port = htons(daemon->query_port);
@@ -175,11 +175,10 @@ int main (int argc, char **argv)
#endif
allocate_sfd(&addr, &daemon->sfds);
#ifdef HAVE_IPV6
memset(&addr, 0, sizeof(addr));
addr.in6.sin6_family = AF_INET6;
addr.in6.sin6_addr = in6addr_any;
addr.in6.sin6_port = htons(daemon->query_port);
addr.in6.sin6_flowinfo = 0;
addr.in6.sin6_scope_id = 0;
#ifdef HAVE_SOCKADDR_SA_LEN
addr.in6.sin6_len = sizeof(struct sockaddr_in6);
#endif
@@ -188,11 +187,7 @@ int main (int argc, char **argv)
}
/* Use a pipe to carry signals back to the event loop in a race-free manner */
if (pipe(pipefd) == -1 ||
(flags = fcntl(pipefd[0], F_GETFL)) == -1 ||
fcntl(pipefd[0], F_SETFL, flags | O_NONBLOCK) == -1 ||
(flags = fcntl(pipefd[1], F_GETFL)) == -1 ||
fcntl(pipefd[1], F_SETFL, flags | O_NONBLOCK) == -1)
if (pipe(pipefd) == -1 || !fix_fd(pipefd[0]) || !fix_fd(pipefd[1]))
die(_("cannot create pipe: %s"), NULL);
piperead = pipefd[0];
@@ -201,12 +196,25 @@ int main (int argc, char **argv)
sig = SIGHUP;
write(pipewrite, &sig, 1);
if (!(daemon->options & OPT_DEBUG))
if (daemon->options & OPT_DEBUG)
{
#ifdef LOG_PERROR
openlog("dnsmasq", LOG_PERROR, daemon->log_fac);
#else
openlog("dnsmasq", 0, daemon->log_fac);
#endif
#ifdef HAVE_LINUX_NETWORK
prctl(PR_SET_DUMPABLE, 1);
#endif
}
else
{
FILE *pidfile;
struct passwd *ent_pw = daemon->username ? getpwnam(daemon->username) : NULL;
fd_set test_set;
int maxfd, i;
int nullfd = open("/dev/null", O_RDWR);
#ifdef HAVE_LINUX_NETWORK
cap_user_header_t hdr = NULL;
@@ -214,7 +222,7 @@ int main (int argc, char **argv)
/* On linux, we keep CAP_NETADMIN (for ARP-injection) and
CAP_NET_RAW (for icmp) if we're doing dhcp */
if (ent_pw)
if (ent_pw && ent_pw->pw_uid != 0)
{
hdr = safe_malloc(sizeof(*hdr));
data = safe_malloc(sizeof(*data));
@@ -246,12 +254,12 @@ int main (int argc, char **argv)
if (!(daemon->options & OPT_NO_FORK))
{
if (fork() != 0 )
exit(0);
_exit(0);
setsid();
if (fork() != 0)
exit(0);
_exit(0);
}
#endif
@@ -289,25 +297,33 @@ int main (int argc, char **argv)
if (i <= maxfd && FD_ISSET(i, &test_set))
continue;
close(i);
/* open stdout etc to /dev/null */
if (i == STDOUT_FILENO || i == STDERR_FILENO || i == STDIN_FILENO)
dup2(nullfd, i);
else
close(i);
}
/* Change uid and gid for security */
if (ent_pw)
if (daemon->groupname || ent_pw)
{
gid_t dummy;
struct group *gp;
/* remove all supplimentary groups */
setgroups(0, &dummy);
/* change group for /etc/ppp/resolv.conf
otherwise get the group for "nobody" */
/* change group for /etc/ppp/resolv.conf otherwise get the group for "nobody" */
if ((daemon->groupname && (gp = getgrnam(daemon->groupname))) ||
(gp = getgrgid(ent_pw->pw_gid)))
setgid(gp->gr_gid);
(ent_pw && (gp = getgrgid(ent_pw->pw_gid))))
{
/* remove all supplimentary groups */
setgroups(0, &dummy);
setgid(gp->gr_gid);
}
}
if (ent_pw && ent_pw->pw_uid != 0)
{
/* finally drop root */
setuid(ent_pw->pw_uid);
#ifdef HAVE_LINUX_NETWORK
data->effective = data->permitted =
(1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
@@ -317,16 +333,10 @@ int main (int argc, char **argv)
capset(hdr, data);
#endif
}
}
#ifdef HAVE_LINUX_NETWORK
else
prctl(PR_SET_DUMPABLE, 1);
#endif
openlog("dnsmasq",
DNSMASQ_LOG_OPT(daemon->options & OPT_DEBUG),
DNSMASQ_LOG_FAC(daemon->options & OPT_DEBUG));
openlog("dnsmasq", LOG_PID, daemon->log_fac);
}
if (daemon->cachesize != 0)
syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize);
else
@@ -379,9 +389,13 @@ int main (int argc, char **argv)
}
check_servers(daemon);
pid = getpid();
pid = getpid();
/* Start lease-change script */
if (daemon->dhcp)
lease_collect(daemon);
while (1)
{
int maxfd;
@@ -435,7 +449,7 @@ int main (int argc, char **argv)
/* 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)
if (last == 0 || difftime(now, last) > 1.0 || difftime(now, last) < -1.0)
{
last = now;
@@ -463,14 +477,11 @@ int main (int argc, char **argv)
else
{
res->logged = 0;
if (statbuf.st_mtime != res->mtime)
if (statbuf.st_mtime != res->mtime &&
difftime(statbuf.st_mtime, last_change) > 0.0)
{
res->mtime = statbuf.st_mtime;
if (difftime(res->mtime, last_change) > 0.0)
{
last_change = res->mtime;
latest = res;
}
last_change = statbuf.st_mtime;
latest = res;
}
}
res = res->next;
@@ -478,19 +489,32 @@ int main (int argc, char **argv)
if (latest)
{
reload_servers(latest->name, daemon);
check_servers(daemon);
static int warned = 0;
if (reload_servers(latest->name, daemon))
{
syslog(LOG_INFO, _("reading %s"), latest->name);
latest->mtime = last_change;
warned = 0;
check_servers(daemon);
}
else if (!warned)
{
syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
warned = 1;
}
}
}
}
if (FD_ISSET(piperead, &rset))
{
pid_t p;
if (read(piperead, &sig, 1) == 1)
switch (sig)
{
case SIGHUP:
clear_cache_and_reload(daemon);
clear_cache_and_reload(daemon, now);
if (daemon->resolv_files && (daemon->options & OPT_NO_POLL))
{
reload_servers(daemon->resolv_files->name, daemon);
@@ -504,24 +528,57 @@ int main (int argc, char **argv)
case SIGALRM:
if (daemon->dhcp)
lease_update_file(daemon);
{
lease_prune(NULL, now);
lease_update_file(daemon, now);
lease_collect(daemon);
}
break;
case SIGTERM:
syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
if (daemon->dhcp)
fclose(daemon->lease_stream);
exit(0);
{
int i;
syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
/* Knock all our children on the head. */
for (i = 0; i < MAX_PROCS; i++)
if (daemon->tcp_pids[i] != 0)
kill(daemon->tcp_pids[i], SIGALRM);
if (daemon->dhcp)
fclose(daemon->lease_stream);
exit(0);
}
case SIGCHLD:
/* See Stevens 5.10 */
while (waitpid(-1, NULL, WNOHANG) > 0)
daemon->num_kids--;
/* Note that if a script process forks and then exits
without waiting for its child, we will reap that child.
It is not therefore safe to assume that any dieing children
whose pid != script_pid are TCP server threads. */
while ((p = waitpid(-1, NULL, WNOHANG)) > 0)
{
if (p == daemon->script_pid)
{
daemon->script_pid = 0;
lease_collect(daemon);
}
else
{
int i;
for (i = 0 ; i < MAX_PROCS; i++)
if (daemon->tcp_pids[i] == p)
{
daemon->tcp_pids[i] = 0;
daemon->num_kids--;
break;
}
}
}
break;
}
}
#ifdef HAVE_LINUX_NETWORK
if (FD_ISSET(daemon->netlinkfd, &rset))
netlink_multicast(daemon);
@@ -529,7 +586,7 @@ int main (int argc, char **argv)
#ifdef HAVE_DBUS
/* if we didn't create a DBus connection, retry now. */
if ((daemon->options & OPT_DBUS) && !daemon->dbus)
if ((daemon->options & OPT_DBUS) && !daemon->dbus)
{
char *err;
if ((err = dbus_init(daemon)))
@@ -567,12 +624,12 @@ static void sig_handler(int sig)
{
/* alarm is used to kill children after a fixed time. */
if (sig == SIGALRM)
exit(0);
_exit(0);
}
}
void clear_cache_and_reload(struct daemon *daemon)
void clear_cache_and_reload(struct daemon *daemon, time_t now)
{
cache_reload(daemon->options, daemon->namebuff, daemon->domain_suffix, daemon->addn_hosts);
if (daemon->dhcp)
@@ -581,7 +638,7 @@ void clear_cache_and_reload(struct daemon *daemon)
dhcp_read_ethers(daemon);
dhcp_update_configs(daemon->dhcp_conf);
lease_update_from_configs(daemon);
lease_update_file(daemon);
lease_update_file(daemon, now);
lease_update_dns(daemon);
}
}
@@ -628,95 +685,115 @@ static void check_dns_listeners(struct daemon *daemon, fd_set *set, time_t now)
if (FD_ISSET(listener->tcpfd, set))
{
int confd;
struct irec *iface = NULL;
pid_t p;
while((confd = accept(listener->tcpfd, NULL, NULL)) == -1 && errno == EINTR);
if (confd != -1)
if (confd == -1)
continue;
if (daemon->options & OPT_NOWILD)
iface = listener->iface;
else
{
struct irec *iface = NULL;
union mysockaddr tcp_addr;
socklen_t tcp_len = sizeof(union mysockaddr);
/* Check for allowed interfaces when binding the wildcard address:
we do this by looking for an interface with the same address as
the local address of the TCP connection, then looking to see if that's
an allowed interface. As a side effect, we get the netmask of the
interface too, for localisation. */
if (daemon->options & OPT_NOWILD)
iface = listener->iface;
else
{
union mysockaddr tcp_addr;
socklen_t tcp_len = sizeof(union mysockaddr);
/* Check for allowed interfaces when binding the wildcard address:
we do this by looking for an interface with the same address as
the local address of the TCP connection, then looking to see if that's
an allowed interface. As a side effect, we get the netmask of the
interface too, for localisation. */
/* interface may be new since startup */
if (enumerate_interfaces(daemon) &&
getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) != -1)
for (iface = daemon->interfaces; iface; iface = iface->next)
if (sockaddr_isequal(&iface->addr, &tcp_addr))
break;
}
if ((daemon->num_kids >= MAX_PROCS) || !iface)
close(confd);
/* interface may be new since startup */
if (enumerate_interfaces(daemon) &&
getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) != -1)
for (iface = daemon->interfaces; iface; iface = iface->next)
if (sockaddr_isequal(&iface->addr, &tcp_addr))
break;
}
if ((daemon->num_kids >= MAX_PROCS) || !iface)
{
shutdown(confd, SHUT_RDWR);
close(confd);
}
#ifndef NO_FORK
else if (!(daemon->options & OPT_DEBUG) && fork())
else if (!(daemon->options & OPT_DEBUG) && (p = fork()) != 0)
{
if (p != -1)
{
int i;
for (i = 0; i < MAX_PROCS; i++)
if (daemon->tcp_pids[i] == 0)
{
daemon->tcp_pids[i] = p;
break;
}
daemon->num_kids++;
close(confd);
}
close(confd);
}
#endif
else
{
unsigned char *buff;
struct server *s;
int flags;
struct in_addr dst_addr_4;
dst_addr_4.s_addr = 0;
/* Arrange for SIGALARM after CHILD_LIFETIME seconds to
terminate the process. */
if (!(daemon->options & OPT_DEBUG))
alarm(CHILD_LIFETIME);
/* start with no upstream connections. */
for (s = daemon->servers; s; s = s->next)
s->tcpfd = -1;
/* The connected socket inherits non-blocking
attribute from the listening socket.
Reset that here. */
if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
if (listener->family == AF_INET)
dst_addr_4 = iface->addr.in.sin_addr;
buff = tcp_request(daemon, confd, now, dst_addr_4, iface->netmask);
shutdown(confd, SHUT_RDWR);
close(confd);
if (buff)
free(buff);
for (s = daemon->servers; s; s = s->next)
if (s->tcpfd != -1)
{
shutdown(s->tcpfd, SHUT_RDWR);
close(s->tcpfd);
}
#ifndef NO_FORK
if (!(daemon->options & OPT_DEBUG))
_exit(0);
#endif
else
{
unsigned char *buff;
struct server *s;
int flags;
struct in_addr dst_addr_4;
dst_addr_4.s_addr = 0;
/* Arrange for SIGALARM after CHILD_LIFETIME seconds to
terminate the process. */
if (!(daemon->options & OPT_DEBUG))
alarm(CHILD_LIFETIME);
/* start with no upstream connections. */
for (s = daemon->servers; s; s = s->next)
s->tcpfd = -1;
/* The connected socket inherits non-blocking
attribute from the listening socket.
Reset that here. */
if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
if (listener->family == AF_INET)
dst_addr_4 = iface->addr.in.sin_addr;
buff = tcp_request(daemon, confd, now, dst_addr_4, iface->netmask);
if (!(daemon->options & OPT_DEBUG))
exit(0);
close(confd);
if (buff)
free(buff);
for (s = daemon->servers; s; s = s->next)
if (s->tcpfd != -1)
close(s->tcpfd);
}
}
}
}
}
int make_icmp_sock(void)
{
int fd, flags;
int fd;
int zeroopt = 0;
if ((fd = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP)) != -1)
{
if ((flags = fcntl(fd, F_GETFL, 0)) == -1 ||
fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1 ||
if (!fix_fd(fd) ||
setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, &zeroopt, sizeof(zeroopt)) == -1)
{
close(fd);

View File

@@ -16,8 +16,6 @@
#include <sys/types.h>
#include <netinet/in.h>
/* get this before config.h too. */
#include <syslog.h>
#ifdef __APPLE__
/* need this before arpa/nameser.h */
# define BIND_8_COMPAT
@@ -69,6 +67,8 @@
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <sys/uio.h>
#include <syslog.h>
#include <dirent.h>
#ifndef HAVE_LINUX_NETWORK
# include <net/if_dl.h>
#endif
@@ -288,7 +288,9 @@ struct dhcp_lease {
int clid_len; /* length of client identifier */
unsigned char *clid; /* clientid */
char *hostname, *fqdn; /* name from client-hostname option or config */
int auth_name; /* hostname came from config, not from client */
char auth_name; /* hostname came from config, not from client */
char new; /* newly created */
char old; /* read from leasefile */
time_t expires; /* lease expiry */
#ifdef HAVE_BROKEN_RTC
unsigned int length;
@@ -317,6 +319,7 @@ struct dhcp_config {
char *hostname;
struct dhcp_netid netid;
struct in_addr addr;
time_t decline_time;
unsigned int lease_time, wildcard_mask;
struct dhcp_config *next;
};
@@ -329,6 +332,9 @@ struct dhcp_config {
#define CONFIG_ADDR 32
#define CONFIG_NETID 64
#define CONFIG_NOCLID 128
#define CONFIG_FROM_ETHERS 256 /* entry created by /etc/ethers */
#define CONFIG_ADDR_HOSTS 512 /* address added by from /etc/hosts */
#define CONFIG_DECLINED 1024 /* address declined by client */
struct dhcp_opt {
int opt, len, flags;
@@ -411,9 +417,11 @@ struct daemon {
char *username, *groupname;
char *domain_suffix;
char *runfile;
char *lease_change_command;
struct iname *if_names, *if_addrs, *if_except, *dhcp_except;
struct bogus_addr *bogus_addr;
struct server *servers;
int log_fac; /* log facility */
int cachesize;
int port, query_port;
unsigned long local_ttl;
@@ -440,6 +448,7 @@ struct daemon {
struct server *last_server;
struct server *srv_save; /* Used for resend on DoD */
size_t packet_len; /* " " */
pid_t script_pid, tcp_pids[MAX_PROCS];
int num_kids;
/* DHCP state */
@@ -522,25 +531,28 @@ int parse_hex(char *in, unsigned char *out, int maxlen,
int memcmp_masked(unsigned char *a, unsigned char *b, int len,
unsigned int mask);
int expand_buf(struct iovec *iov, size_t size);
char *print_mac(struct daemon *daemon, unsigned char *mac, int len);
/* option.c */
struct daemon *read_opts (int argc, char **argv, char *compile_opts);
/* forward.c */
void forward_init(int first);
void reply_query(struct serverfd *sfd, struct daemon *daemon, time_t now);
void receive_query(struct listener *listen, struct daemon *daemon, time_t now);
unsigned char *tcp_request(struct daemon *daemon, int confd, time_t now,
struct in_addr local_addr, struct in_addr netmask);
void server_gone(struct daemon *daemon, struct server *server);
/* network.c */
struct serverfd *allocate_sfd(union mysockaddr *addr, struct serverfd **sfds);
void reload_servers(char *fname, struct daemon *daemon);
int reload_servers(char *fname, struct daemon *daemon);
void check_servers(struct daemon *daemon);
int enumerate_interfaces(struct daemon *daemon);
struct listener *create_wildcard_listeners(int port);
struct listener *create_bound_listeners(struct daemon *daemon);
int iface_check(struct daemon *daemon, int family,
struct all_addr *addr, char *name);
int fix_fd(int fd);
/* dhcp.c */
void dhcp_init(struct daemon *daemon);
@@ -564,12 +576,11 @@ char *strip_hostname(struct daemon *daemon, char *hostname);
char *host_from_dns(struct daemon *daemon, struct in_addr addr);
/* lease.c */
void lease_update_file(struct daemon *daemon);
void lease_update_file(struct daemon *daemon, time_t now);
void lease_update_dns(struct daemon *daemon);
void lease_init(struct daemon *daemon, time_t now);
struct dhcp_lease *lease_allocate(unsigned char *hwaddr, unsigned char *clid,
int hw_len, int hw_type, int clid_len, struct in_addr addr);
int lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
struct dhcp_lease *lease_allocate(struct in_addr addr);
void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
unsigned char *clid, int hw_len, int hw_type, int clid_len);
void lease_set_hostname(struct dhcp_lease *lease, char *name,
char *suffix, int auth);
@@ -579,6 +590,7 @@ struct dhcp_lease *lease_find_by_client(unsigned char *hwaddr, int hw_len, int h
struct dhcp_lease *lease_find_by_addr(struct in_addr addr);
void lease_prune(struct dhcp_lease *target, time_t now);
void lease_update_from_configs(struct daemon *daemon);
void lease_collect(struct daemon *daemon);
/* rfc2131.c */
size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *iface_name, size_t sz, time_t now, int unicast_dest);
@@ -586,7 +598,7 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
/* dnsmasq.c */
int make_icmp_sock(void);
int icmp_ping(struct daemon *daemon, struct in_addr addr);
void clear_cache_and_reload(struct daemon *daemon);
void clear_cache_and_reload(struct daemon *daemon, time_t now);
/* isc.c */
#ifdef HAVE_ISC_READER
@@ -599,8 +611,6 @@ void netlink_init(struct daemon *daemon);
int iface_enumerate(struct daemon *daemon, void *parm,
int (*ipv4_callback)(), int (*ipv6_callback)());
void netlink_multicast(struct daemon *daemon);
void arp_inject(int fd, struct in_addr addr,
int iface, unsigned char *mac, unsigned int mac_len);
#endif
/* bpf.c */

View File

@@ -12,7 +12,7 @@
#include "dnsmasq.h"
static struct frec *frec_list;
static struct frec *frec_list = NULL;
static struct frec *get_new_frec(time_t now);
static struct frec *lookup_frec(unsigned short id);
@@ -21,16 +21,6 @@ static struct frec *lookup_frec_by_sender(unsigned short id,
unsigned int crc);
static unsigned short get_id(void);
/* May be called more than once. */
void forward_init(int first)
{
struct frec *f;
if (first)
frec_list = NULL;
for (f = frec_list; f; f = f->next)
f->new_id = 0;
}
/* Send a UDP packet with it's source address set as "source"
unless nowild is true, when we just send it with the kernel default */
@@ -927,6 +917,21 @@ static struct frec *lookup_frec_by_sender(unsigned short id,
return NULL;
}
/* A server record is going away, remove references to it */
void server_gone(struct daemon *daemon, struct server *server)
{
struct frec *f;
for (f = frec_list; f; f = f->next)
if (f->new_id != 0 && f->sentto == server)
f->new_id = 0;
if (daemon->last_server == server)
daemon->last_server = NULL;
if (daemon->srv_save == server)
daemon->srv_save = NULL;
}
/* return unique random ids between 1 and 65535 */
static unsigned short get_id(void)

View File

@@ -12,64 +12,53 @@
#include "dnsmasq.h"
static struct dhcp_lease *leases;
static struct dhcp_lease *leases, *old_leases;
static int dns_dirty, file_dirty, leases_left;
void lease_init(struct daemon *daemon, time_t now)
{
unsigned int a0, a1, a2, a3;
unsigned long ei;
unsigned char hwaddr[DHCP_CHADDR_MAX];
struct in_addr addr;
struct dhcp_lease *lease;
int clid_len = 0, hw_len, hw_type;
int flags, clid_len, hw_len, hw_type;
dns_dirty = 1;
file_dirty = 0;
leases = NULL;
leases = old_leases = NULL;
leases_left = daemon->dhcp_max;
/* NOTE: need a+ mode to create file if it doesn't exist */
if (!(daemon->lease_stream = fopen(daemon->lease_file, "a+")))
die(_("cannot open or create leases file: %s"), NULL);
flags = fcntl(fileno(daemon->lease_stream), F_GETFD);
if (flags != -1)
fcntl(fileno(daemon->lease_stream), F_SETFD, flags | FD_CLOEXEC);
/* a+ mode lease pointer at end. */
rewind(daemon->lease_stream);
/* client-id max length is 255 which is 255*2 digits + 254 colons
borrow DNS packet buffer which is always larger than 1000 bytes */
while (fscanf(daemon->lease_stream, "%lu %255s %d.%d.%d.%d %255s %764s",
&ei, daemon->dhcp_buff2, &a0, &a1, &a2, &a3,
daemon->dhcp_buff, daemon->packet) == 8)
while (fscanf(daemon->lease_stream, "%lu %255s %16s %255s %764s",
&ei, daemon->dhcp_buff2, daemon->namebuff,
daemon->dhcp_buff, daemon->packet) == 5)
{
#ifndef HAVE_BROKEN_RTC
/* strictly time_t is opaque, but this hack should work on all sane systems,
even when sizeof(time_t) == 8 */
time_t expires = (time_t)ei;
if (ei != 0 && difftime(now, expires) > 0)
{
file_dirty = 1;
continue; /* expired */
}
#endif
hw_len = parse_hex(daemon->dhcp_buff2, hwaddr, DHCP_CHADDR_MAX, NULL, &hw_type);
hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, DHCP_CHADDR_MAX, NULL, &hw_type);
/* For backwards compatibility, no explict MAC address type means ether. */
if (hw_type == 0 && hw_len != 0)
hw_type = ARPHRD_ETHER;
addr.s_addr = htonl((a0<<24) + (a1<<16) + (a2<<8) + a3);
addr.s_addr = inet_addr(daemon->namebuff);
/* decode hex in place */
if (strcmp(daemon->packet, "*") == 0)
clid_len = 0;
else
clid_len = 0;
if (strcmp(daemon->packet, "*") != 0)
clid_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL);
if (!(lease = lease_allocate(hwaddr, (unsigned char *)daemon->packet, hw_len, hw_type, clid_len, addr)))
if (!(lease = lease_allocate(addr)))
die (_("too many stored leases"), NULL);
/* not actually new */
lease->new = 0;
#ifdef HAVE_BROKEN_RTC
if (ei != 0)
lease->expires = (time_t)ei + now;
@@ -77,12 +66,21 @@ void lease_init(struct daemon *daemon, time_t now)
lease->expires = (time_t)0;
lease->length = ei;
#else
lease->expires = expires;
/* strictly time_t is opaque, but this hack should work on all sane systems,
even when sizeof(time_t) == 8 */
lease->expires = (time_t)ei;
#endif
lease_set_hwaddr(lease, (unsigned char *)daemon->dhcp_buff2, (unsigned char *)daemon->packet, hw_len, hw_type, clid_len);
if (strcmp(daemon->dhcp_buff, "*") != 0)
lease_set_hostname(lease, daemon->dhcp_buff, daemon->domain_suffix, 0);
}
/* Some leases may have expired */
file_dirty = 0;
lease_prune(NULL, now);
dns_dirty = 1;
}
void lease_update_from_configs(struct daemon *daemon)
@@ -103,67 +101,83 @@ void lease_update_from_configs(struct daemon *daemon)
lease_set_hostname(lease, name, daemon->domain_suffix, 1); /* updates auth flag only */
}
void lease_update_file(struct daemon *daemon)
static void ourprintf(struct daemon *daemon, int *errp, char *format, ...)
{
va_list ap;
va_start(ap, format);
if (!(*errp) && vfprintf(daemon->lease_stream, format, ap) < 0)
*errp = errno;
va_end(ap);
}
void lease_update_file(struct daemon *daemon, time_t now)
{
struct dhcp_lease *lease;
int i;
time_t next_event;
int i, err = 0;
if (file_dirty != 0)
{
errno = 0;
rewind(daemon->lease_stream);
if (errno != 0 || ftruncate(fileno(daemon->lease_stream), 0) != 0)
{
write_err:
syslog(LOG_ERR, _("failed to write %s: %m (retry in %ds)"), daemon->lease_file, LEASE_RETRY);
alarm(LEASE_RETRY);
return;
}
err = errno;
for (lease = leases; lease; lease = lease->next)
{
#ifdef HAVE_BROKEN_RTC
if (fprintf(daemon->lease_stream, "%u ", lease->length) < 0)
goto write_err;
ourprintf(daemon, &err, "%u ", lease->length);
#else
if (fprintf(daemon->lease_stream, "%lu ", (unsigned long)lease->expires) < 0)
goto write_err;
ourprintf(daemon, &err, "%lu ", (unsigned long)lease->expires);
#endif
if ((lease->hwaddr_type != ARPHRD_ETHER || lease->hwaddr_len == 0) &&
fprintf(daemon->lease_stream, "%.2x-", lease->hwaddr_type) < 0)
goto write_err;
if (lease->hwaddr_type != ARPHRD_ETHER || lease->hwaddr_len == 0)
ourprintf(daemon, &err, "%.2x-", lease->hwaddr_type);
for (i = 0; i < lease->hwaddr_len; i++)
{
if (fprintf(daemon->lease_stream, "%.2x", lease->hwaddr[i]) < 0)
goto write_err;
if (i != lease->hwaddr_len - 1 &&
fprintf(daemon->lease_stream, ":") < 0)
goto write_err;
ourprintf(daemon, &err, "%.2x", lease->hwaddr[i]);
if (i != lease->hwaddr_len - 1)
ourprintf(daemon, &err, ":");
}
if (fprintf(daemon->lease_stream, " %s %s ", inet_ntoa(lease->addr),
lease->hostname && strlen(lease->hostname) != 0 ? lease->hostname : "*") < 0)
goto write_err;
ourprintf(daemon, &err, " %s %s ", inet_ntoa(lease->addr),
lease->hostname && strlen(lease->hostname) != 0 ? lease->hostname : "*");
if (lease->clid && lease->clid_len != 0)
{
for (i = 0; i < lease->clid_len - 1; i++)
if (fprintf(daemon->lease_stream, "%.2x:", lease->clid[i]) < 0)
goto write_err;
if (fprintf(daemon->lease_stream, "%.2x\n", lease->clid[i]) < 0)
goto write_err;
ourprintf(daemon, &err, "%.2x:", lease->clid[i]);
ourprintf(daemon, &err, "%.2x\n", lease->clid[i]);
}
else
if (fprintf(daemon->lease_stream, "*\n") < 0)
goto write_err;
ourprintf(daemon, &err, "*\n");
}
if (fflush(daemon->lease_stream) != 0)
goto write_err;
if (fsync(fileno(daemon->lease_stream)) < 0)
goto write_err;
file_dirty = 0;
if (fflush(daemon->lease_stream) != 0 ||
fsync(fileno(daemon->lease_stream)) < 0)
err = errno;
if (!err)
file_dirty = 0;
}
/* Set alarm for when the first lease expires + slop. */
for (next_event = 0, lease = leases; lease; lease = lease->next)
if (lease->expires != 0 &&
(next_event == 0 || difftime(next_event, lease->expires + 10) > 0.0))
next_event = lease->expires + 10;
if (err)
{
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));
}
if (next_event != 0)
alarm((unsigned)difftime(next_event, now));
}
void lease_update_dns(struct daemon *daemon)
@@ -194,18 +208,16 @@ void lease_prune(struct dhcp_lease *target, time_t now)
if ((lease->expires != 0 && difftime(now, lease->expires) > 0) || lease == target)
{
file_dirty = 1;
*up = lease->next; /* unlink */
if (lease->hostname)
{
free(lease->hostname);
dns_dirty = 1;
}
if (lease->fqdn)
free(lease->fqdn);
if (lease->clid)
free(lease->clid);
free(lease);
dns_dirty = 1;
*up = lease->next; /* unlink */
/* Put on old_leases list 'till we
can run the script */
lease->next = old_leases;
old_leases = lease;
leases_left++;
}
else
@@ -248,30 +260,20 @@ struct dhcp_lease *lease_find_by_addr(struct in_addr addr)
}
struct dhcp_lease *lease_allocate(unsigned char *hwaddr, unsigned char *clid,
int hw_len, int hw_type, int clid_len, struct in_addr addr)
struct dhcp_lease *lease_allocate(struct in_addr addr)
{
struct dhcp_lease *lease;
if (!leases_left || !(lease = malloc(sizeof(struct dhcp_lease))))
return NULL;
lease->clid = NULL;
lease->hostname = lease->fqdn = NULL;
memset(lease, 0, sizeof(struct dhcp_lease));
lease->new = 1;
lease->addr = addr;
memset(lease->hwaddr, 0, DHCP_CHADDR_MAX);
lease->hwaddr_len = 0;
lease->hwaddr_type = 0;
lease->hwaddr_len = 225; /* illegal value */
lease->expires = 1;
#ifdef HAVE_BROKEN_RTC
lease->length = 0xffffffff; /* illegal value */
#endif
if (!lease_set_hwaddr(lease, hwaddr, clid, hw_len, hw_type, clid_len))
{
free(lease);
return NULL;
}
lease->next = leases;
leases = lease;
@@ -309,22 +311,18 @@ void lease_set_expires(struct dhcp_lease *lease, unsigned int len, time_t now)
#endif
}
int lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
unsigned char *clid, int hw_len, int hw_type, int clid_len)
{
/* must have some sort of unique-id */
if (hw_len == 0 && (clid_len == 0 || !clid))
return 0;
if (hw_len != lease->hwaddr_len ||
hw_type != lease->hwaddr_type ||
hw_len == 0 ||
memcmp(lease->hwaddr, hwaddr, hw_len) != 0)
(hw_len != 0 && memcmp(lease->hwaddr, hwaddr, hw_len) != 0))
{
file_dirty = 1;
memcpy(lease->hwaddr, hwaddr, hw_len);
lease->hwaddr_len = hw_len;
lease->hwaddr_type = hw_type;
lease->old = 1; /* run script on change */
}
/* only update clid when one is available, stops packets
@@ -341,7 +339,7 @@ int lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
if (lease->clid)
free(lease->clid);
if (!(lease->clid = malloc(clid_len)))
return 0;
return;
}
else if (memcmp(lease->clid, clid, clid_len) != 0)
file_dirty = 1;
@@ -349,8 +347,6 @@ int lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
lease->clid_len = clid_len;
memcpy(lease->clid, clid, clid_len);
}
return 1;
}
void lease_set_hostname(struct dhcp_lease *lease, char *name, char *suffix, int auth)
@@ -363,7 +359,7 @@ void lease_set_hostname(struct dhcp_lease *lease, char *name, char *suffix, int
lease->auth_name = auth;
return;
}
if (!name && !lease->hostname)
return;
@@ -379,6 +375,7 @@ void lease_set_hostname(struct dhcp_lease *lease, char *name, char *suffix, int
{
if (lease_tmp->auth_name && !auth)
return;
lease_tmp->old = 1; /* call script on change */
new_name = lease_tmp->hostname;
lease_tmp->hostname = NULL;
if (lease_tmp->fqdn)
@@ -410,8 +407,82 @@ void lease_set_hostname(struct dhcp_lease *lease, char *name, char *suffix, int
lease->auth_name = auth;
file_dirty = 1;
dns_dirty = 1;
dns_dirty = 1;
lease->old = 1; /* run script on change */
}
#ifndef NO_FORK
static pid_t run_script(struct daemon *daemon, char *action, struct dhcp_lease *lease)
{
if (daemon->lease_change_command)
{
char *mac = print_mac(daemon, lease->hwaddr, lease->hwaddr_len);
char *addr = inet_ntoa(lease->addr);
char *com = strrchr(daemon->lease_change_command, '/');
pid_t pid = fork();
if (pid == -1)
return 0; /* fork error */
else if (pid != 0)
return pid;
execl(daemon->lease_change_command,
com ? com+1 : daemon->lease_change_command,
action, mac, addr, lease->hostname, (char*)NULL);
/* log socket should still be open, right? */
syslog(LOG_ERR, _("failed to execute %s: %m"),
daemon->lease_change_command);
_exit(0);
}
return 0;
}
#endif
/* deleted leases get transferred to the old_leases list.
remove them here, after calling the lease change
script. Also run the lease change script on new leases */
void lease_collect(struct daemon *daemon)
{
struct dhcp_lease *lease;
while (old_leases)
{
if (daemon->script_pid != 0)
return; /* busy */
lease = old_leases;
old_leases = lease->next;
#ifndef NO_FORK
daemon->script_pid = run_script(daemon, "del", lease);
#endif
if (lease->hostname)
free(lease->hostname);
if (lease->fqdn)
free(lease->fqdn);
if (lease->clid)
free(lease->clid);
free(lease);
}
for (lease = leases; lease; lease = lease->next)
if (lease->new || lease->old)
{
if (daemon->script_pid != 0)
return; /* busy */
#ifndef NO_FORK
daemon->script_pid = run_script(daemon, lease->new ? "add" : "old", lease);
#endif
lease->new = lease->old = 0;
}
}

View File

@@ -48,8 +48,14 @@ void netlink_init(struct daemon *daemon)
}
if (daemon->netlinkfd == -1)
die(_("cannot create RTnetlink socket: %s"), NULL);
die(_("cannot create netlink socket: %s"), NULL);
else
{
int flags = fcntl(daemon->netlinkfd, F_GETFD);
if (flags != -1)
fcntl(daemon->netlinkfd, F_SETFD, flags | FD_CLOEXEC);
}
iov.iov_len = 200;
iov.iov_base = safe_malloc(iov.iov_len);
}
@@ -114,7 +120,7 @@ int iface_enumerate(struct daemon *daemon, void *parm, int (*ipv4_callback)(), i
again:
req.nlh.nlmsg_len = sizeof(req);
req.nlh.nlmsg_type = RTM_GETADDR;
req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST | NLM_F_ACK;
req.nlh.nlmsg_pid = 0;
req.nlh.nlmsg_seq = ++seq;
req.g.rtgen_family = family;
@@ -215,7 +221,7 @@ static void nl_err(struct nlmsghdr *h)
{
struct nlmsgerr *err = NLMSG_DATA(h);
if (err->error != 0)
syslog(LOG_ERR, _("RTnetlink returns error: %s"), strerror(-(err->error)));
syslog(LOG_ERR, _("netlink returns error: %s"), strerror(-(err->error)));
}
/* We arrange to receive netlink multicast messages whenever the network route is added.
@@ -234,45 +240,6 @@ static void nl_routechange(struct daemon *daemon, struct nlmsghdr *h)
&daemon->srv_save->addr.sa, sa_len(&daemon->srv_save->addr)) == -1 && retry_send());
}
}
void arp_inject(int fd, struct in_addr ip_addr, int iface,
unsigned char *mac, unsigned int mac_len)
{
struct sockaddr_nl addr;
struct {
struct nlmsghdr nlh;
struct ndmsg m;
struct rtattr addr_attr;
struct in_addr addr;
struct rtattr ll_attr;
char mac[DHCP_CHADDR_MAX];
} req;
memset(&req, 0, sizeof(req));
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
req.nlh.nlmsg_len = sizeof(req);
req.nlh.nlmsg_type = RTM_NEWNEIGH;
req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE;
req.m.ndm_family = AF_INET;
req.m.ndm_ifindex = iface;
req.m.ndm_state = NUD_REACHABLE;
req.addr_attr.rta_type = NDA_DST;
req.addr_attr.rta_len = RTA_LENGTH(sizeof(struct in_addr));
req.addr = ip_addr;
req.ll_attr.rta_type = NDA_LLADDR;
req.ll_attr.rta_len = RTA_LENGTH(mac_len);
memcpy(req.mac, mac, mac_len);
while(sendto(fd, (void *)&req, sizeof(req), 0, (struct sockaddr *)&addr, sizeof(addr)) == -1 &&
retry_send());
}
#endif

View File

@@ -141,6 +141,7 @@ static int iface_allowed_v6(struct daemon *daemon, struct in6_addr *local,
netmask.s_addr = 0;
memset(&addr, 0, sizeof(addr));
#ifdef HAVE_SOCKADDR_SA_LEN
addr.in6.sin6_len = sizeof(addr.in6);
#endif
@@ -148,8 +149,7 @@ static int iface_allowed_v6(struct daemon *daemon, struct in6_addr *local,
addr.in6.sin6_addr = *local;
addr.in6.sin6_port = htons(daemon->port);
addr.in6.sin6_scope_id = scope;
addr.in6.sin6_flowinfo = 0;
return iface_allowed(daemon, (struct irec **)vparam, if_index, &addr, netmask);
}
#endif
@@ -158,7 +158,8 @@ static int iface_allowed_v4(struct daemon *daemon, struct in_addr local, int if_
struct in_addr netmask, struct in_addr broadcast, void *vparam)
{
union mysockaddr addr;
memset(&addr, 0, sizeof(addr));
#ifdef HAVE_SOCKADDR_SA_LEN
addr.in.sin_len = sizeof(addr.in);
#endif
@@ -180,19 +181,32 @@ int enumerate_interfaces(struct daemon *daemon)
#endif
}
/* set NONBLOCK and CLOEXEC bits on fd: See Stevens 16.6 */
int fix_fd(int fd)
{
int flags;
if ((flags = fcntl(fd, F_GETFL)) == -1 ||
fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1 ||
(flags = fcntl(fd, F_GETFD)) == -1 ||
fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
return 0;
return 1;
}
#if defined(HAVE_IPV6)
static int create_ipv6_listener(struct listener **link, int port)
{
union mysockaddr addr;
int tcpfd, fd, flags;
int tcpfd, fd;
struct listener *l;
int opt = 1;
memset(&addr, 0, sizeof(addr));
addr.in6.sin6_family = AF_INET6;
addr.in6.sin6_addr = in6addr_any;
addr.in6.sin6_port = htons(port);
addr.in6.sin6_flowinfo = 0;
addr.in6.sin6_scope_id = 0;
#ifdef HAVE_SOCKADDR_SA_LEN
addr.in6.sin6_len = sizeof(addr.in6);
#endif
@@ -210,10 +224,8 @@ static int create_ipv6_listener(struct listener **link, int port)
setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
setsockopt(fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
setsockopt(tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
(flags = fcntl(fd, F_GETFL, 0)) == -1 ||
fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1 ||
(flags = fcntl(tcpfd, F_GETFL, 0)) == -1 ||
fcntl(tcpfd, F_SETFL, flags | O_NONBLOCK) == -1 ||
!fix_fd(fd) ||
!fix_fd(tcpfd) ||
#ifdef IPV6_RECVPKTINFO
setsockopt(fd, IPV6_LEVEL, IPV6_RECVPKTINFO, &opt, sizeof(opt)) == -1 ||
#else
@@ -240,9 +252,9 @@ struct listener *create_wildcard_listeners(int port)
union mysockaddr addr;
int opt = 1;
struct listener *l, *l6 = NULL;
int flags;
int tcpfd, fd;
memset(&addr, 0, sizeof(addr));
addr.in.sin_family = AF_INET;
addr.in.sin_addr.s_addr = INADDR_ANY;
addr.in.sin_port = htons(port);
@@ -257,14 +269,12 @@ struct listener *create_wildcard_listeners(int port)
if (setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
bind(tcpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1 ||
listen(tcpfd, 5) == -1 ||
(flags = fcntl(tcpfd, F_GETFL, 0)) == -1 ||
fcntl(tcpfd, F_SETFL, flags | O_NONBLOCK) == -1 ||
!fix_fd(tcpfd) ||
#ifdef HAVE_IPV6
!create_ipv6_listener(&l6, port) ||
#endif
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
(flags = fcntl(fd, F_GETFL, 0)) == -1 ||
fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1 ||
!fix_fd(fd) ||
#if defined(HAVE_LINUX_NETWORK)
setsockopt(fd, SOL_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1 ||
#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
@@ -288,7 +298,7 @@ struct listener *create_bound_listeners(struct daemon *daemon)
struct listener *listeners = NULL;
struct irec *iface;
int flags, opt = 1;
int opt = 1;
for (iface = daemon->interfaces; iface; iface = iface->next)
{
@@ -300,11 +310,8 @@ struct listener *create_bound_listeners(struct daemon *daemon)
(new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
/* See Stevens 16.6 */
(flags = fcntl(new->tcpfd, F_GETFL, 0)) == -1 ||
fcntl(new->tcpfd, F_SETFL, flags | O_NONBLOCK) == -1 ||
(flags = fcntl(new->fd, F_GETFL, 0)) == -1 ||
fcntl(new->fd, F_SETFL, flags | O_NONBLOCK) == -1)
!fix_fd(new->tcpfd) ||
!fix_fd(new->fd))
die(_("failed to create listening socket: %s"), NULL);
#ifdef HAVE_IPV6
@@ -348,7 +355,6 @@ struct listener *create_bound_listeners(struct daemon *daemon)
struct serverfd *allocate_sfd(union mysockaddr *addr, struct serverfd **sfds)
{
struct serverfd *sfd;
int flags;
/* may have a suitable one already */
for (sfd = *sfds; sfd; sfd = sfd->next )
@@ -367,8 +373,7 @@ struct serverfd *allocate_sfd(union mysockaddr *addr, struct serverfd **sfds)
}
if (bind(sfd->fd, (struct sockaddr *)addr, sa_len(addr)) == -1 ||
(flags = fcntl(sfd->fd, F_GETFL, 0)) == -1 ||
fcntl(sfd->fd, F_SETFL, flags | O_NONBLOCK) == -1)
!fix_fd(sfd->fd))
{
int errsave = errno; /* save error from bind. */
close(sfd->fd);
@@ -390,11 +395,6 @@ void check_servers(struct daemon *daemon)
struct server *new, *tmp, *ret = NULL;
int port = 0;
/* forward table rules reference servers, so have to blow them away */
forward_init(0);
daemon->last_server = daemon->srv_save = NULL;
for (new = daemon->servers; new; new = tmp)
{
tmp = new->next;
@@ -446,25 +446,37 @@ void check_servers(struct daemon *daemon)
daemon->servers = ret;
}
void reload_servers(char *fname, struct daemon *daemon)
/* Return zero if no servers found, in that case we keep polling.
This is a protection against an update-time/write race on resolv.conf */
int reload_servers(char *fname, struct daemon *daemon)
{
FILE *f;
char *line;
struct server *old_servers = NULL;
struct server *new_servers = NULL;
struct server *serv = daemon->servers;
struct server *serv;
int gotone = 0;
/* buff happens to be MAXDNAME long... */
if (!(f = fopen(fname, "r")))
{
syslog(LOG_ERR, _("failed to read %s: %m"), fname);
return 0;
}
/* move old servers to free list - we can reuse the memory
and not risk malloc if there are the same or fewer new servers.
Servers which were specced on the command line go to the new list. */
while (serv)
for (serv = daemon->servers; serv;)
{
struct server *tmp = serv->next;
if (serv->flags & SERV_FROM_RESOLV)
{
serv->next = old_servers;
old_servers = serv;
old_servers = serv;
/* forward table rules reference servers, so have to blow them away */
server_gone(daemon, serv);
}
else
{
@@ -473,82 +485,68 @@ void reload_servers(char *fname, struct daemon *daemon)
}
serv = tmp;
}
/* buff happens to be NAXDNAME long... */
f = fopen(fname, "r");
if (!f)
{
syslog(LOG_ERR, _("failed to read %s: %m"), fname);
}
else
{
syslog(LOG_INFO, _("reading %s"), fname);
while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
{
union mysockaddr addr, source_addr;
char *token = strtok(line, " \t\n\r");
struct server *serv;
if (!token || strcmp(token, "nameserver") != 0)
continue;
if (!(token = strtok(NULL, " \t\n\r")))
continue;
#ifdef HAVE_IPV6
if (inet_pton(AF_INET, token, &addr.in.sin_addr) > 0)
#else
if ((addr.in.sin_addr.s_addr = inet_addr(token)) != (in_addr_t) -1)
#endif
{
#ifdef HAVE_SOCKADDR_SA_LEN
source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
#endif
source_addr.in.sin_family = addr.in.sin_family = AF_INET;
addr.in.sin_port = htons(NAMESERVER_PORT);
source_addr.in.sin_addr.s_addr = INADDR_ANY;
source_addr.in.sin_port = htons(daemon->query_port);
}
#ifdef HAVE_IPV6
else if (inet_pton(AF_INET6, token, &addr.in6.sin6_addr) > 0)
{
#ifdef HAVE_SOCKADDR_SA_LEN
source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
#endif
source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
addr.in6.sin6_port = htons(NAMESERVER_PORT);
source_addr.in6.sin6_flowinfo = addr.in6.sin6_flowinfo = 0;
source_addr.in6.sin6_scope_id = addr.in6.sin6_scope_id = 0;
source_addr.in6.sin6_addr = in6addr_any;
source_addr.in6.sin6_port = htons(daemon->query_port);
}
#endif /* IPV6 */
else
continue;
if (old_servers)
{
serv = old_servers;
old_servers = old_servers->next;
}
else if (!(serv = malloc(sizeof (struct server))))
continue;
/* this list is reverse ordered:
it gets reversed again in check_servers */
serv->next = new_servers;
new_servers = serv;
serv->addr = addr;
serv->source_addr = source_addr;
serv->domain = NULL;
serv->sfd = NULL;
serv->flags = SERV_FROM_RESOLV;
}
fclose(f);
}
while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
{
union mysockaddr addr, source_addr;
char *token = strtok(line, " \t\n\r");
if (!token || strcmp(token, "nameserver") != 0)
continue;
if (!(token = strtok(NULL, " \t\n\r")))
continue;
memset(&addr, 0, sizeof(addr));
memset(&source_addr, 0, sizeof(source_addr));
if ((addr.in.sin_addr.s_addr = inet_addr(token)) != (in_addr_t) -1)
{
#ifdef HAVE_SOCKADDR_SA_LEN
source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
#endif
source_addr.in.sin_family = addr.in.sin_family = AF_INET;
addr.in.sin_port = htons(NAMESERVER_PORT);
source_addr.in.sin_addr.s_addr = INADDR_ANY;
source_addr.in.sin_port = htons(daemon->query_port);
}
#ifdef HAVE_IPV6
else if (inet_pton(AF_INET6, token, &addr.in6.sin6_addr) > 0)
{
#ifdef HAVE_SOCKADDR_SA_LEN
source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
#endif
source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
addr.in6.sin6_port = htons(NAMESERVER_PORT);
source_addr.in6.sin6_addr = in6addr_any;
source_addr.in6.sin6_port = htons(daemon->query_port);
}
#endif /* IPV6 */
else
continue;
if (old_servers)
{
serv = old_servers;
old_servers = old_servers->next;
}
else if (!(serv = malloc(sizeof (struct server))))
continue;
/* this list is reverse ordered:
it gets reversed again in check_servers */
serv->next = new_servers;
new_servers = serv;
serv->addr = addr;
serv->source_addr = source_addr;
serv->domain = NULL;
serv->sfd = NULL;
serv->flags = SERV_FROM_RESOLV;
gotone = 1;
}
/* Free any memory not used. */
while(old_servers)
while (old_servers)
{
struct server *tmp = old_servers->next;
free(old_servers);
@@ -556,6 +554,9 @@ void reload_servers(char *fname, struct daemon *daemon)
}
daemon->servers = new_servers;
fclose(f);
return gotone;
}

File diff suppressed because it is too large Load Diff

View File

@@ -72,7 +72,6 @@ static void bootp_option_put(struct dhcp_packet *mess,
struct dhcp_boot *boot_opts, struct dhcp_netid *netids);
static struct in_addr option_addr(unsigned char *opt);
static unsigned int option_uint(unsigned char *opt, int size);
static char *print_mac(struct daemon *daemon, unsigned char *mac, int len);
static void log_packet(struct daemon *daemon, char *type, struct in_addr *addr,
struct dhcp_packet *mess, char *interface, char *string);
static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize);
@@ -110,9 +109,10 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
unsigned short fuzz = 0;
unsigned int mess_type = 0;
unsigned char fqdn_flags = 0;
subnet_addr.s_addr = 0;
unsigned char *agent_id = NULL;
subnet_addr.s_addr = 0;
if (mess->op != BOOTREQUEST || mess->hlen > DHCP_CHADDR_MAX)
return 0;
@@ -329,7 +329,9 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
mess->yiaddr = lease->addr;
}
if (!message && !lease && (!(lease = lease_allocate(mess->chaddr, NULL, mess->hlen, mess->htype, 0, mess->yiaddr))))
if (!message &&
!lease &&
(!(lease = lease_allocate(mess->yiaddr))))
message = _("no leases left");
if (!message && !(context = narrow_context(context, mess->yiaddr)))
@@ -523,13 +525,12 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
*q++ = c;
}
*q++ = 0; /* add terminator */
message = daemon->dhcp_buff;
}
if (!(opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ)))
return 0;
log_packet(daemon, "DECLINE", option_ptr(opt), mess, iface_name, message);
log_packet(daemon, "DECLINE", option_ptr(opt), mess, iface_name, daemon->dhcp_buff);
if (lease && lease->addr.s_addr == option_addr(opt).s_addr)
lease_prune(lease, now);
@@ -537,8 +538,11 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
if (have_config(config, CONFIG_ADDR) &&
config->addr.s_addr == option_addr(opt).s_addr)
{
syslog(LOG_WARNING, _("disabling DHCP static address %s"), inet_ntoa(config->addr));
config->flags &= ~CONFIG_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);
config->flags |= CONFIG_DECLINED;
config->decline_time = now;
}
else
/* make sure this host gets a different address next time. */
@@ -577,18 +581,22 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
conf.s_addr = 0;
if (have_config(config, CONFIG_ADDR))
{
char *addrs = inet_ntoa(config->addr);
if ((ltmp = lease_find_by_addr(config->addr)) && ltmp != lease)
syslog(LOG_WARNING, _("not using configured address %s because it is leased to %s"),
inet_ntoa(config->addr), print_mac(daemon, ltmp->hwaddr, ltmp->hwaddr_len));
addrs, print_mac(daemon, ltmp->hwaddr, ltmp->hwaddr_len));
else
{
struct dhcp_context *tmp;
for (tmp = context; tmp; tmp = tmp->current)
if (context->local.s_addr == config->addr.s_addr)
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"),
inet_ntoa(config->addr));
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);
else
conf = config->addr;
}
@@ -698,7 +706,7 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
if (have_config(config, CONFIG_ADDR))
for (tmp = context; tmp; tmp = tmp->current)
if (context->local.s_addr == config->addr.s_addr)
if (context->router.s_addr == config->addr.s_addr)
break;
if (!(context = narrow_context(context, mess->yiaddr)))
@@ -719,6 +727,8 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
an endless protocol loop will ensue. */
else if (!tmp &&
have_config(config, CONFIG_ADDR) &&
(!have_config(config, CONFIG_DECLINED) ||
difftime(now, config->decline_time) > (float)DECLINE_BACKOFF) &&
config->addr.s_addr != mess->yiaddr.s_addr &&
(!(ltmp = lease_find_by_addr(config->addr)) || ltmp == lease))
message = _("static lease available");
@@ -730,7 +740,11 @@ size_t dhcp_reply(struct daemon *daemon, struct dhcp_context *context, char *ifa
else if ((ltmp = lease_find_by_addr(mess->yiaddr)) && ltmp != lease)
message = _("address in use");
else if (!lease && !(lease = lease_allocate(mess->chaddr, clid, mess->hlen, mess->htype, clid_len, mess->yiaddr)))
else if (!clid && mess->hlen == 0)
message = _("no unique-id");
else if (!lease &&
!(lease = lease_allocate(mess->yiaddr)))
message = _("no leases left");
}
@@ -855,25 +869,10 @@ static unsigned int calc_time(struct dhcp_context *context, struct dhcp_config *
return time;
}
static char *print_mac(struct daemon *daemon, unsigned char *mac, int len)
{
char *p = daemon->namebuff;
int i;
if (len == 0)
sprintf(p, "<null> ");
else
for (i = 0; i < len; i++)
p += sprintf(p, "%.2x%s", mac[i], (i == len - 1) ? " " : ":");
return daemon->namebuff;
}
static void log_packet(struct daemon *daemon, char *type, struct in_addr *addr,
struct dhcp_packet *mess, char *interface, char *string)
{
syslog(LOG_INFO, "%s%s(%s) %s%s%s%s",
syslog(LOG_INFO, "%s%s(%s) %s%s%s %s",
type ? "DHCP" : "BOOTP",
type ? type : "",
interface,

View File

@@ -396,3 +396,17 @@ int expand_buf(struct iovec *iov, size_t size)
return 1;
}
char *print_mac(struct daemon *daemon, unsigned char *mac, int len)
{
char *p = daemon->namebuff;
int i;
if (len == 0)
sprintf(p, "<null>");
else
for (i = 0; i < len; i++)
p += sprintf(p, "%.2x%s", mac[i], (i == len - 1) ? "" : ":");
return daemon->namebuff;
}