Commit c72daea8 authored by Simon Kelley's avatar Simon Kelley

Accumulated 2.60 changes going into git

parent 74c95c25
shlibs:Depends=libc6 (>= 2.1)
version 2.60
Fix compilation problem in Mac OS X Lion. Thanks to Olaf
Flebbe for the patch.
Fix DHCP when using --listen-address with an IP address
which is not the primary address of an interface.
Add --dhcp-client-update option.
Add Lua integration. Dnsmasq can now execute a DHCP
lease-change script written in Lua. This needs to be
enabled at compile time by setting HAVE_LUASCRIPT in
src/config.h or running "make COPTS=-DHAVE_LUASCRIPT"
Thanks to Jan-Piet Mens for the idea and proof-of-concept
implementation.
Tidied src/config.h to distinguish between
platform-dependent compile-time options which are selected
automatically, and builder-selectable compile time
options. Document the latter better, and describe how to
set them from the make command line.
Tidied up IPPROTO_IP/SOL_IP (and IPv6 equivalent)
confusion. IPPROTO_IP works everywhere now.
Set TOS on DHCP sockets, this improves things on busy
wireless networks. Thanks to Dave Taht for the patch.
version 2.59 version 2.59
Fix regression in 2.58 which caused failure to start up Fix regression in 2.58 which caused failure to start up
with some combinations of dnsmasq config and IPv6 kernel with some combinations of dnsmasq config and IPv6 kernel
......
...@@ -38,16 +38,18 @@ IDN_CFLAGS= `echo $(COPTS) | ../bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) --cflags ...@@ -38,16 +38,18 @@ IDN_CFLAGS= `echo $(COPTS) | ../bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) --cflags
IDN_LIBS= `echo $(COPTS) | ../bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) --libs libidn` IDN_LIBS= `echo $(COPTS) | ../bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) --libs libidn`
CT_CFLAGS= `echo $(COPTS) | ../bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --cflags libnetfilter_conntrack` CT_CFLAGS= `echo $(COPTS) | ../bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --cflags libnetfilter_conntrack`
CT_LIBS= `echo $(COPTS) | ../bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --libs libnetfilter_conntrack` CT_LIBS= `echo $(COPTS) | ../bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --libs libnetfilter_conntrack`
LUA_CFLAGS=`echo $(COPTS) | ../bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --cflags lua5.1`
LUA_LIBS= `echo $(COPTS) | ../bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --libs lua5.1`
SUNOS_LIBS= `if uname | grep SunOS 2>&1 >/dev/null; then echo -lsocket -lnsl -lposix4; fi` SUNOS_LIBS= `if uname | grep SunOS 2>&1 >/dev/null; then echo -lsocket -lnsl -lposix4; fi`
OBJS = cache.o rfc1035.o util.o option.o forward.o network.o \ OBJS = cache.o rfc1035.o util.o option.o forward.o network.o \
dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \ dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \
helper.o tftp.o log.o conntrack.o helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o
all : all :
@cd $(SRC) && $(MAKE) \ @cd $(SRC) && $(MAKE) \
BUILD_CFLAGS="$(DBUS_CFLAGS) $(IDN_CFLAGS) $(CT_CFLAGS)" \ BUILD_CFLAGS="$(DBUS_CFLAGS) $(IDN_CFLAGS) $(CT_CFLAGS) $(LUA_CFLAGS)" \
BUILD_LIBS="$(DBUS_LIBS) $(IDN_LIBS) $(CT_LIBS) $(SUNOS_LIBS)" \ BUILD_LIBS="$(DBUS_LIBS) $(IDN_LIBS) $(CT_LIBS) $(LUA_LIBS) $(SUNOS_LIBS)" \
-f ../Makefile dnsmasq -f ../Makefile dnsmasq
clean : clean :
...@@ -64,8 +66,8 @@ install-common : ...@@ -64,8 +66,8 @@ install-common :
all-i18n : all-i18n :
@cd $(SRC) && $(MAKE) \ @cd $(SRC) && $(MAKE) \
I18N=-DLOCALEDIR='\"$(LOCALEDIR)\"' \ I18N=-DLOCALEDIR='\"$(LOCALEDIR)\"' \
BUILD_CFLAGS="$(DBUS_CFLAGS) $(CT_CFLAGS) `$(PKG_CONFIG) --cflags libidn`" \ BUILD_CFLAGS="$(DBUS_CFLAGS) $(CT_CFLAGS) $(LUA_CFLAGS) `$(PKG_CONFIG) --cflags libidn`" \
BUILD_LIBS="$(DBUS_LIBS) $(CT_LIBS) $(SUNOS_LIBS) `$(PKG_CONFIG) --libs libidn`" \ BUILD_LIBS="$(DBUS_LIBS) $(CT_LIBS) $(LUA_LIBS) $(SUNOS_LIBS) `$(PKG_CONFIG) --libs libidn`" \
-f ../Makefile dnsmasq -f ../Makefile dnsmasq
@cd $(PO); for f in *.po; do \ @cd $(PO); for f in *.po; do \
cd ../$(SRC) && $(MAKE) \ cd ../$(SRC) && $(MAKE) \
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
search=$1 search=$1
shift shift
if grep "^\#.*define.*$search" config.h 2>&1 >/dev/null || \ if grep "^\#[[:space:]]*define[[:space:]]*$search" config.h 2>&1 >/dev/null || \
grep $search 2>&1 >/dev/null ; then grep $search 2>&1 >/dev/null ; then
exec $* exec $*
fi fi
......
This diff is collapsed.
/etc/init.d/dnsmasq
/etc/default/dnsmasq
/etc/dnsmasq.conf
/etc/resolvconf/update.d/dnsmasq
/etc/dbus-1/system.d/dnsmasq.conf
/etc/insserv.conf.d/dnsmasq
Source: dnsmasq
Section: net
Priority: optional
Build-depends: gettext, libnetfilter-conntrack-dev [linux-any], libidn11-dev, libdbus-1-dev (>=0.61)
Maintainer: Simon Kelley <simon@thekelleys.org.uk>
Standards-Version: 3.9.2
Package: dnsmasq
Architecture: all
Depends: netbase, adduser, dnsmasq-base(>= ${source:Version})
Suggests: resolvconf
Conflicts: resolvconf (<<1.15)
Description: Small caching DNS proxy and DHCP/TFTP server
Dnsmasq is a lightweight, easy to configure, DNS forwarder and DHCP
server. It is designed to provide DNS and optionally, DHCP, to a
small network. It can serve the names of local machines which are
not in the global DNS. The DHCP server integrates with the DNS
server and allows machines with DHCP-allocated addresses
to appear in the DNS with names configured either in each host or
in a central configuration file. Dnsmasq supports static and dynamic
DHCP leases and BOOTP/TFTP for network booting of diskless machines.
Package: dnsmasq-base
Architecture: any
Depends: ${shlibs:Depends}
Conflicts: dnsmasq (<<2.41)
Description: Small caching DNS proxy and DHCP/TFTP server
This package contains the dnsmasq executable and documentation, but
not the infrastructure required to run it as a system daemon. For
that, install the dnsmasq package.
Package: dnsmasq-utils
Architecture: linux-any
Depends: ${shlibs:Depends}
Conflicts: dnsmasq (<<2.40)
Description: Utilities for manipulating DHCP leases
Small utilities to query a DHCP server's lease database and
remove leases from it. These programs are distributed with dnsmasq
and may not work correctly with other DHCP servers.
dnsmasq is Copyright (c) 2000-2010 Simon Kelley
It was downloaded from: http://www.thekelleys.org.uk/dnsmasq/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
On Debian GNU/Linux systems, the text of the GNU general public license is
available in the file /usr/share/common-licenses/GPL-2 or
/usr/share/common-licenses/GPL-3
The Debian package of dnsmasq was created by Simon Kelley with assistance
from Lars Bahner.
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<policy user="root">
<allow own="uk.org.thekelleys.dnsmasq"/>
<allow send_destination="uk.org.thekelleys.dnsmasq"/>
</policy>
<policy user="dnsmasq">
<allow own="uk.org.thekelleys.dnsmasq"/>
<allow send_destination="uk.org.thekelleys.dnsmasq"/>
</policy>
<policy context="default">
<deny own="uk.org.thekelleys.dnsmasq"/>
<deny send_destination="uk.org.thekelleys.dnsmasq"/>
</policy>
</busconfig>
# This file has five functions:
# 1) to completely disable starting dnsmasq,
# 2) to set DOMAIN_SUFFIX by running `dnsdomainname`
# 3) to select an alternative config file
# by setting DNSMASQ_OPTS to --conf-file=<file>
# 4) to tell dnsmasq to read the files in /etc/dnsmasq.d for
# more configuration variables.
# 5) to stop the resolvconf package from controlling dnsmasq's
# idea of which upstream nameservers to use.
# For upgraders from very old versions, all the shell variables set
# here in previous versions are still honored by the init script
# so if you just keep your old version of this file nothing will break.
#DOMAIN_SUFFIX=`dnsdomainname`
#DNSMASQ_OPTS="--conf-file=/etc/dnsmasq.alt"
# Whether or not to run the dnsmasq daemon; set to 0 to disable.
ENABLED=1
# By default search this drop directory for configuration options.
# Libvirt leaves a file here to make the system dnsmasq play nice.
# Comment out this line if you don't want this. The dpkg-* are file
# endings which cause dnsmasq to skip that file. This avoids pulling
# in backups made by dpkg.
CONFIG_DIR=/etc/dnsmasq.d,.dpkg-dist,.dpkg-old,.dpkg-new
# If the resolvconf package is installed, dnsmasq will use its output
# rather than the contents of /etc/resolv.conf to find upstream
# nameservers. Uncommenting this line inhibits this behaviour.
# Not that including a "resolv-file=<filename>" line in
# /etc/dnsmasq.conf is not enough to override resolvconf if it is
# installed: the line below must be uncommented.
#IGNORE_RESOLVCONF=yes
#!/bin/sh
### BEGIN INIT INFO
# Provides: dnsmasq
# Required-Start: $network $remote_fs $syslog
# Required-Stop: $network $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: DHCP and DNS server
### END INIT INFO
set +e # Don't exit on error status
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/dnsmasq
NAME=dnsmasq
DESC="DNS forwarder and DHCP server"
# Most configuration options in /etc/default/dnsmasq are deprecated
# but still honoured.
ENABLED=1
if [ -r /etc/default/$NAME ]; then
. /etc/default/$NAME
fi
# Get the system locale, so that messages are in the correct language, and the
# charset for IDN is correct
if [ -r /etc/default/locale ]; then
. /etc/default/locale
export LANG
fi
test -x $DAEMON || exit 0
# Provide skeleton LSB log functions for backports which don't have LSB functions.
if [ -f /lib/lsb/init-functions ]; then
. /lib/lsb/init-functions
else
log_warning_msg () {
echo "${@}."
}
log_success_msg () {
echo "${@}."
}
log_daemon_msg () {
echo -n "${1}: $2"
}
log_end_msg () {
if [ $1 -eq 0 ]; then
echo "."
elif [ $1 -eq 255 ]; then
/bin/echo -e " (warning)."
else
/bin/echo -e " failed!"
fi
}
fi
# RESOLV_CONF:
# If the resolvconf package is installed then use the resolv conf file
# that it provides as the default. Otherwise use /etc/resolv.conf as
# the default.
#
# If IGNORE_RESOLVCONF is set in /etc/default/dnsmasq or an explicit
# filename is set there then this inhibits the use of the resolvconf-provided
# information.
#
# Note that if the resolvconf package is installed it is not possible to
# override it just by configuration in /etc/dnsmasq.conf, it is necessary
# to set IGNORE_RESOLVCONF=yes in /etc/default/dnsmasq.
if [ ! "$RESOLV_CONF" ] &&
[ "$IGNORE_RESOLVCONF" != "yes" ] &&
[ -x /sbin/resolvconf ]
then
RESOLV_CONF=/var/run/dnsmasq/resolv.conf
fi
for INTERFACE in $DNSMASQ_INTERFACE; do
DNSMASQ_INTERFACES="$DNSMASQ_INTERFACES -i $INTERFACE"
done
for INTERFACE in $DNSMASQ_EXCEPT; do
DNSMASQ_INTERFACES="$DNSMASQ_INTERFACES -I $INTERFACE"
done
if [ ! "$DNSMASQ_USER" ]; then
DNSMASQ_USER="dnsmasq"
fi
start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
# /var/run may be volatile, so we need to ensure that
# /var/run/dnsmasq exists here as well as in postinst
if [ ! -d /var/run/dnsmasq ]; then
mkdir /var/run/dnsmasq || return 2
chown dnsmasq:nogroup /var/run/dnsmasq || return 2
fi
start-stop-daemon --start --quiet --pidfile /var/run/dnsmasq/$NAME.pid --exec $DAEMON --test > /dev/null || return 1
start-stop-daemon --start --quiet --pidfile /var/run/dnsmasq/$NAME.pid --exec $DAEMON -- \
-x /var/run/dnsmasq/$NAME.pid \
${MAILHOSTNAME:+ -m $MAILHOSTNAME} \
${MAILTARGET:+ -t $MAILTARGET} \
${DNSMASQ_USER:+ -u $DNSMASQ_USER} \
${DNSMASQ_INTERFACES:+ $DNSMASQ_INTERFACES} \
${DHCP_LEASE:+ -l $DHCP_LEASE} \
${DOMAIN_SUFFIX:+ -s $DOMAIN_SUFFIX} \
${RESOLV_CONF:+ -r $RESOLV_CONF} \
${CACHESIZE:+ -c $CACHESIZE} \
${CONFIG_DIR:+ -7 $CONFIG_DIR} \
${DNSMASQ_OPTS:+ $DNSMASQ_OPTS} \
|| return 2
}
start_resolvconf()
{
# If interface "lo" is explicitly disabled in /etc/default/dnsmasq
# Then dnsmasq won't be providing local DNS, so don't add it to
# the resolvconf server set.
for interface in $DNSMASQ_EXCEPT
do
[ $interface = lo ] && return
done
if [ -x /sbin/resolvconf ] ; then
echo "nameserver 127.0.0.1" | /sbin/resolvconf -a lo.$NAME
fi
return 0
}
stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile /var/run/dnsmasq/$NAME.pid --name $NAME
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
return "$RETVAL"
}
stop_resolvconf()
{
if [ -x /sbin/resolvconf ] ; then
/sbin/resolvconf -d lo.$NAME
fi
return 0
}
status()
{
# Return
# 0 if daemon is running
# 1 if daemon is dead and pid file exists
# 3 if daemon is not running
# 4 if daemon status is unknown
start-stop-daemon --start --quiet --pidfile /var/run/dnsmasq/$NAME.pid --exec $DAEMON --test > /dev/null
case "$?" in
0) [ -e "/var/run/dnsmasq/$NAME.pid" ] && return 1 ; return 3 ;;
1) return 0 ;;
*) return 4 ;;
esac
}
case "$1" in
start)
test "$ENABLED" != "0" || exit 0
log_daemon_msg "Starting $DESC" "$NAME"
start
case "$?" in
0)
log_end_msg 0
start_resolvconf
exit 0
;;
1)
log_success_msg "(already running)"
exit 0
;;
*)
log_end_msg 1
exit 1
;;
esac
;;
stop)
stop_resolvconf
if [ "$ENABLED" != "0" ]; then
log_daemon_msg "Stopping $DESC" "$NAME"
fi
stop
RETVAL="$?"
if [ "$ENABLED" = "0" ]; then
case "$RETVAL" in
0) log_daemon_msg "Stopping $DESC" "$NAME"; log_end_msg 0 ;;
esac
exit 0
fi
case "$RETVAL" in
0) log_end_msg 0 ; exit 0 ;;
1) log_warning_msg "(not running)" ; exit 0 ;;
*) log_end_msg 1; exit 1 ;;
esac
;;
restart|force-reload)
test "$ENABLED" != "0" || exit 1
$DAEMON --test ${CONFIG_DIR:+ -7 $CONFIG_DIR} ${DNSMASQ_OPTS:+ $DNSMASQ_OPTS} >/dev/null 2>&1
if [ $? -ne 0 ]; then
NAME="configuration syntax check"
RETVAL="2"
else
stop_resolvconf
stop
RETVAL="$?"
fi
log_daemon_msg "Restarting $DESC" "$NAME"
case "$RETVAL" in
0|1)
sleep 2
start
case "$?" in
0)
log_end_msg 0
start_resolvconf
exit 0
;;
*)
log_end_msg 1
exit 1
;;
esac
;;
*)
log_end_msg 1
exit 1
;;
esac
;;
status)
log_daemon_msg "Checking $DESC" "$NAME"
status
case "$?" in
0) log_success_msg "(running)" ; exit 0 ;;
1) log_success_msg "(dead, pid file exists)" ; exit 1 ;;
3) log_success_msg "(not running)" ; exit 3 ;;
*) log_success_msg "(unknown)" ; exit 4 ;;
esac
;;
*)
echo "Usage: /etc/init.d/$NAME {start|stop|restart|force-reload|status}" >&2
exit 3
;;
esac
exit 0
$named dnsmasq
#!/bin/sh
set -e
# create a user to run as (code stolen from dovecot-common)
if [ "$1" = "configure" ]; then
if [ -z "`id -u dnsmasq 2> /dev/null`" ]; then
adduser --system --home /var/lib/misc --gecos "dnsmasq" \
--no-create-home --disabled-password \
--quiet dnsmasq || true
fi
# Make the directory where we keep the pid file - this
# has to be owned by "dnsmasq" do that the file can be unlinked.
if [ ! -d /var/run/dnsmasq ]; then
mkdir /var/run/dnsmasq
chown dnsmasq:nogroup /var/run/dnsmasq
fi
# handle new location of pidfile during an upgrade
if [ -e /var/run/dnsmasq.pid ]; then
mv /var/run/dnsmasq.pid /var/run/dnsmasq
fi
fi
if [ -x /etc/init.d/dnsmasq ]; then
update-rc.d dnsmasq defaults 15 85 >/dev/null
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ]; then
if [ -e /var/run/dnsmasq/dnsmasq.pid ]; then
ACTION=restart
else
ACTION=start
fi
if [ -x /usr/sbin/invoke-rc.d ] ; then
invoke-rc.d dnsmasq $ACTION || true
else
/etc/init.d/dnsmasq $ACTION || true
fi
fi
fi
# dpkg can botch the change of /usr/share/doc/dnsmasq from
# directory to symlink. Fix up here.
if [ ! -h /usr/share/doc/dnsmasq ] && { rmdir /usr/share/doc/dnsmasq; }; then
cd /usr/share/doc/
ln -s /usr/share/doc/dnsmasq-base dnsmasq
fi
#!/bin/sh
set -e
if [ purge = "$1" ]; then
update-rc.d dnsmasq remove >/dev/null
if [ -x "$(command -v deluser)" ]; then
deluser --quiet --system dnsmasq > /dev/null || true
else
echo >&2 "not removing dnsmasq system account because deluser command was not found"
fi
rm -rf /var/run/dnsmasq
fi
#!/bin/sh
set -e
if [ "$1" = "remove" ]; then
if [ -x /usr/sbin/invoke-rc.d ] ; then
invoke-rc.d dnsmasq stop || true
else
/etc/init.d/dnsmasq stop || true
fi
fi
exit 0
Notes on configuring dnsmasq as packaged for Debian.
(1) To configure dnsmasq edit /etc/dnsmasq.conf. The file is well
commented; see also the dnsmasq.8 man page for explanation of
the options. The file /etc/default/dnsmasq also exists but it
shouldn't need to be touched in most cases. To set up DHCP
options you might need to refer to a copy of RFC 2132. This is
available on Debian systems in the package doc-rfc-std as the file
/usr/share/doc/RFC/draft-standard/rfc2132.txt.gz .
(2) Installing the dnsmasq package also creates the directory
/etc/dnsmasq.d which is searched by dnsmasq for configuration file
fragments. This behaviour can be disabled by editing
/etc/default/dnsmasq.
(3) If the Debian resolvconf package is installed then, regardless
of what interface configuration daemons are employed, the list of
nameservers to which dnsmasq should forward queries can be found
in /var/run/dnsmasq/resolv.conf; also, 127.0.0.1 is listed as the
first nameserver address in /etc/resolv.conf. This works using the
default configurations of resolvconf and dnsmasq.
(4) In the absence of resolvconf, if you are using dhcpcd then
dnsmasq should read the list of nameservers from the automatically
generated file /etc/dhcpc/resolv.conf. You should list 127.0.0.1
as the first nameserver address in /etc/resolv.conf.
(5) In the absence of resolvconf, if you are using pppd then
dnsmasq should read the list of nameservers from the automatically
generated file /etc/ppp/resolv.conf. You should list 127.0.0.1
as the first nameserver address in /etc/resolv.conf.
(6) In the absence of resolvconf, dns-nameservers lines in
/etc/network/interfaces are ignored. If you do do not use
resolvconf, list 127.0.0.1 as the first nameserver address
in /etc/resolv.conf and configure your nameservers using
"server=<IP-address>" lines in /etc/dnsmasq.conf.
(7) If you run multiple DNS servers on a single machine, each
listening on a different interface, then it is necessary to use
the bind-interfaces option by uncommenting "bind-interfaces" in
/etc/dnsmasq.conf. This option stops dnsmasq from binding the
wildcard address and allows servers listening on port 53 on
interfaces not in use by dnsmasq to work. The Debian
libvirt package will add a configuration file in /etc/dnsmasq.d
which does this so that the "system" dnsmasq and "private" dnsmasq
instances started by libvirt do not clash.
(8) The following options are supported in DEB_BUILD_OPTIONS
noopt : compile without optimisation.
nostrip : don't remove symbols from binary.
nodocs : omit documentation.
notftp : omit TFTP support.
nodhcp : omit DHCP support.
noscript : omit lease-change script support.
noipv6 : omit IPv6 support.
nodbus : omit DBus support.
noconntrack : omit connection tracking support.
nortc : compile alternate mode suitable for systems without an RTC.
noi18n : omit translations and internationalisation support.
noidn : omit international domain name support, must be
combined with noi18n to be effective.
(9) Dnsmasq comes as two packages - dnsmasq-base and
dnsmasq. dnsmasq-base provides the dnsmasq executable and
documentation (including this file). Dnsmasq, which depends on
dnsmasq-base, provides the init script and configuration
infrastructure. This file assumes that both are installed. It is
possible to install only dnsmasq-base and use dnsmasq as a
non-"system" daemon. Libvirt, for instance, does this.
# All files in this directory will be read by dnsmasq as
# configuration files, except if their names end in
# ".dpkg-dist",".dpkg-old" or ".dpkg-new"
#
# This can be changed by editing /etc/default/dnsmasq
#!/bin/bash
#
# Script to update the resolver list for dnsmasq
#
# N.B. Resolvconf may run us even if dnsmasq is not running.
# If dnsmasq is installed then we go ahead and update
# the resolver list in case dnsmasq is started later.
#
# Assumption: On entry, PWD contains the resolv.conf-type files
#
# Requires bash because it uses a non-POSIX printf extension.
#
# Licensed under the GNU GPL. See /usr/share/common-licenses/GPL.
#
set -e
RUN_DIR="/var/run/dnsmasq"
RSLVRLIST_FILE="${RUN_DIR}/resolv.conf"
TMP_FILE="${RSLVRLIST_FILE}_new.$$"
[ -x /usr/sbin/dnsmasq ] || exit 0
[ -x /lib/resolvconf/list-records ] || exit 1
PATH=/bin:/sbin
report_err() { echo "$0: Error: $*" >&2 ; }
# Stores arguments (minus duplicates) in RSLT, separated by spaces
# Doesn't work properly if an argument itself contain whitespace
uniquify()
{
RSLT=""
while [ "$1" ] ; do
for E in $RSLT ; do
[ "$1" = "$E" ] && { shift ; continue 2 ; }
done
RSLT="${RSLT:+$RSLT }$1"
shift
done
}
if [ ! -d "$RUN_DIR" ] && ! mkdir --parents --mode=0755 "$RUN_DIR" ; then
report_err "Failed trying to create directory $RUN_DIR"
exit 1
fi
RSLVCNFFILES="$(/lib/resolvconf/list-records | sed -e '/^lo.dnsmasq$/d')"
NMSRVRS=""
if [ "$RSLVCNFFILES" ] ; then
uniquify $(sed -n -e 's/^[[:space:]]*nameserver[[:space:]]\+//p' $RSLVCNFFILES)
NMSRVRS="$RSLT"
fi
# Dnsmasq uses the mtime of $RSLVRLIST_FILE, with a resolution of one second,
# to detect changes in the file. This means that if a resolvconf update occurs
# within one second of the previous one then dnsmasq may fail to notice the
# more recent change. To work around this problem we sleep here to ensure
# that the new mtime is different.
if [ -f "$RSLVRLIST_FILE" ] && [ "$(ls -go --time-style='+%s' "$RSLVRLIST_FILE" | { read p h s t n ; echo "$t" ; })" = "$(date +%s)" ] ; then
sleep 1
fi
clean_up() { rm -f "$TMP_FILE" ; }
trap clean_up EXIT
: >| "$TMP_FILE"
for N in $NMSRVRS ; do echo "nameserver $N" >> "$TMP_FILE" ; done
mv -f "$TMP_FILE" "$RSLVRLIST_FILE"
#!/bin/sh
# Resolvconf packaging event hook script for the dnsmasq package
restart_dnsmasq() {
if which invoke-rc.d >/dev/null 2>&1 ; then
invoke-rc.d dnsmasq restart
elif [ -x /etc/init.d/dnsmasq ] ; then
/etc/init.d/dnsmasq restart
fi
}
case "$1" in
install) restart_dnsmasq ;;
esac
#!/usr/bin/make -f
# debian/rules file - for dnsmasq.
# Copyright 2001-2011 by Simon Kelley
# Based on the sample in the debian hello package which carries the following:
# Copyright 1994,1995 by Ian Jackson.
# I hereby give you perpetual unlimited permission to copy,
# modify and relicense this file, provided that you do not remove
# my name from the file itself. (I assert my moral right of
# paternity under the Copyright, Designs and Patents Act 1988.)
# This file may have to be extensively modified
package=dnsmasq-base
# policy manual, section 10.1
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
CFLAGS = -g -O0 -Wall -W
else
CFLAGS = -g -O2 -Wall -W
endif
COPTS =
TARGET = install-i18n
DEB_BUILD_ARCH_OS := $(shell dpkg-architecture -qDEB_BUILD_ARCH_OS)
ifeq (,$(findstring nodbus,$(DEB_BUILD_OPTIONS)))
COPTS += -DHAVE_DBUS
endif
ifeq (,$(findstring noconntrack,$(DEB_BUILD_OPTIONS)))
ifeq ($(DEB_BUILD_ARCH_OS),linux)
COPTS += -DHAVE_CONNTRACK
endif
endif
ifneq (,$(findstring noipv6,$(DEB_BUILD_OPTIONS)))
COPTS += -DNO_IPV6
endif
ifneq (,$(findstring notftp,$(DEB_BUILD_OPTIONS)))
COPTS += -DNO_TFTP
endif
ifneq (,$(findstring nodhcp,$(DEB_BUILD_OPTIONS)))
COPTS += -DNO_DHCP
endif
ifneq (,$(findstring noscript,$(DEB_BUILD_OPTIONS)))
COPTS += -DNO_SCRIPT
endif
ifneq (,$(findstring nortc,$(DEB_BUILD_OPTIONS)))
COPTS += -DHAVE_BROKEN_RTC
endif
ifneq (,$(findstring noi18n,$(DEB_BUILD_OPTIONS)))
TARGET = install
ifeq (,$(findstring noidn, $(DEB_BUILD_OPTIONS)))
COPTS += -DHAVE_IDN
endif
endif
clean:
$(checkdir)
rm -rf debian/daemon debian/base debian/utils debian/*~ debian/files debian/substvars debian/utils-substvars
make clean
make -C contrib/wrt clean
binary-indep: checkroot
$(checkdir)
rm -rf debian/daemon
install -m 755 \
-d debian/daemon/DEBIAN \
-d debian/daemon/usr/share/doc \
-d debian/daemon/etc/init.d \
-d debian/daemon/etc/dnsmasq.d \
-d debian/daemon/etc/resolvconf/update.d \
-d debian/daemon/usr/lib/resolvconf/dpkg-event.d \
-d debian/daemon/etc/default \
-d debian/daemon/etc/dbus-1/system.d \
-d debian/daemon/lib/systemd/system \
-d debian/daemon/etc/insserv.conf.d
install -m 644 debian/conffiles debian/daemon/DEBIAN
install -m 755 debian/postinst debian/postrm debian/prerm debian/daemon/DEBIAN
install -m 755 debian/init debian/daemon/etc/init.d/dnsmasq
install -m 755 debian/resolvconf debian/daemon/etc/resolvconf/update.d/dnsmasq
install -m 755 debian/resolvconf-package debian/daemon/usr/lib/resolvconf/dpkg-event.d/dnsmasq
install -m 644 debian/default debian/daemon/etc/default/dnsmasq
install -m 644 dnsmasq.conf.example debian/daemon/etc/dnsmasq.conf
install -m 644 debian/readme.dnsmasq.d debian/daemon/etc/dnsmasq.d/README
install -m 644 debian/dbus.conf debian/daemon/etc/dbus-1/system.d/dnsmasq.conf
install -m 644 debian/systemd.service debian/daemon/lib/systemd/system/dnsmasq.service
install -m 644 debian/insserv debian/daemon/etc/insserv.conf.d/dnsmasq
ln -s $(package) debian/daemon/usr/share/doc/dnsmasq
cd debian/daemon && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | xargs -r0 md5sum > DEBIAN/md5sums
dpkg-gencontrol -pdnsmasq -Pdebian/daemon
chown -R root.root debian/daemon
chmod -R g-ws debian/daemon
dpkg --build debian/daemon ..
binary-arch: checkroot
$(checkdir)
rm -rf debian/base
install -m 755 \
-d debian/base/DEBIAN \
-d debian/base/usr/share/doc/$(package) \
-d debian/base/usr/share/doc/$(package)/examples \
-d debian/base/var/run \
-d debian/base/var/lib/misc
make $(TARGET) PREFIX=/usr DESTDIR=`pwd`/debian/base CFLAGS="$(CFLAGS)" COPTS="$(COPTS)" CC=gcc
ifeq (,$(findstring nodocs,$(DEB_BUILD_OPTIONS)))
install -m 644 doc.html debian/base/usr/share/doc/$(package)/.
install -m 644 setup.html debian/base/usr/share/doc/$(package)/.
install -m 644 dnsmasq.conf.example debian/base/usr/share/doc/$(package)/examples/.
install -m 644 FAQ debian/base/usr/share/doc/$(package)/.
gzip -9 debian/base/usr/share/doc/$(package)/FAQ
install -m 644 CHANGELOG debian/base/usr/share/doc/$(package)/changelog
gzip -9 debian/base/usr/share/doc/$(package)/changelog
install -m 644 CHANGELOG.archive debian/base/usr/share/doc/$(package)/changelog.archive
gzip -9 debian/base/usr/share/doc/$(package)/changelog.archive
install -m 644 dbus/DBus-interface debian/base/usr/share/doc/$(package)/.
gzip -9 debian/base/usr/share/doc/$(package)/DBus-interface
endif
install -m 644 debian/changelog debian/base/usr/share/doc/$(package)/changelog.Debian
gzip -9 debian/base/usr/share/doc/$(package)/changelog.Debian
install -m 644 debian/readme debian/base/usr/share/doc/$(package)/README.Debian
install -m 644 debian/copyright debian/base/usr/share/doc/$(package)/copyright
gzip -9 debian/base/usr/share/man/man8/dnsmasq.8
for f in debian/base/usr/share/man/*; do \
if [ -f $$f/man8/dnsmasq.8 ]; then \
gzip -9 $$f/man8/dnsmasq.8 ; \
fi \
done
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
strip -R .note -R .comment debian/base/usr/sbin/dnsmasq
endif
cd debian/base && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | xargs -r0 md5sum > DEBIAN/md5sums
dpkg-shlibdeps debian/base/usr/sbin/dnsmasq
dpkg-gencontrol -pdnsmasq-base -Pdebian/base
chown -R root.root debian/base
chmod -R g-ws debian/base
dpkg --build debian/base ..
ifeq ($(DEB_BUILD_ARCH_OS),linux)
rm -rf debian/utils
install -m 755 -d debian/utils/DEBIAN \
-d debian/utils/usr/share/man/man1 \
-d debian/utils/usr/bin \
-d debian/utils/usr/share/doc/dnsmasq-utils
make -C contrib/wrt PREFIX=/usr DESTDIR=`pwd`/debian/utils CFLAGS="$(CFLAGS)" COPTS="$(COPTS)" CC=gcc
install -m 755 contrib/wrt/dhcp_release debian/utils/usr/bin/dhcp_release
install -m 644 contrib/wrt/dhcp_release.1 debian/utils/usr/share/man/man1/dhcp_release.1
gzip -9 debian/utils/usr/share/man/man1/dhcp_release.1
install -m 755 contrib/wrt/dhcp_lease_time debian/utils/usr/bin/dhcp_lease_time
install -m 644 contrib/wrt/dhcp_lease_time.1 debian/utils/usr/share/man/man1/dhcp_lease_time.1
install -m 644 debian/copyright debian/utils/usr/share/doc/dnsmasq-utils/copyright
install -m 644 debian/changelog debian/utils/usr/share/doc/dnsmasq-utils/changelog.Debian
gzip -9 debian/utils/usr/share/doc/dnsmasq-utils/changelog.Debian
gzip -9 debian/utils/usr/share/man/man1/dhcp_lease_time.1
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
strip -R .note -R .comment debian/utils/usr/bin/dhcp_release
strip -R .note -R .comment debian/utils/usr/bin/dhcp_lease_time
endif
cd debian/utils && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | xargs -r0 md5sum > DEBIAN/md5sums
dpkg-shlibdeps -Tdebian/utils-substvars debian/utils/usr/bin/dhcp_release debian/utils/usr/bin/dhcp_lease_time
dpkg-gencontrol -Tdebian/utils-substvars -pdnsmasq-utils -Pdebian/utils
chown -R root.root debian/utils
chmod -R g-ws debian/utils
dpkg --build debian/utils ..
endif
define checkdir
test -f Makefile -a -f debian/rules
endef
# Below here is fairly generic really
binary: binary-arch binary-indep
build:
checkroot:
test root = "`whoami`"
.PHONY: binary binary-arch binary-indep clean checkroot
[Unit]
Description=A lightweight DHCP and caching DNS server
[Service]
Type=dbus
BusName=uk.org.thekelleys.dnsmasq
# Test the config file and refuse starting if it is not valid.
ExecStartPre=/usr/sbin/dnsmasq --test
# Enable DBus by default because we use DBus activation.
#
# Drop privileges and become the 'dnsmasq' user. It is recommended by dnsmasq
# upstream to run dnsmasq as an isolated user that does not run any other
# processes, owns no files and has no shell. The default 'nobody' user has a
# shell and might be used for other processes.
#
# Debian-specific: add /etc/dnsmasq.d to config search path (with the exception
# of .dpkg-*). Packages such as libvirt leave config files there.
#
# --pid-file without argument disables writing a PIDfile, we don't need one.
ExecStart=/usr/sbin/dnsmasq -k \
--enable-dbus \
--user=dnsmasq \
-7 /etc/dnsmasq.d,.dpkg-dist,.dpkg-old,.dpkg-new \
--pid-file
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
...@@ -51,7 +51,7 @@ apply to domain names in cnames, PTR records, TXT records etc. ...@@ -51,7 +51,7 @@ apply to domain names in cnames, PTR records, TXT records etc.
.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
file dnsmasq by default sets the time-to-live field to zero, meaning file dnsmasq by default sets the time-to-live field to zero, meaning
that the requestor should not itself cache the information. This is that the requester should not itself cache the information. This is
the correct thing to do in almost all situations. This option allows a the correct thing to do in almost all situations. This option allows a
time-to-live (in seconds) to be given for these replies. This will time-to-live (in seconds) to be given for these replies. This will
reduce the load on the server at the expense of clients using stale reduce the load on the server at the expense of clients using stale
...@@ -276,7 +276,7 @@ server strictly in the order they appear in /etc/resolv.conf ...@@ -276,7 +276,7 @@ server strictly in the order they appear in /etc/resolv.conf
By default, when dnsmasq has more than one upstream server available, By default, when dnsmasq has more than one upstream server available,
it will send queries to just one server. Setting this flag forces it will send queries to just one server. Setting this flag forces
dnsmasq to send all queries to all available servers. The reply from dnsmasq to send all queries to all available servers. The reply from
the server which answers first will be returned to the original requestor. the server which answers first will be returned to the original requester.
.TP .TP
.B --stop-dns-rebind .B --stop-dns-rebind
Reject (and log) addresses from upstream nameservers which are in the Reject (and log) addresses from upstream nameservers which are in the
...@@ -545,7 +545,7 @@ Specify per host parameters for the DHCP server. This allows a machine ...@@ -545,7 +545,7 @@ Specify per host parameters for the DHCP server. This allows a machine
with a particular hardware address to be always allocated the same with a particular hardware address to be always allocated the same
hostname, IP address and lease time. A hostname specified like this hostname, IP address and lease time. A hostname specified like this
overrides any supplied by the DHCP client on the machine. It is also overrides any supplied by the DHCP client on the machine. It is also
allowable to ommit the hardware address and include the hostname, in allowable to omit the hardware address and include the hostname, in
which case the IP address and lease times will apply to any machine which case the IP address and lease times will apply to any machine
claiming that name. For example claiming that name. For example
.B --dhcp-host=00:20:e0:3b:13:af,wap,infinite .B --dhcp-host=00:20:e0:3b:13:af,wap,infinite
...@@ -1134,6 +1134,14 @@ without an address specified when ...@@ -1134,6 +1134,14 @@ without an address specified when
.B --dhcp-fqdn .B --dhcp-fqdn
is set. is set.
.TP .TP
.B --dhcp-client-update
Normally, when giving a DHCP lease, dnsmasq sets flags in the FQDN
option to tell the client not to attempt a DDNS update with its name
and IP address. This is because the name-IP pair is automatically
added into dnsmasq's DNS view. This flag suppresses that behaviour,
this is useful, for instance, to allow Windows clients to update
Active Directory servers. See RFC 4702 for details.
.TP
.B --enable-tftp[=<interface>] .B --enable-tftp[=<interface>]
Enable the TFTP server function. This is deliberately limited to that Enable the TFTP server function. This is deliberately limited to that
needed to net-boot a client. Only reading is allowed; the tsize and needed to net-boot a client. Only reading is allowed; the tsize and
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Worry about IPv6 leases and DUID in script-storage.
...@@ -182,7 +182,8 @@ int iface_enumerate(int family, void *parm, int (*callback)()) ...@@ -182,7 +182,8 @@ int iface_enumerate(int family, void *parm, int (*callback)())
addr->s6_addr[2] = 0; addr->s6_addr[2] = 0;
addr->s6_addr[3] = 0; addr->s6_addr[3] = 0;
} }
if (!((*callback)(addr, /* We have no way to determine the prefix, so we assume it's 64 for now....... */
if (!((*callback)(addr, 64,
(int)((struct sockaddr_in6 *)&ifr->ifr_addr)->sin6_scope_id, (int)((struct sockaddr_in6 *)&ifr->ifr_addr)->sin6_scope_id,
(int)if_nametoindex(ifr->ifr_name), 0, (int)if_nametoindex(ifr->ifr_name), 0,
parm))) parm)))
......
...@@ -25,7 +25,6 @@ static int cache_inserted = 0, cache_live_freed = 0, insert_error; ...@@ -25,7 +25,6 @@ static int cache_inserted = 0, cache_live_freed = 0, insert_error;
static union bigname *big_free = NULL; static union bigname *big_free = NULL;
static int bignames_left, hash_size; static int bignames_left, hash_size;
static int uid = 0; static int uid = 0;
static char *addrbuff = NULL;
/* type->string mapping: this is also used by the name-hash function as a mixing table. */ /* type->string mapping: this is also used by the name-hash function as a mixing table. */
static const struct { static const struct {
...@@ -75,9 +74,6 @@ void cache_init(void) ...@@ -75,9 +74,6 @@ void cache_init(void)
struct crec *crecp; struct crec *crecp;
int i; int i;
if (option_bool(OPT_LOG))
addrbuff = safe_malloc(ADDRSTRLEN);
bignames_left = daemon->cachesize/10; bignames_left = daemon->cachesize/10;
if (daemon->cachesize > 0) if (daemon->cachesize > 0)
...@@ -1057,9 +1053,6 @@ void dump_cache(time_t now) ...@@ -1057,9 +1053,6 @@ void dump_cache(time_t now)
my_syslog(LOG_INFO, _("queries forwarded %u, queries answered locally %u"), my_syslog(LOG_INFO, _("queries forwarded %u, queries answered locally %u"),
daemon->queries_forwarded, daemon->local_answer); daemon->queries_forwarded, daemon->local_answer);
if (!addrbuff && !(addrbuff = whine_malloc(ADDRSTRLEN)))
return;
/* sum counts from different records for same server */ /* sum counts from different records for same server */
for (serv = daemon->servers; serv; serv = serv->next) for (serv = daemon->servers; serv; serv = serv->next)
serv->flags &= ~SERV_COUNTED; serv->flags &= ~SERV_COUNTED;
...@@ -1079,8 +1072,8 @@ void dump_cache(time_t now) ...@@ -1079,8 +1072,8 @@ void dump_cache(time_t now)
queries += serv1->queries; queries += serv1->queries;
failed_queries += serv1->failed_queries; failed_queries += serv1->failed_queries;
} }
port = prettyprint_addr(&serv->addr, addrbuff); port = prettyprint_addr(&serv->addr, daemon->addrbuff);
my_syslog(LOG_INFO, _("server %s#%d: queries sent %u, retried or failed %u"), addrbuff, port, queries, failed_queries); my_syslog(LOG_INFO, _("server %s#%d: queries sent %u, retried or failed %u"), daemon->addrbuff, port, queries, failed_queries);
} }
if (option_bool(OPT_DEBUG) || option_bool(OPT_LOG)) if (option_bool(OPT_DEBUG) || option_bool(OPT_LOG))
...@@ -1105,11 +1098,11 @@ void dump_cache(time_t now) ...@@ -1105,11 +1098,11 @@ void dump_cache(time_t now)
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
else else
{ {
a = addrbuff; a = daemon->addrbuff;
if (cache->flags & F_IPV4) if (cache->flags & F_IPV4)
inet_ntop(AF_INET, &cache->addr.addr, addrbuff, ADDRSTRLEN); inet_ntop(AF_INET, &cache->addr.addr, a, ADDRSTRLEN);
else if (cache->flags & F_IPV6) else if (cache->flags & F_IPV6)
inet_ntop(AF_INET6, &cache->addr.addr, addrbuff, ADDRSTRLEN); inet_ntop(AF_INET6, &cache->addr.addr, a, ADDRSTRLEN);
} }
#else #else
else else
...@@ -1164,7 +1157,7 @@ void querystr(char *str, unsigned short type) ...@@ -1164,7 +1157,7 @@ void querystr(char *str, unsigned short type)
void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg) void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg)
{ {
char *source, *dest = addrbuff; char *source, *dest = daemon->addrbuff;
char *verb = "is"; char *verb = "is";
if (!option_bool(OPT_LOG)) if (!option_bool(OPT_LOG))
...@@ -1174,16 +1167,16 @@ void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg) ...@@ -1174,16 +1167,16 @@ void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg)
{ {
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
inet_ntop(flags & F_IPV4 ? AF_INET : AF_INET6, inet_ntop(flags & F_IPV4 ? AF_INET : AF_INET6,
addr, addrbuff, ADDRSTRLEN); addr, daemon->addrbuff, ADDRSTRLEN);
#else #else
strncpy(addrbuff, inet_ntoa(addr->addr.addr4), ADDRSTRLEN); strncpy(daemon->addrbuff, inet_ntoa(addr->addr.addr4), ADDRSTRLEN);
#endif #endif
} }
if (flags & F_REVERSE) if (flags & F_REVERSE)
{ {
dest = name; dest = name;
name = addrbuff; name = daemon->addrbuff;
} }
if (flags & F_NEG) if (flags & F_NEG)
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
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.59" #define VERSION "2.60test6"
#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 */
...@@ -34,60 +34,19 @@ ...@@ -34,60 +34,19 @@
#define SMALLDNAME 40 /* most domain names are smaller than this */ #define SMALLDNAME 40 /* most domain names are smaller than this */
#define HOSTSFILE "/etc/hosts" #define HOSTSFILE "/etc/hosts"
#define ETHERSFILE "/etc/ethers" #define ETHERSFILE "/etc/ethers"
#ifdef __uClinux__
# define RESOLVFILE "/etc/config/resolv.conf"
#else
# define RESOLVFILE "/etc/resolv.conf"
#endif
#define RUNFILE "/var/run/dnsmasq.pid" #define RUNFILE "/var/run/dnsmasq.pid"
#ifndef LEASEFILE
# if defined(__FreeBSD__) || defined (__OpenBSD__) || defined(__DragonFly__) || defined(__NetBSD__)
# define LEASEFILE "/var/db/dnsmasq.leases"
# elif defined(__sun__) || defined (__sun)
# define LEASEFILE "/var/cache/dnsmasq.leases"
# elif defined(__ANDROID__)
# define LEASEFILE "/data/misc/dhcp/dnsmasq.leases"
# else
# define LEASEFILE "/var/lib/misc/dnsmasq.leases"
# endif
#endif
#ifndef CONFFILE
# if defined(__FreeBSD__)
# define CONFFILE "/usr/local/etc/dnsmasq.conf"
# else
# define CONFFILE "/etc/dnsmasq.conf"
# endif
#endif
#define DEFLEASE 3600 /* default lease time, 1 hour */ #define DEFLEASE 3600 /* default lease time, 1 hour */
#define CHUSER "nobody" #define CHUSER "nobody"
#define CHGRP "dip" #define CHGRP "dip"
#define NAMESERVER_PORT 53
#define DHCP_SERVER_PORT 67
#define DHCP_CLIENT_PORT 68
#define DHCP_SERVER_ALTPORT 1067
#define DHCP_CLIENT_ALTPORT 1068
#define PXE_PORT 4011
#define TFTP_PORT 69
#define TFTP_MAX_CONNECTIONS 50 /* max simultaneous connections */ #define TFTP_MAX_CONNECTIONS 50 /* max simultaneous connections */
#define LOG_MAX 5 /* log-queue length */ #define LOG_MAX 5 /* log-queue length */
#define RANDFILE "/dev/urandom" #define RANDFILE "/dev/urandom"
#define EDNS0_OPTION_MAC 5 /* dyndns.org temporary assignment */ #define EDNS0_OPTION_MAC 5 /* dyndns.org temporary assignment */
#define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq" /* DBUS interface specifics */
/* DBUS interface specifics */
#define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq"
#define DNSMASQ_PATH "/uk/org/thekelleys/dnsmasq" #define DNSMASQ_PATH "/uk/org/thekelleys/dnsmasq"
/* Follows system specific switches. If you run on a /* compile-time options: uncomment below to enable or do eg.
new system, you may want to edit these. make COPTS=-DHAVE_BROKEN_RTC
May replace this with Autoconf one day.
HAVE_LINUX_NETWORK
HAVE_BSD_NETWORK
HAVE_SOLARIS_NETWORK
define exactly one of these to alter interaction with kernel networking.
HAVE_BROKEN_RTC HAVE_BROKEN_RTC
define this on embedded systems which don't have an RTC define this on embedded systems which don't have an RTC
...@@ -107,20 +66,16 @@ HAVE_TFTP ...@@ -107,20 +66,16 @@ HAVE_TFTP
define this to get dnsmasq's built-in TFTP server. define this to get dnsmasq's built-in TFTP server.
HAVE_DHCP HAVE_DHCP
define this to get dnsmasq's DHCP server. define this to get dnsmasq's DHCPv4 server.
HAVE_SCRIPT
define this to get the ability to call scripts on lease-change
HAVE_GETOPT_LONG HAVE_DHCP6
define this if you have GNU libc or GNU getopt. define this to get dnsmasq's DHCPv6 server. (implies HAVE_DHCP).
HAVE_ARC4RANDOM HAVE_SCRIPT
define this if you have arc4random() to get better security from DNS spoofs define this to get the ability to call scripts on lease-change.
by using really random ids (OpenBSD)
HAVE_SOCKADDR_SA_LEN HAVE_LUASCRIPT
define this if struct sockaddr has sa_len field (*BSD) define this to get the ability to call Lua script on lease-change. (implies HAVE_SCRIPT)
HAVE_DBUS HAVE_DBUS
define this if you want to link against libdbus, and have dnsmasq define this if you want to link against libdbus, and have dnsmasq
...@@ -139,51 +94,90 @@ HAVE_CONNTRACK ...@@ -139,51 +94,90 @@ HAVE_CONNTRACK
a build-dependency on libnetfilter_conntrack, but the resulting binary will a build-dependency on libnetfilter_conntrack, but the resulting binary will
still run happily on a kernel without conntrack support. still run happily on a kernel without conntrack support.
NOTES: NO_IPV6
For Linux you should define NO_TFTP
HAVE_LINUX_NETWORK NO_DHCP
HAVE_GETOPT_LONG NO_DHCP6
you should NOT define NO_SCRIPT
HAVE_ARC4RANDOM NO_LARGEFILE
HAVE_SOCKADDR_SA_LEN these are avilable to explictly disable compile time options which would
otherwise be enabled automatically (HAVE_IPV6, >2Gb file sizes) or
For *BSD systems you should define which are enabled by default in the distributed source tree. Building dnsmasq
HAVE_BSD_NETWORK with something like "make COPTS=-DNO_SCRIPT" will do the trick.
HAVE_SOCKADDR_SA_LEN
and you MAY define LEASEFILE
HAVE_ARC4RANDOM - OpenBSD and FreeBSD and NetBSD version 2.0 or later CONFFILE
HAVE_GETOPT_LONG - NetBSD, later FreeBSD RESOLVFILE
(FreeBSD and OpenBSD only if you link GNU getopt) the default locations of these files are determined below, but may be overridden
in a build command line using COPTS.
*/ */
/* platform independent options- uncomment to enable */
/* The default set of options to build. Built with these options, dnsmasq
has no library dependencies other than libc */
#define HAVE_DHCP #define HAVE_DHCP
/* #define HAVE_DHCP6 */
#define HAVE_TFTP #define HAVE_TFTP
#define HAVE_SCRIPT #define HAVE_SCRIPT
/* #define HAVE_LUASCRIPT */
/* #define HAVE_BROKEN_RTC */ /* #define HAVE_BROKEN_RTC */
/* #define HAVE_DBUS */ /* #define HAVE_DBUS */
/* #define HAVE_IDN */ /* #define HAVE_IDN */
/* #define HAVE_CONNTRACK */ /* #define HAVE_CONNTRACK */
/* Allow TFTP to be disabled with COPTS=-DNO_TFTP */
#ifdef NO_TFTP
#undef HAVE_TFTP /* Default locations for important system files. */
#ifndef LEASEFILE
# if defined(__FreeBSD__) || defined (__OpenBSD__) || defined(__DragonFly__) || defined(__NetBSD__)
# define LEASEFILE "/var/db/dnsmasq.leases"
# elif defined(__sun__) || defined (__sun)
# define LEASEFILE "/var/cache/dnsmasq.leases"
# elif defined(__ANDROID__)
# define LEASEFILE "/data/misc/dhcp/dnsmasq.leases"
# else
# define LEASEFILE "/var/lib/misc/dnsmasq.leases"
# endif
#endif #endif
/* Allow DHCP to be disabled with COPTS=-DNO_DHCP */ #ifndef CONFFILE
#ifdef NO_DHCP # if defined(__FreeBSD__)
#undef HAVE_DHCP # define CONFFILE "/usr/local/etc/dnsmasq.conf"
# else
# define CONFFILE "/etc/dnsmasq.conf"
# endif
#endif #endif
/* Allow scripts to be disabled with COPTS=-DNO_SCRIPT */ #ifndef RESOLVFILE
#ifdef NO_SCRIPT # if defined(__uClinux__)
#undef HAVE_SCRIPT # define RESOLVFILE "/etc/config/resolv.conf"
# else
# define RESOLVFILE "/etc/resolv.conf"
# endif
#endif #endif
/* platform dependent options. */ /* platform dependent options: these are determined automatically below
HAVE_LINUX_NETWORK
HAVE_BSD_NETWORK
HAVE_SOLARIS_NETWORK
define exactly one of these to alter interaction with kernel networking.
HAVE_GETOPT_LONG
defined when GNU-sty;e getopt_long available.
HAVE_ARC4RANDOM
defined if arc4random() available to get better security from DNS spoofs
by using really random ids (OpenBSD)
HAVE_SOCKADDR_SA_LEN
defined if struct sockaddr has sa_len field (*BSD)
*/
/* Must preceed __linux__ since uClinux defines __linux__ too. */ /* Must preceed __linux__ since uClinux defines __linux__ too. */
#if defined(__uClinux__) #if defined(__uClinux__)
...@@ -259,18 +253,12 @@ NOTES: ...@@ -259,18 +253,12 @@ NOTES:
#endif #endif
/* Decide if we're going to support IPv6 */ /* Decide if we're going to support IPv6 */
/* IPv6 can be forced off with "make COPTS=-DNO_IPV6" */
/* We assume that systems which don't have IPv6 /* We assume that systems which don't have IPv6
headers don't have ntop and pton either */ headers don't have ntop and pton either */
#if defined(INET6_ADDRSTRLEN) && defined(IPV6_V6ONLY) && !defined(NO_IPV6) #if defined(INET6_ADDRSTRLEN) && defined(IPV6_V6ONLY)
# define HAVE_IPV6 # define HAVE_IPV6
# define ADDRSTRLEN INET6_ADDRSTRLEN # define ADDRSTRLEN INET6_ADDRSTRLEN
# if defined(SOL_IPV6)
# define IPV6_LEVEL SOL_IPV6
# else
# define IPV6_LEVEL IPPROTO_IPV6
# endif
#elif defined(INET_ADDRSTRLEN) #elif defined(INET_ADDRSTRLEN)
# undef HAVE_IPV6 # undef HAVE_IPV6
# define ADDRSTRLEN INET_ADDRSTRLEN # define ADDRSTRLEN INET_ADDRSTRLEN
...@@ -279,8 +267,103 @@ NOTES: ...@@ -279,8 +267,103 @@ 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 /* rules to implement compile-time option dependencies and
# undef HAVE_SCRIPT the NO_XXX flags */
#ifdef NO_IPV6
#undef HAVE_IPV6
#endif
#ifdef NO_TFTP
#undef HAVE_TFTP
#endif
#ifdef NO_DHCP
#undef HAVE_DHCP
#undef HAVE_DHCP6
#endif
#if defined(NO_DHCP6) || !defined(HAVE_IPV6)
#undef HAVE_DHCP6
#endif #endif
/* DHCP6 needs DHCP too */
#ifdef HAVE_DHCP6
#define HAVE_DHCP
#endif
#if defined(NO_SCRIPT) || !defined(HAVE_DHCP) || defined(NO_FORK)
#undef HAVE_SCRIPT
#undef HAVE_LUASCRIPT
#endif
/* Must HAVE_SCRIPT to HAVE_LUASCRIPT */
#ifdef HAVE_LUASCRIPT
#define HAVE_SCRIPT
#endif
/* Define a string indicating which options are in use.
DNSMASQP_COMPILE_OPTS is only defined in dnsmasq.c */
#ifdef DNSMASQ_COMPILE_OPTS
static char *compile_opts =
#ifndef HAVE_IPV6
"no-"
#endif
"IPv6 "
#ifndef HAVE_GETOPT_LONG
"no-"
#endif
"GNU-getopt "
#ifdef HAVE_BROKEN_RTC
"no-RTC "
#endif
#ifdef NO_FORK
"no-MMU "
#endif
#ifndef HAVE_DBUS
"no-"
#endif
"DBus "
#ifndef LOCALEDIR
"no-"
#endif
"i18n "
#if !defined(LOCALEDIR) && !defined(HAVE_IDN)
"no-"
#endif
"IDN "
#ifndef HAVE_DHCP
"no-"
#endif
"DHCP "
#if defined(HAVE_DHCP)
# if !defined (HAVE_DHCP6)
"no-"
# endif
"DHCPv6 "
# if !defined(HAVE_SCRIPT)
"no-scripts "
# else
# if !defined(HAVE_LUASCRIPT)
"no-"
# endif
"Lua "
# endif
#endif
#ifndef HAVE_TFTP
"no-"
#endif
"TFTP "
#ifndef HAVE_CONNTRACK
"no-"
#endif
"conntrack";
#endif
...@@ -23,8 +23,15 @@ struct iface_param { ...@@ -23,8 +23,15 @@ struct iface_param {
int ind; int ind;
}; };
struct match_param {
int ind, matched;
struct in_addr netmask, broadcast, addr;
};
static int complete_context(struct in_addr local, int if_index, static int complete_context(struct in_addr local, int if_index,
struct in_addr netmask, struct in_addr broadcast, void *vparam); struct in_addr netmask, struct in_addr broadcast, void *vparam);
static int check_listen_addrs(struct in_addr local, int if_index,
struct in_addr netmask, struct in_addr broadcast, void *vparam);
static int make_fd(int port) static int make_fd(int port)
{ {
...@@ -34,16 +41,22 @@ static int make_fd(int port) ...@@ -34,16 +41,22 @@ static int make_fd(int 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 mtu = IP_PMTUDISC_DONT;
#endif #endif
#if defined(IP_TOS) && defined(IPTOS_CLASS_CS6)
int tos = IPTOS_CLASS_CS6;
#endif
if (fd == -1) if (fd == -1)
die (_("cannot create DHCP socket: %s"), NULL, EC_BADNET); die (_("cannot create DHCP socket: %s"), NULL, EC_BADNET);
if (!fix_fd(fd) || if (!fix_fd(fd) ||
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu)) == -1 || setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu)) == -1 ||
#endif
#if defined(IP_TOS) && defined(IPTOS_CLASS_CS6)
setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) == -1 ||
#endif #endif
#if defined(HAVE_LINUX_NETWORK) #if defined(HAVE_LINUX_NETWORK)
setsockopt(fd, SOL_IP, IP_PKTINFO, &oneopt, sizeof(oneopt)) == -1 || setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &oneopt, sizeof(oneopt)) == -1 ||
#else #else
setsockopt(fd, IPPROTO_IP, IP_RECVIF, &oneopt, sizeof(oneopt)) == -1 || setsockopt(fd, IPPROTO_IP, IP_RECVIF, &oneopt, sizeof(oneopt)) == -1 ||
#endif #endif
...@@ -111,6 +124,40 @@ void dhcp_init(void) ...@@ -111,6 +124,40 @@ void dhcp_init(void)
daemon->dhcp_packet.iov_base = safe_malloc(daemon->dhcp_packet.iov_len); daemon->dhcp_packet.iov_base = safe_malloc(daemon->dhcp_packet.iov_len);
} }
ssize_t recv_dhcp_packet(int fd, struct msghdr *msg)
{
ssize_t sz;
while (1)
{
msg->msg_flags = 0;
while ((sz = recvmsg(fd, msg, MSG_PEEK | MSG_TRUNC)) == -1 && errno == EINTR);
if (sz == -1)
return -1;
if (!(msg->msg_flags & MSG_TRUNC))
break;
/* Very new Linux kernels return the actual size needed,
older ones always return truncated size */
if ((size_t)sz == daemon->dhcp_packet.iov_len)
{
if (!expand_buf(&daemon->dhcp_packet, sz + 100))
return -1;
}
else
{
expand_buf(&daemon->dhcp_packet, sz);
break;
}
}
while ((sz = recvmsg(fd, msg, 0)) == -1 && errno == EINTR);
return (msg->msg_flags & MSG_TRUNC) ? -1 : sz;
}
void dhcp_packet(time_t now, int pxe_fd) void dhcp_packet(time_t now, int pxe_fd)
{ {
int fd = pxe_fd ? daemon->pxefd : daemon->dhcpfd; int fd = pxe_fd ? daemon->pxefd : daemon->dhcpfd;
...@@ -124,7 +171,7 @@ void dhcp_packet(time_t now, int pxe_fd) ...@@ -124,7 +171,7 @@ void dhcp_packet(time_t now, int pxe_fd)
struct iovec iov; struct iovec iov;
ssize_t sz; ssize_t sz;
int iface_index = 0, unicast_dest = 0, is_inform = 0; int iface_index = 0, unicast_dest = 0, is_inform = 0;
struct in_addr iface_addr, *addrp = NULL; struct in_addr iface_addr;
struct iface_param parm; struct iface_param parm;
#ifdef HAVE_LINUX_NETWORK #ifdef HAVE_LINUX_NETWORK
struct arpreq arp_req; struct arpreq arp_req;
...@@ -140,56 +187,23 @@ void dhcp_packet(time_t now, int pxe_fd) ...@@ -140,56 +187,23 @@ void dhcp_packet(time_t now, int pxe_fd)
char control[CMSG_SPACE(sizeof(struct sockaddr_dl))]; char control[CMSG_SPACE(sizeof(struct sockaddr_dl))];
#endif #endif
} control_u; } control_u;
struct dhcp_bridge *bridge, *alias;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &daemon->dhcp_packet;
msg.msg_iovlen = 1;
while (1)
{
msg.msg_flags = 0;
while ((sz = recvmsg(fd, &msg, MSG_PEEK | MSG_TRUNC)) == -1 && errno == EINTR);
if (sz == -1)
return;
if (!(msg.msg_flags & MSG_TRUNC))
break;
/* Very new Linux kernels return the actual size needed,
older ones always return truncated size */
if ((size_t)sz == daemon->dhcp_packet.iov_len)
{
if (!expand_buf(&daemon->dhcp_packet, sz + 100))
return;
}
else
{
expand_buf(&daemon->dhcp_packet, sz);
break;
}
}
/* expand_buf may have moved buffer */
mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
msg.msg_controllen = sizeof(control_u); msg.msg_controllen = sizeof(control_u);
msg.msg_control = control_u.control; msg.msg_control = control_u.control;
msg.msg_flags = 0;
msg.msg_name = &dest; msg.msg_name = &dest;
msg.msg_namelen = sizeof(dest); msg.msg_namelen = sizeof(dest);
msg.msg_iov = &daemon->dhcp_packet;
msg.msg_iovlen = 1;
while ((sz = recvmsg(fd, &msg, 0)) == -1 && errno == EINTR); if ((sz = recv_dhcp_packet(fd, &msg)) == -1 ||
(sz < (ssize_t)(sizeof(*mess) - sizeof(mess->options))))
if ((msg.msg_flags & MSG_TRUNC) || sz < (ssize_t)(sizeof(*mess) - sizeof(mess->options)))
return; return;
#if defined (HAVE_LINUX_NETWORK) #if defined (HAVE_LINUX_NETWORK)
if (msg.msg_controllen >= sizeof(struct cmsghdr)) if (msg.msg_controllen >= sizeof(struct cmsghdr))
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr)) for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
if (cmptr->cmsg_level == SOL_IP && cmptr->cmsg_type == IP_PKTINFO) if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
{ {
union { union {
unsigned char *c; unsigned char *c;
...@@ -236,6 +250,31 @@ void dhcp_packet(time_t now, int pxe_fd) ...@@ -236,6 +250,31 @@ void dhcp_packet(time_t now, int pxe_fd)
strncpy(arp_req.arp_dev, ifr.ifr_name, 16); strncpy(arp_req.arp_dev, ifr.ifr_name, 16);
#endif #endif
/* One form of bridging on BSD has the property that packets
can be recieved on bridge interfaces which do not have an IP address.
We allow these to be treated as aliases of another interface which does have
an IP address with --dhcp-bridge=interface,alias,alias */
for (bridge = daemon->bridges; bridge; bridge = bridge->next)
{
for (alias = bridge->alias; alias; alias = alias->next)
if (strncmp(ifr.ifr_name, alias->iface, IF_NAMESIZE) == 0)
{
if (!(iface_index = if_nametoindex(bridge->iface)))
{
my_syslog(LOG_WARNING, _("unknown interface %s in bridge-interface"), ifr.ifr_name);
return;
}
else
{
strncpy(ifr.ifr_name, bridge->iface, IF_NAMESIZE);
break;
}
}
if (alias)
break;
}
#ifdef MSG_BCAST #ifdef MSG_BCAST
/* OpenBSD tells us when a packet was broadcast */ /* OpenBSD tells us when a packet was broadcast */
if (!(msg.msg_flags & MSG_BCAST)) if (!(msg.msg_flags & MSG_BCAST))
...@@ -244,13 +283,12 @@ void dhcp_packet(time_t now, int pxe_fd) ...@@ -244,13 +283,12 @@ void dhcp_packet(time_t now, int pxe_fd)
ifr.ifr_addr.sa_family = AF_INET; ifr.ifr_addr.sa_family = AF_INET;
if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) != -1 ) if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) != -1 )
{
addrp = &iface_addr;
iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr; iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
} else
{
if (!iface_check(AF_INET, (struct all_addr *)addrp, ifr.ifr_name, &iface_index)) my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
return; return;
}
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next) for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0)) if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
...@@ -271,29 +309,29 @@ void dhcp_packet(time_t now, int pxe_fd) ...@@ -271,29 +309,29 @@ void dhcp_packet(time_t now, int pxe_fd)
parm.current = NULL; parm.current = NULL;
parm.ind = iface_index; parm.ind = iface_index;
/* interface may have been changed by alias in iface_check, make sure it gets priority in case if (!iface_check(AF_INET, (struct all_addr *)&iface_addr, ifr.ifr_name))
there is more than one address on the interface in the same subnet */
if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) == -1)
{ {
my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name); /* If we failed to match the primary address of the interface, see if we've got a --listen-address
for a secondary */
struct match_param match;
match.matched = 0;
match.ind = iface_index;
if (!daemon->if_addrs ||
!iface_enumerate(AF_INET, &match, check_listen_addrs) ||
!match.matched)
return; return;
}
else iface_addr = match.addr;
{ /* make sure secondary address gets priority in case
iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr; there is more than one address on the interface in the same subnet */
if (ioctl(daemon->dhcpfd, SIOCGIFNETMASK, &ifr) != -1) complete_context(match.addr, iface_index, match.netmask, match.broadcast, &parm);
{
struct in_addr netmask = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
if (ioctl(daemon->dhcpfd, SIOCGIFBRDADDR, &ifr) != -1)
{
struct in_addr broadcast = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
complete_context(iface_addr, iface_index, netmask, broadcast, &parm);
}
}
} }
if (!iface_enumerate(AF_INET, &parm, complete_context)) if (!iface_enumerate(AF_INET, &parm, complete_context))
return; return;
lease_prune(NULL, now); /* lose any expired leases */ lease_prune(NULL, now); /* lose any expired leases */
iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t)sz, iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t)sz,
now, unicast_dest, &is_inform, pxe_fd, iface_addr); now, unicast_dest, &is_inform, pxe_fd, iface_addr);
...@@ -354,7 +392,7 @@ void dhcp_packet(time_t now, int pxe_fd) ...@@ -354,7 +392,7 @@ void dhcp_packet(time_t now, int pxe_fd)
pkt->ipi_ifindex = iface_index; pkt->ipi_ifindex = iface_index;
pkt->ipi_spec_dst.s_addr = 0; pkt->ipi_spec_dst.s_addr = 0;
msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
cmptr->cmsg_level = SOL_IP; cmptr->cmsg_level = IPPROTO_IP;
cmptr->cmsg_type = IP_PKTINFO; cmptr->cmsg_type = IP_PKTINFO;
dest.sin_addr.s_addr = INADDR_BROADCAST; dest.sin_addr.s_addr = INADDR_BROADCAST;
dest.sin_port = htons(daemon->dhcp_client_port); dest.sin_port = htons(daemon->dhcp_client_port);
...@@ -411,6 +449,30 @@ void dhcp_packet(time_t now, int pxe_fd) ...@@ -411,6 +449,30 @@ void dhcp_packet(time_t now, int pxe_fd)
while(sendmsg(fd, &msg, 0) == -1 && retry_send()); while(sendmsg(fd, &msg, 0) == -1 && retry_send());
} }
/* check against secondary interface addresses */
static int check_listen_addrs(struct in_addr local, int if_index,
struct in_addr netmask, struct in_addr broadcast, void *vparam)
{
struct match_param *param = vparam;
struct iname *tmp;
if (if_index == param->ind)
{
for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
if ( tmp->addr.sa.sa_family == AF_INET &&
tmp->addr.in.sin_addr.s_addr == local.s_addr)
{
param->matched = 1;
param->addr = local;
param->netmask = netmask;
param->broadcast = broadcast;
break;
}
}
return 1;
}
/* This is a complex routine: it gets called with each (address,netmask,broadcast) triple /* This is a complex routine: it gets called with each (address,netmask,broadcast) triple
of each interface (and any relay address) and does the following things: of each interface (and any relay address) and does the following things:
......
/* dnsmasq is Copyright (c) 2000-2011 Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "dnsmasq.h"
#ifdef HAVE_DHCP6
struct iface_param {
struct dhcp_context *current;
int ind;
};
static int join_multicast(struct in6_addr *local, int prefix,
int scope, int if_index, void *vparam);
static int complete_context6(struct in6_addr *local, int prefix,
int scope, int if_index, void *vparam);
void dhcp6_init(void)
{
int fd;
struct sockaddr_in6 saddr;
int class = IPTOS_CLASS_CS6;
if ((fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1 ||
setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &class, sizeof(class)) == -1 ||
!fix_fd(fd) ||
!set_ipv6pktinfo(fd))
die (_("cannot create DHCPv6 socket: %s"), NULL, EC_BADNET);
memset(&saddr, 0, sizeof(saddr));
#ifdef HAVE_SOCKADDR_SA_LEN
saddr.sin6_len = sizeof(addr.in6);
#endif
saddr.sin6_family = AF_INET6;
saddr.sin6_addr = in6addr_any;
saddr.sin6_port = htons(DHCPV6_SERVER_PORT);
if (bind(fd, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in6)))
die(_("failed to bind DHCPv6 server socket: %s"), NULL, EC_BADNET);
/* join multicast groups on each interface we're interested in */
if (!iface_enumerate(AF_INET6, &fd, join_multicast))
die(_("failed to join DHCPv6 multicast group: %s"), NULL, EC_BADNET);
daemon->dhcp6fd = fd;
}
static int join_multicast(struct in6_addr *local, int prefix,
int scope, int if_index, void *vparam)
{
char ifrn_name[IFNAMSIZ];
struct ipv6_mreq mreq;
struct in6_addr maddr;
int fd = *((int *)vparam);
struct dhcp_context *context;
struct iname *tmp;
(void)prefix;
(void)scope; /* warnings */
if (!indextoname(fd, if_index, ifrn_name))
return 0;
/* Are we doing DHCP on this interface? */
if (!iface_check(AF_INET6, (struct all_addr *)local, ifrn_name))
return 1;
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
if (tmp->name && (strcmp(tmp->name, ifrn_name) == 0))
return 1;
/* weird libvirt-inspired access control */
for (context = daemon->dhcp; context; context = context->next)
if (!context->interface || strcmp(context->interface, ifrn_name) == 0)
break;
if (!context)
return 1;
mreq.ipv6mr_interface = if_index;
inet_pton(AF_INET6, ALL_RELAY_AGENTS_AND_SERVERS, &maddr);
if (!setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
return 0;
inet_pton(AF_INET6, ALL_SERVERS, &maddr);
if (!setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
return 0;
return 1;
}
void dhcp6_packet(time_t now)
{
struct dhcp_context *context;
struct iface_param parm;
struct cmsghdr *cmptr;
struct msghdr msg;
int if_index = 0;
union {
struct cmsghdr align; /* this ensures alignment */
char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
} control_u;
union mysockaddr from;
struct all_addr dest;
ssize_t sz;
struct ifreq ifr;
struct iname *tmp;
msg.msg_control = control_u.control6;
msg.msg_controllen = sizeof(control_u);
msg.msg_flags = 0;
msg.msg_name = &from;
msg.msg_namelen = sizeof(from);
msg.msg_iov = &daemon->dhcp_packet;
msg.msg_iovlen = 1;
if ((sz = recv_dhcp_packet(daemon->dhcp6fd, &msg) == -1) || sz <= 4)
return;
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
{
union {
unsigned char *c;
struct in6_pktinfo *p;
} p;
p.c = CMSG_DATA(cmptr);
if_index = p.p->ipi6_ifindex;
dest.addr.addr6 = p.p->ipi6_addr;
}
if (!indextoname(daemon->dhcp6fd, if_index, ifr.ifr_name))
return;
ls -l
if (!iface_check(AF_INET6, (struct all_addr *)&dest, ifr.ifr_name))
return;
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
return;
/* weird libvirt-inspired access control */
for (context = daemon->dhcp; context; context = context->next)
if (!context->interface || strcmp(context->interface, ifr.ifr_name) == 0)
break;
if (!context)
return;
/* unlinked contexts are marked by context->current == context */
for (context = daemon->dhcp; context; context = context->next)
context->current = context;
parm.current = NULL;
parm.ind = if_index;
if (!iface_enumerate(AF_INET6, &parm, complete_context6))
return;
lease_prune(NULL, now); /* lose any expired leases */
msg.msg_iov = &daemon->dhcp_packet;
sz = dhcp6_reply(parm.current, sz);
/* ifr.ifr_name, if_index, (size_t)sz,
now, unicast_dest, &is_inform, pxe_fd, iface_addr); */
lease_update_file(now);
lease_update_dns();
if (sz != 0)
send_from(daemon->dhcp6fd, 0, daemon->outpacket.iov_base, sz, &from, &dest, if_index);
}
static int complete_context6(struct in6_addr *local, int prefix,
int scope, int if_index, void *vparam)
{
struct dhcp_context *context;
struct iface_param *param = vparam;
for (context = daemon->dhcp6; context; context = context->next)
{
if ((context->flags & CONTEXT_IPV6) &&
prefix == context->prefix &&
is_same_net6(local, &context->start6, prefix) &&
is_same_net6(local, &context->end6, prefix))
{
/* link it onto the current chain if we've not seen it before */
if (if_index == param->ind && context->current == context)
{
context->current = param->current;
param->current = context;
}
}
}
return 1;
}
#endif
/* dnsmasq is Copyright (c) 2000-2011 Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define DHCPV6_SERVER_PORT 547
#define DHCPV6_CLIENT_PORT 546
#define ALL_SERVERS "FF05::1:3"
#define ALL_RELAY_AGENTS_AND_SERVERS "FF02::1:2"
#define DHCP6SOLICIT 1
#define DHCP6ADVERTISE 2
#define DHCP6REQUEST 3
#define DHCP6CONFIRM 4
#define DHCP6RENEW 5
#define DHCP6REBIND 6
#define DHCP6REPLY 7
#define DHCP6RELEASE 8
#define DHCP6DECLINE 9
#define DHCP6RECONFIGURE 10
#define DHCP6IREQ 11
#define DHCP6RELAYFORW 12
#define DHCP6RELAYREPL 13
#define OPTION6_CLIENT_ID 1
#define OPTION6_SERVER_ID 2
#define OPTION6_IA_NA 3
#define OPTION6_IA_TA 4
#define OPTION6_IAADDR 5
#define OPTION6_ORO 6
#define OPTION6_PREFERENCE 7
#define OPTION6_ELAPSED_TIME 8
#define OPTION6_RELAY_MSG 9
#define OPTION6_AUTH 11
#define OPTION6_UNICAST 12
#define OPTION6_STATUS_CODE 13
#define OPTION6_RAPID_COMMIT 14
#define OPTION6_USER_CLASS 15
#define OPTION6_VENDOR_CLASS 16
#define OPTION6_VENDOR_OPTS 17
#define OPTION6_INTERFACE_ID 18
#define OPTION6_RECONFIGURE_MSG 19
#define OPTION6_RECONF_ACCEPT 20
...@@ -13,6 +13,11 @@ ...@@ -13,6 +13,11 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
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 DHCP_SERVER_PORT 67
#define DHCP_CLIENT_PORT 68
#define DHCP_SERVER_ALTPORT 1067
#define DHCP_CLIENT_ALTPORT 1068
#define PXE_PORT 4011
#define BOOTREQUEST 1 #define BOOTREQUEST 1
#define BOOTREPLY 2 #define BOOTREPLY 2
......
...@@ -14,6 +14,9 @@ ...@@ -14,6 +14,9 @@
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 NAMESERVER_PORT 53
#define TFTP_PORT 69
#define IN6ADDRSZ 16 #define IN6ADDRSZ 16
#define INADDRSZ 4 #define INADDRSZ 4
......
This diff is collapsed.
...@@ -39,9 +39,14 @@ ...@@ -39,9 +39,14 @@
/* 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 <sys/socket.h>
#ifdef __APPLE__
/* Define before netinet/in.h to select API. OSX Lion onwards. */
# define __APPLE_USE_RFC_3542
#endif
#include <netinet/in.h> #include <netinet/in.h>
/* and this. */ /* Also needed before config.h. */
#include <getopt.h> #include <getopt.h>
#include "config.h" #include "config.h"
...@@ -52,6 +57,9 @@ typedef unsigned int u32; ...@@ -52,6 +57,9 @@ typedef unsigned int u32;
#include "dns_protocol.h" #include "dns_protocol.h"
#include "dhcp_protocol.h" #include "dhcp_protocol.h"
#ifdef HAVE_DHCP6
#include "dhcp6_protocol.h"
#endif
#define gettext_noop(S) (S) #define gettext_noop(S) (S)
#ifndef LOCALEDIR #ifndef LOCALEDIR
...@@ -127,7 +135,7 @@ extern int capget(cap_user_header_t header, cap_user_data_t data); ...@@ -127,7 +135,7 @@ extern int capget(cap_user_header_t header, cap_user_data_t data);
/* Async event queue */ /* Async event queue */
struct event_desc { struct event_desc {
int event, data; int event, data, msg_sz;
}; };
#define EVENT_RELOAD 1 #define EVENT_RELOAD 1
...@@ -148,6 +156,7 @@ struct event_desc { ...@@ -148,6 +156,7 @@ struct event_desc {
#define EVENT_DIE 16 #define EVENT_DIE 16
#define EVENT_LOG_ERR 17 #define EVENT_LOG_ERR 17
#define EVENT_FORK_ERR 18 #define EVENT_FORK_ERR 18
#define EVENT_LUA_ERR 19
/* Exit codes. */ /* Exit codes. */
#define EC_GOOD 0 #define EC_GOOD 0
...@@ -204,7 +213,8 @@ struct event_desc { ...@@ -204,7 +213,8 @@ struct event_desc {
#define OPT_DNSSEC 33 #define OPT_DNSSEC 33
#define OPT_CONSEC_ADDR 34 #define OPT_CONSEC_ADDR 34
#define OPT_CONNTRACK 35 #define OPT_CONNTRACK 35
#define OPT_LAST 36 #define OPT_FQDN_UPDATE 36
#define OPT_LAST 37
/* extra flags for my_syslog, we use a couple of facilities since they are known /* extra flags for my_syslog, we use a couple of facilities since they are known
not to occupy the same bits as priorities, no matter how syslog.h is set up. */ not to occupy the same bits as priorities, no matter how syslog.h is set up. */
...@@ -444,6 +454,9 @@ struct dhcp_lease { ...@@ -444,6 +454,9 @@ struct dhcp_lease {
unsigned char *extradata; unsigned char *extradata;
unsigned int extradata_len, extradata_size; unsigned int extradata_len, extradata_size;
int last_interface; int last_interface;
#ifdef HAVE_DHCP6
char is_ipv6;
#endif
struct dhcp_lease *next; struct dhcp_lease *next;
}; };
...@@ -573,6 +586,10 @@ struct dhcp_context { ...@@ -573,6 +586,10 @@ struct dhcp_context {
struct in_addr netmask, broadcast; struct in_addr netmask, broadcast;
struct in_addr local, router; struct in_addr local, router;
struct in_addr start, end; /* range of available addresses */ struct in_addr start, end; /* range of available addresses */
#ifdef HAVE_DHCP6
struct in6_addr start6, end6; /* range of available addresses */
int prefix;
#endif
int flags; int flags;
char *interface; char *interface;
struct dhcp_netid netid, *filter; struct dhcp_netid netid, *filter;
...@@ -583,6 +600,7 @@ struct dhcp_context { ...@@ -583,6 +600,7 @@ struct dhcp_context {
#define CONTEXT_NETMASK 2 #define CONTEXT_NETMASK 2
#define CONTEXT_BRDCAST 4 #define CONTEXT_BRDCAST 4
#define CONTEXT_PROXY 8 #define CONTEXT_PROXY 8
#define CONTEXT_IPV6 16
struct ping_result { struct ping_result {
struct in_addr addr; struct in_addr addr;
...@@ -645,6 +663,7 @@ extern struct daemon { ...@@ -645,6 +663,7 @@ extern struct daemon {
char *mxtarget; char *mxtarget;
char *lease_file; char *lease_file;
char *username, *groupname, *scriptuser; char *username, *groupname, *scriptuser;
char *luascript;
int group_set, osport; int group_set, osport;
char *domain_suffix; char *domain_suffix;
struct cond_domain *cond_domain; struct cond_domain *cond_domain;
...@@ -660,7 +679,7 @@ extern struct daemon { ...@@ -660,7 +679,7 @@ extern struct daemon {
int port, query_port, min_port; int port, query_port, min_port;
unsigned long local_ttl, neg_ttl, max_ttl; unsigned long local_ttl, neg_ttl, max_ttl;
struct hostsfile *addn_hosts; struct hostsfile *addn_hosts;
struct dhcp_context *dhcp; struct dhcp_context *dhcp, *dhcp6;
struct dhcp_config *dhcp_conf; struct dhcp_config *dhcp_conf;
struct dhcp_opt *dhcp_opts, *dhcp_match; struct dhcp_opt *dhcp_opts, *dhcp_match;
struct dhcp_vendor *dhcp_vendors; struct dhcp_vendor *dhcp_vendors;
...@@ -716,7 +735,12 @@ extern struct daemon { ...@@ -716,7 +735,12 @@ extern struct daemon {
struct ping_result *ping_results; struct ping_result *ping_results;
FILE *lease_stream; FILE *lease_stream;
struct dhcp_bridge *bridges; struct dhcp_bridge *bridges;
#ifdef HAVE_DHCP6
int duid_len;
unsigned char *duid;
struct iovec outpacket;
int dhcp6fd;
#endif
/* DBus stuff */ /* DBus stuff */
/* void * here to avoid depending on dbus headers outside dbus.c */ /* void * here to avoid depending on dbus headers outside dbus.c */
void *dbus; void *dbus;
...@@ -727,6 +751,9 @@ extern struct daemon { ...@@ -727,6 +751,9 @@ extern struct daemon {
/* TFTP stuff */ /* TFTP stuff */
struct tftp_transfer *tftp_trans; struct tftp_transfer *tftp_trans;
/* utility string buffer, hold max sized IP address as string */
char *addrbuff;
} *daemon; } *daemon;
/* cache.c */ /* cache.c */
...@@ -785,6 +812,9 @@ int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2); ...@@ -785,6 +812,9 @@ int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2);
int hostname_isequal(char *a, char *b); int hostname_isequal(char *a, char *b);
time_t dnsmasq_time(void); time_t dnsmasq_time(void);
int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask); int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask);
#ifdef HAVE_IPV6
int is_same_net6(struct in6_addr *a, struct in6_addr *b, int prefixlen);
#endif
int retry_send(void); int retry_send(void);
void prettyprint_time(char *buf, unsigned int t); void prettyprint_time(char *buf, unsigned int t);
int prettyprint_addr(union mysockaddr *addr, char *buf); int prettyprint_addr(union mysockaddr *addr, char *buf);
...@@ -820,6 +850,9 @@ unsigned char *tcp_request(int confd, time_t now, ...@@ -820,6 +850,9 @@ unsigned char *tcp_request(int confd, time_t now,
union mysockaddr *local_addr, struct in_addr netmask); union mysockaddr *local_addr, struct in_addr netmask);
void server_gone(struct server *server); void server_gone(struct server *server);
struct frec *get_new_frec(time_t now, int *wait); struct frec *get_new_frec(time_t now, int *wait);
void send_from(int fd, int nowild, char *packet, size_t len,
union mysockaddr *to, struct all_addr *source,
unsigned int iface);
/* network.c */ /* network.c */
int indextoname(int fd, int index, char *name); int indextoname(int fd, int index, char *name);
...@@ -832,14 +865,18 @@ int enumerate_interfaces(); ...@@ -832,14 +865,18 @@ int enumerate_interfaces();
void create_wildcard_listeners(void); void create_wildcard_listeners(void);
void create_bound_listeners(int die); void create_bound_listeners(int die);
int is_dad_listeners(void); int is_dad_listeners(void);
int iface_check(int family, struct all_addr *addr, char *name, int *indexp); int iface_check(int family, struct all_addr *addr, char *name);
int fix_fd(int fd); int fix_fd(int fd);
struct in_addr get_ifaddr(char *intr); struct in_addr get_ifaddr(char *intr);
#ifdef HAVE_IPV6
int set_ipv6pktinfo(int fd);
#endif
/* dhcp.c */ /* dhcp.c */
#ifdef HAVE_DHCP #ifdef HAVE_DHCP
void dhcp_init(void); void dhcp_init(void);
void dhcp_packet(time_t now, int pxe_fd); void dhcp_packet(time_t now, int pxe_fd);
ssize_t recv_dhcp_packet(int fd, struct msghdr *msg);
struct dhcp_context *address_available(struct dhcp_context *context, struct dhcp_context *address_available(struct dhcp_context *context,
struct in_addr addr, struct in_addr addr,
struct dhcp_netid *netids); struct dhcp_netid *netids);
...@@ -871,7 +908,10 @@ char *get_domain(struct in_addr addr); ...@@ -871,7 +908,10 @@ char *get_domain(struct in_addr addr);
void lease_update_file(time_t now); void lease_update_file(time_t now);
void lease_update_dns(); void lease_update_dns();
void lease_init(time_t now); void lease_init(time_t now);
struct dhcp_lease *lease_allocate(struct in_addr addr); struct dhcp_lease *lease_allocate4(struct in_addr addr);
#ifdef HAVE_DHCP6
struct dhcp_lease *lease_allocate6(struct in6_addr *addrp);
#endif
void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr, void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
unsigned char *clid, int hw_len, int hw_type, int clid_len); unsigned char *clid, int hw_len, int hw_type, int clid_len);
void lease_set_hostname(struct dhcp_lease *lease, char *name, int auth); void lease_set_hostname(struct dhcp_lease *lease, char *name, int auth);
...@@ -900,7 +940,7 @@ unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr, ...@@ -900,7 +940,7 @@ unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr,
int make_icmp_sock(void); int make_icmp_sock(void);
int icmp_ping(struct in_addr addr); int icmp_ping(struct in_addr addr);
#endif #endif
void send_event(int fd, int event, int data); void send_event(int fd, int event, int data, char *msg);
void clear_cache_and_reload(time_t now); void clear_cache_and_reload(time_t now);
void poll_resolv(int force, int do_reload, time_t now); void poll_resolv(int force, int do_reload, time_t now);
...@@ -950,3 +990,9 @@ void check_tftp_listeners(fd_set *rset, time_t now); ...@@ -950,3 +990,9 @@ void check_tftp_listeners(fd_set *rset, time_t now);
int get_incoming_mark(union mysockaddr *peer_addr, struct all_addr *local_addr, int get_incoming_mark(union mysockaddr *peer_addr, struct all_addr *local_addr,
int istcp, unsigned int *markp); int istcp, unsigned int *markp);
#endif #endif
/* rfc3315.c */
#ifdef HAVE_DHCP6
void make_duid(time_t now);
size_t dhcp6_reply(struct dhcp_context *context, size_t sz);
#endif
...@@ -26,7 +26,7 @@ static struct randfd *allocate_rfd(int family); ...@@ -26,7 +26,7 @@ static struct randfd *allocate_rfd(int family);
/* Send a UDP packet with its source address set as "source" /* Send a UDP packet with its source address set as "source"
unless nowild is true, when we just send it with the kernel default */ unless nowild is true, when we just send it with the kernel default */
static void send_from(int fd, int nowild, char *packet, size_t len, void send_from(int fd, int nowild, char *packet, size_t len,
union mysockaddr *to, struct all_addr *source, union mysockaddr *to, struct all_addr *source,
unsigned int iface) unsigned int iface)
{ {
...@@ -70,7 +70,7 @@ static void send_from(int fd, int nowild, char *packet, size_t len, ...@@ -70,7 +70,7 @@ static void send_from(int fd, int nowild, char *packet, size_t len,
p.ipi_spec_dst = source->addr.addr4; p.ipi_spec_dst = source->addr.addr4;
memcpy(CMSG_DATA(cmptr), &p, sizeof(p)); memcpy(CMSG_DATA(cmptr), &p, sizeof(p));
msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
cmptr->cmsg_level = SOL_IP; cmptr->cmsg_level = IPPROTO_IP;
cmptr->cmsg_type = IP_PKTINFO; cmptr->cmsg_type = IP_PKTINFO;
#elif defined(IP_SENDSRCADDR) #elif defined(IP_SENDSRCADDR)
memcpy(CMSG_DATA(cmptr), &(source->addr.addr4), sizeof(source->addr.addr4)); memcpy(CMSG_DATA(cmptr), &(source->addr.addr4), sizeof(source->addr.addr4));
...@@ -88,10 +88,10 @@ static void send_from(int fd, int nowild, char *packet, size_t len, ...@@ -88,10 +88,10 @@ static void send_from(int fd, int nowild, char *packet, size_t len,
memcpy(CMSG_DATA(cmptr), &p, sizeof(p)); memcpy(CMSG_DATA(cmptr), &p, sizeof(p));
msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
cmptr->cmsg_type = daemon->v6pktinfo; cmptr->cmsg_type = daemon->v6pktinfo;
cmptr->cmsg_level = IPV6_LEVEL; cmptr->cmsg_level = IPPROTO_IPV6;
} }
#else #else
iface = 0; /* eliminate warning */ (void)iface; /* eliminate warning */
#endif #endif
} }
...@@ -703,7 +703,7 @@ void receive_query(struct listener *listen, time_t now) ...@@ -703,7 +703,7 @@ void receive_query(struct listener *listen, time_t now)
#if defined(HAVE_LINUX_NETWORK) #if defined(HAVE_LINUX_NETWORK)
if (listen->family == AF_INET) if (listen->family == AF_INET)
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr)) for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
if (cmptr->cmsg_level == SOL_IP && cmptr->cmsg_type == IP_PKTINFO) if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
{ {
union { union {
unsigned char *c; unsigned char *c;
...@@ -743,7 +743,7 @@ void receive_query(struct listener *listen, time_t now) ...@@ -743,7 +743,7 @@ void receive_query(struct listener *listen, time_t now)
if (listen->family == AF_INET6) if (listen->family == AF_INET6)
{ {
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr)) for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
if (cmptr->cmsg_level == IPV6_LEVEL && cmptr->cmsg_type == daemon->v6pktinfo) if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
{ {
union { union {
unsigned char *c; unsigned char *c;
...@@ -760,7 +760,7 @@ void receive_query(struct listener *listen, time_t now) ...@@ -760,7 +760,7 @@ void receive_query(struct listener *listen, time_t now)
/* enforce available interface configuration */ /* enforce available interface configuration */
if (!indextoname(listen->fd, if_index, ifr.ifr_name) || if (!indextoname(listen->fd, if_index, ifr.ifr_name) ||
!iface_check(listen->family, &dst_addr, ifr.ifr_name, &if_index)) !iface_check(listen->family, &dst_addr, ifr.ifr_name))
return; return;
if (listen->family == AF_INET && if (listen->family == AF_INET &&
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment