mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-06 15:51:41 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f15b81d61 | ||
|
|
77e94da7bb |
No files matched your search
@@ -1,3 +1,91 @@
|
|||||||
|
version 2.51
|
||||||
|
Add support for internationalised DNS. Non-ASCII characters
|
||||||
|
in domain names found in /etc/hosts, /etc/ethers and
|
||||||
|
/etc/dnsmasq.conf will be correctly handled by translation to
|
||||||
|
punycode, as specified in RFC3490. This function is only
|
||||||
|
available if dnsmasq is compiled with internationalisation
|
||||||
|
support, and adds a dependency on GNU libidn. Without i18n
|
||||||
|
support, dnsmasq continues to be compilable with just
|
||||||
|
standard tools. Thanks to Yves Dorfsman for the
|
||||||
|
suggestion.
|
||||||
|
|
||||||
|
Add two more environment variables for lease-change scripts:
|
||||||
|
First, DNSMASQ_SUPPLIED_HOSTNAME; this is set to the hostname
|
||||||
|
supplied by a client, even if the actual hostname used is
|
||||||
|
over-ridden by dhcp-host or dhcp-ignore-names directives.
|
||||||
|
Also DNSMASQ_RELAY_ADDRESS which gives the address of
|
||||||
|
a DHCP relay, if used.
|
||||||
|
Suggestions from Michael Rack.
|
||||||
|
|
||||||
|
Fix regression which broke echo of relay-agent
|
||||||
|
options. Thanks to Michael Rack for spotting this.
|
||||||
|
|
||||||
|
Don't treat option 67 as being interchangeable with
|
||||||
|
dhcp-boot parameters if it's specified as
|
||||||
|
dhcp-option-force.
|
||||||
|
|
||||||
|
Make the code to call scripts on lease-change compile-time
|
||||||
|
optional. It can be switched off by editing src/config.h
|
||||||
|
or building with "make COPTS=-DNO_SCRIPT".
|
||||||
|
|
||||||
|
Make the TFTP server cope with filenames from Windows/DOS
|
||||||
|
which use '\' as pathname separator. Thanks to Ralf for
|
||||||
|
the patch.
|
||||||
|
|
||||||
|
Updated Polish translation. Thanks to Jan Psota.
|
||||||
|
|
||||||
|
Warn if an IP address is duplicated in /etc/ethers. Thanks
|
||||||
|
to Felix Schwarz for pointing this out.
|
||||||
|
|
||||||
|
Teach --conf-dir to take an option list of file suffices
|
||||||
|
which will be ignored when scanning the directory. Useful
|
||||||
|
for backup files etc. Thanks to Helmut Hullen for the
|
||||||
|
suggestion.
|
||||||
|
|
||||||
|
Add new DHCP option named tftpserver-address, which
|
||||||
|
corresponds to the third argument of dhcp-boot. This
|
||||||
|
allows the complete functionality of dhcp-boot to be
|
||||||
|
replicated with dhcp-option. Useful when using
|
||||||
|
dhcp-optsfile.
|
||||||
|
|
||||||
|
Test which upstream nameserver to use every 10 seconds
|
||||||
|
or 50 queries and not just when a query times out and
|
||||||
|
is retried. This should improve performance when there
|
||||||
|
is a slow nameserver in the list. Thanks to Joe for the
|
||||||
|
suggestion.
|
||||||
|
|
||||||
|
Don't do any PXE processing, even for clients with the
|
||||||
|
correct vendorclass, unless at least one pxe-prompt or
|
||||||
|
pxe-service option is given. This stops dnsmasq
|
||||||
|
interfering with proxy PXE subsystems when it is just
|
||||||
|
the DHCP server. Thanks to Spencer Clark for spotting this.
|
||||||
|
|
||||||
|
Limit the blocksize used for TFTP transfers to a value
|
||||||
|
which avoids packet fragmentation, based on the MTU of the
|
||||||
|
local interface. Many netboot ROMs can't cope with
|
||||||
|
fragmented packets.
|
||||||
|
|
||||||
|
Honour dhcp-ignore configuration for PXE and proxy-PXE
|
||||||
|
requests. Thanks to Niels Basjes for the bug report.
|
||||||
|
|
||||||
|
Updated French translation. Thanks to Gildas Le Nadan.
|
||||||
|
|
||||||
|
|
||||||
|
version 2.50
|
||||||
|
Fix security problem which allowed any host permitted to
|
||||||
|
do TFTP to possibly compromise dnsmasq by remote buffer
|
||||||
|
overflow when TFTP enabled. Thanks to Core Security
|
||||||
|
Technologies and Iván Arce, Pablo Hernán Jorge, Alejandro
|
||||||
|
Pablo Rodriguez, Martín Coco, Alberto Soliño Testa and
|
||||||
|
Pablo Annetta. This problem has Bugtraq id: 36121
|
||||||
|
and CVE: 2009-2957
|
||||||
|
|
||||||
|
Fix a problem which allowed a malicious TFTP client to
|
||||||
|
crash dnsmasq. Thanks to Steve Grubb at Red Hat for
|
||||||
|
spotting this. This problem has Bugtraq id: 36120 and
|
||||||
|
CVE: 2009-2958
|
||||||
|
|
||||||
|
|
||||||
version 2.49
|
version 2.49
|
||||||
Fix regression in 2.48 which disables the lease-change
|
Fix regression in 2.48 which disables the lease-change
|
||||||
script. Thanks to Jose Luis Duran for spotting this.
|
script. Thanks to Jose Luis Duran for spotting this.
|
||||||
@@ -343,3 +431,8 @@ version 2.43
|
|||||||
ports. Thanks to Patrick McLean for spotting this.
|
ports. Thanks to Patrick McLean for spotting this.
|
||||||
|
|
||||||
Updated French translation. Thanks to Gildas Le Nadan.
|
Updated French translation. Thanks to Gildas Le Nadan.
|
||||||
|
|
||||||
|
|
||||||
|
version 2.42
|
||||||
|
The changelog for version 2.42 and earlier is
|
||||||
|
available in CHANGELOG.archive.
|
||||||
@@ -24,18 +24,22 @@ MAN = man
|
|||||||
|
|
||||||
PKG_CONFIG = pkg-config
|
PKG_CONFIG = pkg-config
|
||||||
INSTALL = install
|
INSTALL = install
|
||||||
|
MSGMERGE = msgmerge
|
||||||
|
MSGFMT = msgfmt
|
||||||
|
XGETTEXT = xgettext
|
||||||
|
|
||||||
DBUS_CFLAGS="`echo $(COPTS) | ../bld/pkg-wrapper $(PKG_CONFIG) --cflags dbus-1`"
|
#################################################################
|
||||||
DBUS_LIBS=" `echo $(COPTS) | ../bld/pkg-wrapper $(PKG_CONFIG) --libs dbus-1`"
|
|
||||||
SUNOS_LIBS=" `if uname | grep SunOS 2>&1 >/dev/null; then echo -lsocket -lnsl -lposix4; fi `"
|
DNSMASQ_CFLAGS=`echo $(COPTS) | ../bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG) --cflags dbus-1`
|
||||||
|
DNSMASQ_LIBS= `echo $(COPTS) | ../bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG) --libs dbus-1`
|
||||||
|
SUNOS_LIBS= `if uname | grep SunOS 2>&1 >/dev/null; then echo -lsocket -lnsl -lposix4; fi`
|
||||||
|
|
||||||
all : dnsmasq
|
all : dnsmasq
|
||||||
|
|
||||||
dnsmasq :
|
dnsmasq :
|
||||||
cd $(SRC) && $(MAKE) \
|
@cd $(SRC) && $(MAKE) \
|
||||||
DBUS_CFLAGS=$(DBUS_CFLAGS) \
|
DNSMASQ_CFLAGS="$(DNSMASQ_CFLAGS)" \
|
||||||
DBUS_LIBS=$(DBUS_LIBS) \
|
DNSMASQ_LIBS="$(DNSMASQ_LIBS) $(SUNOS_LIBS)" \
|
||||||
SUNOS_LIBS=$(SUNOS_LIBS) \
|
|
||||||
-f ../bld/Makefile dnsmasq
|
-f ../bld/Makefile dnsmasq
|
||||||
|
|
||||||
clean :
|
clean :
|
||||||
@@ -50,24 +54,25 @@ install-common :
|
|||||||
$(INSTALL) -m 755 $(SRC)/dnsmasq $(DESTDIR)$(BINDIR)
|
$(INSTALL) -m 755 $(SRC)/dnsmasq $(DESTDIR)$(BINDIR)
|
||||||
|
|
||||||
all-i18n :
|
all-i18n :
|
||||||
cd $(SRC) && $(MAKE) \
|
@cd $(SRC) && $(MAKE) \
|
||||||
I18N=-DLOCALEDIR='\"$(LOCALEDIR)\"' \
|
I18N=-DLOCALEDIR='\"$(LOCALEDIR)\"' \
|
||||||
DBUS_CFLAGS=$(DBUS_CFLAGS) \
|
DNSMASQ_CFLAGS="$(DNSMASQ_CFLAGS) `$(PKG_CONFIG) --cflags libidn`" \
|
||||||
DBUS_LIBS=$(DBUS_LIBS) \
|
DNSMASQ_LIBS="$(DNSMASQ_LIBS) $(SUNOS_LIBS) `$(PKG_CONFIG) --libs libidn`" \
|
||||||
SUNOS_LIBS=$(SUNOS_LIBS) \
|
|
||||||
-f ../bld/Makefile dnsmasq
|
-f ../bld/Makefile dnsmasq
|
||||||
cd $(PO); for f in *.po; do \
|
@cd $(PO); for f in *.po; do \
|
||||||
cd ../$(SRC) && $(MAKE) -f ../bld/Makefile $${f%.po}.mo; \
|
cd ../$(SRC) && $(MAKE) \
|
||||||
|
MSGMERGE=$(MSGMERGE) MSGFMT=$(MSGFMT) XGETTEXT=$(XGETTEXT) \
|
||||||
|
-f ../bld/Makefile $${f%.po}.mo; \
|
||||||
done
|
done
|
||||||
|
|
||||||
install-i18n : all-i18n install-common
|
install-i18n : all-i18n install-common
|
||||||
cd $(SRC); ../bld/install-mo $(DESTDIR)$(LOCALEDIR)
|
cd $(SRC); ../bld/install-mo $(DESTDIR)$(LOCALEDIR) $(INSTALL)
|
||||||
cd $(MAN); ../bld/install-man $(DESTDIR)$(MANDIR)
|
cd $(MAN); ../bld/install-man $(DESTDIR)$(MANDIR) $(INSTALL)
|
||||||
|
|
||||||
merge :
|
merge :
|
||||||
$(MAKE) I18N=-DLOCALEDIR='\"$(LOCALEDIR)\"' -f ../bld/Makefile -C $(SRC) dnsmasq.pot
|
@cd $(SRC) && $(MAKE) XGETTEXT=$(XGETTEXT) -f ../bld/Makefile dnsmasq.pot
|
||||||
cd $(PO); for f in *.po; do \
|
@cd $(PO); for f in *.po; do \
|
||||||
msgmerge --no-wrap -U $$f ../$(SRC)/dnsmasq.pot; \
|
echo -n msgmerge $$f && $(MSGMERGE) --no-wrap -U $$f ../$(SRC)/dnsmasq.pot; \
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
+4
-4
@@ -5,13 +5,13 @@ OBJS = cache.o rfc1035.o util.o option.o forward.o network.o \
|
|||||||
helper.o tftp.o log.o
|
helper.o tftp.o log.o
|
||||||
|
|
||||||
.c.o:
|
.c.o:
|
||||||
$(CC) $(CFLAGS) $(COPTS) $(DBUS_MINOR) $(I18N) $(DBUS_CFLAGS) $(SUNOS_VER) $(RPM_OPT_FLAGS) -c $<
|
$(CC) $(CFLAGS) $(COPTS) $(I18N) $(DNSMASQ_CFLAGS) $(RPM_OPT_FLAGS) -c $<
|
||||||
|
|
||||||
dnsmasq : $(OBJS)
|
dnsmasq : $(OBJS)
|
||||||
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(DBUS_LIBS) $(SUNOS_LIBS) $(LIBS)
|
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(DNSMASQ_LIBS) $(LIBS)
|
||||||
|
|
||||||
dnsmasq.pot : $(OBJS:.o=.c) dnsmasq.h config.h
|
dnsmasq.pot : $(OBJS:.o=.c) dnsmasq.h config.h
|
||||||
xgettext -d dnsmasq --foreign-user --keyword=_ -o dnsmasq.pot -i $(OBJS:.o=.c)
|
$(XGETTEXT) -d dnsmasq --foreign-user --omit-header --keyword=_ -o $@ -i $(OBJS:.o=.c)
|
||||||
|
|
||||||
%.mo : ../po/%.po dnsmasq.pot
|
%.mo : ../po/%.po dnsmasq.pot
|
||||||
msgmerge -o - ../po/$*.po dnsmasq.pot | msgfmt -o $*.mo -
|
$(MSGMERGE) -o - ../po/$*.po dnsmasq.pot | $(MSGFMT) -o $*.mo -
|
||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
for f in *; do
|
for f in *; do
|
||||||
if [ -d $f ]; then
|
if [ -d $f ]; then
|
||||||
install -m 755 -d $1/$f/man8
|
$2 -m 755 -d $1/$f/man8
|
||||||
install -m 644 $f/dnsmasq.8 $1/$f/man8
|
$2 -m 644 $f/dnsmasq.8 $1/$f/man8
|
||||||
echo installing $1/$f/man8/dnsmasq.8
|
echo installing $1/$f/man8/dnsmasq.8
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
for f in *.mo; do
|
for f in *.mo; do
|
||||||
install -m 755 -d $1/${f%.mo}/LC_MESSAGES
|
$2 -m 755 -d $1/${f%.mo}/LC_MESSAGES
|
||||||
install -m 644 $f $1/${f%.mo}/LC_MESSAGES/dnsmasq.mo
|
$2 -m 644 $f $1/${f%.mo}/LC_MESSAGES/dnsmasq.mo
|
||||||
echo installing $1/${f%.mo}/LC_MESSAGES/dnsmasq.mo
|
echo installing $1/${f%.mo}/LC_MESSAGES/dnsmasq.mo
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|||||||
+5
-2
@@ -1,7 +1,10 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
if grep "^\#.*define.*HAVE_DBUS" config.h 2>&1 >/dev/null || \
|
search=$1
|
||||||
grep HAVE_DBUS 2>&1 >/dev/null ; then
|
shift
|
||||||
|
|
||||||
|
if grep "^\#.*define.*$search" config.h 2>&1 >/dev/null || \
|
||||||
|
grep $search 2>&1 >/dev/null ; then
|
||||||
exec $*
|
exec $*
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -396,6 +396,11 @@
|
|||||||
# the user dnsmasq is running as will be send over the net.
|
# the user dnsmasq is running as will be send over the net.
|
||||||
#tftp-secure
|
#tftp-secure
|
||||||
|
|
||||||
|
# This option stops dnsmasq from negotiating a larger blocksize for TFTP
|
||||||
|
# transfers. It will slow things down, but may rescue some broken TFTP
|
||||||
|
# clients.
|
||||||
|
#tftp-no-blocksize
|
||||||
|
|
||||||
# Set the boot file name only when the "red" tag is set.
|
# Set the boot file name only when the "red" tag is set.
|
||||||
#dhcp-boot=net:red,pxelinux.red-net
|
#dhcp-boot=net:red,pxelinux.red-net
|
||||||
|
|
||||||
|
|||||||
+35
-8
@@ -45,7 +45,8 @@ additional hosts file. If a directory is given, then read all the files containe
|
|||||||
.TP
|
.TP
|
||||||
.B \-E, --expand-hosts
|
.B \-E, --expand-hosts
|
||||||
Add the domain to simple names (without a period) in /etc/hosts
|
Add the domain to simple names (without a period) in /etc/hosts
|
||||||
in the same way as for DHCP-derived names.
|
in the same way as for DHCP-derived names. Note that this does not
|
||||||
|
apply to domain names in cnames, PTR records, TXT records etc.
|
||||||
.TP
|
.TP
|
||||||
.B \-T, --local-ttl=<time>
|
.B \-T, --local-ttl=<time>
|
||||||
When replying with information from /etc/hosts or the DHCP leases
|
When replying with information from /etc/hosts or the DHCP leases
|
||||||
@@ -547,7 +548,12 @@ the file will be re-read when dnsmasq receives SIGHUP.
|
|||||||
.B --dhcp-optsfile=<file>
|
.B --dhcp-optsfile=<file>
|
||||||
Read DHCP option information from the specified file. The advantage of
|
Read DHCP option information from the specified file. The advantage of
|
||||||
using this option is the same as for --dhcp-hostsfile: the
|
using this option is the same as for --dhcp-hostsfile: the
|
||||||
dhcp-optsfile will be re-read when dnsmasq receives SIGHUP.
|
dhcp-optsfile will be re-read when dnsmasq receives SIGHUP. Note that
|
||||||
|
it is possible to encode the information in a
|
||||||
|
.B --dhcp-boot
|
||||||
|
flag as DHCP options, using the options names bootfile-name,
|
||||||
|
server-ip-address and tftp-server. This allows these to be included
|
||||||
|
in a dhcp-optsfile.
|
||||||
.TP
|
.TP
|
||||||
.B \-Z, --read-ethers
|
.B \-Z, --read-ethers
|
||||||
Read /etc/ethers for information about hosts for the DHCP server. The
|
Read /etc/ethers for information about hosts for the DHCP server. The
|
||||||
@@ -842,8 +848,9 @@ The environment is inherited from the invoker of dnsmasq, and if the
|
|||||||
host provided a client-id, this is stored in the environment variable
|
host provided a client-id, this is stored in the environment variable
|
||||||
DNSMASQ_CLIENT_ID. If the fully-qualified domain name of the host is
|
DNSMASQ_CLIENT_ID. If the fully-qualified domain name of the host is
|
||||||
known, the domain part is stored in DNSMASQ_DOMAIN.
|
known, the domain part is stored in DNSMASQ_DOMAIN.
|
||||||
If the client provides vendor-class or user-class
|
If the client provides vendor-class, hostname or user-class,
|
||||||
information, these are provided in DNSMASQ_VENDOR_CLASS and
|
these are provided in DNSMASQ_VENDOR_CLASS
|
||||||
|
DNSMASQ_SUPPLIED_HOSTNAME and
|
||||||
DNSMASQ_USER_CLASS0..DNSMASQ_USER_CLASSn variables, but only for
|
DNSMASQ_USER_CLASS0..DNSMASQ_USER_CLASSn variables, but only for
|
||||||
"add" actions or "old" actions when a host resumes an existing lease,
|
"add" actions or "old" actions when a host resumes an existing lease,
|
||||||
since these data are not held in dnsmasq's lease
|
since these data are not held in dnsmasq's lease
|
||||||
@@ -857,7 +864,8 @@ removed, an "old" event is generated with the new state of the lease,
|
|||||||
ie no name, and the former name is provided in the environment
|
ie no name, and the former name is provided in the environment
|
||||||
variable DNSMASQ_OLD_HOSTNAME. DNSMASQ_INTERFACE stores the name of
|
variable DNSMASQ_OLD_HOSTNAME. DNSMASQ_INTERFACE stores the name of
|
||||||
the interface on which the request arrived; this is not set for "old"
|
the interface on which the request arrived; this is not set for "old"
|
||||||
actions when dnsmasq restarts.
|
actions when dnsmasq restarts. DNSMASQ_RELAY_ADDRESS is set if the client
|
||||||
|
used a DHCP relay to contact dnsmasq and the IP address of the relay is known.
|
||||||
All file descriptors are
|
All file descriptors are
|
||||||
closed except stdin, stdout and stderr which are open to /dev/null
|
closed except stdin, stdout and stderr which are open to /dev/null
|
||||||
(except in debug mode).
|
(except in debug mode).
|
||||||
@@ -995,10 +1003,11 @@ of concurrent TFTP connections is limited by the size of the port range.
|
|||||||
Specify a different configuration file. The conf-file option is also allowed in
|
Specify a different configuration file. The conf-file option is also allowed in
|
||||||
configuration files, to include multiple configuration files.
|
configuration files, to include multiple configuration files.
|
||||||
.TP
|
.TP
|
||||||
.B \-7, --conf-dir=<directory>
|
.B \-7, --conf-dir=<directory>[,<file-extension>......]
|
||||||
Read all the files in the given directory as configuration
|
Read all the files in the given directory as configuration
|
||||||
files. Files whose names end in ~ or start with . or start and end
|
files. If extension(s) are given, any files which end in those
|
||||||
with # are skipped. This flag may be given on the command
|
extensions are skipped. Any files whose names end in ~ or start with . or start and end
|
||||||
|
with # are always skipped. This flag may be given on the command
|
||||||
line or in a configuration file.
|
line or in a configuration file.
|
||||||
.SH CONFIG FILE
|
.SH CONFIG FILE
|
||||||
At startup, dnsmasq reads
|
At startup, dnsmasq reads
|
||||||
@@ -1238,6 +1247,24 @@ or an additional hosts file. The list can be very long,
|
|||||||
dnsmasq has been tested successfully with one million names. That size
|
dnsmasq has been tested successfully with one million names. That size
|
||||||
file needs a 1GHz processor and about 60Mb of RAM.
|
file needs a 1GHz processor and about 60Mb of RAM.
|
||||||
|
|
||||||
|
.SH INTERNATIONALISATION
|
||||||
|
Dnsmasq can be compiled to support internationalisation. To do this,
|
||||||
|
the make targets "all-i18n" and "install-i18n" should be used instead of
|
||||||
|
the standard targets "all" and "install". When internationalisation
|
||||||
|
is compiled in, dnsmasq will produce log messages in the local
|
||||||
|
language and support internationalised domain names (IDN). Domain
|
||||||
|
names in /etc/hosts, /etc/ethers and /etc/dnsmasq.conf which contain
|
||||||
|
non-ASCII characters will be translated to the DNS-internal punycode
|
||||||
|
representation. Note that
|
||||||
|
dnsmasq determines both the language for messages and the assumed
|
||||||
|
charset for configuration
|
||||||
|
files from the LANG environment variable. This should be set to the system
|
||||||
|
default value by the script which is responsible for starting
|
||||||
|
dnsmasq. When editing the configuration files, be careful to do so
|
||||||
|
using only the system-default locale and not user-specific one, since
|
||||||
|
dnsmasq has no direct way of determining the charset in use, and must
|
||||||
|
assume that it is the system default.
|
||||||
|
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.IR /etc/dnsmasq.conf
|
.IR /etc/dnsmasq.conf
|
||||||
|
|
||||||
|
|||||||
+31
-21
@@ -51,7 +51,8 @@ fichiers contenus dans ce répertoire.
|
|||||||
.B \-E, --expand-hosts
|
.B \-E, --expand-hosts
|
||||||
Ajoute le nom de domaine aux noms simples (ne contenant pas de point dans le
|
Ajoute le nom de domaine aux noms simples (ne contenant pas de point dans le
|
||||||
nom) contenus dans le fichier /etc/hosts, de la même façon que pour le service
|
nom) contenus dans le fichier /etc/hosts, de la même façon que pour le service
|
||||||
DHCP.
|
DHCP. Notez que cela ne s'applique pas au nom de domaine dans les CNAME, les
|
||||||
|
enregistrements PTR, TXT, etc...
|
||||||
.TP
|
.TP
|
||||||
.B \-T, --local-ttl=<durée>
|
.B \-T, --local-ttl=<durée>
|
||||||
Lorsque Dnsmasq répond avec une information provenant du fichier /etc/hosts ou
|
Lorsque Dnsmasq répond avec une information provenant du fichier /etc/hosts ou
|
||||||
@@ -634,7 +635,11 @@ relu lorsque Dnsmasq reçoit un signal SIGHUP.
|
|||||||
.B --dhcp-optsfile=<fichier>
|
.B --dhcp-optsfile=<fichier>
|
||||||
Lis les informations relatives aux options DHCP dans le fichier spécifié.
|
Lis les informations relatives aux options DHCP dans le fichier spécifié.
|
||||||
L'intérêt d'utiliser cette option est le même que pour --dhcp-hostsfile : le
|
L'intérêt d'utiliser cette option est le même que pour --dhcp-hostsfile : le
|
||||||
fichier spécifié ser rechargé à la réception par dnsmasq d'un signal SIGHUP.
|
fichier spécifié sera rechargé à la réception par dnsmasq d'un signal SIGHUP.
|
||||||
|
Notez qu'il est possible d'encoder l'information via
|
||||||
|
.B --dhcp-boot
|
||||||
|
en utilisant les noms optionnels bootfile-name, server-ip-address et
|
||||||
|
tftp-server. Ceci permet d'inclure ces options dans un fichier "dhcp-optsfile".DNSMASQ_SUPPLIED_HOSTNAME
|
||||||
.TP
|
.TP
|
||||||
.B \-Z, --read-ethers
|
.B \-Z, --read-ethers
|
||||||
Lis les informations d'hôtes DHCP dans le fichier /etc/ethers. Le format de
|
Lis les informations d'hôtes DHCP dans le fichier /etc/ethers. Le format de
|
||||||
@@ -961,22 +966,25 @@ L'environnement est hérité de celui de l'invocation du processus Dnsmasq, et
|
|||||||
si l'hôte fournit un identifiant de client, celui-ci est stocké dans la
|
si l'hôte fournit un identifiant de client, celui-ci est stocké dans la
|
||||||
variable d'environnement DNSMASQ_CLIENT_ID. Si un nom de domaine pleinement
|
variable d'environnement DNSMASQ_CLIENT_ID. Si un nom de domaine pleinement
|
||||||
qualifié (FQDN) est connu pour l'hôte, la part relative au domaine est stockée
|
qualifié (FQDN) est connu pour l'hôte, la part relative au domaine est stockée
|
||||||
dans DNSMASQ_DOMAIN. Si le client fournit une information de classe de vendeur
|
dans DNSMASQ_DOMAIN. Si le client fournit une information de classe de vendeur,
|
||||||
ou de classe d'utilisateur, celles-ci sont positionnées dans les variables
|
de classe d'utilisateur ou un nom d'hôte, celles-ci sont positionnées dans les
|
||||||
DNSMASQ_VENDOR_CLASS et DNSMASQ_USER_CLASS0 à DNSMASQ_USER_CLASSn
|
variables DNSMASQ_VENDOR_CLASS et DNSMASQ_USER_CLASS0 à DNSMASQ_USER_CLASSn
|
||||||
respectivement, mais seulement pour les actions "add" et "old" lorsqu'un hôte
|
et DNSMASQ_SUPPLIED_HOSTNAME respectivement, mais seulement pour les actions
|
||||||
reprend un bail existant, ces variables n'étant pas stockées dans la base de
|
"add" et "old" lorsqu'un hôte reprend un bail existant, ces variables n'étant
|
||||||
baux de Dnsmasq. Si Dnsmasq a été compilé avec l'option HAVE_BROKEN_RTC
|
pas stockées dans la base de baux de Dnsmasq. Si Dnsmasq a été compilé avec
|
||||||
("horloge RTC défectueuse"), alors la durée du bail (en secondes) est stockée
|
l'option HAVE_BROKEN_RTC ("horloge RTC défectueuse"), alors la durée du bail
|
||||||
dans la variable DNSMASQ_LEASE_LENGTH, sinon la date d'expiration du bail est
|
(en secondes) est stockée dans la variable DNSMASQ_LEASE_LENGTH, sinon la date
|
||||||
toujours stocké dans la variable d'environnement DNSMASQ_LEASE_EXPIRES. Le
|
d'expiration du bail est toujours stocké dans la variable d'environnement
|
||||||
nombre de secondes avant expiration est toujours stocké dans
|
DNSMASQ_LEASE_EXPIRES. Le nombre de secondes avant expiration est toujours
|
||||||
DNSMASQ_TIME_REMAINING. Si un bail était associé à un nom d'hôte et que celui-ci
|
stocké dans DNSMASQ_TIME_REMAINING. Si un bail était associé à un nom d'hôte et
|
||||||
est supprimé, un évênement de type "old" est généré avec le nouveau statut du
|
que celui-ci est supprimé, un évênement de type "old" est généré avec le
|
||||||
bail, c-à-d sans nom d'hôte, et le nom initial est fourni dans la variable
|
nouveau statut du bail, c-à-d sans nom d'hôte, et le nom initial est fourni
|
||||||
d'environnement DNSMASQ_OLD_HOSTNAME. La variable DNSMASQ_INTERFACE contient le nom de
|
dans la variable d'environnement DNSMASQ_OLD_HOSTNAME. La variable
|
||||||
l'interface sur laquelle la requête est arrivée; ceci n'est pas renseigné
|
DNSMASQ_INTERFACE contient le nom de l'interface sur laquelle la requête est
|
||||||
dans le cas des actions "old" ayant lieu après un redémarrage de dnsmasq.
|
arrivée; ceci n'est pas renseigné dans le cas des actions "old" ayant lieu
|
||||||
|
après un redémarrage de dnsmasq. La variable DNSMASQ_RELAY_ADDRESS est
|
||||||
|
renseignée si le client a utilisé un relai DHCP pour contacter Dnsmasq, si
|
||||||
|
l'adresse IP du relai est connue.
|
||||||
Tous les descripteurs de fichiers sont fermés, sauf stdin, stdout et stderr qui
|
Tous les descripteurs de fichiers sont fermés, sauf stdin, stdout et stderr qui
|
||||||
sont ouverts sur /dev/null (sauf en mode déverminage).
|
sont ouverts sur /dev/null (sauf en mode déverminage).
|
||||||
Le script n'est pas lancé de manière concurrente : si un autre changement de
|
Le script n'est pas lancé de manière concurrente : si un autre changement de
|
||||||
@@ -1152,10 +1160,12 @@ Spécifie un fichier de configuration différent. L'option "conf-file" est
|
|||||||
également autorisée dans des fichiers de configuration, ce qui permet
|
également autorisée dans des fichiers de configuration, ce qui permet
|
||||||
l'inclusion de multiples fichiers de configuration.
|
l'inclusion de multiples fichiers de configuration.
|
||||||
.TP
|
.TP
|
||||||
.B \-7, --conf-dir=<répertoire>
|
.B \-7, --conf-dir=<répertoire>[,<extension de fichier>...]
|
||||||
Lis tous les fichiers du répertoire spécifié et les traite comme des fichiers de
|
Lis tous les fichiers du répertoire spécifié et les traite comme des fichiers de
|
||||||
configuration. Les fichiers dont les noms se terminent en ~ ou commençant par .,
|
configuration. Si des extensions sont données, tout fichier finissant par ces
|
||||||
ainsi que ceux commençant ou se terminant par # ne sont pas pris en compte.
|
extensions seront ignorés. Tout fichier dont le nom se termine en ~ ou commence
|
||||||
|
par ., ainsi que ceux commençant ou se terminant par # seront systématiquement
|
||||||
|
ignorés.
|
||||||
Cette option peut être donnée en ligne de commande ou dans un fichier de
|
Cette option peut être donnée en ligne de commande ou dans un fichier de
|
||||||
configuration.
|
configuration.
|
||||||
.SH FICHIER DE CONFIGURATION
|
.SH FICHIER DE CONFIGURATION
|
||||||
|
|||||||
+204
-187
File diff suppressed because it is too large.
Load diff
+19
-16
@@ -226,7 +226,7 @@ char *cache_get_name(struct crec *crecp)
|
|||||||
{
|
{
|
||||||
if (crecp->flags & F_BIGNAME)
|
if (crecp->flags & F_BIGNAME)
|
||||||
return crecp->name.bname->name;
|
return crecp->name.bname->name;
|
||||||
else if (crecp->flags & F_DHCP)
|
else if (crecp->flags & (F_DHCP | F_CONFIG))
|
||||||
return crecp->name.namep;
|
return crecp->name.namep;
|
||||||
|
|
||||||
return crecp->name.sname;
|
return crecp->name.sname;
|
||||||
@@ -366,7 +366,7 @@ struct crec *cache_insert(char *name, struct all_addr *addr,
|
|||||||
|
|
||||||
log_query(flags | F_UPSTREAM, name, addr, NULL);
|
log_query(flags | F_UPSTREAM, name, addr, NULL);
|
||||||
|
|
||||||
/* CONFIG bit no needed except for logging */
|
/* CONFIG bit means something else when stored in cache entries */
|
||||||
flags &= ~F_CONFIG;
|
flags &= ~F_CONFIG;
|
||||||
|
|
||||||
/* if previous insertion failed give up now. */
|
/* if previous insertion failed give up now. */
|
||||||
@@ -693,10 +693,10 @@ static void add_hosts_entry(struct crec *cache, struct all_addr *addr, int addrl
|
|||||||
if (!nameexists)
|
if (!nameexists)
|
||||||
for (a = daemon->cnames; a; a = a->next)
|
for (a = daemon->cnames; a; a = a->next)
|
||||||
if (hostname_isequal(cache->name.sname, a->target) &&
|
if (hostname_isequal(cache->name.sname, a->target) &&
|
||||||
(lookup = whine_malloc(sizeof(struct crec) + strlen(a->alias)+1-SMALLDNAME)))
|
(lookup = whine_malloc(sizeof(struct crec))))
|
||||||
{
|
{
|
||||||
lookup->flags = F_FORWARD | F_IMMORTAL | F_HOSTS | F_CNAME;
|
lookup->flags = F_FORWARD | F_IMMORTAL | F_CONFIG | F_HOSTS | F_CNAME;
|
||||||
strcpy(lookup->name.sname, a->alias);
|
lookup->name.namep = a->alias;
|
||||||
lookup->addr.cname.cache = cache;
|
lookup->addr.cname.cache = cache;
|
||||||
lookup->addr.cname.uid = index;
|
lookup->addr.cname.uid = index;
|
||||||
cache_hash(lookup);
|
cache_hash(lookup);
|
||||||
@@ -821,35 +821,38 @@ static int read_hostsfile(char *filename, int index, int cache_size)
|
|||||||
while (atnl == 0)
|
while (atnl == 0)
|
||||||
{
|
{
|
||||||
struct crec *cache;
|
struct crec *cache;
|
||||||
int fqdn;
|
int fqdn, nomem;
|
||||||
|
char *canon;
|
||||||
|
|
||||||
if ((atnl = gettok(f, token)) == EOF)
|
if ((atnl = gettok(f, token)) == EOF)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
fqdn = !!strchr(token, '.');
|
fqdn = !!strchr(token, '.');
|
||||||
|
|
||||||
if (canonicalise(token))
|
if ((canon = canonicalise(token, &nomem)))
|
||||||
{
|
{
|
||||||
/* If set, add a version of the name with a default domain appended */
|
/* If set, add a version of the name with a default domain appended */
|
||||||
if ((daemon->options & OPT_EXPAND) && domain_suffix && !fqdn &&
|
if ((daemon->options & OPT_EXPAND) && domain_suffix && !fqdn &&
|
||||||
(cache = whine_malloc(sizeof(struct crec) +
|
(cache = whine_malloc(sizeof(struct crec) +
|
||||||
strlen(token)+2+strlen(domain_suffix)-SMALLDNAME)))
|
strlen(canon)+2+strlen(domain_suffix)-SMALLDNAME)))
|
||||||
{
|
{
|
||||||
strcpy(cache->name.sname, token);
|
strcpy(cache->name.sname, canon);
|
||||||
strcat(cache->name.sname, ".");
|
strcat(cache->name.sname, ".");
|
||||||
strcat(cache->name.sname, domain_suffix);
|
strcat(cache->name.sname, domain_suffix);
|
||||||
add_hosts_entry(cache, &addr, addrlen, flags, index, addr_dup);
|
add_hosts_entry(cache, &addr, addrlen, flags, index, addr_dup);
|
||||||
addr_dup = 1;
|
addr_dup = 1;
|
||||||
name_count++;
|
name_count++;
|
||||||
}
|
}
|
||||||
if ((cache = whine_malloc(sizeof(struct crec) + strlen(token)+1-SMALLDNAME)))
|
if ((cache = whine_malloc(sizeof(struct crec) + strlen(canon)+1-SMALLDNAME)))
|
||||||
{
|
{
|
||||||
strcpy(cache->name.sname, token);
|
strcpy(cache->name.sname, canon);
|
||||||
add_hosts_entry(cache, &addr, addrlen, flags, index, addr_dup);
|
add_hosts_entry(cache, &addr, addrlen, flags, index, addr_dup);
|
||||||
name_count++;
|
name_count++;
|
||||||
}
|
}
|
||||||
|
free(canon);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else if (!nomem)
|
||||||
my_syslog(LOG_ERR, _("bad name at %s line %d"), filename, lineno);
|
my_syslog(LOG_ERR, _("bad name at %s line %d"), filename, lineno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1103,7 +1106,7 @@ void cache_add_dhcp_entry(char *host_name,
|
|||||||
|
|
||||||
if (aliasc)
|
if (aliasc)
|
||||||
{
|
{
|
||||||
aliasc->flags = F_FORWARD | F_DHCP | F_CNAME;
|
aliasc->flags = F_FORWARD | F_CONFIG | F_DHCP | F_CNAME;
|
||||||
if (ttd == 0)
|
if (ttd == 0)
|
||||||
aliasc->flags |= F_IMMORTAL;
|
aliasc->flags |= F_IMMORTAL;
|
||||||
else
|
else
|
||||||
@@ -1285,12 +1288,12 @@ void log_query(unsigned short flags, char *name, struct all_addr *addr, char *ar
|
|||||||
dest = "<CNAME>";
|
dest = "<CNAME>";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & F_DHCP)
|
if (flags & F_CONFIG)
|
||||||
|
source = "config";
|
||||||
|
else if (flags & F_DHCP)
|
||||||
source = "DHCP";
|
source = "DHCP";
|
||||||
else if (flags & F_HOSTS)
|
else if (flags & F_HOSTS)
|
||||||
source = arg;
|
source = arg;
|
||||||
else if (flags & F_CONFIG)
|
|
||||||
source = "config";
|
|
||||||
else if (flags & F_UPSTREAM)
|
else if (flags & F_UPSTREAM)
|
||||||
source = "reply";
|
source = "reply";
|
||||||
else if (flags & F_SERVER)
|
else if (flags & F_SERVER)
|
||||||
|
|||||||
+19
-1
@@ -14,13 +14,15 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VERSION "2.49"
|
#define VERSION "2.51"
|
||||||
|
|
||||||
#define FTABSIZ 150 /* max number of outstanding requests (default) */
|
#define FTABSIZ 150 /* max number of outstanding requests (default) */
|
||||||
#define MAX_PROCS 20 /* max no children for TCP requests */
|
#define MAX_PROCS 20 /* max no children for TCP requests */
|
||||||
#define CHILD_LIFETIME 150 /* secs 'till terminated (RFC1035 suggests > 120s) */
|
#define CHILD_LIFETIME 150 /* secs 'till terminated (RFC1035 suggests > 120s) */
|
||||||
#define EDNS_PKTSZ 1280 /* default max EDNS.0 UDP packet from RFC2671 */
|
#define EDNS_PKTSZ 1280 /* default max EDNS.0 UDP packet from RFC2671 */
|
||||||
#define TIMEOUT 10 /* drop UDP queries after TIMEOUT seconds */
|
#define TIMEOUT 10 /* drop UDP queries after TIMEOUT seconds */
|
||||||
|
#define FORWARD_TEST 50 /* try all servers every 50 queries */
|
||||||
|
#define FORWARD_TIME 10 /* or 10 seconds */
|
||||||
#define RANDOM_SOCKS 64 /* max simultaneous random ports */
|
#define RANDOM_SOCKS 64 /* max simultaneous random ports */
|
||||||
#define LEASE_RETRY 60 /* on error, retry writing leasefile after LEASE_RETRY seconds */
|
#define LEASE_RETRY 60 /* on error, retry writing leasefile after LEASE_RETRY seconds */
|
||||||
#define CACHESIZ 150 /* default cache size */
|
#define CACHESIZ 150 /* default cache size */
|
||||||
@@ -126,6 +128,9 @@ HAVE_TFTP
|
|||||||
HAVE_DHCP
|
HAVE_DHCP
|
||||||
define this to get dnsmasq's DHCP server.
|
define this to get dnsmasq's DHCP server.
|
||||||
|
|
||||||
|
HAVE_SCRIPT
|
||||||
|
define this to get the ability to call scripts on lease-change
|
||||||
|
|
||||||
HAVE_GETOPT_LONG
|
HAVE_GETOPT_LONG
|
||||||
define this if you have GNU libc or GNU getopt.
|
define this if you have GNU libc or GNU getopt.
|
||||||
|
|
||||||
@@ -162,6 +167,7 @@ NOTES:
|
|||||||
/* platform independent options- uncomment to enable */
|
/* platform independent options- uncomment to enable */
|
||||||
#define HAVE_DHCP
|
#define HAVE_DHCP
|
||||||
#define HAVE_TFTP
|
#define HAVE_TFTP
|
||||||
|
#define HAVE_SCRIPT
|
||||||
/* #define HAVE_BROKEN_RTC */
|
/* #define HAVE_BROKEN_RTC */
|
||||||
/* #define HAVE_DBUS */
|
/* #define HAVE_DBUS */
|
||||||
|
|
||||||
@@ -175,6 +181,13 @@ NOTES:
|
|||||||
#undef HAVE_DHCP
|
#undef HAVE_DHCP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Allow scripts to be disabled with COPTS=-DNO_SCRIPT */
|
||||||
|
#ifdef NO_SCRIPT
|
||||||
|
#undef HAVE_SCRIPT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* platform dependent options. */
|
/* platform dependent options. */
|
||||||
|
|
||||||
/* Must preceed __linux__ since uClinux defines __linux__ too. */
|
/* Must preceed __linux__ since uClinux defines __linux__ too. */
|
||||||
@@ -273,3 +286,8 @@ NOTES:
|
|||||||
# define ADDRSTRLEN 16 /* 4*3 + 3 dots + NULL */
|
# define ADDRSTRLEN 16 /* 4*3 + 3 dots + NULL */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Can't do scripts without fork */
|
||||||
|
#ifdef NOFORK
|
||||||
|
# undef HAVE_SCRIPT
|
||||||
|
#endif
|
||||||
|
|
||||||
+14
-3
@@ -390,16 +390,25 @@ void check_dbus_listeners(fd_set *rset, fd_set *wset, fd_set *eset)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void emit_dbus_signal(int action, char *mac, char *hostname, char *addr)
|
void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname)
|
||||||
{
|
{
|
||||||
DBusConnection *connection = (DBusConnection *)daemon->dbus;
|
DBusConnection *connection = (DBusConnection *)daemon->dbus;
|
||||||
DBusMessage* message = NULL;
|
DBusMessage* message = NULL;
|
||||||
DBusMessageIter args;
|
DBusMessageIter args;
|
||||||
const char *action_str;
|
char *action_str, *addr, *mac = daemon->namebuff;
|
||||||
|
unsigned char *p;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (!connection)
|
if (!connection)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!hostname)
|
||||||
|
hostname = "";
|
||||||
|
|
||||||
|
p = extended_hwaddr(lease->hwaddr_type, lease->hwaddr_len,
|
||||||
|
lease->hwaddr, lease->clid_len, lease->clid, &i);
|
||||||
|
print_mac(mac, p, i);
|
||||||
|
|
||||||
if (action == ACTION_DEL)
|
if (action == ACTION_DEL)
|
||||||
action_str = "DhcpLeaseDeleted";
|
action_str = "DhcpLeaseDeleted";
|
||||||
else if (action == ACTION_ADD)
|
else if (action == ACTION_ADD)
|
||||||
@@ -409,6 +418,8 @@ void emit_dbus_signal(int action, char *mac, char *hostname, char *addr)
|
|||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
addr = inet_ntoa(lease->addr);
|
||||||
|
|
||||||
if (!(message = dbus_message_new_signal(DNSMASQ_PATH, DNSMASQ_SERVICE, action_str)))
|
if (!(message = dbus_message_new_signal(DNSMASQ_PATH, DNSMASQ_SERVICE, action_str)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
+23
-10
@@ -754,6 +754,8 @@ void dhcp_read_ethers(void)
|
|||||||
|
|
||||||
while (fgets(buff, MAXDNAME, f))
|
while (fgets(buff, MAXDNAME, f))
|
||||||
{
|
{
|
||||||
|
char *host = NULL;
|
||||||
|
|
||||||
lineno++;
|
lineno++;
|
||||||
|
|
||||||
while (strlen(buff) > 0 && isspace((int)buff[strlen(buff)-1]))
|
while (strlen(buff) > 0 && isspace((int)buff[strlen(buff)-1]))
|
||||||
@@ -792,19 +794,28 @@ void dhcp_read_ethers(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!canonicalise(ip))
|
int nomem;
|
||||||
|
if (!(host = canonicalise(ip, &nomem)) || !legal_hostname(host))
|
||||||
{
|
{
|
||||||
my_syslog(MS_DHCP | LOG_ERR, _("bad name at %s line %d"), ETHERSFILE, lineno);
|
if (!nomem)
|
||||||
|
my_syslog(MS_DHCP | LOG_ERR, _("bad name at %s line %d"), ETHERSFILE, lineno);
|
||||||
|
free(host);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = CONFIG_NAME;
|
flags = CONFIG_NAME;
|
||||||
|
|
||||||
for (config = daemon->dhcp_conf; config; config = config->next)
|
for (config = daemon->dhcp_conf; config; config = config->next)
|
||||||
if ((config->flags & CONFIG_NAME) && hostname_isequal(config->hostname, ip))
|
if ((config->flags & CONFIG_NAME) && hostname_isequal(config->hostname, host))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config && (config->flags & CONFIG_FROM_ETHERS))
|
||||||
|
{
|
||||||
|
my_syslog(MS_DHCP | LOG_ERR, _("ignoring %s line %d, duplicate name or IP address"), ETHERSFILE, lineno);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!config)
|
if (!config)
|
||||||
{
|
{
|
||||||
for (config = daemon->dhcp_conf; config; config = config->next)
|
for (config = daemon->dhcp_conf; config; config = config->next)
|
||||||
@@ -834,10 +845,8 @@ void dhcp_read_ethers(void)
|
|||||||
|
|
||||||
if (flags & CONFIG_NAME)
|
if (flags & CONFIG_NAME)
|
||||||
{
|
{
|
||||||
if ((config->hostname = whine_malloc(strlen(ip)+1)))
|
config->hostname = host;
|
||||||
strcpy(config->hostname, ip);
|
host = NULL;
|
||||||
else
|
|
||||||
config->flags &= ~CONFIG_NAME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & CONFIG_ADDR)
|
if (flags & CONFIG_ADDR)
|
||||||
@@ -856,6 +865,9 @@ void dhcp_read_ethers(void)
|
|||||||
config->hwaddr->next = NULL;
|
config->hwaddr->next = NULL;
|
||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
|
free(host);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
@@ -945,7 +957,8 @@ void dhcp_update_configs(struct dhcp_config *configs)
|
|||||||
|
|
||||||
/* If we've not found a hostname any other way, try and see if there's one in /etc/hosts
|
/* If we've not found a hostname any other way, try and see if there's one in /etc/hosts
|
||||||
for this address. If it has a domain part, that must match the set domain and
|
for this address. If it has a domain part, that must match the set domain and
|
||||||
it gets stripped. */
|
it gets stripped. The set of legal domain names is bigger than the set of legal hostnames
|
||||||
|
so check here that the domain name is legal as a hostname. */
|
||||||
char *host_from_dns(struct in_addr addr)
|
char *host_from_dns(struct in_addr addr)
|
||||||
{
|
{
|
||||||
struct crec *lookup;
|
struct crec *lookup;
|
||||||
@@ -963,7 +976,7 @@ char *host_from_dns(struct in_addr addr)
|
|||||||
hostname[255] = 0;
|
hostname[255] = 0;
|
||||||
d1 = strip_hostname(hostname);
|
d1 = strip_hostname(hostname);
|
||||||
d2 = get_domain(addr);
|
d2 = get_domain(addr);
|
||||||
if (d1 && (!d2 || hostname_isequal(d1, d2)))
|
if (!legal_hostname(hostname) || (d1 && (!d2 || !hostname_isequal(d1, d2))))
|
||||||
hostname = NULL;
|
hostname = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-6
@@ -45,11 +45,16 @@ static char *compile_opts =
|
|||||||
"no-"
|
"no-"
|
||||||
#endif
|
#endif
|
||||||
"DHCP "
|
"DHCP "
|
||||||
|
#if defined(HAVE_DHCP) && !defined(HAVE_SCRIPT)
|
||||||
|
"no-scripts "
|
||||||
|
#endif
|
||||||
#ifndef HAVE_TFTP
|
#ifndef HAVE_TFTP
|
||||||
"no-"
|
"no-"
|
||||||
#endif
|
#endif
|
||||||
"TFTP";
|
"TFTP";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static volatile pid_t pid = 0;
|
static volatile pid_t pid = 0;
|
||||||
static volatile int pipewrite;
|
static volatile int pipewrite;
|
||||||
|
|
||||||
@@ -68,7 +73,7 @@ int main (int argc, char **argv)
|
|||||||
struct iname *if_tmp;
|
struct iname *if_tmp;
|
||||||
int piperead, pipefd[2], err_pipe[2];
|
int piperead, pipefd[2], err_pipe[2];
|
||||||
struct passwd *ent_pw = NULL;
|
struct passwd *ent_pw = NULL;
|
||||||
#ifdef HAVE_DHCP
|
#if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
|
||||||
uid_t script_uid = 0;
|
uid_t script_uid = 0;
|
||||||
gid_t script_gid = 0;
|
gid_t script_gid = 0;
|
||||||
#endif
|
#endif
|
||||||
@@ -202,7 +207,7 @@ int main (int argc, char **argv)
|
|||||||
if (daemon->port != 0)
|
if (daemon->port != 0)
|
||||||
pre_allocate_sfds();
|
pre_allocate_sfds();
|
||||||
|
|
||||||
#ifdef HAVE_DHCP
|
#if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
|
||||||
/* Note getpwnam returns static storage */
|
/* Note getpwnam returns static storage */
|
||||||
if (daemon->dhcp && daemon->lease_change_command && daemon->scriptuser)
|
if (daemon->dhcp && daemon->lease_change_command && daemon->scriptuser)
|
||||||
{
|
{
|
||||||
@@ -352,7 +357,7 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
/* if we are to run scripts, we need to fork a helper before dropping root. */
|
/* if we are to run scripts, we need to fork a helper before dropping root. */
|
||||||
daemon->helperfd = -1;
|
daemon->helperfd = -1;
|
||||||
#if defined(HAVE_DHCP) && !defined(NO_FORK)
|
#if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
|
||||||
if (daemon->dhcp && daemon->lease_change_command)
|
if (daemon->dhcp && daemon->lease_change_command)
|
||||||
daemon->helperfd = create_helper(pipewrite, err_pipe[1], script_uid, script_gid, max_fd);
|
daemon->helperfd = create_helper(pipewrite, err_pipe[1], script_uid, script_gid, max_fd);
|
||||||
#endif
|
#endif
|
||||||
@@ -603,7 +608,7 @@ int main (int argc, char **argv)
|
|||||||
bump_maxfd(piperead, &maxfd);
|
bump_maxfd(piperead, &maxfd);
|
||||||
|
|
||||||
#ifdef HAVE_DHCP
|
#ifdef HAVE_DHCP
|
||||||
# ifndef NO_FORK
|
# ifdef HAVE_SCRIPT
|
||||||
while (helper_buf_empty() && do_script_run(now));
|
while (helper_buf_empty() && do_script_run(now));
|
||||||
|
|
||||||
if (!helper_buf_empty())
|
if (!helper_buf_empty())
|
||||||
@@ -674,7 +679,7 @@ int main (int argc, char **argv)
|
|||||||
if (daemon->dhcp && FD_ISSET(daemon->dhcpfd, &rset))
|
if (daemon->dhcp && FD_ISSET(daemon->dhcpfd, &rset))
|
||||||
dhcp_packet(now);
|
dhcp_packet(now);
|
||||||
|
|
||||||
# ifndef NO_FORK
|
# ifdef HAVE_SCRIPT
|
||||||
if (daemon->helperfd != -1 && FD_ISSET(daemon->helperfd, &wset))
|
if (daemon->helperfd != -1 && FD_ISSET(daemon->helperfd, &wset))
|
||||||
helper_write();
|
helper_write();
|
||||||
# endif
|
# endif
|
||||||
@@ -857,7 +862,7 @@ static void async_event(int pipe, time_t now)
|
|||||||
if (daemon->tcp_pids[i] != 0)
|
if (daemon->tcp_pids[i] != 0)
|
||||||
kill(daemon->tcp_pids[i], SIGALRM);
|
kill(daemon->tcp_pids[i], SIGALRM);
|
||||||
|
|
||||||
#if defined(HAVE_DHCP) && !defined(NO_FORK)
|
#if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
|
||||||
/* handle pending lease transitions */
|
/* handle pending lease transitions */
|
||||||
if (daemon->helperfd != -1)
|
if (daemon->helperfd != -1)
|
||||||
{
|
{
|
||||||
|
|||||||
+11
-8
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
/* get these before config.h for IPv6 stuff... */
|
/* get these before config.h for IPv6 stuff... */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
@@ -55,7 +56,6 @@
|
|||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#if defined(HAVE_SOLARIS_NETWORK)
|
#if defined(HAVE_SOLARIS_NETWORK)
|
||||||
#include <sys/sockio.h>
|
#include <sys/sockio.h>
|
||||||
@@ -335,7 +335,7 @@ struct server {
|
|||||||
struct irec {
|
struct irec {
|
||||||
union mysockaddr addr;
|
union mysockaddr addr;
|
||||||
struct in_addr netmask; /* only valid for IPv4 */
|
struct in_addr netmask; /* only valid for IPv4 */
|
||||||
int dhcp_ok;
|
int dhcp_ok, mtu;
|
||||||
struct irec *next;
|
struct irec *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -410,9 +410,9 @@ struct dhcp_lease {
|
|||||||
#endif
|
#endif
|
||||||
int hwaddr_len, hwaddr_type;
|
int hwaddr_len, hwaddr_type;
|
||||||
unsigned char hwaddr[DHCP_CHADDR_MAX];
|
unsigned char hwaddr[DHCP_CHADDR_MAX];
|
||||||
struct in_addr addr, override;
|
struct in_addr addr, override, giaddr;
|
||||||
unsigned char *vendorclass, *userclass;
|
unsigned char *vendorclass, *userclass, *supplied_hostname;
|
||||||
unsigned int vendorclass_len, userclass_len;
|
unsigned int vendorclass_len, userclass_len, supplied_hostname_len;
|
||||||
int last_interface;
|
int last_interface;
|
||||||
struct dhcp_lease *next;
|
struct dhcp_lease *next;
|
||||||
};
|
};
|
||||||
@@ -626,6 +626,7 @@ extern struct daemon {
|
|||||||
struct dhcp_mac *dhcp_macs;
|
struct dhcp_mac *dhcp_macs;
|
||||||
struct dhcp_boot *boot_config;
|
struct dhcp_boot *boot_config;
|
||||||
struct pxe_service *pxe_services;
|
struct pxe_service *pxe_services;
|
||||||
|
int enable_pxe;
|
||||||
struct dhcp_netid_list *dhcp_ignore, *dhcp_ignore_names, *force_broadcast, *bootp_dynamic;
|
struct dhcp_netid_list *dhcp_ignore, *dhcp_ignore_names, *force_broadcast, *bootp_dynamic;
|
||||||
char *dhcp_hosts_file, *dhcp_opts_file;
|
char *dhcp_hosts_file, *dhcp_opts_file;
|
||||||
int dhcp_max, tftp_max;
|
int dhcp_max, tftp_max;
|
||||||
@@ -646,6 +647,8 @@ extern struct daemon {
|
|||||||
struct irec *interfaces;
|
struct irec *interfaces;
|
||||||
struct listener *listeners;
|
struct listener *listeners;
|
||||||
struct server *last_server;
|
struct server *last_server;
|
||||||
|
time_t forwardtime;
|
||||||
|
int forwardcount;
|
||||||
struct server *srv_save; /* Used for resend on DoD */
|
struct server *srv_save; /* Used for resend on DoD */
|
||||||
size_t packet_len; /* " " */
|
size_t packet_len; /* " " */
|
||||||
struct randfd *rfd_save; /* " " */
|
struct randfd *rfd_save; /* " " */
|
||||||
@@ -719,8 +722,8 @@ size_t resize_packet(HEADER *header, size_t plen,
|
|||||||
/* util.c */
|
/* util.c */
|
||||||
void rand_init(void);
|
void rand_init(void);
|
||||||
unsigned short rand16(void);
|
unsigned short rand16(void);
|
||||||
int legal_char(char c);
|
int legal_hostname(char *c);
|
||||||
int canonicalise(char *s);
|
char *canonicalise(char *s, int *nomem);
|
||||||
unsigned char *do_rfc1035_name(unsigned char *p, char *sval);
|
unsigned char *do_rfc1035_name(unsigned char *p, char *sval);
|
||||||
void *safe_malloc(size_t size);
|
void *safe_malloc(size_t size);
|
||||||
void safe_pipe(int *fd, int read_noblock);
|
void safe_pipe(int *fd, int read_noblock);
|
||||||
@@ -863,7 +866,7 @@ int iface_enumerate(void *parm, int (*ipv4_callback)(), int (*ipv6_callback)());
|
|||||||
char *dbus_init(void);
|
char *dbus_init(void);
|
||||||
void check_dbus_listeners(fd_set *rset, fd_set *wset, fd_set *eset);
|
void check_dbus_listeners(fd_set *rset, fd_set *wset, fd_set *eset);
|
||||||
void set_dbus_listeners(int *maxfdp, fd_set *rset, fd_set *wset, fd_set *eset);
|
void set_dbus_listeners(int *maxfdp, fd_set *rset, fd_set *wset, fd_set *eset);
|
||||||
void emit_dbus_signal(int action, char *mac, char *hostname, char *addr);
|
void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* helper.c */
|
/* helper.c */
|
||||||
|
|||||||
+5
-1
@@ -262,10 +262,14 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
|
|
||||||
if (type != 0 || (daemon->options & OPT_ORDER))
|
if (type != 0 || (daemon->options & OPT_ORDER))
|
||||||
start = daemon->servers;
|
start = daemon->servers;
|
||||||
else if (!(start = daemon->last_server))
|
else if (!(start = daemon->last_server) ||
|
||||||
|
daemon->forwardcount++ > FORWARD_TEST ||
|
||||||
|
difftime(now, daemon->forwardtime) > FORWARD_TIME)
|
||||||
{
|
{
|
||||||
start = daemon->servers;
|
start = daemon->servers;
|
||||||
forward->forwardall = 1;
|
forward->forwardall = 1;
|
||||||
|
daemon->forwardcount = 0;
|
||||||
|
daemon->forwardtime = now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+38
-24
@@ -28,15 +28,15 @@
|
|||||||
main process.
|
main process.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(HAVE_DHCP) && !defined(NO_FORK)
|
#if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
|
||||||
|
|
||||||
static void my_setenv(const char *name, const char *value, int *error);
|
static void my_setenv(const char *name, const char *value, int *error);
|
||||||
|
|
||||||
struct script_data
|
struct script_data
|
||||||
{
|
{
|
||||||
unsigned char action, hwaddr_len, hwaddr_type;
|
unsigned char action, hwaddr_len, hwaddr_type;
|
||||||
unsigned char clid_len, hostname_len, uclass_len, vclass_len;
|
unsigned char clid_len, hostname_len, uclass_len, vclass_len, shost_len;
|
||||||
struct in_addr addr;
|
struct in_addr addr, giaddr;
|
||||||
unsigned int remaining_time;
|
unsigned int remaining_time;
|
||||||
#ifdef HAVE_BROKEN_RTC
|
#ifdef HAVE_BROKEN_RTC
|
||||||
unsigned int length;
|
unsigned int length;
|
||||||
@@ -101,7 +101,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
|
|
||||||
/* close all the sockets etc, we don't need them here. This closes err_fd, so that
|
/* close all the sockets etc, we don't need them here. This closes err_fd, so that
|
||||||
main process can return. */
|
main process can return. */
|
||||||
for (max_fd--; max_fd > 0; max_fd--)
|
for (max_fd--; max_fd >= 0; max_fd--)
|
||||||
if (max_fd != STDOUT_FILENO && max_fd != STDERR_FILENO &&
|
if (max_fd != STDOUT_FILENO && max_fd != STDERR_FILENO &&
|
||||||
max_fd != STDIN_FILENO && max_fd != pipefd[0] && max_fd != event_fd)
|
max_fd != STDIN_FILENO && max_fd != pipefd[0] && max_fd != event_fd)
|
||||||
close(max_fd);
|
close(max_fd);
|
||||||
@@ -155,7 +155,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
sprintf(daemon->dhcp_buff2, "%lu ", (unsigned long)data.expires);
|
sprintf(daemon->dhcp_buff2, "%lu ", (unsigned long)data.expires);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!read_write(pipefd[0], buf, data.hostname_len + data.uclass_len + data.vclass_len, 1))
|
if (!read_write(pipefd[0], buf,
|
||||||
|
data.hostname_len + data.uclass_len + data.vclass_len + data.shost_len, 1))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* possible fork errors are all temporary resource problems */
|
/* possible fork errors are all temporary resource problems */
|
||||||
@@ -232,6 +233,19 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.shost_len != 0)
|
||||||
|
{
|
||||||
|
buf[data.shost_len - 1] = 0; /* don't trust zero-term */
|
||||||
|
/* cannot have = chars in env - truncate if found . */
|
||||||
|
if ((p = strchr((char *)buf, '=')))
|
||||||
|
*p = 0;
|
||||||
|
my_setenv("DNSMASQ_SUPPLIED_HOSTNAME", (char *)buf, &err);
|
||||||
|
buf += data.shost_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.giaddr.s_addr != 0)
|
||||||
|
my_setenv("DNSMASQ_RELAY_ADDRESS", inet_ntoa(data.giaddr), &err);
|
||||||
|
|
||||||
sprintf(daemon->dhcp_buff2, "%u ", data.remaining_time);
|
sprintf(daemon->dhcp_buff2, "%u ", data.remaining_time);
|
||||||
my_setenv("DNSMASQ_TIME_REMAINING", daemon->dhcp_buff2, &err);
|
my_setenv("DNSMASQ_TIME_REMAINING", daemon->dhcp_buff2, &err);
|
||||||
|
|
||||||
@@ -240,7 +254,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
char *dot;
|
char *dot;
|
||||||
hostname = (char *)buf;
|
hostname = (char *)buf;
|
||||||
hostname[data.hostname_len - 1] = 0;
|
hostname[data.hostname_len - 1] = 0;
|
||||||
if (!canonicalise(hostname))
|
if (!legal_hostname(hostname))
|
||||||
hostname = NULL;
|
hostname = NULL;
|
||||||
else if ((dot = strchr(hostname, '.')))
|
else if ((dot = strchr(hostname, '.')))
|
||||||
{
|
{
|
||||||
@@ -285,16 +299,9 @@ void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t n
|
|||||||
{
|
{
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
size_t size;
|
size_t size;
|
||||||
int i;
|
unsigned int hostname_len = 0, clid_len = 0, vclass_len = 0;
|
||||||
unsigned int hostname_len = 0, clid_len = 0, vclass_len = 0, uclass_len = 0;
|
unsigned int uclass_len = 0, shost_len = 0;
|
||||||
|
|
||||||
#ifdef HAVE_DBUS
|
|
||||||
p = extended_hwaddr(lease->hwaddr_type, lease->hwaddr_len,
|
|
||||||
lease->hwaddr, lease->clid_len, lease->clid, &i);
|
|
||||||
print_mac(daemon->namebuff, p, i);
|
|
||||||
emit_dbus_signal(action, daemon->namebuff, hostname ? hostname : "", inet_ntoa(lease->addr));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* no script */
|
/* no script */
|
||||||
if (daemon->helperfd == -1)
|
if (daemon->helperfd == -1)
|
||||||
return;
|
return;
|
||||||
@@ -303,12 +310,14 @@ void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t n
|
|||||||
vclass_len = lease->vendorclass_len;
|
vclass_len = lease->vendorclass_len;
|
||||||
if (lease->userclass)
|
if (lease->userclass)
|
||||||
uclass_len = lease->userclass_len;
|
uclass_len = lease->userclass_len;
|
||||||
|
if (lease->supplied_hostname)
|
||||||
|
shost_len = lease->supplied_hostname_len;
|
||||||
if (lease->clid)
|
if (lease->clid)
|
||||||
clid_len = lease->clid_len;
|
clid_len = lease->clid_len;
|
||||||
if (hostname)
|
if (hostname)
|
||||||
hostname_len = strlen(hostname) + 1;
|
hostname_len = strlen(hostname) + 1;
|
||||||
|
|
||||||
size = sizeof(struct script_data) + clid_len + vclass_len + uclass_len + hostname_len;
|
size = sizeof(struct script_data) + clid_len + vclass_len + uclass_len + shost_len + hostname_len;
|
||||||
|
|
||||||
if (size > buf_size)
|
if (size > buf_size)
|
||||||
{
|
{
|
||||||
@@ -332,8 +341,10 @@ void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t n
|
|||||||
buf->clid_len = clid_len;
|
buf->clid_len = clid_len;
|
||||||
buf->vclass_len = vclass_len;
|
buf->vclass_len = vclass_len;
|
||||||
buf->uclass_len = uclass_len;
|
buf->uclass_len = uclass_len;
|
||||||
|
buf->shost_len = shost_len;
|
||||||
buf->hostname_len = hostname_len;
|
buf->hostname_len = hostname_len;
|
||||||
buf->addr = lease->addr;
|
buf->addr = lease->addr;
|
||||||
|
buf->giaddr = lease->giaddr;
|
||||||
memcpy(buf->hwaddr, lease->hwaddr, lease->hwaddr_len);
|
memcpy(buf->hwaddr, lease->hwaddr, lease->hwaddr_len);
|
||||||
buf->interface[0] = 0;
|
buf->interface[0] = 0;
|
||||||
#ifdef HAVE_LINUX_NETWORK
|
#ifdef HAVE_LINUX_NETWORK
|
||||||
@@ -372,14 +383,17 @@ void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t n
|
|||||||
memcpy(p, lease->userclass, uclass_len);
|
memcpy(p, lease->userclass, uclass_len);
|
||||||
p += uclass_len;
|
p += uclass_len;
|
||||||
}
|
}
|
||||||
/* substitute * for space: spaces are allowed in hostnames (for DNS-SD)
|
if (shost_len != 0)
|
||||||
and are likley to be a security hole in most scripts. */
|
{
|
||||||
for (i = 0; i < (int)hostname_len; i++)
|
memcpy(p, lease->supplied_hostname, shost_len);
|
||||||
if ((daemon->options & OPT_LEASE_RO) && hostname[i] == ' ')
|
p += shost_len;
|
||||||
*(p++) = '*';
|
}
|
||||||
else
|
if (hostname_len != 0)
|
||||||
*(p++) = hostname[i];
|
{
|
||||||
|
memcpy(p, hostname, hostname_len);
|
||||||
|
p += hostname_len;
|
||||||
|
}
|
||||||
|
|
||||||
bytes_in_buf = p - (unsigned char *)buf;
|
bytes_in_buf = p - (unsigned char *)buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+33
-28
@@ -42,14 +42,20 @@ void lease_init(time_t now)
|
|||||||
initial state of the database. If leasefile-ro is
|
initial state of the database. If leasefile-ro is
|
||||||
set without a script, we just do without any
|
set without a script, we just do without any
|
||||||
lease database. */
|
lease database. */
|
||||||
if (!daemon->lease_change_command)
|
#ifdef HAVE_SCRIPT
|
||||||
|
if (daemon->lease_change_command)
|
||||||
{
|
{
|
||||||
file_dirty = dns_dirty = 0;
|
strcpy(daemon->dhcp_buff, daemon->lease_change_command);
|
||||||
return;
|
strcat(daemon->dhcp_buff, " init");
|
||||||
|
leasestream = popen(daemon->dhcp_buff, "r");
|
||||||
}
|
}
|
||||||
strcpy(daemon->dhcp_buff, daemon->lease_change_command);
|
else
|
||||||
strcat(daemon->dhcp_buff, " init");
|
#endif
|
||||||
leasestream = popen(daemon->dhcp_buff, "r");
|
{
|
||||||
|
file_dirty = dns_dirty = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -100,19 +106,14 @@ void lease_init(time_t now)
|
|||||||
lease_set_hwaddr(lease, (unsigned char *)daemon->dhcp_buff2, (unsigned char *)daemon->packet, hw_len, hw_type, clid_len);
|
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)
|
if (strcmp(daemon->dhcp_buff, "*") != 0)
|
||||||
{
|
lease_set_hostname(lease, daemon->dhcp_buff, 0);
|
||||||
char *p;
|
|
||||||
/* unprotect spaces */
|
|
||||||
for (p = strchr(daemon->dhcp_buff, '*'); p; p = strchr(p, '*'))
|
|
||||||
*p = ' ';
|
|
||||||
lease_set_hostname(lease, daemon->dhcp_buff, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set these correctly: the "old" events are generated later from
|
/* set these correctly: the "old" events are generated later from
|
||||||
the startup synthesised SIGHUP. */
|
the startup synthesised SIGHUP. */
|
||||||
lease->new = lease->changed = 0;
|
lease->new = lease->changed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_SCRIPT
|
||||||
if (!daemon->lease_stream)
|
if (!daemon->lease_stream)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@@ -133,6 +134,7 @@ void lease_init(time_t now)
|
|||||||
die(_("lease-init script returned exit code %s"), daemon->dhcp_buff, WEXITSTATUS(rc) + EC_INIT_OFFSET);
|
die(_("lease-init script returned exit code %s"), daemon->dhcp_buff, WEXITSTATUS(rc) + EC_INIT_OFFSET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Some leases may have expired */
|
/* Some leases may have expired */
|
||||||
file_dirty = 0;
|
file_dirty = 0;
|
||||||
@@ -173,7 +175,6 @@ void lease_update_file(time_t now)
|
|||||||
struct dhcp_lease *lease;
|
struct dhcp_lease *lease;
|
||||||
time_t next_event;
|
time_t next_event;
|
||||||
int i, err = 0;
|
int i, err = 0;
|
||||||
char *p;
|
|
||||||
|
|
||||||
if (file_dirty != 0 && daemon->lease_stream)
|
if (file_dirty != 0 && daemon->lease_stream)
|
||||||
{
|
{
|
||||||
@@ -199,15 +200,8 @@ void lease_update_file(time_t now)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ourprintf(&err, " %s ", inet_ntoa(lease->addr));
|
ourprintf(&err, " %s ", inet_ntoa(lease->addr));
|
||||||
|
ourprintf(&err, "%s ", lease->hostname ? lease->hostname : "*");
|
||||||
/* substitute * for space: "*" is an illegal name, as is " " */
|
|
||||||
if (lease->hostname)
|
|
||||||
for (p = lease->hostname; *p; p++)
|
|
||||||
ourprintf(&err, "%c", *p == ' ' ? '*' : *p);
|
|
||||||
else
|
|
||||||
ourprintf(&err, "*");
|
|
||||||
ourprintf(&err, " ");
|
|
||||||
|
|
||||||
if (lease->clid && lease->clid_len != 0)
|
if (lease->clid && lease->clid_len != 0)
|
||||||
{
|
{
|
||||||
for (i = 0; i < lease->clid_len - 1; i++)
|
for (i = 0; i < lease->clid_len - 1; i++)
|
||||||
@@ -550,7 +544,7 @@ int do_script_run(time_t now)
|
|||||||
/* If the lease still has an old_hostname, do the "old" action on that first */
|
/* If the lease still has an old_hostname, do the "old" action on that first */
|
||||||
if (lease->old_hostname)
|
if (lease->old_hostname)
|
||||||
{
|
{
|
||||||
#ifndef NO_FORK
|
#ifdef HAVE_SCRIPT
|
||||||
queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now);
|
queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now);
|
||||||
#endif
|
#endif
|
||||||
free(lease->old_hostname);
|
free(lease->old_hostname);
|
||||||
@@ -560,8 +554,11 @@ int do_script_run(time_t now)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
kill_name(lease);
|
kill_name(lease);
|
||||||
#ifndef NO_FORK
|
#ifdef HAVE_SCRIPT
|
||||||
queue_script(ACTION_DEL, lease, lease->old_hostname, now);
|
queue_script(ACTION_DEL, lease, lease->old_hostname, now);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_DBUS
|
||||||
|
emit_dbus_signal(ACTION_DEL, lease, lease->old_hostname);
|
||||||
#endif
|
#endif
|
||||||
old_leases = lease->next;
|
old_leases = lease->next;
|
||||||
|
|
||||||
@@ -569,6 +566,7 @@ int do_script_run(time_t now)
|
|||||||
free(lease->clid);
|
free(lease->clid);
|
||||||
free(lease->vendorclass);
|
free(lease->vendorclass);
|
||||||
free(lease->userclass);
|
free(lease->userclass);
|
||||||
|
free(lease->supplied_hostname);
|
||||||
free(lease);
|
free(lease);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -579,7 +577,7 @@ int do_script_run(time_t now)
|
|||||||
for (lease = leases; lease; lease = lease->next)
|
for (lease = leases; lease; lease = lease->next)
|
||||||
if (lease->old_hostname)
|
if (lease->old_hostname)
|
||||||
{
|
{
|
||||||
#ifndef NO_FORK
|
#ifdef HAVE_SCRIPT
|
||||||
queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now);
|
queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now);
|
||||||
#endif
|
#endif
|
||||||
free(lease->old_hostname);
|
free(lease->old_hostname);
|
||||||
@@ -591,9 +589,13 @@ int do_script_run(time_t now)
|
|||||||
if (lease->new || lease->changed ||
|
if (lease->new || lease->changed ||
|
||||||
(lease->aux_changed && (daemon->options & OPT_LEASE_RO)))
|
(lease->aux_changed && (daemon->options & OPT_LEASE_RO)))
|
||||||
{
|
{
|
||||||
#ifndef NO_FORK
|
#ifdef HAVE_SCRIPT
|
||||||
queue_script(lease->new ? ACTION_ADD : ACTION_OLD, lease,
|
queue_script(lease->new ? ACTION_ADD : ACTION_OLD, lease,
|
||||||
lease->fqdn ? lease->fqdn : lease->hostname, now);
|
lease->fqdn ? lease->fqdn : lease->hostname, now);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_DBUS
|
||||||
|
emit_dbus_signal(lease->new ? ACTION_ADD : ACTION_OLD, lease,
|
||||||
|
lease->fqdn ? lease->fqdn : lease->hostname);
|
||||||
#endif
|
#endif
|
||||||
lease->new = lease->changed = lease->aux_changed = 0;
|
lease->new = lease->changed = lease->aux_changed = 0;
|
||||||
|
|
||||||
@@ -603,7 +605,10 @@ int do_script_run(time_t now)
|
|||||||
|
|
||||||
free(lease->userclass);
|
free(lease->userclass);
|
||||||
lease->userclass = NULL;
|
lease->userclass = NULL;
|
||||||
|
|
||||||
|
free(lease->supplied_hostname);
|
||||||
|
lease->supplied_hostname = NULL;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-2
@@ -119,7 +119,7 @@ static int iface_allowed(struct irec **irecp, int if_index,
|
|||||||
union mysockaddr *addr, struct in_addr netmask)
|
union mysockaddr *addr, struct in_addr netmask)
|
||||||
{
|
{
|
||||||
struct irec *iface;
|
struct irec *iface;
|
||||||
int fd;
|
int fd, mtu = 0, loopback;
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
int dhcp_ok = 1;
|
int dhcp_ok = 1;
|
||||||
struct iname *tmp;
|
struct iname *tmp;
|
||||||
@@ -142,12 +142,17 @@ static int iface_allowed(struct irec **irecp, int if_index,
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loopback = ifr.ifr_flags & IFF_LOOPBACK;
|
||||||
|
|
||||||
|
if (ioctl(fd, SIOCGIFMTU, &ifr) != -1)
|
||||||
|
mtu = ifr.ifr_mtu;
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
/* If we are restricting the set of interfaces to use, make
|
/* If we are restricting the set of interfaces to use, make
|
||||||
sure that loopback interfaces are in that set. */
|
sure that loopback interfaces are in that set. */
|
||||||
if (daemon->if_names && (ifr.ifr_flags & IFF_LOOPBACK))
|
if (daemon->if_names && loopback)
|
||||||
{
|
{
|
||||||
struct iname *lo;
|
struct iname *lo;
|
||||||
for (lo = daemon->if_names; lo; lo = lo->next)
|
for (lo = daemon->if_names; lo; lo = lo->next)
|
||||||
@@ -188,6 +193,7 @@ static int iface_allowed(struct irec **irecp, int if_index,
|
|||||||
iface->addr = *addr;
|
iface->addr = *addr;
|
||||||
iface->netmask = netmask;
|
iface->netmask = netmask;
|
||||||
iface->dhcp_ok = dhcp_ok;
|
iface->dhcp_ok = dhcp_ok;
|
||||||
|
iface->mtu = mtu;
|
||||||
iface->next = *irecp;
|
iface->next = *irecp;
|
||||||
*irecp = iface;
|
*irecp = iface;
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
+130
-77
@@ -406,6 +406,7 @@ static const struct {
|
|||||||
{ "domain-search", 119, 0 },
|
{ "domain-search", 119, 0 },
|
||||||
{ "sip-server", 120, 0 },
|
{ "sip-server", 120, 0 },
|
||||||
{ "classless-static-route", 121, 0 },
|
{ "classless-static-route", 121, 0 },
|
||||||
|
{ "server-ip-address", 255, OT_ADDR_LIST }, /* special, internal only, sets siaddr */
|
||||||
{ NULL, 0, 0 }
|
{ NULL, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -530,13 +531,24 @@ static char *split(char *s)
|
|||||||
return split_chr(s, ',');
|
return split_chr(s, ',');
|
||||||
}
|
}
|
||||||
|
|
||||||
static int canonicalise_opt(char *s)
|
static char *canonicalise_opt(char *s)
|
||||||
{
|
{
|
||||||
|
char *ret;
|
||||||
|
int nomem;
|
||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unhide_metas(s);
|
unhide_metas(s);
|
||||||
return canonicalise(s);
|
if (!(ret = canonicalise(s, &nomem)) && nomem)
|
||||||
|
{
|
||||||
|
if (mem_recover)
|
||||||
|
longjmp(mem_jmp, 1);
|
||||||
|
else
|
||||||
|
die(_("could not get memory"), NULL, EC_NOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int atoi_check(char *a, int *res)
|
static int atoi_check(char *a, int *res)
|
||||||
@@ -646,7 +658,7 @@ static void display_opts(void)
|
|||||||
printf(_("Known DHCP options:\n"));
|
printf(_("Known DHCP options:\n"));
|
||||||
|
|
||||||
for (i = 0; opttab[i].name; i++)
|
for (i = 0; opttab[i].name; i++)
|
||||||
if (opttab[i].size != OT_INTERNAL)
|
if (!(opttab[i].size & OT_INTERNAL))
|
||||||
printf("%3d %s\n", opttab[i].val, opttab[i].name);
|
printf("%3d %s\n", opttab[i].val, opttab[i].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -684,7 +696,7 @@ static char *parse_dhcp_opt(char *arg, int flags)
|
|||||||
if (strstr(arg, "option:") == arg)
|
if (strstr(arg, "option:") == arg)
|
||||||
{
|
{
|
||||||
for (i = 0; opttab[i].name; i++)
|
for (i = 0; opttab[i].name; i++)
|
||||||
if (opttab[i].size != OT_INTERNAL &&
|
if (!(opttab[i].size & OT_INTERNAL) &&
|
||||||
strcasecmp(opttab[i].name, arg+7) == 0)
|
strcasecmp(opttab[i].name, arg+7) == 0)
|
||||||
{
|
{
|
||||||
new->opt = opttab[i].val;
|
new->opt = opttab[i].val;
|
||||||
@@ -873,7 +885,8 @@ static char *parse_dhcp_opt(char *arg, int flags)
|
|||||||
|
|
||||||
while (arg && *arg)
|
while (arg && *arg)
|
||||||
{
|
{
|
||||||
if (!canonicalise_opt(arg))
|
char *dom;
|
||||||
|
if (!(dom = arg = canonicalise_opt(arg)))
|
||||||
{
|
{
|
||||||
problem = _("bad domain in dhcp-option");
|
problem = _("bad domain in dhcp-option");
|
||||||
break;
|
break;
|
||||||
@@ -898,7 +911,8 @@ static char *parse_dhcp_opt(char *arg, int flags)
|
|||||||
arg++;
|
arg++;
|
||||||
}
|
}
|
||||||
*q++ = 0;
|
*q++ = 0;
|
||||||
|
free(dom);
|
||||||
|
|
||||||
/* Now tail-compress using earlier names. */
|
/* Now tail-compress using earlier names. */
|
||||||
newlen = q - p;
|
newlen = q - p;
|
||||||
for (tail = p + len; *tail; tail += (*tail) + 1)
|
for (tail = p + len; *tail; tail += (*tail) + 1)
|
||||||
@@ -1018,25 +1032,51 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
|||||||
DIR *dir_stream;
|
DIR *dir_stream;
|
||||||
struct dirent *ent;
|
struct dirent *ent;
|
||||||
char *directory, *path;
|
char *directory, *path;
|
||||||
|
struct list {
|
||||||
|
char *suffix;
|
||||||
|
struct list *next;
|
||||||
|
} *ignore_suffix = NULL, *li;
|
||||||
|
|
||||||
|
comma = split(arg);
|
||||||
if (!(directory = opt_string_alloc(arg)))
|
if (!(directory = opt_string_alloc(arg)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
for (arg = comma; arg; arg = comma)
|
||||||
|
{
|
||||||
|
comma = split(arg);
|
||||||
|
li = opt_malloc(sizeof(struct list));
|
||||||
|
li->next = ignore_suffix;
|
||||||
|
ignore_suffix = li;
|
||||||
|
/* Have to copy: buffer is overwritten */
|
||||||
|
li->suffix = opt_string_alloc(arg);
|
||||||
|
};
|
||||||
|
|
||||||
if (!(dir_stream = opendir(directory)))
|
if (!(dir_stream = opendir(directory)))
|
||||||
die(_("cannot access directory %s: %s"), directory, EC_FILE);
|
die(_("cannot access directory %s: %s"), directory, EC_FILE);
|
||||||
|
|
||||||
while ((ent = readdir(dir_stream)))
|
while ((ent = readdir(dir_stream)))
|
||||||
{
|
{
|
||||||
size_t len = strlen(ent->d_name);
|
size_t len = strlen(ent->d_name);
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
|
|
||||||
/* ignore emacs backups and dotfiles */
|
/* ignore emacs backups and dotfiles */
|
||||||
if (len == 0 ||
|
if (len == 0 ||
|
||||||
ent->d_name[len - 1] == '~' ||
|
ent->d_name[len - 1] == '~' ||
|
||||||
(ent->d_name[0] == '#' && ent->d_name[len - 1] == '#') ||
|
(ent->d_name[0] == '#' && ent->d_name[len - 1] == '#') ||
|
||||||
ent->d_name[0] == '.')
|
ent->d_name[0] == '.')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
for (li = ignore_suffix; li; li = li->next)
|
||||||
|
{
|
||||||
|
/* check for proscribed suffices */
|
||||||
|
size_t ls = strlen(li->suffix);
|
||||||
|
if (len > ls &&
|
||||||
|
strcmp(li->suffix, &ent->d_name[len - ls]) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (li)
|
||||||
|
continue;
|
||||||
|
|
||||||
path = opt_malloc(strlen(directory) + len + 2);
|
path = opt_malloc(strlen(directory) + len + 2);
|
||||||
strcpy(path, directory);
|
strcpy(path, directory);
|
||||||
strcat(path, "/");
|
strcat(path, "/");
|
||||||
@@ -1055,6 +1095,13 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
|||||||
|
|
||||||
closedir(dir_stream);
|
closedir(dir_stream);
|
||||||
free(directory);
|
free(directory);
|
||||||
|
for(; ignore_suffix; ignore_suffix = li)
|
||||||
|
{
|
||||||
|
li = ignore_suffix->next;
|
||||||
|
free(ignore_suffix->suffix);
|
||||||
|
free(ignore_suffix);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1127,32 +1174,32 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
|||||||
{
|
{
|
||||||
int pref = 1;
|
int pref = 1;
|
||||||
struct mx_srv_record *new;
|
struct mx_srv_record *new;
|
||||||
|
char *name, *target = NULL;
|
||||||
|
|
||||||
if ((comma = split(arg)))
|
if ((comma = split(arg)))
|
||||||
{
|
{
|
||||||
char *prefstr;
|
char *prefstr;
|
||||||
if ((prefstr=split(comma)) && !atoi_check16(prefstr, &pref))
|
if ((prefstr = split(comma)) && !atoi_check16(prefstr, &pref))
|
||||||
problem = _("bad MX preference");
|
problem = _("bad MX preference");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!canonicalise_opt(arg) || (comma && !canonicalise_opt(comma)))
|
if (!(name = canonicalise_opt(arg)) ||
|
||||||
|
(comma && !(target = canonicalise_opt(comma))))
|
||||||
problem = _("bad MX name");
|
problem = _("bad MX name");
|
||||||
|
|
||||||
new = opt_malloc(sizeof(struct mx_srv_record));
|
new = opt_malloc(sizeof(struct mx_srv_record));
|
||||||
new->next = daemon->mxnames;
|
new->next = daemon->mxnames;
|
||||||
daemon->mxnames = new;
|
daemon->mxnames = new;
|
||||||
new->issrv = 0;
|
new->issrv = 0;
|
||||||
new->name = opt_string_alloc(arg);
|
new->name = name;
|
||||||
new->target = opt_string_alloc(comma); /* may be NULL */
|
new->target = target; /* may be NULL */
|
||||||
new->weight = pref;
|
new->weight = pref;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 't': /* --mx-target */
|
case 't': /* --mx-target */
|
||||||
if (!canonicalise_opt(arg))
|
if (!(daemon->mxtarget = canonicalise_opt(arg)))
|
||||||
problem = _("bad MX target");
|
problem = _("bad MX target");
|
||||||
else
|
|
||||||
daemon->mxtarget = opt_string_alloc(arg);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef HAVE_DHCP
|
#ifdef HAVE_DHCP
|
||||||
@@ -1161,8 +1208,10 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case '6': /* --dhcp-script */
|
case '6': /* --dhcp-script */
|
||||||
# ifdef NO_FORK
|
# if defined(NO_FORK)
|
||||||
problem = _("cannot run scripts under uClinux");
|
problem = _("cannot run scripts under uClinux");
|
||||||
|
# elif !defined(HAVE_SCRIPT)
|
||||||
|
problem = _("recompile with HAVE_SCRIPT defined to enable lease-change scripts");
|
||||||
# else
|
# else
|
||||||
daemon->lease_change_command = opt_string_alloc(arg);
|
daemon->lease_change_command = opt_string_alloc(arg);
|
||||||
# endif
|
# endif
|
||||||
@@ -1186,12 +1235,12 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
|||||||
daemon->options |= OPT_RESOLV_DOMAIN;
|
daemon->options |= OPT_RESOLV_DOMAIN;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
char *d;
|
||||||
comma = split(arg);
|
comma = split(arg);
|
||||||
if (!canonicalise_opt(arg))
|
if (!(d = canonicalise_opt(arg)))
|
||||||
option = '?';
|
option = '?';
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *d = opt_string_alloc(arg);
|
|
||||||
if (comma)
|
if (comma)
|
||||||
{
|
{
|
||||||
struct cond_domain *new = safe_malloc(sizeof(struct cond_domain));
|
struct cond_domain *new = safe_malloc(sizeof(struct cond_domain));
|
||||||
@@ -1346,10 +1395,8 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
|||||||
/* # matches everything and becomes a zero length domain string */
|
/* # matches everything and becomes a zero length domain string */
|
||||||
if (strcmp(arg, "#") == 0)
|
if (strcmp(arg, "#") == 0)
|
||||||
domain = "";
|
domain = "";
|
||||||
else if (!canonicalise_opt(arg) && strlen(arg) != 0)
|
else if (strlen (arg) != 0 && !(domain = canonicalise_opt(arg)))
|
||||||
option = '?';
|
option = '?';
|
||||||
else
|
|
||||||
domain = opt_string_alloc(arg); /* NULL if strlen is zero */
|
|
||||||
serv = opt_malloc(sizeof(struct server));
|
serv = opt_malloc(sizeof(struct server));
|
||||||
memset(serv, 0, sizeof(struct server));
|
memset(serv, 0, sizeof(struct server));
|
||||||
serv->next = newlist;
|
serv->next = newlist;
|
||||||
@@ -1662,7 +1709,7 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
|||||||
if (!(a[k] = split(a[k-1])))
|
if (!(a[k] = split(a[k-1])))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (option == '?' || (k < 2) || ((new->start.s_addr = inet_addr(a[0])) == (in_addr_t)-1))
|
if ((k < 2) || ((new->start.s_addr = inet_addr(a[0])) == (in_addr_t)-1))
|
||||||
option = '?';
|
option = '?';
|
||||||
else if (strcmp(a[1], "static") == 0)
|
else if (strcmp(a[1], "static") == 0)
|
||||||
{
|
{
|
||||||
@@ -1860,15 +1907,12 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
|||||||
new->flags |= CONFIG_DISABLE;
|
new->flags |= CONFIG_DISABLE;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int len = strlen(a[j]) + 1;
|
if (!(new->hostname = canonicalise_opt(a[j])) ||
|
||||||
if (!canonicalise_opt(a[j]))
|
!legal_hostname(new->hostname))
|
||||||
problem = _("bad DHCP host name");
|
problem = _("bad DHCP host name");
|
||||||
else if ((new->hostname = opt_malloc(len)))
|
else
|
||||||
{
|
new->flags |= CONFIG_NAME;
|
||||||
new->flags |= CONFIG_NAME;
|
new->domain = NULL;
|
||||||
strcpy(new->hostname, a[j]);
|
|
||||||
new->domain = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1983,6 +2027,7 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
|||||||
|
|
||||||
new->next = daemon->dhcp_opts;
|
new->next = daemon->dhcp_opts;
|
||||||
daemon->dhcp_opts = new;
|
daemon->dhcp_opts = new;
|
||||||
|
daemon->enable_pxe = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -2051,6 +2096,7 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
|||||||
s->next = new;
|
s->next = new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
daemon->enable_pxe = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2243,19 +2289,20 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
|||||||
case LOPT_INTNAME: /* --interface-name */
|
case LOPT_INTNAME: /* --interface-name */
|
||||||
{
|
{
|
||||||
struct interface_name *new, **up;
|
struct interface_name *new, **up;
|
||||||
|
char *domain = NULL;
|
||||||
|
|
||||||
comma = split(arg);
|
comma = split(arg);
|
||||||
|
|
||||||
if (!comma || !canonicalise_opt(arg))
|
if (!comma || !(domain = canonicalise_opt(arg)))
|
||||||
problem = _("bad interface name");
|
problem = _("bad interface name");
|
||||||
|
|
||||||
new = opt_malloc(sizeof(struct interface_name));
|
new = opt_malloc(sizeof(struct interface_name));
|
||||||
new->next = NULL;
|
new->next = NULL;
|
||||||
/* Add to the end of the list, so that first name
|
/* Add to the end of the list, so that first name
|
||||||
of an interface is used for PTR lookups. */
|
of an interface is used for PTR lookups. */
|
||||||
for (up = &daemon->int_names; *up; up = &((*up)->next));
|
for (up = &daemon->int_names; *up; up = &((*up)->next));
|
||||||
*up = new;
|
*up = new;
|
||||||
new->name = opt_string_alloc(arg);
|
new->name = domain;
|
||||||
new->intr = opt_string_alloc(comma);
|
new->intr = opt_string_alloc(comma);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2268,14 +2315,22 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
|||||||
option = '?';
|
option = '?';
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (new = daemon->cnames; new; new = new->next)
|
char *alias = canonicalise_opt(arg);
|
||||||
if (hostname_isequal(new->alias, arg))
|
char *target = canonicalise_opt(comma);
|
||||||
problem = _("duplicate CNAME");
|
|
||||||
new = opt_malloc(sizeof(struct cname));
|
if (!alias || !target)
|
||||||
new->next = daemon->cnames;
|
problem = _("bad CNAME");
|
||||||
daemon->cnames = new;
|
else
|
||||||
new->alias = opt_string_alloc(arg);
|
{
|
||||||
new->target = opt_string_alloc(comma);
|
for (new = daemon->cnames; new; new = new->next)
|
||||||
|
if (hostname_isequal(new->alias, arg))
|
||||||
|
problem = _("duplicate CNAME");
|
||||||
|
new = opt_malloc(sizeof(struct cname));
|
||||||
|
new->next = daemon->cnames;
|
||||||
|
daemon->cnames = new;
|
||||||
|
new->alias = alias;
|
||||||
|
new->target = target;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2283,19 +2338,21 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
|||||||
case LOPT_PTR: /* --ptr-record */
|
case LOPT_PTR: /* --ptr-record */
|
||||||
{
|
{
|
||||||
struct ptr_record *new;
|
struct ptr_record *new;
|
||||||
|
char *dom, *target = NULL;
|
||||||
|
|
||||||
comma = split(arg);
|
comma = split(arg);
|
||||||
|
|
||||||
if (!canonicalise_opt(arg))
|
if (!(dom = canonicalise_opt(arg)) ||
|
||||||
|
(comma && !(target = canonicalise_opt(comma))))
|
||||||
problem = _("bad PTR record");
|
problem = _("bad PTR record");
|
||||||
|
else
|
||||||
new = opt_malloc(sizeof(struct ptr_record));
|
{
|
||||||
new->next = daemon->ptr;
|
new = opt_malloc(sizeof(struct ptr_record));
|
||||||
daemon->ptr = new;
|
new->next = daemon->ptr;
|
||||||
new->name = opt_string_alloc(arg);
|
daemon->ptr = new;
|
||||||
new->ptr = NULL;
|
new->name = dom;
|
||||||
if (comma)
|
new->ptr = target;
|
||||||
new->ptr = opt_string_alloc(comma);
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2305,6 +2362,7 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
|||||||
int k = 0;
|
int k = 0;
|
||||||
struct naptr *new;
|
struct naptr *new;
|
||||||
int order, pref;
|
int order, pref;
|
||||||
|
char *name, *replace = NULL;
|
||||||
|
|
||||||
if ((a[0] = arg))
|
if ((a[0] = arg))
|
||||||
for (k = 1; k < 7; k++)
|
for (k = 1; k < 7; k++)
|
||||||
@@ -2313,22 +2371,21 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
|||||||
|
|
||||||
|
|
||||||
if (k < 6 ||
|
if (k < 6 ||
|
||||||
!canonicalise_opt(a[0]) ||
|
!(name = canonicalise_opt(a[0])) ||
|
||||||
!atoi_check16(a[1], &order) ||
|
!atoi_check16(a[1], &order) ||
|
||||||
!atoi_check16(a[2], &pref) ||
|
!atoi_check16(a[2], &pref) ||
|
||||||
(k == 7 && !canonicalise_opt(a[6])))
|
(k == 7 && !(replace = canonicalise_opt(a[6]))))
|
||||||
problem = _("bad NAPTR record");
|
problem = _("bad NAPTR record");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
new = opt_malloc(sizeof(struct naptr));
|
new = opt_malloc(sizeof(struct naptr));
|
||||||
new->next = daemon->naptr;
|
new->next = daemon->naptr;
|
||||||
daemon->naptr = new;
|
daemon->naptr = new;
|
||||||
new->name = opt_string_alloc(a[0]);
|
new->name = name;
|
||||||
new->flags = opt_string_alloc(a[3]);
|
new->flags = opt_string_alloc(a[3]);
|
||||||
new->services = opt_string_alloc(a[4]);
|
new->services = opt_string_alloc(a[4]);
|
||||||
new->regexp = opt_string_alloc(a[5]);
|
new->regexp = opt_string_alloc(a[5]);
|
||||||
if (k == 7)
|
new->replace = replace;
|
||||||
new->replace = opt_string_alloc(a[6]);
|
|
||||||
new->order = order;
|
new->order = order;
|
||||||
new->pref = pref;
|
new->pref = pref;
|
||||||
}
|
}
|
||||||
@@ -2345,12 +2402,6 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
|||||||
|
|
||||||
gen_prob = _("TXT record string too long");
|
gen_prob = _("TXT record string too long");
|
||||||
|
|
||||||
if (!canonicalise_opt(arg))
|
|
||||||
{
|
|
||||||
problem = _("bad TXT record");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((q = (unsigned char *)comma))
|
if ((q = (unsigned char *)comma))
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@@ -2394,7 +2445,13 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
|||||||
/* ensure arg is terminated */
|
/* ensure arg is terminated */
|
||||||
if (comma)
|
if (comma)
|
||||||
*comma = 0;
|
*comma = 0;
|
||||||
new->name = opt_string_alloc(arg);
|
|
||||||
|
if (!(new->name = canonicalise_opt(arg)))
|
||||||
|
{
|
||||||
|
problem = _("bad TXT record");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2406,19 +2463,16 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
|||||||
|
|
||||||
comma = split(arg);
|
comma = split(arg);
|
||||||
|
|
||||||
if (!canonicalise_opt(arg))
|
if (!(name = canonicalise_opt(arg)))
|
||||||
problem = _("bad SRV record");
|
problem = _("bad SRV record");
|
||||||
|
|
||||||
name = opt_string_alloc(arg);
|
|
||||||
|
|
||||||
if (comma)
|
if (comma)
|
||||||
{
|
{
|
||||||
arg = comma;
|
arg = comma;
|
||||||
comma = split(arg);
|
comma = split(arg);
|
||||||
if (!canonicalise_opt(arg))
|
if (!(target = canonicalise_opt(arg))
|
||||||
problem = _("bad SRV target");
|
) problem = _("bad SRV target");
|
||||||
|
|
||||||
target = opt_string_alloc(arg);
|
|
||||||
if (comma)
|
if (comma)
|
||||||
{
|
{
|
||||||
arg = comma;
|
arg = comma;
|
||||||
@@ -2683,7 +2737,7 @@ void reread_dhcp(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
one_file(daemon->dhcp_hosts_file, 1, LOPT_BANK);
|
one_file(daemon->dhcp_hosts_file, 1, LOPT_BANK);
|
||||||
my_syslog(LOG_INFO, _("read %s"), daemon->dhcp_hosts_file);
|
my_syslog(MS_DHCP | LOG_INFO, _("read %s"), daemon->dhcp_hosts_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (daemon->dhcp_opts_file)
|
if (daemon->dhcp_opts_file)
|
||||||
@@ -2714,7 +2768,7 @@ void reread_dhcp(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
one_file(daemon->dhcp_opts_file, 1, LOPT_OPTS);
|
one_file(daemon->dhcp_opts_file, 1, LOPT_OPTS);
|
||||||
my_syslog(LOG_INFO, _("read %s"), daemon->dhcp_opts_file);
|
my_syslog(MS_DHCP | LOG_INFO, _("read %s"), daemon->dhcp_opts_file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -2898,8 +2952,7 @@ void read_opts(int argc, char **argv, char *compile_opts)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((token = strtok(NULL, " \t\n\r")) &&
|
if ((token = strtok(NULL, " \t\n\r")) &&
|
||||||
canonicalise_opt(token) &&
|
(daemon->domain_suffix = canonicalise_opt(token)))
|
||||||
(daemon->domain_suffix = opt_string_alloc(token)))
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -138,7 +138,8 @@ static int extract_name(HEADER *header, size_t plen, unsigned char **pp,
|
|||||||
for(j=0; j<l; j++, p++)
|
for(j=0; j<l; j++, p++)
|
||||||
if (isExtract)
|
if (isExtract)
|
||||||
{
|
{
|
||||||
if (legal_char(*p))
|
unsigned char c = *p;
|
||||||
|
if (isascii(c) && !iscntrl(c) && c != '.')
|
||||||
*cp++ = *p;
|
*cp++ = *p;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+38
-17
@@ -415,7 +415,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
|
|
||||||
for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
|
for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
|
||||||
if (match_netid(id_list->list, netid, 0))
|
if (match_netid(id_list->list, netid, 0))
|
||||||
message = _("disabled");
|
message = _("ignored");
|
||||||
|
|
||||||
if (!message)
|
if (!message)
|
||||||
{
|
{
|
||||||
@@ -536,7 +536,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
|
|
||||||
*pq = 0;
|
*pq = 0;
|
||||||
|
|
||||||
if (canonicalise(daemon->dhcp_buff))
|
if (legal_hostname(daemon->dhcp_buff))
|
||||||
offer_hostname = client_hostname = daemon->dhcp_buff;
|
offer_hostname = client_hostname = daemon->dhcp_buff;
|
||||||
}
|
}
|
||||||
else if ((opt = option_find(mess, sz, OPTION_HOSTNAME, 1)))
|
else if ((opt = option_find(mess, sz, OPTION_HOSTNAME, 1)))
|
||||||
@@ -550,7 +550,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
borken_opt = 1;
|
borken_opt = 1;
|
||||||
else
|
else
|
||||||
daemon->dhcp_buff[len] = 0;
|
daemon->dhcp_buff[len] = 0;
|
||||||
if (canonicalise(daemon->dhcp_buff))
|
if (legal_hostname(daemon->dhcp_buff))
|
||||||
client_hostname = daemon->dhcp_buff;
|
client_hostname = daemon->dhcp_buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -708,7 +708,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
clid = NULL;
|
clid = NULL;
|
||||||
|
|
||||||
/* Check if client is PXE client. */
|
/* Check if client is PXE client. */
|
||||||
if ((opt = option_find(mess, sz, OPTION_VENDOR_ID, 9)) &&
|
if (daemon->enable_pxe &&
|
||||||
|
(opt = option_find(mess, sz, OPTION_VENDOR_ID, 9)) &&
|
||||||
strncmp(option_ptr(opt, 0), "PXEClient", 9) == 0)
|
strncmp(option_ptr(opt, 0), "PXEClient", 9) == 0)
|
||||||
{
|
{
|
||||||
if ((opt = option_find(mess, sz, OPTION_PXE_UUID, 17)))
|
if ((opt = option_find(mess, sz, OPTION_PXE_UUID, 17)))
|
||||||
@@ -728,6 +729,9 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
unsigned char save71[4];
|
unsigned char save71[4];
|
||||||
struct dhcp_opt opt71;
|
struct dhcp_opt opt71;
|
||||||
|
|
||||||
|
if (ignore)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (layer & 0x8000)
|
if (layer & 0x8000)
|
||||||
{
|
{
|
||||||
my_syslog(MS_DHCP | LOG_ERR, _("PXE BIS not supported"));
|
my_syslog(MS_DHCP | LOG_ERR, _("PXE BIS not supported"));
|
||||||
@@ -807,8 +811,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
prune_vendor_opts(netid);
|
prune_vendor_opts(netid);
|
||||||
do_encap_opts(pxe_opts(pxearch, netid), OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
|
do_encap_opts(pxe_opts(pxearch, netid), OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
|
||||||
|
|
||||||
log_packet("PXE", NULL, emac, emac_len, iface_name, "proxy", mess->xid);
|
log_packet("PXE", NULL, emac, emac_len, iface_name, ignore ? "proxy" : "proxy-ignored", mess->xid);
|
||||||
return dhcp_packet_size(mess, netid, agent_id, real_end);
|
return ignore ? 0 : dhcp_packet_size(mess, netid, agent_id, real_end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1133,6 +1137,9 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
{
|
{
|
||||||
if (do_classes)
|
if (do_classes)
|
||||||
{
|
{
|
||||||
|
if (mess->giaddr.s_addr)
|
||||||
|
lease->giaddr = mess->giaddr;
|
||||||
|
|
||||||
lease->changed = 1;
|
lease->changed = 1;
|
||||||
/* copy user-class and vendor class into new lease, for the script */
|
/* copy user-class and vendor class into new lease, for the script */
|
||||||
if ((opt = option_find(mess, sz, OPTION_USER_CLASS, 1)))
|
if ((opt = option_find(mess, sz, OPTION_USER_CLASS, 1)))
|
||||||
@@ -1162,6 +1169,18 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
lease->vendorclass_len = len+1;
|
lease->vendorclass_len = len+1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((opt = option_find(mess, sz, OPTION_HOSTNAME, 1)))
|
||||||
|
{
|
||||||
|
int len = option_len(opt);
|
||||||
|
unsigned char *ucp = option_ptr(opt, 0);
|
||||||
|
free(lease->supplied_hostname);
|
||||||
|
if ((lease->supplied_hostname = whine_malloc(len+1)))
|
||||||
|
{
|
||||||
|
memcpy(lease->supplied_hostname, ucp, len);
|
||||||
|
lease->supplied_hostname[len] = 0;
|
||||||
|
lease->supplied_hostname_len = len+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hostname_auth && (client_hostname = host_from_dns(mess->yiaddr)))
|
if (!hostname_auth && (client_hostname = host_from_dns(mess->yiaddr)))
|
||||||
@@ -1538,7 +1557,6 @@ static size_t dhcp_packet_size(struct dhcp_packet *mess, struct dhcp_netid *neti
|
|||||||
/* move agent_id back down to the end of the packet */
|
/* move agent_id back down to the end of the packet */
|
||||||
if (agent_id)
|
if (agent_id)
|
||||||
{
|
{
|
||||||
unsigned char *p = dhcp_skip_opts(&mess->options[0] + sizeof(u32));
|
|
||||||
memmove(p, agent_id, real_end - agent_id);
|
memmove(p, agent_id, real_end - agent_id);
|
||||||
p += real_end - agent_id;
|
p += real_end - agent_id;
|
||||||
memset(p, 0, real_end - p); /* in case of overlap */
|
memset(p, 0, real_end - p); /* in case of overlap */
|
||||||
@@ -1547,9 +1565,8 @@ static size_t dhcp_packet_size(struct dhcp_packet *mess, struct dhcp_netid *neti
|
|||||||
/* We do logging too */
|
/* We do logging too */
|
||||||
if (netid && (daemon->options & OPT_LOG_OPTS))
|
if (netid && (daemon->options & OPT_LOG_OPTS))
|
||||||
{
|
{
|
||||||
char *p = daemon->namebuff;
|
char *s = daemon->namebuff;
|
||||||
*p = 0;
|
for (*s = 0; netid; netid = netid->next)
|
||||||
for (; netid; netid = netid->next)
|
|
||||||
{
|
{
|
||||||
/* kill dupes. */
|
/* kill dupes. */
|
||||||
for (n = netid->next; n; n = n->next)
|
for (n = netid->next; n; n = n->next)
|
||||||
@@ -1558,13 +1575,12 @@ static size_t dhcp_packet_size(struct dhcp_packet *mess, struct dhcp_netid *neti
|
|||||||
|
|
||||||
if (!n)
|
if (!n)
|
||||||
{
|
{
|
||||||
strncat (p, netid->net, MAXDNAME);
|
strncat (s, netid->net, (MAXDNAME-1) - strlen(s));
|
||||||
if (netid->next)
|
if (netid->next)
|
||||||
strncat (p, ", ", MAXDNAME);
|
strncat (s, ", ", (MAXDNAME-1) - strlen(s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p[MAXDNAME - 1] = 0;
|
my_syslog(MS_DHCP | LOG_INFO, _("%u tags: %s"), ntohl(mess->xid), s);
|
||||||
my_syslog(MS_DHCP | LOG_INFO, _("%u tags: %s"), ntohl(mess->xid), p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add END options to the regions. */
|
/* add END options to the regions. */
|
||||||
@@ -2074,21 +2090,26 @@ static void do_options(struct dhcp_context *context,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Use the values of the relevant options if no dhcp-boot given and
|
/* Use the values of the relevant options if no dhcp-boot given and
|
||||||
they're not explicitly asked for as options. */
|
they're not explicitly asked for as options. OPTION_END is used
|
||||||
|
as an internal way to specify siaddr without using dhcp-boot, for use in
|
||||||
|
dhcp-optsfile. */
|
||||||
{
|
{
|
||||||
if ((!req_options || !in_list(req_options, OPTION_FILENAME)) && mess->file[0] == 0 &&
|
if ((!req_options || !in_list(req_options, OPTION_FILENAME)) && mess->file[0] == 0 &&
|
||||||
(opt = option_find2(netid, config_opts, OPTION_FILENAME)))
|
(opt = option_find2(netid, config_opts, OPTION_FILENAME)) && !(opt->flags & DHOPT_FORCE))
|
||||||
{
|
{
|
||||||
strncpy((char *)mess->file, (char *)opt->val, sizeof(mess->file)-1);
|
strncpy((char *)mess->file, (char *)opt->val, sizeof(mess->file)-1);
|
||||||
done_file = 1;
|
done_file = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!req_options || !in_list(req_options, OPTION_SNAME)) &&
|
if ((!req_options || !in_list(req_options, OPTION_SNAME)) &&
|
||||||
(opt = option_find2(netid, config_opts, OPTION_SNAME)))
|
(opt = option_find2(netid, config_opts, OPTION_SNAME)) && !(opt->flags & DHOPT_FORCE))
|
||||||
{
|
{
|
||||||
strncpy((char *)mess->sname, (char *)opt->val, sizeof(mess->sname)-1);
|
strncpy((char *)mess->sname, (char *)opt->val, sizeof(mess->sname)-1);
|
||||||
done_server = 1;
|
done_server = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((opt = option_find2(netid, config_opts, OPTION_END)))
|
||||||
|
mess->siaddr.s_addr = ((struct in_addr *)opt->val)->s_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We don't want to do option-overload for BOOTP, so make the file and sname
|
/* We don't want to do option-overload for BOOTP, so make the file and sname
|
||||||
|
|||||||
+37
-23
@@ -46,12 +46,13 @@ void tftp_request(struct listener *listen, time_t now)
|
|||||||
struct sockaddr_in addr, peer;
|
struct sockaddr_in addr, peer;
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct iovec iov;
|
struct iovec iov;
|
||||||
int is_err = 1, if_index = 0;
|
struct ifreq ifr;
|
||||||
|
int is_err = 1, if_index = 0, mtu = 0;
|
||||||
struct iname *tmp;
|
struct iname *tmp;
|
||||||
struct tftp_transfer *transfer;
|
struct tftp_transfer *transfer;
|
||||||
int port = daemon->start_tftp_port; /* may be zero to use ephemeral port */
|
int port = daemon->start_tftp_port; /* may be zero to use ephemeral port */
|
||||||
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
|
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
|
||||||
int mtu = IP_PMTUDISC_DONT;
|
int mtuflag = IP_PMTUDISC_DONT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
union {
|
union {
|
||||||
@@ -83,7 +84,10 @@ void tftp_request(struct listener *listen, time_t now)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (daemon->options & OPT_NOWILD)
|
if (daemon->options & OPT_NOWILD)
|
||||||
addr = listen->iface->addr.in;
|
{
|
||||||
|
addr = listen->iface->addr.in;
|
||||||
|
mtu = listen->iface->mtu;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char name[IF_NAMESIZE];
|
char name[IF_NAMESIZE];
|
||||||
@@ -125,7 +129,10 @@ void tftp_request(struct listener *listen, time_t now)
|
|||||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||||
if (tmp->name && (strcmp(tmp->name, name) == 0))
|
if (tmp->name && (strcmp(tmp->name, name) == 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
strncpy(name, ifr.ifr_name, IF_NAMESIZE);
|
||||||
|
if (ioctl(listen->tftpfd, SIOCGIFMTU, &ifr) != -1)
|
||||||
|
mtu = ifr.ifr_mtu;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr.sin_port = htons(port);
|
addr.sin_port = htons(port);
|
||||||
@@ -158,7 +165,7 @@ void tftp_request(struct listener *listen, time_t now)
|
|||||||
{
|
{
|
||||||
if (bind(transfer->sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1 ||
|
if (bind(transfer->sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1 ||
|
||||||
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
|
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
|
||||||
setsockopt(transfer->sockfd, SOL_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu)) == -1 ||
|
setsockopt(transfer->sockfd, SOL_IP, IP_MTU_DISCOVER, &mtuflag, sizeof(mtuflag)) == -1 ||
|
||||||
#endif
|
#endif
|
||||||
!fix_fd(transfer->sockfd))
|
!fix_fd(transfer->sockfd))
|
||||||
{
|
{
|
||||||
@@ -192,42 +199,50 @@ void tftp_request(struct listener *listen, time_t now)
|
|||||||
|
|
||||||
while ((opt = next(&p, end)))
|
while ((opt = next(&p, end)))
|
||||||
{
|
{
|
||||||
if (strcasecmp(opt, "blksize") == 0 &&
|
if (strcasecmp(opt, "blksize") == 0)
|
||||||
(opt = next(&p, end)) &&
|
|
||||||
!(daemon->options & OPT_TFTP_NOBLOCK))
|
|
||||||
{
|
{
|
||||||
transfer->blocksize = atoi(opt);
|
if ((opt = next(&p, end)) &&
|
||||||
if (transfer->blocksize < 1)
|
!(daemon->options & OPT_TFTP_NOBLOCK))
|
||||||
transfer->blocksize = 1;
|
{
|
||||||
if (transfer->blocksize > (unsigned)daemon->packet_buff_sz - 4)
|
transfer->blocksize = atoi(opt);
|
||||||
transfer->blocksize = (unsigned)daemon->packet_buff_sz - 4;
|
if (transfer->blocksize < 1)
|
||||||
transfer->opt_blocksize = 1;
|
transfer->blocksize = 1;
|
||||||
transfer->block = 0;
|
if (transfer->blocksize > (unsigned)daemon->packet_buff_sz - 4)
|
||||||
|
transfer->blocksize = (unsigned)daemon->packet_buff_sz - 4;
|
||||||
|
/* 32 bytes for IP, UDP and TFTP headers */
|
||||||
|
if (mtu != 0 && transfer->blocksize > (unsigned)mtu - 32)
|
||||||
|
transfer->blocksize = (unsigned)mtu - 32;
|
||||||
|
transfer->opt_blocksize = 1;
|
||||||
|
transfer->block = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (strcasecmp(opt, "tsize") == 0 && next(&p, end) && !transfer->netascii)
|
||||||
if (strcasecmp(opt, "tsize") == 0 && next(&p, end) && !transfer->netascii)
|
|
||||||
{
|
{
|
||||||
transfer->opt_transize = 1;
|
transfer->opt_transize = 1;
|
||||||
transfer->block = 0;
|
transfer->block = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* cope with backslashes from windows boxen. */
|
||||||
|
while ((p = strchr(filename, '\\')))
|
||||||
|
*p = '/';
|
||||||
|
|
||||||
strcpy(daemon->namebuff, "/");
|
strcpy(daemon->namebuff, "/");
|
||||||
if (daemon->tftp_prefix)
|
if (daemon->tftp_prefix)
|
||||||
{
|
{
|
||||||
if (daemon->tftp_prefix[0] == '/')
|
if (daemon->tftp_prefix[0] == '/')
|
||||||
daemon->namebuff[0] = 0;
|
daemon->namebuff[0] = 0;
|
||||||
strncat(daemon->namebuff, daemon->tftp_prefix, MAXDNAME);
|
strncat(daemon->namebuff, daemon->tftp_prefix, (MAXDNAME-1) - strlen(daemon->namebuff));
|
||||||
if (daemon->tftp_prefix[strlen(daemon->tftp_prefix)-1] != '/')
|
if (daemon->tftp_prefix[strlen(daemon->tftp_prefix)-1] != '/')
|
||||||
strncat(daemon->namebuff, "/", MAXDNAME);
|
strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff));
|
||||||
|
|
||||||
if (daemon->options & OPT_TFTP_APREF)
|
if (daemon->options & OPT_TFTP_APREF)
|
||||||
{
|
{
|
||||||
size_t oldlen = strlen(daemon->namebuff);
|
size_t oldlen = strlen(daemon->namebuff);
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
|
||||||
strncat(daemon->namebuff, inet_ntoa(peer.sin_addr), MAXDNAME);
|
strncat(daemon->namebuff, inet_ntoa(peer.sin_addr), (MAXDNAME-1) - strlen(daemon->namebuff));
|
||||||
strncat(daemon->namebuff, "/", MAXDNAME);
|
strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff));
|
||||||
|
|
||||||
/* remove unique-directory if it doesn't exist */
|
/* remove unique-directory if it doesn't exist */
|
||||||
if (stat(daemon->namebuff, &statbuf) == -1 || !S_ISDIR(statbuf.st_mode))
|
if (stat(daemon->namebuff, &statbuf) == -1 || !S_ISDIR(statbuf.st_mode))
|
||||||
@@ -245,8 +260,7 @@ void tftp_request(struct listener *listen, time_t now)
|
|||||||
}
|
}
|
||||||
else if (filename[0] == '/')
|
else if (filename[0] == '/')
|
||||||
daemon->namebuff[0] = 0;
|
daemon->namebuff[0] = 0;
|
||||||
strncat(daemon->namebuff, filename, MAXDNAME);
|
strncat(daemon->namebuff, filename, (MAXDNAME-1) - strlen(daemon->namebuff));
|
||||||
daemon->namebuff[MAXDNAME-1] = 0;
|
|
||||||
|
|
||||||
/* check permissions and open file */
|
/* check permissions and open file */
|
||||||
if ((transfer->file = check_tftp_fileperm(&len)))
|
if ((transfer->file = check_tftp_fileperm(&len)))
|
||||||
|
|||||||
+91
-26
@@ -24,6 +24,9 @@
|
|||||||
#include <sys/times.h>
|
#include <sys/times.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef LOCALEDIR
|
||||||
|
#include <idna.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_ARC4RANDOM
|
#ifdef HAVE_ARC4RANDOM
|
||||||
void rand_init(void)
|
void rand_init(void)
|
||||||
@@ -95,48 +98,110 @@ unsigned short rand16(void)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int check_name(char *in)
|
||||||
int legal_char(char c)
|
|
||||||
{
|
{
|
||||||
/* check for legal char a-z A-Z 0-9 -
|
/* remove trailing .
|
||||||
(also / , used for RFC2317 and _ used in windows queries
|
|
||||||
and space, for DNS-SD stuff) */
|
|
||||||
if ((c >= 'A' && c <= 'Z') ||
|
|
||||||
(c >= 'a' && c <= 'z') ||
|
|
||||||
(c >= '0' && c <= '9') ||
|
|
||||||
c == '-' || c == '/' || c == '_' || c == ' ')
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int canonicalise(char *s)
|
|
||||||
{
|
|
||||||
/* check for legal chars and remove trailing .
|
|
||||||
also fail empty string and label > 63 chars */
|
also fail empty string and label > 63 chars */
|
||||||
size_t dotgap = 0, l = strlen(s);
|
size_t dotgap = 0, l = strlen(in);
|
||||||
char c;
|
char c;
|
||||||
int nowhite = 0;
|
int nowhite = 0;
|
||||||
|
|
||||||
if (l == 0 || l > MAXDNAME) return 0;
|
if (l == 0 || l > MAXDNAME) return 0;
|
||||||
|
|
||||||
if (s[l-1] == '.')
|
if (in[l-1] == '.')
|
||||||
{
|
{
|
||||||
if (l == 1) return 0;
|
if (l == 1) return 0;
|
||||||
s[l-1] = 0;
|
in[l-1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((c = *s))
|
for (; (c = *in); in++)
|
||||||
{
|
{
|
||||||
if (c == '.')
|
if (c == '.')
|
||||||
dotgap = 0;
|
dotgap = 0;
|
||||||
else if (!legal_char(c) || (++dotgap > MAXLABEL))
|
else if (++dotgap > MAXLABEL)
|
||||||
return 0;
|
return 0;
|
||||||
|
else if (isascii(c) && iscntrl(c))
|
||||||
|
/* iscntrl only gives expected results for ascii */
|
||||||
|
return 0;
|
||||||
|
#ifndef LOCALEDIR
|
||||||
|
else if (!isascii(c))
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
else if (c != ' ')
|
else if (c != ' ')
|
||||||
nowhite = 1;
|
nowhite = 1;
|
||||||
s++;
|
|
||||||
}
|
}
|
||||||
return nowhite;
|
|
||||||
|
if (!nowhite)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hostnames have a more limited valid charset than domain names
|
||||||
|
so check for legal char a-z A-Z 0-9 - _
|
||||||
|
Note that this may receive a FQDN, so only check the first label
|
||||||
|
for the tighter criteria. */
|
||||||
|
int legal_hostname(char *name)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
|
||||||
|
if (!check_name(name))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (; (c = *name); name++)
|
||||||
|
/* check for legal char a-z A-Z 0-9 - _ . */
|
||||||
|
{
|
||||||
|
if ((c >= 'A' && c <= 'Z') ||
|
||||||
|
(c >= 'a' && c <= 'z') ||
|
||||||
|
(c >= '0' && c <= '9') ||
|
||||||
|
c == '-' || c == '_')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* end of hostname part */
|
||||||
|
if (c == '.')
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *canonicalise(char *in, int *nomem)
|
||||||
|
{
|
||||||
|
char *ret = NULL;
|
||||||
|
#ifdef LOCALEDIR
|
||||||
|
int rc;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (nomem)
|
||||||
|
*nomem = 0;
|
||||||
|
|
||||||
|
if (!check_name(in))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
#ifdef LOCALEDIR
|
||||||
|
if ((rc = idna_to_ascii_lz(in, &ret, 0)) != IDNA_SUCCESS)
|
||||||
|
{
|
||||||
|
if (ret)
|
||||||
|
free(ret);
|
||||||
|
|
||||||
|
if (nomem && (rc == IDNA_MALLOC_ERROR || rc == IDNA_DLOPEN_ERROR))
|
||||||
|
{
|
||||||
|
my_syslog(LOG_ERR, _("failed to allocate memory"));
|
||||||
|
*nomem = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if ((ret = whine_malloc(strlen(in)+1)))
|
||||||
|
strcpy(ret, in);
|
||||||
|
else if (nomem)
|
||||||
|
*nomem = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char *do_rfc1035_name(unsigned char *p, char *sval)
|
unsigned char *do_rfc1035_name(unsigned char *p, char *sval)
|
||||||
|
|||||||
Reference in new issue
Block a user