commit
8f6a1c5683
@ -0,0 +1 @@
|
|||||||
|
fb0417530e49368fe032cd9722f51c74f93180ac SOURCES/dhcp-4.3.6.tar.gz
|
@ -0,0 +1 @@
|
|||||||
|
SOURCES/dhcp-4.3.6.tar.gz
|
@ -0,0 +1,37 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run dhclient.d scripts in an emulated environment
|
||||||
|
|
||||||
|
PATH=/bin:/usr/bin:/sbin
|
||||||
|
ETCDIR=/etc/dhcp
|
||||||
|
SAVEDIR=/var/lib/dhclient
|
||||||
|
interface=$1
|
||||||
|
|
||||||
|
for optname in "${!DHCP4_@}"; do
|
||||||
|
newoptname=${optname,,};
|
||||||
|
newoptname=new_${newoptname#dhcp4_};
|
||||||
|
export "${newoptname}"="${!optname}";
|
||||||
|
done
|
||||||
|
|
||||||
|
[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network
|
||||||
|
|
||||||
|
[ -f /etc/sysconfig/network-scripts/ifcfg-"${interface}" ] && \
|
||||||
|
. /etc/sysconfig/network-scripts/ifcfg-"${interface}"
|
||||||
|
|
||||||
|
if [ -d $ETCDIR/dhclient.d ]; then
|
||||||
|
for f in $ETCDIR/dhclient.d/*.sh; do
|
||||||
|
if [ -x "${f}" ]; then
|
||||||
|
subsystem="${f%.sh}"
|
||||||
|
subsystem="${subsystem##*/}"
|
||||||
|
. "${f}"
|
||||||
|
if [ "$2" = "up" ]; then
|
||||||
|
"${subsystem}_config"
|
||||||
|
elif [ "$2" = "dhcp4-change" ]; then
|
||||||
|
if [ "$subsystem" = "chrony" -o "$subsystem" = "ntp" ]; then
|
||||||
|
"${subsystem}_config"
|
||||||
|
fi
|
||||||
|
elif [ "$2" = "down" ]; then
|
||||||
|
"${subsystem}_restore"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
@ -0,0 +1,61 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# If we are running dhclient, shutdown running instances cleanly and
|
||||||
|
# bring them back up on resume.
|
||||||
|
|
||||||
|
. "${PM_FUNCTIONS}"
|
||||||
|
|
||||||
|
PM_DHCLIENT_RUNDIR="${PM_UTILS_RUNDIR}/network"
|
||||||
|
PM_DHCLIENT_SUSPEND="${PM_DHCLIENT_RUNDIR}/dhclient.suspend"
|
||||||
|
|
||||||
|
suspend_dhclient() {
|
||||||
|
[ ! -d /etc/sysconfig/network-scripts ] && return
|
||||||
|
[ ! -x /sbin/ifdown ] && return
|
||||||
|
|
||||||
|
[ ! -d ${PM_DHCLIENT_RUNDIR} ] && /bin/mkdir -p ${PM_DHCLIENT_RUNDIR}
|
||||||
|
[ -f ${PM_DHCLIENT_SUSPEND} ] && /bin/rm -f ${PM_DHCLIENT_SUSPEND}
|
||||||
|
|
||||||
|
cd /etc/sysconfig/network-scripts
|
||||||
|
for ifcfg in ifcfg-* ; do
|
||||||
|
# Clear relevant parameters set by previous interface
|
||||||
|
# (lo doesn't set them)
|
||||||
|
NM_CONTROLLED=
|
||||||
|
BOOTPROTO=
|
||||||
|
|
||||||
|
. ./"${ifcfg}"
|
||||||
|
|
||||||
|
if [ "${NM_CONTROLLED}" = "no" ] || [ "${NM_CONTROLLED}" = "n" ] || [ "${NM_CONTROLLED}" = "false" ]; then
|
||||||
|
if [ "${BOOTPROTO}" = "bootp" ] || [ "${BOOTPROTO}" = "dhcp" ] || [ -z "${BOOTPROTO}" ]; then
|
||||||
|
# device is not NetworkManager controlled and uses dhcp,
|
||||||
|
# now see if it's actually up at the moment
|
||||||
|
/sbin/ip link show ${DEVICE} | /bin/grep -qE "state (UP|UNKNOWN)" >/dev/null 2>&1
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "${DEVICE}" >> ${PM_DHCLIENT_SUSPEND}
|
||||||
|
/sbin/ifdown ${DEVICE}
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
resume_dhclient() {
|
||||||
|
[ ! -f ${PM_DHCLIENT_SUSPEND} ] && return
|
||||||
|
[ ! -x /sbin/ifup ] && return
|
||||||
|
|
||||||
|
cd /etc/sysconfig/network-scripts
|
||||||
|
while read device ; do
|
||||||
|
/sbin/ifup ${device}
|
||||||
|
done < ${PM_DHCLIENT_SUSPEND}
|
||||||
|
|
||||||
|
/bin/rm -f ${PM_DHCLIENT_SUSPEND}
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
hibernate|suspend)
|
||||||
|
suspend_dhclient
|
||||||
|
;;
|
||||||
|
thaw|resume)
|
||||||
|
resume_dhclient
|
||||||
|
;;
|
||||||
|
*) exit $NA
|
||||||
|
;;
|
||||||
|
esac
|
@ -0,0 +1,47 @@
|
|||||||
|
The /etc/dhcp/dhclient.d directory allows other packages and system
|
||||||
|
administrators to create application-specific option handlers for dhclient.
|
||||||
|
|
||||||
|
When dhclient is run, any option listed in the dhcp-options(5) man page can
|
||||||
|
be requested. dhclient-script does not handle every option available
|
||||||
|
because doing so would make the script unmaintainable as the components
|
||||||
|
using those options might change over time. The knowledge of how to handle
|
||||||
|
those options should be under the responsibility of the package maintainer
|
||||||
|
for that component (e.g., NTP options belong in a handler in the ntp
|
||||||
|
package).
|
||||||
|
|
||||||
|
To make maintenance easier, application specific DHCP options can be handled
|
||||||
|
by creating a bash script with two functions and placing it in /etc/dhcp/dhclient.d
|
||||||
|
|
||||||
|
The script must follow a specific form:
|
||||||
|
|
||||||
|
(1) The script must be named NAME.sh. NAME can be anything, but it makes
|
||||||
|
sense to name it for the service it handles. e.g., ntp.sh
|
||||||
|
|
||||||
|
(2) The script must provide a NAME_config() function to read the options and
|
||||||
|
do whatever it takes to put those options in place.
|
||||||
|
|
||||||
|
(3) The script must provide a NAME_restore() function to restore original
|
||||||
|
configuration state when dhclient stops.
|
||||||
|
|
||||||
|
(4) The script must be 'chmod +x' or dhclient-script will ignore it.
|
||||||
|
|
||||||
|
The scripts execute in the same environment as dhclient-script. That means
|
||||||
|
all of the functions and variables available to it are available to your
|
||||||
|
NAME.sh script. Things of note:
|
||||||
|
|
||||||
|
${SAVEDIR} is where original configuration files are saved. Save your
|
||||||
|
original configuration files here before you take the DHCP provided
|
||||||
|
values and generate new files.
|
||||||
|
|
||||||
|
Variables set in /etc/sysconfig/network, /etc/sysconfig/networking/network,
|
||||||
|
and /etc/sysconfig/network-scripts/ifcfg-$interface are available to
|
||||||
|
you.
|
||||||
|
|
||||||
|
See the scripts in /etc/dhcp/dhclient.d for examples.
|
||||||
|
|
||||||
|
NOTE: Do not use functions defined in /usr/sbin/dhclient-script. Consider
|
||||||
|
dhclient-script a black box. This script may change over time, so the
|
||||||
|
dhclient.d scripts should not be using functions defined in it.
|
||||||
|
|
||||||
|
--
|
||||||
|
David Cantrell <dcantrell@redhat.com>
|
@ -0,0 +1,975 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# dhclient-script: Network interface configuration script run by
|
||||||
|
# dhclient based on DHCP client communication
|
||||||
|
#
|
||||||
|
# Copyright (C) 2008-2014 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# 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; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# 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/>.
|
||||||
|
#
|
||||||
|
# Author(s): David Cantrell <dcantrell@redhat.com>
|
||||||
|
# Jiri Popelka <jpopelka@redhat.com>
|
||||||
|
#
|
||||||
|
# ----------
|
||||||
|
# This script is a rewrite/reworking on dhclient-script originally
|
||||||
|
# included as part of dhcp-970306:
|
||||||
|
# dhclient-script for Linux. Dan Halbert, March, 1997.
|
||||||
|
# Updated for Linux 2.[12] by Brian J. Murrell, January 1999.
|
||||||
|
# Modified by David Cantrell <dcantrell@redhat.com> for Fedora and RHEL
|
||||||
|
# ----------
|
||||||
|
#
|
||||||
|
|
||||||
|
PATH=/bin:/usr/bin:/sbin
|
||||||
|
# scripts in dhclient.d/ use $SAVEDIR (#833054)
|
||||||
|
export SAVEDIR=/var/lib/dhclient
|
||||||
|
|
||||||
|
LOGFACILITY="local7"
|
||||||
|
LOGLEVEL="notice"
|
||||||
|
|
||||||
|
ETCDIR="/etc/dhcp"
|
||||||
|
|
||||||
|
RESOLVCONF="/etc/resolv.conf"
|
||||||
|
|
||||||
|
logmessage() {
|
||||||
|
msg="${1}"
|
||||||
|
logger -p "${LOGFACILITY}.${LOGLEVEL}" -t "NET" "dhclient: ${msg}"
|
||||||
|
}
|
||||||
|
|
||||||
|
eventually_add_hostnames_domain_to_search() {
|
||||||
|
# For the case when hostname for this machine has a domain that is not in domain_search list
|
||||||
|
# 1) get a hostname with `ipcalc --hostname` or `hostnamectl --transient`
|
||||||
|
# 2) get the domain from this hostname
|
||||||
|
# 3) add this domain to search line in resolv.conf if it's not already
|
||||||
|
# there (domain list that we have recently added there is a parameter of this function)
|
||||||
|
# We can't do this directly when generating resolv.conf in make_resolv_conf(), because
|
||||||
|
# we need to first save the resolv.conf with obtained values before we can call `ipcalc --hostname`.
|
||||||
|
# See bug 637763
|
||||||
|
search="${1}"
|
||||||
|
if need_hostname; then
|
||||||
|
status=1
|
||||||
|
OLD_HOSTNAME=$HOSTNAME
|
||||||
|
if [ -n "${new_ip_address}" ]; then
|
||||||
|
eval $(/usr/bin/ipcalc --silent --hostname "${new_ip_address}" ; echo "status=$?")
|
||||||
|
elif [ -n "${new_ip6_address}" ]; then
|
||||||
|
eval $(/usr/bin/ipcalc --silent --hostname "${new_ip6_address}" ; echo "status=$?")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ${status} -eq 0 ]; then
|
||||||
|
domain=$(echo "${HOSTNAME}" | cut -s -d "." -f 2-)
|
||||||
|
fi
|
||||||
|
HOSTNAME=$OLD_HOSTNAME
|
||||||
|
else
|
||||||
|
domain=$(hostnamectl --transient 2>/dev/null | cut -s -d "." -f 2-)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${domain}" ] &&
|
||||||
|
[ ! "${domain}" = "localdomain" ] &&
|
||||||
|
[ ! "${domain}" = "localdomain6" ] &&
|
||||||
|
[ ! "${domain}" = "(none)" ] &&
|
||||||
|
[[ ! "${domain}" = *\ * ]]; then
|
||||||
|
is_in="false"
|
||||||
|
for s in ${search}; do
|
||||||
|
if [ "${s}" = "${domain}" ] ||
|
||||||
|
[ "${s}" = "${domain}." ]; then
|
||||||
|
is_in="true"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${is_in}" = "false" ]; then
|
||||||
|
# Add domain name to search list (#637763)
|
||||||
|
sed -i -e "s/${search}/${search} ${domain}/" "${RESOLVCONF}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
make_resolv_conf() {
|
||||||
|
[ "${PEERDNS}" = "no" ] && return
|
||||||
|
|
||||||
|
if [ "${reason}" = "RENEW" ] &&
|
||||||
|
[ "${new_domain_name}" = "${old_domain_name}" ] &&
|
||||||
|
[ "${new_domain_name_servers}" = "${old_domain_name_servers}" ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${new_domain_name}" ] ||
|
||||||
|
[ -n "${new_domain_name_servers}" ] ||
|
||||||
|
[ -n "${new_domain_search}" ]; then
|
||||||
|
rscf="$(mktemp "${TMPDIR:-/tmp}/XXXXXX")"
|
||||||
|
[[ -z "${rscf}" ]] && return
|
||||||
|
echo "; generated by /usr/sbin/dhclient-script" > "${rscf}"
|
||||||
|
|
||||||
|
if [ -n "${SEARCH}" ]; then
|
||||||
|
search="${SEARCH}"
|
||||||
|
else
|
||||||
|
if [ -n "${new_domain_search}" ]; then
|
||||||
|
# Remove instaces of \032 (#450042)
|
||||||
|
search="${new_domain_search//\\032/ }"
|
||||||
|
elif [ -n "${new_domain_name}" ]; then
|
||||||
|
# Note that the DHCP 'Domain Name Option' is really just a domain
|
||||||
|
# name, and that this practice of using the domain name option as
|
||||||
|
# a search path is both nonstandard and deprecated.
|
||||||
|
search="${new_domain_name}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${search}" ]; then
|
||||||
|
echo "search ${search}" >> "${rscf}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${RES_OPTIONS}" ]; then
|
||||||
|
echo "options ${RES_OPTIONS}" >> "${rscf}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${new_domain_name_servers}" ]; then
|
||||||
|
for nameserver in ${new_domain_name_servers} ; do
|
||||||
|
echo "nameserver ${nameserver}" >> "${rscf}"
|
||||||
|
done
|
||||||
|
else # keep 'old' nameservers
|
||||||
|
sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p "${RESOLVCONF}" >> "${rscf}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
change_resolv_conf "${rscf}"
|
||||||
|
rm -f "${rscf}"
|
||||||
|
|
||||||
|
if [ -n "${search}" ]; then
|
||||||
|
eventually_add_hostnames_domain_to_search "${search}"
|
||||||
|
fi
|
||||||
|
elif [ -n "${new_dhcp6_name_servers}" ] ||
|
||||||
|
[ -n "${new_dhcp6_domain_search}" ]; then
|
||||||
|
rscf="$(mktemp "${TMPDIR:-/tmp}/XXXXXX")"
|
||||||
|
[[ -z "${rscf}" ]] && return
|
||||||
|
echo "; generated by /usr/sbin/dhclient-script" > "${rscf}"
|
||||||
|
|
||||||
|
if [ -n "${SEARCH}" ]; then
|
||||||
|
search="${SEARCH}"
|
||||||
|
else
|
||||||
|
if [ -n "${new_dhcp6_domain_search}" ]; then
|
||||||
|
search="${new_dhcp6_domain_search//\\032/ }"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${search}" ]; then
|
||||||
|
echo "search ${search}" >> "${rscf}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${RES_OPTIONS}" ]; then
|
||||||
|
echo "options ${RES_OPTIONS}" >> "${rscf}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
shopt -s nocasematch
|
||||||
|
if [ -n "${new_dhcp6_name_servers}" ]; then
|
||||||
|
for nameserver in ${new_dhcp6_name_servers} ; do
|
||||||
|
# If the nameserver has a link-local address
|
||||||
|
# add a <zone_id> (interface name) to it.
|
||||||
|
if [[ "$nameserver" =~ ^fe80:: ]]
|
||||||
|
then
|
||||||
|
zone_id="%${interface}"
|
||||||
|
else
|
||||||
|
zone_id=
|
||||||
|
fi
|
||||||
|
echo "nameserver ${nameserver}$zone_id" >> "${rscf}"
|
||||||
|
done
|
||||||
|
else # keep 'old' nameservers
|
||||||
|
sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p "${RESOLVCONF}" >> "${rscf}"
|
||||||
|
fi
|
||||||
|
shopt -u nocasematch
|
||||||
|
|
||||||
|
change_resolv_conf "${rscf}"
|
||||||
|
rm -f "${rscf}"
|
||||||
|
|
||||||
|
if [ -n "${search}" ]; then
|
||||||
|
eventually_add_hostnames_domain_to_search "${search}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# run given script
|
||||||
|
run_hook() {
|
||||||
|
local script
|
||||||
|
local exit_status
|
||||||
|
script="${1}"
|
||||||
|
|
||||||
|
if [ -f ${script} ]; then
|
||||||
|
. ${script}
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${exit_status}" ] && [ "${exit_status}" -ne 0 ]; then
|
||||||
|
logmessage "${script} returned non-zero exit status ${exit_status}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
return ${exit_status}
|
||||||
|
}
|
||||||
|
|
||||||
|
# run scripts in given directory
|
||||||
|
run_hookdir() {
|
||||||
|
local dir
|
||||||
|
dir="${1}"
|
||||||
|
|
||||||
|
if [ -d "${dir}" ]; then
|
||||||
|
for script in $(find $dir -executable ! -empty); do
|
||||||
|
run_hook ${script} || return $?
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_with_hooks() {
|
||||||
|
# Source the documented exit-hook script, if it exists
|
||||||
|
run_hook "${ETCDIR}/dhclient-exit-hooks" || exit $?
|
||||||
|
# Now run scripts in the hooks directory.
|
||||||
|
run_hookdir "${ETCDIR}/dhclient-exit-hooks.d" || exit $?
|
||||||
|
|
||||||
|
exit ${1}
|
||||||
|
}
|
||||||
|
|
||||||
|
quad2num() {
|
||||||
|
if [ $# -eq 4 ]; then
|
||||||
|
let n="${1} << 24 | ${2} << 16 | ${3} << 8 | ${4}"
|
||||||
|
echo "${n}"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo "0"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ip2num() {
|
||||||
|
IFS='.' quad2num ${1}
|
||||||
|
}
|
||||||
|
|
||||||
|
num2ip() {
|
||||||
|
let n="${1}"
|
||||||
|
let o1="(${n} >> 24) & 0xff"
|
||||||
|
let o2="(${n} >> 16) & 0xff"
|
||||||
|
let o3="(${n} >> 8) & 0xff"
|
||||||
|
let o4="${n} & 0xff"
|
||||||
|
echo "${o1}.${o2}.${o3}.${o4}"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_network_address() {
|
||||||
|
# get network address for the given IP address and (netmask or prefix)
|
||||||
|
ip="${1}"
|
||||||
|
nm="${2}"
|
||||||
|
|
||||||
|
if [ -n "${ip}" -a -n "${nm}" ]; then
|
||||||
|
if [[ "${nm}" = *.* ]]; then
|
||||||
|
ipcalc -s -n "${ip}" "${nm}" | cut -d '=' -f 2
|
||||||
|
else
|
||||||
|
ipcalc -s -n "${ip}/${nm}" | cut -d '=' -f 2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
get_prefix() {
|
||||||
|
# get prefix for the given IP address and mask
|
||||||
|
ip="${1}"
|
||||||
|
nm="${2}"
|
||||||
|
|
||||||
|
if [ -n "${ip}" -a -n "${nm}" ]; then
|
||||||
|
ipcalc -s -p "${ip}" "${nm}" | cut -d '=' -f 2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
class_bits() {
|
||||||
|
let ip=$(IFS='.' ip2num "${1}")
|
||||||
|
let bits=32
|
||||||
|
let mask='255'
|
||||||
|
for ((i=0; i <= 3; i++, 'mask<<=8')); do
|
||||||
|
let v='ip&mask'
|
||||||
|
if [ "$v" -eq 0 ] ; then
|
||||||
|
let bits-=8
|
||||||
|
else
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo $bits
|
||||||
|
}
|
||||||
|
|
||||||
|
is_router_reachable() {
|
||||||
|
# handle DHCP servers that give us a router not on our subnet
|
||||||
|
router="${1}"
|
||||||
|
routersubnet="$(get_network_address "${router}" "${new_subnet_mask}")"
|
||||||
|
mysubnet="$(get_network_address "${new_ip_address}" "${new_subnet_mask}")"
|
||||||
|
|
||||||
|
if [ ! "${routersubnet}" = "${mysubnet}" ]; then
|
||||||
|
# TODO: This function should not have side effects such as adding or
|
||||||
|
# removing routes. Can this be done with "ip route get" or similar
|
||||||
|
# instead? Are there cases that rely on this route being created here?
|
||||||
|
ip -4 route replace "${router}/32" dev "${interface}"
|
||||||
|
if [ "$?" -ne 0 ]; then
|
||||||
|
logmessage "failed to create host route for ${router}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
add_default_gateway() {
|
||||||
|
router="${1}"
|
||||||
|
|
||||||
|
if is_router_reachable "${router}" ; then
|
||||||
|
if [ $# -gt 1 ] && [ -n "${2}" ] && [[ "${2}" -gt 0 ]]; then
|
||||||
|
ip -4 route replace default via "${router}" dev "${interface}" metric "${2}"
|
||||||
|
else
|
||||||
|
ip -4 route replace default via "${router}" dev "${interface}"
|
||||||
|
fi
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
logmessage "failed to create default route: ${router} dev ${interface} ${metric}"
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
execute_client_side_configuration_scripts() {
|
||||||
|
# execute any additional client side configuration scripts we have
|
||||||
|
if [ "${1}" == "config" ] || [ "${1}" == "restore" ]; then
|
||||||
|
for f in ${ETCDIR}/dhclient.d/*.sh ; do
|
||||||
|
if [ -x "${f}" ]; then
|
||||||
|
subsystem="${f%.sh}"
|
||||||
|
subsystem="${subsystem##*/}"
|
||||||
|
. "${f}"
|
||||||
|
"${subsystem}_${1}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
flush_dev() {
|
||||||
|
# Instead of bringing the interface down (#574568)
|
||||||
|
# explicitly clear ARP cache and flush all addresses & routes.
|
||||||
|
ip -4 addr flush dev "${1}" >/dev/null 2>&1
|
||||||
|
ip -4 route flush dev "${1}" >/dev/null 2>&1
|
||||||
|
ip -4 neigh flush dev "${1}" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_old_addr() {
|
||||||
|
if [ -n "${old_ip_address}" ]; then
|
||||||
|
if [ -n "${old_prefix}" ]; then
|
||||||
|
ip -4 addr del "${old_ip_address}/${old_prefix}" dev "${interface}" >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
ip -4 addr del "${old_ip_address}" dev "${interface}" >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
dhconfig() {
|
||||||
|
if [ -n "${old_ip_address}" ] && [ -n "${alias_ip_address}" ] &&
|
||||||
|
[ ! "${alias_ip_address}" = "${old_ip_address}" ]; then
|
||||||
|
# possible new alias, remove old alias first
|
||||||
|
ip -4 addr del "${old_ip_address}" dev "${interface}" label "${interface}:0"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${old_ip_address}" ] &&
|
||||||
|
[ ! "${old_ip_address}" = "${new_ip_address}" ]; then
|
||||||
|
# IP address changed. Delete all routes, and clear the ARP cache.
|
||||||
|
flush_dev "${interface}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# make sure the interface is up
|
||||||
|
ip link set dev "${interface}" up
|
||||||
|
|
||||||
|
# replace = add if it doesn't exist or override (update lifetimes) if it's there
|
||||||
|
ip -4 addr replace "${new_ip_address}/${new_prefix}" broadcast "${new_broadcast_address}" dev "${interface}" \
|
||||||
|
valid_lft "${new_dhcp_lease_time}" preferred_lft "${new_dhcp_lease_time}" >/dev/null 2>&1
|
||||||
|
|
||||||
|
if [ "${reason}" = "BOUND" ] || [ "${reason}" = "REBOOT" ] ||
|
||||||
|
[ ! "${old_ip_address}" = "${new_ip_address}" ] ||
|
||||||
|
[ ! "${old_subnet_mask}" = "${new_subnet_mask}" ] ||
|
||||||
|
[ ! "${old_network_number}" = "${new_network_number}" ] ||
|
||||||
|
[ ! "${old_broadcast_address}" = "${new_broadcast_address}" ] ||
|
||||||
|
[ ! "${old_routers}" = "${new_routers}" ] ||
|
||||||
|
[ ! "${old_interface_mtu}" = "${new_interface_mtu}" ]; then
|
||||||
|
|
||||||
|
# The 576 MTU is only used for X.25 and dialup connections
|
||||||
|
# where the admin wants low latency. Such a low MTU can cause
|
||||||
|
# problems with UDP traffic, among other things. As such,
|
||||||
|
# disallow MTUs from 576 and below by default, so that broken
|
||||||
|
# MTUs are ignored, but higher stuff is allowed (1492, 1500, etc).
|
||||||
|
if [ -n "${new_interface_mtu}" ] && [ "${new_interface_mtu}" -gt 576 ]; then
|
||||||
|
ip link set dev "${interface}" mtu "${new_interface_mtu}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# static routes
|
||||||
|
if [ -n "${new_classless_static_routes}" ] ||
|
||||||
|
[ -n "${new_static_routes}" ]; then
|
||||||
|
if [ -n "${new_classless_static_routes}" ]; then
|
||||||
|
IFS=', |' static_routes=(${new_classless_static_routes})
|
||||||
|
# If the DHCP server returns both a Classless Static Routes option and
|
||||||
|
# a Router option, the DHCP client MUST ignore the Router option. (RFC3442)
|
||||||
|
new_routers=""
|
||||||
|
else
|
||||||
|
IFS=', |' static_routes=(${new_static_routes})
|
||||||
|
fi
|
||||||
|
route_targets=()
|
||||||
|
|
||||||
|
for((i=0; i<${#static_routes[@]}; i+=2)); do
|
||||||
|
target=${static_routes[$i]}
|
||||||
|
if [ -n "${new_classless_static_routes}" ]; then
|
||||||
|
if [ "${target}" = "0" ]; then
|
||||||
|
new_routers="${static_routes[$i+1]}"
|
||||||
|
continue
|
||||||
|
else
|
||||||
|
prefix=${target%%.*}
|
||||||
|
target=${target#*.}
|
||||||
|
IFS="." target_arr=(${target})
|
||||||
|
unset IFS
|
||||||
|
((pads=4-${#target_arr[@]}))
|
||||||
|
for j in $(seq $pads); do
|
||||||
|
target="${target}.0"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Client MUST zero any bits in the subnet number where the corresponding bit in the mask is zero.
|
||||||
|
# In other words, the subnet number installed in the routing table is the logical AND of
|
||||||
|
# the subnet number and subnet mask given in the Classless Static Routes option. (RFC3442)
|
||||||
|
target="$(get_network_address "${target}" "${prefix}")"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
prefix=$(class_bits "${target}")
|
||||||
|
fi
|
||||||
|
gateway=${static_routes[$i+1]}
|
||||||
|
|
||||||
|
# special case 0.0.0.0 to allow static routing for link-local addresses
|
||||||
|
# (including IPv4 multicast) which will not have a next-hop (#769463, #787318)
|
||||||
|
if [ "${gateway}" = "0.0.0.0" ]; then
|
||||||
|
valid_gateway=0
|
||||||
|
scope='scope link'
|
||||||
|
else
|
||||||
|
is_router_reachable "${gateway}"
|
||||||
|
valid_gateway=$?
|
||||||
|
scope=''
|
||||||
|
fi
|
||||||
|
if [ "${valid_gateway}" -eq 0 ]; then
|
||||||
|
metric=''
|
||||||
|
for t in "${route_targets[@]}"; do
|
||||||
|
if [ "${t}" = "${target}" ]; then
|
||||||
|
if [ -z "${metric}" ]; then
|
||||||
|
metric=1
|
||||||
|
else
|
||||||
|
((metric=metric+1))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "${metric}" ]; then
|
||||||
|
metric="metric ${metric}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
ip -4 route replace "${target}/${prefix}" proto static via "${gateway}" dev "${interface}" ${metric} ${scope}
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
logmessage "failed to create static route: ${target}/${prefix} via ${gateway} dev ${interface} ${metric}"
|
||||||
|
else
|
||||||
|
route_targets=(${route_targets[@]} ${target})
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# gateways
|
||||||
|
if [[ ( "${DEFROUTE}" != "no" ) &&
|
||||||
|
(( -z "${GATEWAYDEV}" ) || ( "${GATEWAYDEV}" = "${interface}" )) ]]; then
|
||||||
|
if [[ ( -z "${GATEWAY}" ) ||
|
||||||
|
(( -n "${DHCLIENT_IGNORE_GATEWAY}" ) && ( "${DHCLIENT_IGNORE_GATEWAY}" = [Yy]* )) ]]; then
|
||||||
|
metric="${METRIC:-}"
|
||||||
|
let i="${METRIC:-0}"
|
||||||
|
default_routers=()
|
||||||
|
|
||||||
|
for router in ${new_routers} ; do
|
||||||
|
added_router=-
|
||||||
|
|
||||||
|
for r in "${default_routers[@]}" ; do
|
||||||
|
if [ "${r}" = "${router}" ]; then
|
||||||
|
added_router=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "${router}" ] ||
|
||||||
|
[ "${added_router}" = "1" ] ||
|
||||||
|
[ "$(IFS='.' ip2num ${router})" -le 0 ] ||
|
||||||
|
[[ ( "${router}" = "${new_broadcast_address}" ) &&
|
||||||
|
( "${new_subnet_mask}" != "255.255.255.255" ) ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
default_routers=(${default_routers[@]} ${router})
|
||||||
|
add_default_gateway "${router}" "${metric}"
|
||||||
|
let i=i+1
|
||||||
|
metric=${i}
|
||||||
|
done
|
||||||
|
elif [ -n "${GATEWAY}" ]; then
|
||||||
|
routersubnet=$(get_network_address "${GATEWAY}" "${new_subnet_mask}")
|
||||||
|
mysubnet=$(get_network_address "${new_ip_address}" "${new_subnet_mask}")
|
||||||
|
|
||||||
|
if [ "${routersubnet}" = "${mysubnet}" ]; then
|
||||||
|
ip -4 route replace default via "${GATEWAY}" dev "${interface}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! "${new_ip_address}" = "${alias_ip_address}" ] &&
|
||||||
|
[ -n "${alias_ip_address}" ]; then
|
||||||
|
# Reset the alias address (fix: this should really only do this on changes)
|
||||||
|
ip -4 addr flush dev "${interface}" label "${interface}:0" >/dev/null 2>&1
|
||||||
|
ip -4 addr replace "${alias_ip_address}/${alias_prefix}" broadcast "${alias_broadcast_address}" dev "${interface}" label "${interface}:0"
|
||||||
|
ip -4 route replace "${alias_ip_address}/32" dev "${interface}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# After dhclient brings an interface UP with a new IP address, subnet mask,
|
||||||
|
# and routes, in the REBOOT/BOUND states -> search for "dhclient-up-hooks".
|
||||||
|
if [ "${reason}" = "BOUND" ] || [ "${reason}" = "REBOOT" ] ||
|
||||||
|
[ ! "${old_ip_address}" = "${new_ip_address}" ] ||
|
||||||
|
[ ! "${old_subnet_mask}" = "${new_subnet_mask}" ] ||
|
||||||
|
[ ! "${old_network_number}" = "${new_network_number}" ] ||
|
||||||
|
[ ! "${old_broadcast_address}" = "${new_broadcast_address}" ] ||
|
||||||
|
[ ! "${old_routers}" = "${new_routers}" ] ||
|
||||||
|
[ ! "${old_interface_mtu}" = "${new_interface_mtu}" ]; then
|
||||||
|
|
||||||
|
if [ -x "${ETCDIR}/dhclient-${interface}-up-hooks" ]; then
|
||||||
|
. "${ETCDIR}/dhclient-${interface}-up-hooks"
|
||||||
|
elif [ -x ${ETCDIR}/dhclient-up-hooks ]; then
|
||||||
|
. ${ETCDIR}/dhclient-up-hooks
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
make_resolv_conf
|
||||||
|
|
||||||
|
if [ -n "${new_host_name}" ] && need_hostname; then
|
||||||
|
hostnamectl set-hostname --transient --no-ask-password "${new_host_name}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ( "${DHCP_TIME_OFFSET_SETS_TIMEZONE}" = [yY1]* ) &&
|
||||||
|
( -n "${new_time_offset}" ) ]]; then
|
||||||
|
# DHCP option "time-offset" is requested by default and should be
|
||||||
|
# handled. The geographical zone abbreviation cannot be determined
|
||||||
|
# from the GMT offset, but the $ZONEINFO/Etc/GMT$offset file can be
|
||||||
|
# used - note: this disables DST.
|
||||||
|
((z=new_time_offset/3600))
|
||||||
|
((hoursWest=$(printf '%+d' $z)))
|
||||||
|
|
||||||
|
if (( $hoursWest < 0 )); then
|
||||||
|
# tzdata treats negative 'hours west' as positive 'gmtoff'!
|
||||||
|
((hoursWest*=-1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
tzfile=/usr/share/zoneinfo/Etc/GMT$(printf '%+d' ${hoursWest})
|
||||||
|
if [ -e "${tzfile}" ]; then
|
||||||
|
cp -fp "${tzfile}" /etc/localtime
|
||||||
|
touch /etc/localtime
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
execute_client_side_configuration_scripts "config"
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_link_local() {
|
||||||
|
# we need a link-local address to be ready (not tentative)
|
||||||
|
for i in $(seq 50); do
|
||||||
|
linklocal=$(ip -6 addr show dev "${interface}" scope link)
|
||||||
|
# tentative flag means DAD is still not complete
|
||||||
|
tentative=$(echo "${linklocal}" | grep tentative)
|
||||||
|
[[ -n "${linklocal}" && -z "${tentative}" ]] && exit_with_hooks 0
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Section 18.1.8. (Receipt of Reply Messages) of RFC 3315 says:
|
||||||
|
# The client SHOULD perform duplicate address detection on each of
|
||||||
|
# the addresses in any IAs it receives in the Reply message before
|
||||||
|
# using that address for traffic.
|
||||||
|
add_ipv6_addr_with_DAD() {
|
||||||
|
ip -6 addr replace "${new_ip6_address}/${new_ip6_prefixlen}" \
|
||||||
|
dev "${interface}" scope global valid_lft "${new_max_life}" \
|
||||||
|
preferred_lft "${new_preferred_life}"
|
||||||
|
|
||||||
|
# repeatedly test whether newly added address passed
|
||||||
|
# duplicate address detection (DAD)
|
||||||
|
for i in $(seq 5); do
|
||||||
|
sleep 1 # give the DAD some time
|
||||||
|
|
||||||
|
addr=$(ip -6 addr show dev "${interface}" \
|
||||||
|
| grep "${new_ip6_address}/${new_ip6_prefixlen}")
|
||||||
|
|
||||||
|
# tentative flag == DAD is still not complete
|
||||||
|
tentative=$(echo "${addr}" | grep tentative)
|
||||||
|
# dadfailed flag == address is already in use somewhere else
|
||||||
|
dadfailed=$(echo "${addr}" | grep dadfailed)
|
||||||
|
|
||||||
|
if [ -n "${dadfailed}" ] ; then
|
||||||
|
# address was added with valid_lft/preferred_lft 'forever', remove it
|
||||||
|
ip -6 addr del "${new_ip6_address}/${new_ip6_prefixlen}" dev "${interface}"
|
||||||
|
exit_with_hooks 3
|
||||||
|
fi
|
||||||
|
if [ -z "${tentative}" ] ; then
|
||||||
|
if [ -n "${addr}" ]; then
|
||||||
|
# DAD is over
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
# address was auto-removed (or not added at all)
|
||||||
|
exit_with_hooks 3
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
dh6config() {
|
||||||
|
if [ -n "${old_ip6_prefix}" ] ||
|
||||||
|
[ -n "${new_ip6_prefix}" ]; then
|
||||||
|
echo "Prefix ${reason} old=${old_ip6_prefix} new=${new_ip6_prefix}"
|
||||||
|
exit_with_hooks 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "${reason}" in
|
||||||
|
BOUND6)
|
||||||
|
if [ -z "${new_ip6_address}" ] ||
|
||||||
|
[ -z "${new_ip6_prefixlen}" ]; then
|
||||||
|
exit_with_hooks 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
add_ipv6_addr_with_DAD
|
||||||
|
|
||||||
|
make_resolv_conf
|
||||||
|
;;
|
||||||
|
|
||||||
|
RENEW6|REBIND6)
|
||||||
|
if [[ -n "${new_ip6_address}" ]] &&
|
||||||
|
[[ -n "${new_ip6_prefixlen}" ]]; then
|
||||||
|
if [[ ! "${new_ip6_address}" = "${old_ip6_address}" ]]; then
|
||||||
|
[[ -n "${old_ip6_address}" ]] && ip -6 addr del "${old_ip6_address}" dev "${interface}"
|
||||||
|
fi
|
||||||
|
# call it even if new_ip6_address = old_ip6_address to update lifetimes
|
||||||
|
add_ipv6_addr_with_DAD
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! "${new_dhcp6_name_servers}" = "${old_dhcp6_name_servers}" ] ||
|
||||||
|
[ ! "${new_dhcp6_domain_search}" = "${old_dhcp6_domain_search}" ]; then
|
||||||
|
make_resolv_conf
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
DEPREF6)
|
||||||
|
if [ -z "${new_ip6_prefixlen}" ]; then
|
||||||
|
exit_with_hooks 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
ip -6 addr change "${new_ip6_address}/${new_ip6_prefixlen}" \
|
||||||
|
dev "${interface}" scope global preferred_lft 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
execute_client_side_configuration_scripts "config"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Functions from /etc/sysconfig/network-scripts/network-functions
|
||||||
|
|
||||||
|
need_hostname ()
|
||||||
|
{
|
||||||
|
CHECK_HOSTNAME=$(hostnamectl --transient)
|
||||||
|
if [[ "${CHECK_HOSTNAME}" = "(none)" ]] ||
|
||||||
|
[[ "${CHECK_HOSTNAME}" = "localhost" ]] ||
|
||||||
|
[[ "${CHECK_HOSTNAME}" = "localhost.localdomain" ]]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Takes one argument - temporary resolv.conf file
|
||||||
|
change_resolv_conf ()
|
||||||
|
{
|
||||||
|
options=$(grep '^[\ \ ]*option' "${RESOLVCONF}" 2>/dev/null);
|
||||||
|
if [[ -n "${options}" ]]; then
|
||||||
|
# merge options from existing resolv.conf with specified resolv.conf content
|
||||||
|
newres="${options}"$'\n'$(grep -vF "${options}" "${1}");
|
||||||
|
else
|
||||||
|
newres=$(cat "${1}");
|
||||||
|
fi;
|
||||||
|
|
||||||
|
eval $(echo "${newres}" > "${RESOLVCONF}"; echo "status=$?")
|
||||||
|
if [[ $status -eq 0 ]]; then
|
||||||
|
logger -p local7.notice -t "NET" -i "${0} : updated ${RESOLVCONF}";
|
||||||
|
[[ -e /var/run/nscd/socket ]] && /usr/sbin/nscd -i hosts; # invalidate cache
|
||||||
|
fi;
|
||||||
|
return $status;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_config_by_name ()
|
||||||
|
{
|
||||||
|
LANG=C grep -E -i -l \
|
||||||
|
"^[[:space:]]*NAME=\"(Auto |System )?${1}\"" \
|
||||||
|
/etc/sysconfig/network-scripts/ifcfg-* \
|
||||||
|
| LC_ALL=C sed -e "$__sed_discard_ignored_files"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_hwaddr ()
|
||||||
|
{
|
||||||
|
if [ -f /sys/class/net/${1}/address ]; then
|
||||||
|
awk '{ print toupper($0) }' < /sys/class/net/${1}/address
|
||||||
|
elif [ -d "/sys/class/net/${1}" ]; then
|
||||||
|
LC_ALL= LANG= ip -o link show ${1} 2>/dev/null | \
|
||||||
|
awk '{ print toupper(gensub(/.*link\/[^ ]* ([[:alnum:]:]*).*/,
|
||||||
|
"\\1", 1)); }'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_resolv_conf()
|
||||||
|
{
|
||||||
|
# It's possible to have broken symbolic link $RESOLVCONF -> <some_nm_dir>
|
||||||
|
# https://bugzilla.redhat.com/1475279
|
||||||
|
# Remove broken link and hope NM will survive
|
||||||
|
if [ -h "${RESOLVCONF}" -a ! -e "${RESOLVCONF}" ];
|
||||||
|
then
|
||||||
|
logmessage "${RESOLVCONF} is broken symlink. Recreating..."
|
||||||
|
unlink "${RESOLVCONF}"
|
||||||
|
touch "${RESOLVCONF}"
|
||||||
|
fi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
get_config_by_hwaddr ()
|
||||||
|
{
|
||||||
|
LANG=C grep -il "^[[:space:]]*HWADDR=\"\?${1}\"\?\([[:space:]#]\|$\)" /etc/sysconfig/network-scripts/ifcfg-* \
|
||||||
|
| LC_ALL=C sed -e "$__sed_discard_ignored_files"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_config_by_device ()
|
||||||
|
{
|
||||||
|
LANG=C grep -l "^[[:space:]]*DEVICE=\"\?${1}\"\?\([[:space:]#]\|$\)" \
|
||||||
|
/etc/sysconfig/network-scripts/ifcfg-* \
|
||||||
|
| LC_ALL=C sed -e "$__sed_discard_ignored_files"
|
||||||
|
}
|
||||||
|
|
||||||
|
need_config ()
|
||||||
|
{
|
||||||
|
# A sed expression to filter out the files that is_ignored_file recognizes
|
||||||
|
__sed_discard_ignored_files='/\(~\|\.bak\|\.orig\|\.rpmnew\|\.rpmorig\|\.rpmsave\)$/d'
|
||||||
|
|
||||||
|
local nconfig
|
||||||
|
|
||||||
|
CONFIG="ifcfg-${1}"
|
||||||
|
[ -f "${CONFIG}" ] && return
|
||||||
|
CONFIG="${1##*/}"
|
||||||
|
[ -f "${CONFIG}" ] && return
|
||||||
|
nconfig=$(get_config_by_name "${1}")
|
||||||
|
if [ -n "$nconfig" ] && [ -f "$nconfig" ]; then
|
||||||
|
CONFIG=${nconfig##*/}
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local addr=$(get_hwaddr ${1})
|
||||||
|
if [ -n "$addr" ]; then
|
||||||
|
nconfig=$(get_config_by_hwaddr ${addr})
|
||||||
|
if [ -n "$nconfig" ] ; then
|
||||||
|
CONFIG=${nconfig##*/}
|
||||||
|
[ -f "${CONFIG}" ] && return
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
nconfig=$(get_config_by_device ${1})
|
||||||
|
if [ -n "$nconfig" ] && [ -f "$nconfig" ]; then
|
||||||
|
CONFIG=${nconfig##*/}
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# We need this because of PEERDNS
|
||||||
|
source_config ()
|
||||||
|
{
|
||||||
|
CONFIG=${CONFIG##*/}
|
||||||
|
. /etc/sysconfig/network-scripts/$CONFIG
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# ### MAIN
|
||||||
|
#
|
||||||
|
|
||||||
|
# Invoke the local dhcp client enter hooks, if they exist.
|
||||||
|
run_hook "${ETCDIR}/dhclient-enter-hooks" || exit $?
|
||||||
|
run_hookdir "${ETCDIR}/dhclient-enter-hooks.d" || exit $?
|
||||||
|
|
||||||
|
[ "${PEERDNS}" = "no" ] || validate_resolv_conf
|
||||||
|
|
||||||
|
if [ -f /etc/sysconfig/network ]; then
|
||||||
|
. /etc/sysconfig/network
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f /etc/sysconfig/networking/network ]; then
|
||||||
|
. /etc/sysconfig/networking/network
|
||||||
|
fi
|
||||||
|
|
||||||
|
## it's possible initscripts package is not installed
|
||||||
|
## for example in container. Don't flood stderr then
|
||||||
|
if [ -d /etc/sysconfig/network-scripts ]; then
|
||||||
|
cd /etc/sysconfig/network-scripts
|
||||||
|
CONFIG="${interface}"
|
||||||
|
need_config "${CONFIG}"
|
||||||
|
source_config >/dev/null 2>&1
|
||||||
|
fi;
|
||||||
|
|
||||||
|
# In case there's some delay in rebinding, it might happen, that the valid_lft drops to 0,
|
||||||
|
# address is removed by kernel and then re-added few seconds later by dhclient-script.
|
||||||
|
# With this work-around the address lives a minute longer.
|
||||||
|
# "4294967235" = infinite (forever) - 60
|
||||||
|
[[ "${new_dhcp_lease_time}" -lt "4294967235" ]] && new_dhcp_lease_time=$((new_dhcp_lease_time + 60))
|
||||||
|
[[ "${new_max_life}" -lt "4294967235" ]] && new_max_life=$((new_max_life + 60))
|
||||||
|
|
||||||
|
new_prefix="$(get_prefix "${new_ip_address}" "${new_subnet_mask}")"
|
||||||
|
old_prefix="$(get_prefix "${old_ip_address}" "${old_subnet_mask}")"
|
||||||
|
alias_prefix="$(get_prefix "${alias_ip_address}" "${alias_subnet_mask}")"
|
||||||
|
|
||||||
|
case "${reason}" in
|
||||||
|
MEDIUM|ARPCHECK|ARPSEND)
|
||||||
|
# Do nothing
|
||||||
|
exit_with_hooks 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
PREINIT)
|
||||||
|
if [ -n "${alias_ip_address}" ]; then
|
||||||
|
# Flush alias, its routes will disappear too.
|
||||||
|
ip -4 addr flush dev "${interface}" label "${interface}:0" >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# upstream dhclient-script removes (ifconfig $interface 0 up) old adresses in PREINIT,
|
||||||
|
# but we sometimes (#125298) need (for iSCSI/nfs root to have a dhcp interface) to keep the existing ip
|
||||||
|
# flush_dev ${interface}
|
||||||
|
ip link set dev "${interface}" up
|
||||||
|
if [ -n "${DHCLIENT_DELAY}" ] && [ "${DHCLIENT_DELAY}" -gt 0 ]; then
|
||||||
|
# We need to give the kernel some time to get the interface up.
|
||||||
|
sleep "${DHCLIENT_DELAY}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit_with_hooks 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
PREINIT6)
|
||||||
|
# ensure interface is up
|
||||||
|
ip link set dev "${interface}" up
|
||||||
|
|
||||||
|
# Removing stale addresses from aborted clients shouldn't be needed
|
||||||
|
# since we've been adding addresses with lifetimes.
|
||||||
|
# Which means that kernel eventually removes them automatically.
|
||||||
|
# ip -6 addr flush dev "${interface}" scope global permanent
|
||||||
|
|
||||||
|
wait_for_link_local
|
||||||
|
|
||||||
|
exit_with_hooks 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
BOUND|RENEW|REBIND|REBOOT)
|
||||||
|
if [ -z "${interface}" ] || [ -z "${new_ip_address}" ]; then
|
||||||
|
exit_with_hooks 2
|
||||||
|
fi
|
||||||
|
if arping -D -q -c2 -I "${interface}" "${new_ip_address}"; then
|
||||||
|
dhconfig
|
||||||
|
exit_with_hooks 0
|
||||||
|
else # DAD failed, i.e. address is already in use
|
||||||
|
ARP_REPLY=$(arping -D -c2 -I "${interface}" "${new_ip_address}" | grep reply | awk '{print toupper($5)}' | cut -d "[" -f2 | cut -d "]" -f1)
|
||||||
|
OUR_MACS=$(ip link show | grep link | awk '{print toupper($2)}' | uniq)
|
||||||
|
if [[ "${OUR_MACS}" = *"${ARP_REPLY}"* ]]; then
|
||||||
|
# the reply can come from our system, that's OK (#1116004#c33)
|
||||||
|
dhconfig
|
||||||
|
exit_with_hooks 0
|
||||||
|
else
|
||||||
|
exit_with_hooks 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
BOUND6|RENEW6|REBIND6|DEPREF6)
|
||||||
|
dh6config
|
||||||
|
exit_with_hooks 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
EXPIRE6|RELEASE6|STOP6)
|
||||||
|
if [ -z "${old_ip6_address}" ] || [ -z "${old_ip6_prefixlen}" ]; then
|
||||||
|
exit_with_hooks 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
ip -6 addr del "${old_ip6_address}/${old_ip6_prefixlen}" \
|
||||||
|
dev "${interface}"
|
||||||
|
|
||||||
|
execute_client_side_configuration_scripts "restore"
|
||||||
|
|
||||||
|
if [ -x "${ETCDIR}/dhclient-${interface}-down-hooks" ]; then
|
||||||
|
. "${ETCDIR}/dhclient-${interface}-down-hooks"
|
||||||
|
elif [ -x ${ETCDIR}/dhclient-down-hooks ]; then
|
||||||
|
. ${ETCDIR}/dhclient-down-hooks
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit_with_hooks 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
EXPIRE|FAIL|RELEASE|STOP)
|
||||||
|
execute_client_side_configuration_scripts "restore"
|
||||||
|
|
||||||
|
if [ -x "${ETCDIR}/dhclient-${interface}-down-hooks" ]; then
|
||||||
|
. "${ETCDIR}/dhclient-${interface}-down-hooks"
|
||||||
|
elif [ -x ${ETCDIR}/dhclient-down-hooks ]; then
|
||||||
|
. ${ETCDIR}/dhclient-down-hooks
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${alias_ip_address}" ]; then
|
||||||
|
# Flush alias
|
||||||
|
ip -4 addr flush dev "${interface}" label "${interface}:0" >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# upstream script sets interface down here,
|
||||||
|
# we only remove old ip address
|
||||||
|
#flush_dev ${interface}
|
||||||
|
remove_old_addr
|
||||||
|
|
||||||
|
if [ -n "${alias_ip_address}" ]; then
|
||||||
|
ip -4 addr replace "${alias_ip_address}/${alias_prefix}" broadcast "${alias_broadcast_address}" dev "${interface}" label "${interface}:0"
|
||||||
|
ip -4 route replace "${alias_ip_address}/32" dev "${interface}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit_with_hooks 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
TIMEOUT)
|
||||||
|
if [ -n "${new_routers}" ]; then
|
||||||
|
if [ -n "${alias_ip_address}" ]; then
|
||||||
|
ip -4 addr flush dev "${interface}" label "${interface}:0" >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ip -4 addr replace "${new_ip_address}/${new_prefix}" \
|
||||||
|
broadcast "${new_broadcast_address}" dev "${interface}" \
|
||||||
|
valid_lft "${new_dhcp_lease_time}" preferred_lft "${new_dhcp_lease_time}"
|
||||||
|
set ${new_routers}
|
||||||
|
|
||||||
|
if ping -q -c 1 -w 10 -I "${interface}" "${1}"; then
|
||||||
|
dhconfig
|
||||||
|
exit_with_hooks 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
#flush_dev ${interface}
|
||||||
|
remove_old_addr
|
||||||
|
exit_with_hooks 1
|
||||||
|
else
|
||||||
|
exit_with_hooks 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
logmessage "unhandled state: ${reason}"
|
||||||
|
exit_with_hooks 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit_with_hooks 0
|
@ -0,0 +1,31 @@
|
|||||||
|
diff -up dhcp-4.2.5/client/dhclient.c.orig dhcp-4.2.5/client/dhclient.c
|
||||||
|
--- dhcp-4.2.5/client/dhclient.c.orig 2018-11-07 14:21:16.756152614 +0100
|
||||||
|
+++ dhcp-4.2.5/client/dhclient.c 2018-11-08 17:30:15.754440523 +0100
|
||||||
|
@@ -1618,8 +1618,14 @@ void dhcpack (packet)
|
||||||
|
} else
|
||||||
|
client -> new -> renewal = 0;
|
||||||
|
|
||||||
|
- /* If it wasn't specified by the server, calculate it. */
|
||||||
|
- if (!client -> new -> renewal)
|
||||||
|
+ /*
|
||||||
|
+ * If it wasn't specified by the server, calculate it. Also use expiry
|
||||||
|
+ * instead of renewal time when it is shorter. This better follows
|
||||||
|
+ * RFC 2131 (section 4.4.5) when dealing with some DHCP servers.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ if (!client -> new -> renewal ||
|
||||||
|
+ client -> new -> renewal > client -> new -> expiry)
|
||||||
|
client -> new -> renewal = client -> new -> expiry / 2 + 1;
|
||||||
|
|
||||||
|
if (client -> new -> renewal <= 0)
|
||||||
|
@@ -1645,7 +1651,9 @@ void dhcpack (packet)
|
||||||
|
} else
|
||||||
|
client -> new -> rebind = 0;
|
||||||
|
|
||||||
|
- if (client -> new -> rebind <= 0) {
|
||||||
|
+ /* Rebinding time must not be longer than expiry. */
|
||||||
|
+ if (client -> new -> rebind <= 0 ||
|
||||||
|
+ client -> new -> rebind > client -> new -> expiry) {
|
||||||
|
if (client -> new -> expiry <= TIME_MAX / 7)
|
||||||
|
client -> new -> rebind =
|
||||||
|
client -> new -> expiry * 7 / 8;
|
@ -0,0 +1,77 @@
|
|||||||
|
From c37721f799e6b32da156759a830011949311205a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Petr Mensik <pemensik@redhat.com>
|
||||||
|
Date: Fri, 16 Feb 2018 17:50:40 +0100
|
||||||
|
Subject: [PATCH] New bind includes never includes isc/util.h from any public
|
||||||
|
headers. Include them to all compiled files that require it.
|
||||||
|
|
||||||
|
---
|
||||||
|
client/dhclient.c | 1 +
|
||||||
|
common/execute.c | 1 +
|
||||||
|
common/parse.c | 1 +
|
||||||
|
common/socket.c | 1 +
|
||||||
|
omapip/connection.c | 1 +
|
||||||
|
5 files changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/client/dhclient.c b/client/dhclient.c
|
||||||
|
index 228b4fe..014365d 100644
|
||||||
|
--- a/client/dhclient.c
|
||||||
|
+++ b/client/dhclient.c
|
||||||
|
@@ -38,6 +38,7 @@
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <isc/file.h>
|
||||||
|
+#include <isc/util.h>
|
||||||
|
#include <dns/result.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBCAP_NG
|
||||||
|
diff --git a/common/execute.c b/common/execute.c
|
||||||
|
index fa4e0f8..1ee1e7d 100644
|
||||||
|
--- a/common/execute.c
|
||||||
|
+++ b/common/execute.c
|
||||||
|
@@ -28,6 +28,7 @@
|
||||||
|
|
||||||
|
#include "dhcpd.h"
|
||||||
|
#include <omapip/omapip_p.h>
|
||||||
|
+#include <isc/util.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
diff --git a/common/parse.c b/common/parse.c
|
||||||
|
index d08cd2c..729d442 100644
|
||||||
|
--- a/common/parse.c
|
||||||
|
+++ b/common/parse.c
|
||||||
|
@@ -27,6 +27,7 @@
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dhcpd.h"
|
||||||
|
+#include <isc/util.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
/* Enumerations can be specified in option formats, and are used for
|
||||||
|
diff --git a/common/socket.c b/common/socket.c
|
||||||
|
index 2b352a1..94ce334 100644
|
||||||
|
--- a/common/socket.c
|
||||||
|
+++ b/common/socket.c
|
||||||
|
@@ -35,6 +35,7 @@
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dhcpd.h"
|
||||||
|
+#include <isc/util.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
diff --git a/omapip/connection.c b/omapip/connection.c
|
||||||
|
index 9aac0c8..a74becc 100644
|
||||||
|
--- a/omapip/connection.c
|
||||||
|
+++ b/omapip/connection.c
|
||||||
|
@@ -30,6 +30,7 @@
|
||||||
|
#include "dhcpd.h"
|
||||||
|
|
||||||
|
#include <omapip/omapip_p.h>
|
||||||
|
+#include <isc/util.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <arpa/nameser.h>
|
||||||
|
#include <errno.h>
|
||||||
|
--
|
||||||
|
2.14.3
|
||||||
|
|
@ -0,0 +1,52 @@
|
|||||||
|
commit ccff9ed69d0b26d33ce9cac8e83dab535b64d627
|
||||||
|
Author: Thomas Markwalder <tmark@isc.org>
|
||||||
|
Date: Tue Dec 5 15:12:34 2017 -0500
|
||||||
|
|
||||||
|
[46767] Plugged a socket descriptor leak in OMAPI
|
||||||
|
|
||||||
|
If disconnect is triggered by the reader closing the socket, while there
|
||||||
|
is data left to write, the socket would be orphaned.
|
||||||
|
|
||||||
|
omapip/buffer.c
|
||||||
|
omapi_connection_writea() - added logic to recall disconnect once
|
||||||
|
pending data has been written
|
||||||
|
|
||||||
|
omapip/message.c
|
||||||
|
Removed static declaration from omapi_message_unregister so you can
|
||||||
|
actually compile when DEBUG_PROTOCOL is defined.
|
||||||
|
|
||||||
|
Added a release note
|
||||||
|
|
||||||
|
diff --git a/omapip/buffer.c b/omapip/buffer.c
|
||||||
|
index 6e0621b..a21f0a8 100644
|
||||||
|
--- a/omapip/buffer.c
|
||||||
|
+++ b/omapip/buffer.c
|
||||||
|
@@ -565,6 +565,15 @@ isc_result_t omapi_connection_writer (omapi_object_t *h)
|
||||||
|
omapi_buffer_dereference (&buffer, MDL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ /* If we had data left to write when we're told to disconnect,
|
||||||
|
+ * we need recall disconnect, now that we're done writing.
|
||||||
|
+ * See rt46767. */
|
||||||
|
+ if (c->out_bytes == 0 && c->state == omapi_connection_disconnecting) {
|
||||||
|
+ omapi_disconnect (h, 1);
|
||||||
|
+ return ISC_R_SHUTTINGDOWN;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return ISC_R_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/omapip/message.c b/omapip/message.c
|
||||||
|
index ee15d82..37abbd2 100644
|
||||||
|
--- a/omapip/message.c
|
||||||
|
+++ b/omapip/message.c
|
||||||
|
@@ -339,7 +339,7 @@ isc_result_t omapi_message_unregister (omapi_object_t *mo)
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_PROTOCOL
|
||||||
|
-static const char *omapi_message_op_name(int op) {
|
||||||
|
+const char *omapi_message_op_name(int op) {
|
||||||
|
switch (op) {
|
||||||
|
case OMAPI_OP_OPEN: return "OMAPI_OP_OPEN";
|
||||||
|
case OMAPI_OP_REFRESH: return "OMAPI_OP_REFRESH";
|
@ -0,0 +1,41 @@
|
|||||||
|
diff --git a/common/options.c b/common/options.c
|
||||||
|
index 83e0384..8a1deca 100644
|
||||||
|
--- a/common/options.c
|
||||||
|
+++ b/common/options.c
|
||||||
|
@@ -1672,7 +1672,8 @@ format_min_length(format, oc)
|
||||||
|
|
||||||
|
|
||||||
|
/* Format the specified option so that a human can easily read it. */
|
||||||
|
-
|
||||||
|
+/* Maximum pretty printed size */
|
||||||
|
+#define MAX_OUTPUT_SIZE 32*1024
|
||||||
|
const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
|
||||||
|
struct option *option;
|
||||||
|
const unsigned char *data;
|
||||||
|
@@ -1680,8 +1681,9 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
|
||||||
|
int emit_commas;
|
||||||
|
int emit_quotes;
|
||||||
|
{
|
||||||
|
- static char optbuf [32768]; /* XXX */
|
||||||
|
- static char *endbuf = &optbuf[sizeof(optbuf)];
|
||||||
|
+ /* We add 128 byte pad so we don't have to add checks everywhere. */
|
||||||
|
+ static char optbuf [MAX_OUTPUT_SIZE + 128]; /* XXX */
|
||||||
|
+ static char *endbuf = optbuf + MAX_OUTPUT_SIZE;
|
||||||
|
int hunksize = 0;
|
||||||
|
int opthunk = 0;
|
||||||
|
int hunkinc = 0;
|
||||||
|
@@ -2132,7 +2134,14 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
|
||||||
|
log_error ("Unexpected format code %c",
|
||||||
|
fmtbuf [j]);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
op += strlen (op);
|
||||||
|
+ if (op >= endbuf) {
|
||||||
|
+ log_error ("Option data exceeds"
|
||||||
|
+ " maximum size %d", MAX_OUTPUT_SIZE);
|
||||||
|
+ return ("<error>");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (dp == data + len)
|
||||||
|
break;
|
||||||
|
if (j + 1 < numelem && comma != ':')
|
@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/common/options.c b/common/options.c
|
||||||
|
index 83e0384..a58c5fc 100644
|
||||||
|
--- a/common/options.c
|
||||||
|
+++ b/common/options.c
|
||||||
|
@@ -189,6 +189,8 @@ int parse_option_buffer (options, buffer, length, universe)
|
||||||
|
|
||||||
|
/* If the length is outrageous, the options are bad. */
|
||||||
|
if (offset + len > length) {
|
||||||
|
+ /* Avoid reference count overflow */
|
||||||
|
+ option_dereference(&option, MDL);
|
||||||
|
reason = "option length exceeds option buffer length";
|
||||||
|
bogus:
|
||||||
|
log_error("parse_option_buffer: malformed option "
|
@ -0,0 +1,75 @@
|
|||||||
|
diff -up dhcp-4.3.0a1/common/parse.c.64-bit_lease_parse dhcp-4.3.0a1/common/parse.c
|
||||||
|
--- dhcp-4.3.0a1/common/parse.c.64-bit_lease_parse 2013-12-11 01:25:12.000000000 +0100
|
||||||
|
+++ dhcp-4.3.0a1/common/parse.c 2013-12-19 15:45:25.990771814 +0100
|
||||||
|
@@ -938,8 +938,8 @@ TIME
|
||||||
|
parse_date_core(cfile)
|
||||||
|
struct parse *cfile;
|
||||||
|
{
|
||||||
|
- int guess;
|
||||||
|
- int tzoff, year, mon, mday, hour, min, sec;
|
||||||
|
+ TIME guess;
|
||||||
|
+ long int tzoff, year, mon, mday, hour, min, sec;
|
||||||
|
const char *val;
|
||||||
|
enum dhcp_token token;
|
||||||
|
static int months[11] = { 31, 59, 90, 120, 151, 181,
|
||||||
|
@@ -965,7 +965,7 @@ parse_date_core(cfile)
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_token(&val, NULL, cfile); /* consume number */
|
||||||
|
- guess = atoi(val);
|
||||||
|
+ guess = atol(val);
|
||||||
|
|
||||||
|
return((TIME)guess);
|
||||||
|
}
|
||||||
|
@@ -993,7 +993,7 @@ parse_date_core(cfile)
|
||||||
|
somebody invents a time machine, I think we can safely disregard
|
||||||
|
it. This actually works around a stupid Y2K bug that was present
|
||||||
|
in a very early beta release of dhcpd. */
|
||||||
|
- year = atoi(val);
|
||||||
|
+ year = atol(val);
|
||||||
|
if (year > 1900)
|
||||||
|
year -= 1900;
|
||||||
|
|
||||||
|
@@ -1039,7 +1039,7 @@ parse_date_core(cfile)
|
||||||
|
return((TIME)0);
|
||||||
|
}
|
||||||
|
skip_token(&val, NULL, cfile); /* consume day of month */
|
||||||
|
- mday = atoi(val);
|
||||||
|
+ mday = atol(val);
|
||||||
|
|
||||||
|
/* Hour... */
|
||||||
|
token = peek_token(&val, NULL, cfile);
|
||||||
|
@@ -1050,7 +1050,7 @@ parse_date_core(cfile)
|
||||||
|
return((TIME)0);
|
||||||
|
}
|
||||||
|
skip_token(&val, NULL, cfile); /* consume hour */
|
||||||
|
- hour = atoi(val);
|
||||||
|
+ hour = atol(val);
|
||||||
|
|
||||||
|
/* Colon separating hour from minute... */
|
||||||
|
token = peek_token(&val, NULL, cfile);
|
||||||
|
@@ -1072,7 +1072,7 @@ parse_date_core(cfile)
|
||||||
|
return((TIME)0);
|
||||||
|
}
|
||||||
|
skip_token(&val, NULL, cfile); /* consume minute */
|
||||||
|
- min = atoi(val);
|
||||||
|
+ min = atol(val);
|
||||||
|
|
||||||
|
/* Colon separating minute from second... */
|
||||||
|
token = peek_token(&val, NULL, cfile);
|
||||||
|
@@ -1094,13 +1094,13 @@ parse_date_core(cfile)
|
||||||
|
return((TIME)0);
|
||||||
|
}
|
||||||
|
skip_token(&val, NULL, cfile); /* consume second */
|
||||||
|
- sec = atoi(val);
|
||||||
|
+ sec = atol(val);
|
||||||
|
|
||||||
|
tzoff = 0;
|
||||||
|
token = peek_token(&val, NULL, cfile);
|
||||||
|
if (token == NUMBER) {
|
||||||
|
skip_token(&val, NULL, cfile); /* consume tzoff */
|
||||||
|
- tzoff = atoi(val);
|
||||||
|
+ tzoff = atol(val);
|
||||||
|
} else if (token != SEMI) {
|
||||||
|
skip_token(&val, NULL, cfile);
|
||||||
|
parse_warn(cfile,
|
@ -0,0 +1,336 @@
|
|||||||
|
diff -up dhcp-4.3.3b1/client/clparse.c.cloexec dhcp-4.3.3b1/client/clparse.c
|
||||||
|
--- dhcp-4.3.3b1/client/clparse.c.cloexec 2015-08-10 10:46:20.264755543 +0200
|
||||||
|
+++ dhcp-4.3.3b1/client/clparse.c 2015-08-10 10:46:20.274755510 +0200
|
||||||
|
@@ -247,7 +247,7 @@ int read_client_conf_file (const char *n
|
||||||
|
int token;
|
||||||
|
isc_result_t status;
|
||||||
|
|
||||||
|
- if ((file = open (name, O_RDONLY)) < 0)
|
||||||
|
+ if ((file = open (name, O_RDONLY | O_CLOEXEC)) < 0)
|
||||||
|
return uerr2isc (errno);
|
||||||
|
|
||||||
|
cfile = NULL;
|
||||||
|
@@ -323,7 +323,7 @@ void read_client_leases ()
|
||||||
|
|
||||||
|
/* Open the lease file. If we can't open it, just return -
|
||||||
|
we can safely trust the server to remember our state. */
|
||||||
|
- if ((file = open (path_dhclient_db, O_RDONLY)) < 0)
|
||||||
|
+ if ((file = open (path_dhclient_db, O_RDONLY | O_CLOEXEC)) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cfile = NULL;
|
||||||
|
diff -up dhcp-4.3.3b1/client/dhclient.c.cloexec dhcp-4.3.3b1/client/dhclient.c
|
||||||
|
--- dhcp-4.3.3b1/client/dhclient.c.cloexec 2015-08-10 10:46:20.260755556 +0200
|
||||||
|
+++ dhcp-4.3.3b1/client/dhclient.c 2015-08-10 10:46:20.275755506 +0200
|
||||||
|
@@ -153,11 +153,11 @@ main(int argc, char **argv) {
|
||||||
|
/* Make sure that file descriptors 0 (stdin), 1, (stdout), and
|
||||||
|
2 (stderr) are open. To do this, we assume that when we
|
||||||
|
open a file the lowest available file descriptor is used. */
|
||||||
|
- fd = open("/dev/null", O_RDWR);
|
||||||
|
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||||
|
if (fd == 0)
|
||||||
|
- fd = open("/dev/null", O_RDWR);
|
||||||
|
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||||
|
if (fd == 1)
|
||||||
|
- fd = open("/dev/null", O_RDWR);
|
||||||
|
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||||
|
if (fd == 2)
|
||||||
|
log_perror = 0; /* No sense logging to /dev/null. */
|
||||||
|
else if (fd != -1)
|
||||||
|
@@ -519,7 +519,7 @@ main(int argc, char **argv) {
|
||||||
|
long temp;
|
||||||
|
int e;
|
||||||
|
|
||||||
|
- if ((pidfd = fopen(path_dhclient_pid, "r")) != NULL) {
|
||||||
|
+ if ((pidfd = fopen(path_dhclient_pid, "re")) != NULL) {
|
||||||
|
e = fscanf(pidfd, "%ld\n", &temp);
|
||||||
|
oldpid = (pid_t)temp;
|
||||||
|
|
||||||
|
@@ -574,7 +574,7 @@ main(int argc, char **argv) {
|
||||||
|
strncpy(new_path_dhclient_pid, path_dhclient_pid, pfx);
|
||||||
|
sprintf(new_path_dhclient_pid + pfx, "-%s.pid", ip->name);
|
||||||
|
|
||||||
|
- if ((pidfd = fopen(new_path_dhclient_pid, "r")) != NULL) {
|
||||||
|
+ if ((pidfd = fopen(new_path_dhclient_pid, "re")) != NULL) {
|
||||||
|
e = fscanf(pidfd, "%ld\n", &temp);
|
||||||
|
oldpid = (pid_t)temp;
|
||||||
|
|
||||||
|
@@ -599,7 +599,7 @@ main(int argc, char **argv) {
|
||||||
|
int dhc_running = 0;
|
||||||
|
char procfn[256] = "";
|
||||||
|
|
||||||
|
- if ((pidfp = fopen(path_dhclient_pid, "r")) != NULL) {
|
||||||
|
+ if ((pidfp = fopen(path_dhclient_pid, "re")) != NULL) {
|
||||||
|
if ((fscanf(pidfp, "%ld", &temp)==1) && ((dhcpid=(pid_t)temp) > 0)) {
|
||||||
|
snprintf(procfn,256,"/proc/%u",dhcpid);
|
||||||
|
dhc_running = (access(procfn, F_OK) == 0);
|
||||||
|
@@ -3120,7 +3120,7 @@ void rewrite_client_leases ()
|
||||||
|
|
||||||
|
if (leaseFile != NULL)
|
||||||
|
fclose (leaseFile);
|
||||||
|
- leaseFile = fopen (path_dhclient_db, "w");
|
||||||
|
+ leaseFile = fopen (path_dhclient_db, "we");
|
||||||
|
if (leaseFile == NULL) {
|
||||||
|
log_error ("can't create %s: %m", path_dhclient_db);
|
||||||
|
return;
|
||||||
|
@@ -3313,7 +3313,7 @@ write_duid(struct data_string *duid)
|
||||||
|
return DHCP_R_INVALIDARG;
|
||||||
|
|
||||||
|
if (leaseFile == NULL) { /* XXX? */
|
||||||
|
- leaseFile = fopen(path_dhclient_db, "w");
|
||||||
|
+ leaseFile = fopen(path_dhclient_db, "we");
|
||||||
|
if (leaseFile == NULL) {
|
||||||
|
log_error("can't create %s: %m", path_dhclient_db);
|
||||||
|
return ISC_R_IOERROR;
|
||||||
|
@@ -3493,7 +3493,7 @@ int write_client_lease (client, lease, r
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (leaseFile == NULL) { /* XXX */
|
||||||
|
- leaseFile = fopen (path_dhclient_db, "w");
|
||||||
|
+ leaseFile = fopen (path_dhclient_db, "we");
|
||||||
|
if (leaseFile == NULL) {
|
||||||
|
log_error ("can't create %s: %m", path_dhclient_db);
|
||||||
|
return 0;
|
||||||
|
@@ -4011,9 +4011,9 @@ void go_daemon ()
|
||||||
|
(void) close(2);
|
||||||
|
|
||||||
|
/* Reopen them on /dev/null. */
|
||||||
|
- (void) open("/dev/null", O_RDWR);
|
||||||
|
- (void) open("/dev/null", O_RDWR);
|
||||||
|
- (void) open("/dev/null", O_RDWR);
|
||||||
|
+ (void) open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||||
|
+ (void) open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||||
|
+ (void) open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||||
|
|
||||||
|
write_client_pid_file ();
|
||||||
|
|
||||||
|
@@ -4030,14 +4030,14 @@ void write_client_pid_file ()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY, 0644);
|
||||||
|
+ pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
|
||||||
|
|
||||||
|
if (pfdesc < 0) {
|
||||||
|
log_error ("Can't create %s: %m", path_dhclient_pid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- pf = fdopen (pfdesc, "w");
|
||||||
|
+ pf = fdopen (pfdesc, "we");
|
||||||
|
if (!pf) {
|
||||||
|
close(pfdesc);
|
||||||
|
log_error ("Can't fdopen %s: %m", path_dhclient_pid);
|
||||||
|
diff -up dhcp-4.3.3b1/common/bpf.c.cloexec dhcp-4.3.3b1/common/bpf.c
|
||||||
|
--- dhcp-4.3.3b1/common/bpf.c.cloexec 2015-07-30 15:17:16.000000000 +0200
|
||||||
|
+++ dhcp-4.3.3b1/common/bpf.c 2015-08-10 10:46:20.275755506 +0200
|
||||||
|
@@ -95,7 +95,7 @@ int if_register_bpf (info)
|
||||||
|
for (b = 0; 1; b++) {
|
||||||
|
/* %Audit% 31 bytes max. %2004.06.17,Safe% */
|
||||||
|
sprintf(filename, BPF_FORMAT, b);
|
||||||
|
- sock = open (filename, O_RDWR, 0);
|
||||||
|
+ sock = open (filename, O_RDWR | O_CLOEXEC, 0);
|
||||||
|
if (sock < 0) {
|
||||||
|
if (errno == EBUSY) {
|
||||||
|
continue;
|
||||||
|
diff -up dhcp-4.3.3b1/common/dlpi.c.cloexec dhcp-4.3.3b1/common/dlpi.c
|
||||||
|
--- dhcp-4.3.3b1/common/dlpi.c.cloexec 2015-07-30 15:17:16.000000000 +0200
|
||||||
|
+++ dhcp-4.3.3b1/common/dlpi.c 2015-08-10 10:46:20.275755506 +0200
|
||||||
|
@@ -804,7 +804,7 @@ dlpiopen(const char *ifname) {
|
||||||
|
}
|
||||||
|
*dp = '\0';
|
||||||
|
|
||||||
|
- return open (devname, O_RDWR, 0);
|
||||||
|
+ return open (devname, O_RDWR | O_CLOEXEC, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff -up dhcp-4.3.3b1/common/nit.c.cloexec dhcp-4.3.3b1/common/nit.c
|
||||||
|
--- dhcp-4.3.3b1/common/nit.c.cloexec 2015-07-30 15:17:16.000000000 +0200
|
||||||
|
+++ dhcp-4.3.3b1/common/nit.c 2015-08-10 10:46:20.275755506 +0200
|
||||||
|
@@ -75,7 +75,7 @@ int if_register_nit (info)
|
||||||
|
struct strioctl sio;
|
||||||
|
|
||||||
|
/* Open a NIT device */
|
||||||
|
- sock = open ("/dev/nit", O_RDWR);
|
||||||
|
+ sock = open ("/dev/nit", O_RDWR | O_CLOEXEC);
|
||||||
|
if (sock < 0)
|
||||||
|
log_fatal ("Can't open NIT device for %s: %m", info -> name);
|
||||||
|
|
||||||
|
diff -up dhcp-4.3.3b1/common/resolv.c.cloexec dhcp-4.3.3b1/common/resolv.c
|
||||||
|
--- dhcp-4.3.3b1/common/resolv.c.cloexec 2015-07-30 15:17:16.000000000 +0200
|
||||||
|
+++ dhcp-4.3.3b1/common/resolv.c 2015-08-10 10:46:20.276755503 +0200
|
||||||
|
@@ -44,7 +44,7 @@ void read_resolv_conf (parse_time)
|
||||||
|
struct domain_search_list *dp, *dl, *nd;
|
||||||
|
isc_result_t status;
|
||||||
|
|
||||||
|
- if ((file = open (path_resolv_conf, O_RDONLY)) < 0) {
|
||||||
|
+ if ((file = open (path_resolv_conf, O_RDONLY | O_CLOEXEC)) < 0) {
|
||||||
|
log_error ("Can't open %s: %m", path_resolv_conf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
diff -up dhcp-4.3.3b1/common/upf.c.cloexec dhcp-4.3.3b1/common/upf.c
|
||||||
|
--- dhcp-4.3.3b1/common/upf.c.cloexec 2015-07-30 15:17:16.000000000 +0200
|
||||||
|
+++ dhcp-4.3.3b1/common/upf.c 2015-08-10 10:46:20.276755503 +0200
|
||||||
|
@@ -71,7 +71,7 @@ int if_register_upf (info)
|
||||||
|
/* %Audit% Cannot exceed 36 bytes. %2004.06.17,Safe% */
|
||||||
|
sprintf(filename, "/dev/pf/pfilt%d", b);
|
||||||
|
|
||||||
|
- sock = open (filename, O_RDWR, 0);
|
||||||
|
+ sock = open (filename, O_RDWR | O_CLOEXEC, 0);
|
||||||
|
if (sock < 0) {
|
||||||
|
if (errno == EBUSY) {
|
||||||
|
continue;
|
||||||
|
diff -up dhcp-4.3.3b1/omapip/trace.c.cloexec dhcp-4.3.3b1/omapip/trace.c
|
||||||
|
--- dhcp-4.3.3b1/omapip/trace.c.cloexec 2015-07-30 15:17:16.000000000 +0200
|
||||||
|
+++ dhcp-4.3.3b1/omapip/trace.c 2015-08-10 10:46:20.276755503 +0200
|
||||||
|
@@ -138,10 +138,10 @@ isc_result_t trace_begin (const char *fi
|
||||||
|
return DHCP_R_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
- traceoutfile = open (filename, O_CREAT | O_WRONLY | O_EXCL, 0600);
|
||||||
|
+ traceoutfile = open (filename, O_CREAT | O_WRONLY | O_EXCL | O_CLOEXEC, 0600);
|
||||||
|
if (traceoutfile < 0 && errno == EEXIST) {
|
||||||
|
log_error ("WARNING: Overwriting trace file \"%s\"", filename);
|
||||||
|
- traceoutfile = open (filename, O_WRONLY | O_EXCL | O_TRUNC,
|
||||||
|
+ traceoutfile = open (filename, O_WRONLY | O_EXCL | O_TRUNC | O_CLOEXEC,
|
||||||
|
0600);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -429,7 +429,7 @@ void trace_file_replay (const char *file
|
||||||
|
isc_result_t result;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
- traceinfile = fopen (filename, "r");
|
||||||
|
+ traceinfile = fopen (filename, "re");
|
||||||
|
if (!traceinfile) {
|
||||||
|
log_error("Can't open tracefile %s: %m", filename);
|
||||||
|
return;
|
||||||
|
diff -up dhcp-4.3.3b1/relay/dhcrelay.c.cloexec dhcp-4.3.3b1/relay/dhcrelay.c
|
||||||
|
--- dhcp-4.3.3b1/relay/dhcrelay.c.cloexec 2015-07-30 15:17:16.000000000 +0200
|
||||||
|
+++ dhcp-4.3.3b1/relay/dhcrelay.c 2015-08-10 10:46:20.276755503 +0200
|
||||||
|
@@ -187,11 +187,11 @@ main(int argc, char **argv) {
|
||||||
|
/* Make sure that file descriptors 0(stdin), 1,(stdout), and
|
||||||
|
2(stderr) are open. To do this, we assume that when we
|
||||||
|
open a file the lowest available file descriptor is used. */
|
||||||
|
- fd = open("/dev/null", O_RDWR);
|
||||||
|
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||||
|
if (fd == 0)
|
||||||
|
- fd = open("/dev/null", O_RDWR);
|
||||||
|
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||||
|
if (fd == 1)
|
||||||
|
- fd = open("/dev/null", O_RDWR);
|
||||||
|
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||||
|
if (fd == 2)
|
||||||
|
log_perror = 0; /* No sense logging to /dev/null. */
|
||||||
|
else if (fd != -1)
|
||||||
|
@@ -558,13 +558,13 @@ main(int argc, char **argv) {
|
||||||
|
|
||||||
|
if (no_pid_file == ISC_FALSE) {
|
||||||
|
pfdesc = open(path_dhcrelay_pid,
|
||||||
|
- O_CREAT | O_TRUNC | O_WRONLY, 0644);
|
||||||
|
+ O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
|
||||||
|
|
||||||
|
if (pfdesc < 0) {
|
||||||
|
log_error("Can't create %s: %m",
|
||||||
|
path_dhcrelay_pid);
|
||||||
|
} else {
|
||||||
|
- pf = fdopen(pfdesc, "w");
|
||||||
|
+ pf = fdopen(pfdesc, "we");
|
||||||
|
if (!pf)
|
||||||
|
log_error("Can't fdopen %s: %m",
|
||||||
|
path_dhcrelay_pid);
|
||||||
|
diff -up dhcp-4.3.3b1/server/confpars.c.cloexec dhcp-4.3.3b1/server/confpars.c
|
||||||
|
--- dhcp-4.3.3b1/server/confpars.c.cloexec 2015-07-30 15:17:16.000000000 +0200
|
||||||
|
+++ dhcp-4.3.3b1/server/confpars.c 2015-08-10 10:46:20.277755500 +0200
|
||||||
|
@@ -111,7 +111,7 @@ isc_result_t read_conf_file (const char
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- if ((file = open (filename, O_RDONLY)) < 0) {
|
||||||
|
+ if ((file = open (filename, O_RDONLY | O_CLOEXEC)) < 0) {
|
||||||
|
if (leasep) {
|
||||||
|
log_error ("Can't open lease database %s: %m --",
|
||||||
|
path_dhcpd_db);
|
||||||
|
diff -up dhcp-4.3.3b1/server/db.c.cloexec dhcp-4.3.3b1/server/db.c
|
||||||
|
--- dhcp-4.3.3b1/server/db.c.cloexec 2015-07-30 15:17:16.000000000 +0200
|
||||||
|
+++ dhcp-4.3.3b1/server/db.c 2015-08-10 10:47:32.644518358 +0200
|
||||||
|
@@ -1072,7 +1072,7 @@ void db_startup (testp)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!testp) {
|
||||||
|
- db_file = fopen (path_dhcpd_db, "a");
|
||||||
|
+ db_file = fopen (path_dhcpd_db, "ae");
|
||||||
|
if (!db_file)
|
||||||
|
log_fatal ("Can't open %s for append.", path_dhcpd_db);
|
||||||
|
expire_all_pools ();
|
||||||
|
@@ -1120,7 +1120,7 @@ int new_lease_file ()
|
||||||
|
path_dhcpd_db, (int)t) >= sizeof newfname)
|
||||||
|
log_fatal("new_lease_file: lease file path too long");
|
||||||
|
|
||||||
|
- db_fd = open (newfname, O_WRONLY | O_TRUNC | O_CREAT, 0664);
|
||||||
|
+ db_fd = open (newfname, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0664);
|
||||||
|
if (db_fd < 0) {
|
||||||
|
log_error ("Can't create new lease file: %m");
|
||||||
|
return 0;
|
||||||
|
@@ -1141,7 +1141,7 @@ int new_lease_file ()
|
||||||
|
}
|
||||||
|
#endif /* PARANOIA */
|
||||||
|
|
||||||
|
- if ((new_db_file = fdopen(db_fd, "w")) == NULL) {
|
||||||
|
+ if ((new_db_file = fdopen(db_fd, "we")) == NULL) {
|
||||||
|
log_error("Can't fdopen new lease file: %m");
|
||||||
|
close(db_fd);
|
||||||
|
goto fdfail;
|
||||||
|
diff -up dhcp-4.3.3b1/server/dhcpd.c.cloexec dhcp-4.3.3b1/server/dhcpd.c
|
||||||
|
--- dhcp-4.3.3b1/server/dhcpd.c.cloexec 2015-07-30 15:17:16.000000000 +0200
|
||||||
|
+++ dhcp-4.3.3b1/server/dhcpd.c 2015-08-10 10:46:20.278755497 +0200
|
||||||
|
@@ -194,11 +194,11 @@ main(int argc, char **argv) {
|
||||||
|
/* Make sure that file descriptors 0 (stdin), 1, (stdout), and
|
||||||
|
2 (stderr) are open. To do this, we assume that when we
|
||||||
|
open a file the lowest available file descriptor is used. */
|
||||||
|
- fd = open("/dev/null", O_RDWR);
|
||||||
|
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||||
|
if (fd == 0)
|
||||||
|
- fd = open("/dev/null", O_RDWR);
|
||||||
|
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||||
|
if (fd == 1)
|
||||||
|
- fd = open("/dev/null", O_RDWR);
|
||||||
|
+ fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||||
|
if (fd == 2)
|
||||||
|
log_perror = 0; /* No sense logging to /dev/null. */
|
||||||
|
else if (fd != -1)
|
||||||
|
@@ -743,7 +743,7 @@ main(int argc, char **argv) {
|
||||||
|
* appropriate.
|
||||||
|
*/
|
||||||
|
if (no_pid_file == ISC_FALSE) {
|
||||||
|
- i = open(path_dhcpd_pid, O_WRONLY|O_CREAT|O_TRUNC, 0644);
|
||||||
|
+ i = open(path_dhcpd_pid, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0644);
|
||||||
|
if (i >= 0) {
|
||||||
|
sprintf(pbuf, "%d\n", (int) getpid());
|
||||||
|
IGNORE_RET(write(i, pbuf, strlen(pbuf)));
|
||||||
|
@@ -787,9 +787,9 @@ main(int argc, char **argv) {
|
||||||
|
(void) close(2);
|
||||||
|
|
||||||
|
/* Reopen them on /dev/null. */
|
||||||
|
- (void) open("/dev/null", O_RDWR);
|
||||||
|
- (void) open("/dev/null", O_RDWR);
|
||||||
|
- (void) open("/dev/null", O_RDWR);
|
||||||
|
+ (void) open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||||
|
+ (void) open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||||
|
+ (void) open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||||
|
log_perror = 0; /* No sense logging to /dev/null. */
|
||||||
|
|
||||||
|
IGNORE_RET (chdir("/"));
|
||||||
|
diff -up dhcp-4.3.3b1/server/ldap.c.cloexec dhcp-4.3.3b1/server/ldap.c
|
||||||
|
--- dhcp-4.3.3b1/server/ldap.c.cloexec 2015-07-30 21:03:40.000000000 +0200
|
||||||
|
+++ dhcp-4.3.3b1/server/ldap.c 2015-08-10 10:46:20.279755493 +0200
|
||||||
|
@@ -1442,7 +1442,7 @@ ldap_start (void)
|
||||||
|
|
||||||
|
if (ldap_debug_file != NULL && ldap_debug_fd == -1)
|
||||||
|
{
|
||||||
|
- if ((ldap_debug_fd = open (ldap_debug_file, O_CREAT | O_TRUNC | O_WRONLY,
|
||||||
|
+ if ((ldap_debug_fd = open (ldap_debug_file, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC,
|
||||||
|
S_IRUSR | S_IWUSR)) < 0)
|
||||||
|
log_error ("Error opening debug LDAP log file %s: %s", ldap_debug_file,
|
||||||
|
strerror (errno));
|
@ -0,0 +1,32 @@
|
|||||||
|
diff --git a/common/options.c b/common/options.c
|
||||||
|
index ed8ac38..addc65a 100644
|
||||||
|
--- a/common/options.c
|
||||||
|
+++ b/common/options.c
|
||||||
|
@@ -4397,6 +4397,8 @@ add_option(struct option_state *options,
|
||||||
|
if (!option_cache_allocate(&oc, MDL)) {
|
||||||
|
log_error("No memory for option cache adding %s (option %d).",
|
||||||
|
option->name, option_num);
|
||||||
|
+ /* Get rid of reference created during hash lookup. */
|
||||||
|
+ option_dereference(&option, MDL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -4408,6 +4410,8 @@ add_option(struct option_state *options,
|
||||||
|
MDL)) {
|
||||||
|
log_error("No memory for constant data adding %s (option %d).",
|
||||||
|
option->name, option_num);
|
||||||
|
+ /* Get rid of reference created during hash lookup. */
|
||||||
|
+ option_dereference(&option, MDL);
|
||||||
|
option_cache_dereference(&oc, MDL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -4416,6 +4420,9 @@ add_option(struct option_state *options,
|
||||||
|
save_option(&dhcp_universe, options, oc);
|
||||||
|
option_cache_dereference(&oc, MDL);
|
||||||
|
|
||||||
|
+ /* Get rid of reference created during hash lookup. */
|
||||||
|
+ option_dereference(&option, MDL);
|
||||||
|
+
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
|||||||
|
diff --git a/common/options.c b/common/options.c
|
||||||
|
index addc65a..3e6383a 100644
|
||||||
|
--- a/common/options.c
|
||||||
|
+++ b/common/options.c
|
||||||
|
@@ -435,16 +435,16 @@ int fqdn_universe_decode (struct option_state *options,
|
||||||
|
while (s < &bp -> data[0] + length + 2) {
|
||||||
|
len = *s;
|
||||||
|
if (len > 63) {
|
||||||
|
- log_info ("fancy bits in fqdn option");
|
||||||
|
- return 0;
|
||||||
|
+ log_info ("label length exceeds 63 in fqdn option");
|
||||||
|
+ goto bad;
|
||||||
|
}
|
||||||
|
if (len == 0) {
|
||||||
|
terminated = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (s + len > &bp -> data [0] + length + 3) {
|
||||||
|
- log_info ("fqdn tag longer than buffer");
|
||||||
|
- return 0;
|
||||||
|
+ log_info ("fqdn label longer than buffer");
|
||||||
|
+ goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first_len == 0) {
|
@ -0,0 +1,164 @@
|
|||||||
|
--- a/server/dhcp.c 2017-07-14 15:32:14.611104590 +0200
|
||||||
|
+++ b/server/dhcp.c 2017-07-14 15:34:17.508858018 +0200
|
||||||
|
@@ -87,6 +87,42 @@
|
||||||
|
|
||||||
|
static TIME leaseTimeCheck(TIME calculated, TIME alternate);
|
||||||
|
|
||||||
|
+char *print_client_identifier_from_packet (packet)
|
||||||
|
+ struct packet *packet;
|
||||||
|
+{
|
||||||
|
+ struct option_cache *oc;
|
||||||
|
+ struct data_string client_identifier;
|
||||||
|
+ char *ci;
|
||||||
|
+
|
||||||
|
+ memset (&client_identifier, 0, sizeof client_identifier);
|
||||||
|
+
|
||||||
|
+ oc = lookup_option (&dhcp_universe, packet -> options,
|
||||||
|
+ DHO_DHCP_CLIENT_IDENTIFIER);
|
||||||
|
+ if (oc &&
|
||||||
|
+ evaluate_option_cache (&client_identifier,
|
||||||
|
+ packet, (struct lease *)0,
|
||||||
|
+ (struct client_state *)0,
|
||||||
|
+ packet -> options,
|
||||||
|
+ (struct option_state *)0,
|
||||||
|
+ &global_scope, oc, MDL)) {
|
||||||
|
+ ci = print_hw_addr (HTYPE_INFINIBAND, client_identifier.len, client_identifier.data);
|
||||||
|
+ data_string_forget (&client_identifier, MDL);
|
||||||
|
+ return ci;
|
||||||
|
+ } else
|
||||||
|
+ return "\"no client id\"";
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+char *print_hw_addr_or_client_id (packet)
|
||||||
|
+ struct packet *packet;
|
||||||
|
+{
|
||||||
|
+ if (packet -> raw -> htype == HTYPE_INFINIBAND)
|
||||||
|
+ return print_client_identifier_from_packet (packet);
|
||||||
|
+ else
|
||||||
|
+ return print_hw_addr (packet -> raw -> htype,
|
||||||
|
+ packet -> raw -> hlen,
|
||||||
|
+ packet -> raw -> chaddr);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
dhcp (struct packet *packet) {
|
||||||
|
int ms_nulltp = 0;
|
||||||
|
@@ -129,9 +165,7 @@
|
||||||
|
|
||||||
|
log_info("%s from %s via %s: %s", s,
|
||||||
|
(packet->raw->htype
|
||||||
|
- ? print_hw_addr(packet->raw->htype,
|
||||||
|
- packet->raw->hlen,
|
||||||
|
- packet->raw->chaddr)
|
||||||
|
+ ? print_hw_addr_or_client_id(packet)
|
||||||
|
: "<no identifier>"),
|
||||||
|
packet->raw->giaddr.s_addr
|
||||||
|
? inet_ntoa(packet->raw->giaddr)
|
||||||
|
@@ -328,9 +362,7 @@
|
||||||
|
#endif
|
||||||
|
snprintf (msgbuf, sizeof msgbuf, "DHCPDISCOVER from %s %s%s%svia %s",
|
||||||
|
(packet -> raw -> htype
|
||||||
|
- ? print_hw_addr (packet -> raw -> htype,
|
||||||
|
- packet -> raw -> hlen,
|
||||||
|
- packet -> raw -> chaddr)
|
||||||
|
+ ? print_hw_addr_or_client_id (packet)
|
||||||
|
: (lease
|
||||||
|
? print_hex_1(lease->uid_len, lease->uid, 60)
|
||||||
|
: "<no identifier>")),
|
||||||
|
@@ -542,9 +574,7 @@
|
||||||
|
"DHCPREQUEST for %s%s from %s %s%s%svia %s",
|
||||||
|
piaddr (cip), smbuf,
|
||||||
|
(packet -> raw -> htype
|
||||||
|
- ? print_hw_addr (packet -> raw -> htype,
|
||||||
|
- packet -> raw -> hlen,
|
||||||
|
- packet -> raw -> chaddr)
|
||||||
|
+ ? print_hw_addr_or_client_id(packet)
|
||||||
|
: (lease
|
||||||
|
? print_hex_1(lease->uid_len, lease->uid, 60)
|
||||||
|
: "<no identifier>")),
|
||||||
|
@@ -785,9 +815,7 @@
|
||||||
|
if ((oc = lookup_option (&dhcp_universe, packet -> options,
|
||||||
|
DHO_DHCP_REQUESTED_ADDRESS))) {
|
||||||
|
log_info ("DHCPRELEASE from %s specified requested-address.",
|
||||||
|
- print_hw_addr (packet -> raw -> htype,
|
||||||
|
- packet -> raw -> hlen,
|
||||||
|
- packet -> raw -> chaddr));
|
||||||
|
+ print_hw_addr_or_client_id(packet));
|
||||||
|
}
|
||||||
|
|
||||||
|
oc = lookup_option (&dhcp_universe, packet -> options,
|
||||||
|
@@ -879,9 +907,7 @@
|
||||||
|
"DHCPRELEASE of %s from %s %s%s%svia %s (%sfound)",
|
||||||
|
cstr,
|
||||||
|
(packet -> raw -> htype
|
||||||
|
- ? print_hw_addr (packet -> raw -> htype,
|
||||||
|
- packet -> raw -> hlen,
|
||||||
|
- packet -> raw -> chaddr)
|
||||||
|
+ ? print_hw_addr_or_client_id(packet)
|
||||||
|
: (lease
|
||||||
|
? print_hex_1(lease->uid_len, lease->uid, 60)
|
||||||
|
: "<no identifier>")),
|
||||||
|
@@ -986,9 +1012,7 @@
|
||||||
|
"DHCPDECLINE of %s from %s %s%s%svia %s",
|
||||||
|
piaddr (cip),
|
||||||
|
(packet -> raw -> htype
|
||||||
|
- ? print_hw_addr (packet -> raw -> htype,
|
||||||
|
- packet -> raw -> hlen,
|
||||||
|
- packet -> raw -> chaddr)
|
||||||
|
+ ? print_hw_addr_or_client_id(packet)
|
||||||
|
: (lease
|
||||||
|
? print_hex_1(lease->uid_len, lease->uid, 60)
|
||||||
|
: "<no identifier>")),
|
||||||
|
@@ -1707,8 +1731,7 @@
|
||||||
|
/* Report what we're sending. */
|
||||||
|
snprintf(msgbuf, sizeof msgbuf, "DHCPACK to %s (%s) via", piaddr(cip),
|
||||||
|
(packet->raw->htype && packet->raw->hlen) ?
|
||||||
|
- print_hw_addr(packet->raw->htype, packet->raw->hlen,
|
||||||
|
- packet->raw->chaddr) :
|
||||||
|
+ print_hw_addr_or_client_id(packet) :
|
||||||
|
"<no client hardware address>");
|
||||||
|
log_info("%s %s", msgbuf, gip.len ? piaddr(gip) :
|
||||||
|
packet->interface->name);
|
||||||
|
@@ -1886,9 +1909,7 @@
|
||||||
|
#endif
|
||||||
|
log_info ("DHCPNAK on %s to %s via %s",
|
||||||
|
piaddr (*cip),
|
||||||
|
- print_hw_addr (packet -> raw -> htype,
|
||||||
|
- packet -> raw -> hlen,
|
||||||
|
- packet -> raw -> chaddr),
|
||||||
|
+ print_hw_addr_or_client_id(packet),
|
||||||
|
packet -> raw -> giaddr.s_addr
|
||||||
|
? inet_ntoa (packet -> raw -> giaddr)
|
||||||
|
: packet -> interface -> name);
|
||||||
|
@@ -3897,7 +3918,7 @@
|
||||||
|
? (state -> offer == DHCPACK ? "DHCPACK" : "DHCPOFFER")
|
||||||
|
: "BOOTREPLY"),
|
||||||
|
piaddr (lease -> ip_addr),
|
||||||
|
- (lease -> hardware_addr.hlen
|
||||||
|
+ (lease -> hardware_addr.hlen > 1
|
||||||
|
? print_hw_addr (lease -> hardware_addr.hbuf [0],
|
||||||
|
lease -> hardware_addr.hlen - 1,
|
||||||
|
&lease -> hardware_addr.hbuf [1])
|
||||||
|
@@ -4450,10 +4471,7 @@
|
||||||
|
if (uid_lease) {
|
||||||
|
if (uid_lease->binding_state == FTS_ACTIVE) {
|
||||||
|
log_error ("client %s has duplicate%s on %s",
|
||||||
|
- (print_hw_addr
|
||||||
|
- (packet -> raw -> htype,
|
||||||
|
- packet -> raw -> hlen,
|
||||||
|
- packet -> raw -> chaddr)),
|
||||||
|
+ (print_hw_addr_or_client_id(packet)),
|
||||||
|
" leases",
|
||||||
|
(ip_lease -> subnet ->
|
||||||
|
shared_network -> name));
|
||||||
|
@@ -4620,9 +4638,7 @@
|
||||||
|
log_error("uid lease %s for client %s is duplicate "
|
||||||
|
"on %s",
|
||||||
|
piaddr(uid_lease->ip_addr),
|
||||||
|
- print_hw_addr(packet->raw->htype,
|
||||||
|
- packet->raw->hlen,
|
||||||
|
- packet->raw->chaddr),
|
||||||
|
+ print_hw_addr_or_client_id(packet),
|
||||||
|
uid_lease->subnet->shared_network->name);
|
||||||
|
|
||||||
|
if (!packet -> raw -> ciaddr.s_addr &&
|
@ -0,0 +1,150 @@
|
|||||||
|
diff -up dhcp-4.3.4/client/dhc6.c.PPP dhcp-4.3.4/client/dhc6.c
|
||||||
|
--- dhcp-4.3.4/client/dhc6.c.PPP 2016-04-29 12:46:29.824988665 +0200
|
||||||
|
+++ dhcp-4.3.4/client/dhc6.c 2016-04-29 12:46:29.828988666 +0200
|
||||||
|
@@ -5641,7 +5641,8 @@ make_client6_options(struct client_state
|
||||||
|
*/
|
||||||
|
if ((oc = lookup_option(&dhcpv6_universe, *op,
|
||||||
|
D6O_CLIENTID)) == NULL) {
|
||||||
|
- if (!option_cache(&oc, &default_duid, NULL, clientid_option,
|
||||||
|
+ if (default_duid.len == 0 ||
|
||||||
|
+ !option_cache(&oc, &default_duid, NULL, clientid_option,
|
||||||
|
MDL))
|
||||||
|
log_fatal("Failure assembling a DUID.");
|
||||||
|
|
||||||
|
diff -up dhcp-4.3.4/client/dhclient.c.PPP dhcp-4.3.4/client/dhclient.c
|
||||||
|
--- dhcp-4.3.4/client/dhclient.c.PPP 2016-04-29 12:46:29.815988664 +0200
|
||||||
|
+++ dhcp-4.3.4/client/dhclient.c 2016-04-29 12:46:29.830988666 +0200
|
||||||
|
@@ -1077,8 +1077,8 @@ main(int argc, char **argv) {
|
||||||
|
if (default_duid.buffer != NULL)
|
||||||
|
data_string_forget(&default_duid, MDL);
|
||||||
|
|
||||||
|
- form_duid(&default_duid, MDL);
|
||||||
|
- write_duid(&default_duid);
|
||||||
|
+ if (form_duid(&default_duid, MDL) == ISC_R_SUCCESS)
|
||||||
|
+ write_duid(&default_duid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -3808,7 +3808,7 @@ write_options(struct client_state *clien
|
||||||
|
* is not how it is intended. Upcoming rearchitecting the client should
|
||||||
|
* address this "one daemon model."
|
||||||
|
*/
|
||||||
|
-void
|
||||||
|
+isc_result_t
|
||||||
|
form_duid(struct data_string *duid, const char *file, int line)
|
||||||
|
{
|
||||||
|
struct interface_info *ip;
|
||||||
|
@@ -3821,6 +3821,15 @@ form_duid(struct data_string *duid, cons
|
||||||
|
if (ip == NULL)
|
||||||
|
log_fatal("Impossible condition at %s:%d.", MDL);
|
||||||
|
|
||||||
|
+ while (ip && ip->hw_address.hbuf[0] == HTYPE_RESERVED) {
|
||||||
|
+ /* Try the other interfaces */
|
||||||
|
+ log_debug("Cannot form default DUID from interface %s.", ip->name);
|
||||||
|
+ ip = ip->next;
|
||||||
|
+ }
|
||||||
|
+ if (ip == NULL) {
|
||||||
|
+ return ISC_R_UNEXPECTED;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if ((ip->hw_address.hlen == 0) ||
|
||||||
|
(ip->hw_address.hlen > sizeof(ip->hw_address.hbuf)))
|
||||||
|
log_fatal("Impossible hardware address length at %s:%d.", MDL);
|
||||||
|
@@ -3866,6 +3875,8 @@ form_duid(struct data_string *duid, cons
|
||||||
|
log_info("Created duid %s.", str);
|
||||||
|
dfree(str, MDL);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ return ISC_R_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write the default DUID to the lease store. */
|
||||||
|
diff -up dhcp-4.3.4/common/bpf.c.PPP dhcp-4.3.4/common/bpf.c
|
||||||
|
--- dhcp-4.3.4/common/bpf.c.PPP 2016-04-29 12:46:29.794988660 +0200
|
||||||
|
+++ dhcp-4.3.4/common/bpf.c 2016-04-29 12:46:29.830988666 +0200
|
||||||
|
@@ -599,6 +599,22 @@ get_hw_addr(const char *name, struct har
|
||||||
|
memcpy(&hw->hbuf[1], LLADDR(sa), sa->sdl_alen);
|
||||||
|
break;
|
||||||
|
#endif /* IFT_FDDI */
|
||||||
|
+#if defined(IFT_PPP)
|
||||||
|
+ case IFT_PPP:
|
||||||
|
+ if (local_family != AF_INET6)
|
||||||
|
+ log_fatal("Unsupported device type %d for \"%s\"",
|
||||||
|
+ sa->sdl_type, name);
|
||||||
|
+ hw->hlen = 0;
|
||||||
|
+ hw->hbuf[0] = HTYPE_RESERVED;
|
||||||
|
+ /* 0xdeadbeef should never occur on the wire,
|
||||||
|
+ * and is a signature that something went wrong.
|
||||||
|
+ */
|
||||||
|
+ hw->hbuf[1] = 0xde;
|
||||||
|
+ hw->hbuf[2] = 0xad;
|
||||||
|
+ hw->hbuf[3] = 0xbe;
|
||||||
|
+ hw->hbuf[4] = 0xef;
|
||||||
|
+ break;
|
||||||
|
+#endif
|
||||||
|
default:
|
||||||
|
log_fatal("Unsupported device type %d for \"%s\"",
|
||||||
|
sa->sdl_type, name);
|
||||||
|
diff -up dhcp-4.3.4/common/lpf.c.PPP dhcp-4.3.4/common/lpf.c
|
||||||
|
--- dhcp-4.3.4/common/lpf.c.PPP 2016-03-22 14:16:51.000000000 +0100
|
||||||
|
+++ dhcp-4.3.4/common/lpf.c 2016-04-29 12:46:29.830988666 +0200
|
||||||
|
@@ -548,6 +548,22 @@ get_hw_addr(const char *name, struct har
|
||||||
|
hw->hbuf[0] = HTYPE_FDDI;
|
||||||
|
memcpy(&hw->hbuf[1], sa->sa_data, 6);
|
||||||
|
break;
|
||||||
|
+#if defined(ARPHRD_PPP)
|
||||||
|
+ case ARPHRD_PPP:
|
||||||
|
+ if (local_family != AF_INET6)
|
||||||
|
+ log_fatal("Unsupported device type %d for \"%s\"",
|
||||||
|
+ sa->sa_family, name);
|
||||||
|
+ hw->hlen = 0;
|
||||||
|
+ hw->hbuf[0] = HTYPE_RESERVED;
|
||||||
|
+ /* 0xdeadbeef should never occur on the wire,
|
||||||
|
+ * and is a signature that something went wrong.
|
||||||
|
+ */
|
||||||
|
+ hw->hbuf[1] = 0xde;
|
||||||
|
+ hw->hbuf[2] = 0xad;
|
||||||
|
+ hw->hbuf[3] = 0xbe;
|
||||||
|
+ hw->hbuf[4] = 0xef;
|
||||||
|
+ break;
|
||||||
|
+#endif
|
||||||
|
default:
|
||||||
|
log_fatal("Unsupported device type %ld for \"%s\"",
|
||||||
|
(long int)sa->sa_family, name);
|
||||||
|
diff -up dhcp-4.3.4/includes/dhcpd.h.PPP dhcp-4.3.4/includes/dhcpd.h
|
||||||
|
--- dhcp-4.3.4/includes/dhcpd.h.PPP 2016-04-29 12:46:29.831988667 +0200
|
||||||
|
+++ dhcp-4.3.4/includes/dhcpd.h 2016-04-29 12:47:13.167995959 +0200
|
||||||
|
@@ -2990,7 +2990,7 @@ void client_dns_remove(struct client_sta
|
||||||
|
|
||||||
|
void dhcpv4_client_assignments(void);
|
||||||
|
void dhcpv6_client_assignments(void);
|
||||||
|
-void form_duid(struct data_string *duid, const char *file, int line);
|
||||||
|
+isc_result_t form_duid(struct data_string *duid, const char *file, int line);
|
||||||
|
|
||||||
|
void dhcp4o6_start(void);
|
||||||
|
|
||||||
|
diff -up dhcp-4.3.4/includes/dhcp.h.PPP dhcp-4.3.4/includes/dhcp.h
|
||||||
|
--- dhcp-4.3.4/includes/dhcp.h.PPP 2016-04-29 12:46:29.822988665 +0200
|
||||||
|
+++ dhcp-4.3.4/includes/dhcp.h 2016-04-29 12:46:29.832988667 +0200
|
||||||
|
@@ -81,6 +81,8 @@ struct dhcp_packet {
|
||||||
|
* is no standard for this so we
|
||||||
|
* just steal a type */
|
||||||
|
|
||||||
|
+#define HTYPE_RESERVED 0 /* RFC 5494 */
|
||||||
|
+
|
||||||
|
/* Magic cookie validating dhcp options field (and bootp vendor
|
||||||
|
extensions field). */
|
||||||
|
#define DHCP_OPTIONS_COOKIE "\143\202\123\143"
|
||||||
|
diff -up dhcp-4.3.4/server/dhcpv6.c.PPP dhcp-4.3.4/server/dhcpv6.c
|
||||||
|
--- dhcp-4.3.4/server/dhcpv6.c.PPP 2016-03-22 14:16:51.000000000 +0100
|
||||||
|
+++ dhcp-4.3.4/server/dhcpv6.c 2016-04-29 12:46:29.833988667 +0200
|
||||||
|
@@ -454,6 +454,9 @@ generate_new_server_duid(void) {
|
||||||
|
if (p->hw_address.hlen > 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+ if (p->next == NULL && p->hw_address.hbuf[0] == HTYPE_RESERVED) {
|
||||||
|
+ log_error("Can not generate DUID from interfaces which do not have hardware addresses, please configure server-duid!");
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
if (p == NULL) {
|
||||||
|
return ISC_R_UNEXPECTED;
|
@ -0,0 +1,14 @@
|
|||||||
|
diff -up dhcp-4.3.0a1/common/dispatch.c.dracut dhcp-4.3.0a1/common/dispatch.c
|
||||||
|
--- dhcp-4.3.0a1/common/dispatch.c.dracut 2013-12-11 01:25:12.000000000 +0100
|
||||||
|
+++ dhcp-4.3.0a1/common/dispatch.c 2013-12-19 15:39:50.350505860 +0100
|
||||||
|
@@ -210,6 +210,10 @@ void add_timeout (when, where, what, ref
|
||||||
|
isc_interval_t interval;
|
||||||
|
isc_time_t expires;
|
||||||
|
|
||||||
|
+ if (when == NULL) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* See if this timeout supersedes an existing timeout. */
|
||||||
|
t = (struct timeout *)0;
|
||||||
|
for (q = timeouts; q; q = q->next) {
|
@ -0,0 +1,85 @@
|
|||||||
|
From ffb24c0bbd4d6f2b4718a1a8f4f2da237cc6ed66 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Markwalder <tmark@isc.org>
|
||||||
|
Date: Fri, 14 Sep 2018 13:41:41 -0400
|
||||||
|
Subject: [PATCH] [master] Added includes of new BIND9 compatibility headers,
|
||||||
|
updated util/bind.sh
|
||||||
|
|
||||||
|
Merges in rt48072.
|
||||||
|
|
||||||
|
(cherry picked from commit 8194daabfd590f17825f0c61e9534bee5c99cc86)
|
||||||
|
---
|
||||||
|
includes/omapip/isclib.h | 3 +++
|
||||||
|
includes/omapip/result.h | 1 +
|
||||||
|
server/dhcpv6.c | 13 +++++++++----
|
||||||
|
3 files changed, 13 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/includes/omapip/isclib.h b/includes/omapip/isclib.h
|
||||||
|
index e2963089..fa5d9ad3 100644
|
||||||
|
--- a/includes/omapip/isclib.h
|
||||||
|
+++ b/includes/omapip/isclib.h
|
||||||
|
@@ -48,6 +48,9 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
|
+#include <isc/boolean.h>
|
||||||
|
+#include <isc/int.h>
|
||||||
|
+
|
||||||
|
#include <isc/buffer.h>
|
||||||
|
#include <isc/lex.h>
|
||||||
|
#include <isc/lib.h>
|
||||||
|
diff --git a/includes/omapip/result.h b/includes/omapip/result.h
|
||||||
|
index ae5f7d6a..9c1fab23 100644
|
||||||
|
--- a/includes/omapip/result.h
|
||||||
|
+++ b/includes/omapip/result.h
|
||||||
|
@@ -26,6 +26,7 @@
|
||||||
|
#ifndef DHCP_RESULT_H
|
||||||
|
#define DHCP_RESULT_H 1
|
||||||
|
|
||||||
|
+#include <isc/boolean.h>
|
||||||
|
#include <isc/lang.h>
|
||||||
|
#include <isc/resultclass.h>
|
||||||
|
#include <isc/types.h>
|
||||||
|
diff --git a/server/dhcpv6.c b/server/dhcpv6.c
|
||||||
|
index 74487667..1a6ff241 100644
|
||||||
|
--- a/server/dhcpv6.c
|
||||||
|
+++ b/server/dhcpv6.c
|
||||||
|
@@ -1003,7 +1003,8 @@ void check_pool6_threshold(struct reply_state *reply,
|
||||||
|
shared_name,
|
||||||
|
inet_ntop(AF_INET6, &lease->addr,
|
||||||
|
tmp_addr, sizeof(tmp_addr)),
|
||||||
|
- used, count);
|
||||||
|
+ (long long unsigned)(used),
|
||||||
|
+ (long long unsigned)(count));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@@ -1035,7 +1036,8 @@ void check_pool6_threshold(struct reply_state *reply,
|
||||||
|
"address: %s; high threshold %d%% %llu/%llu.",
|
||||||
|
shared_name,
|
||||||
|
inet_ntop(AF_INET6, &lease->addr, tmp_addr, sizeof(tmp_addr)),
|
||||||
|
- poolhigh, used, count);
|
||||||
|
+ poolhigh, (long long unsigned)(used),
|
||||||
|
+ (long long unsigned)(count));
|
||||||
|
|
||||||
|
/* handle the low threshold now, if we don't
|
||||||
|
* have one we default to 0. */
|
||||||
|
@@ -1383,12 +1385,15 @@ pick_v6_address(struct reply_state *reply)
|
||||||
|
log_debug("Unable to pick client address: "
|
||||||
|
"no addresses available - shared network %s: "
|
||||||
|
" 2^64-1 < total, %llu active, %llu abandoned",
|
||||||
|
- shared_name, active - abandoned, abandoned);
|
||||||
|
+ shared_name, (long long unsigned)(active - abandoned),
|
||||||
|
+ (long long unsigned)(abandoned));
|
||||||
|
} else {
|
||||||
|
log_debug("Unable to pick client address: "
|
||||||
|
"no addresses available - shared network %s: "
|
||||||
|
"%llu total, %llu active, %llu abandoned",
|
||||||
|
- shared_name, total, active - abandoned, abandoned);
|
||||||
|
+ shared_name, (long long unsigned)(total),
|
||||||
|
+ (long long unsigned)(active - abandoned),
|
||||||
|
+ (long long unsigned)(abandoned));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ISC_R_NORESOURCES;
|
||||||
|
--
|
||||||
|
2.14.5
|
@ -0,0 +1,257 @@
|
|||||||
|
diff --git a/client/Makefile.am b/client/Makefile.am
|
||||||
|
index b1ecf82..387c097 100644
|
||||||
|
--- a/client/Makefile.am
|
||||||
|
+++ b/client/Makefile.am
|
||||||
|
@@ -15,6 +15,7 @@ dhclient_SOURCES = clparse.c dhclient.c dhc6.c \
|
||||||
|
scripts/bsdos scripts/freebsd scripts/linux scripts/macos \
|
||||||
|
scripts/netbsd scripts/nextstep scripts/openbsd \
|
||||||
|
scripts/solaris scripts/openwrt
|
||||||
|
-dhclient_LDADD = ../common/libdhcp.a ../omapip/libomapi.la $(BIND_LIBS)
|
||||||
|
+dhclient_LDADD = ../common/libdhcp.a ../omapip/libomapi.la \
|
||||||
|
+ $(CAPNG_LDADD) $(BIND_LIBS)
|
||||||
|
man_MANS = dhclient.8 dhclient-script.8 dhclient.conf.5 dhclient.leases.5
|
||||||
|
EXTRA_DIST = $(man_MANS)
|
||||||
|
diff --git a/client/dhclient-script.8 b/client/dhclient-script.8
|
||||||
|
index 3a3aaf7..fec726c 100644
|
||||||
|
--- a/client/dhclient-script.8
|
||||||
|
+++ b/client/dhclient-script.8
|
||||||
|
@@ -245,6 +245,16 @@ repeatedly initialized to the values provided by one server, and then
|
||||||
|
the other. Assuming the information provided by both servers is
|
||||||
|
valid, this shouldn't cause any real problems, but it could be
|
||||||
|
confusing.
|
||||||
|
+.PP
|
||||||
|
+Normally, if dhclient was compiled with libcap-ng support,
|
||||||
|
+dhclient drops most capabilities immediately upon startup.
|
||||||
|
+While more secure, this greatly restricts the additional actions that
|
||||||
|
+hooks in dhclient-script can take. For example, any daemons that
|
||||||
|
+dhclient-script starts or restarts will inherit the restricted
|
||||||
|
+capabilities as well, which may interfere with their correct operation.
|
||||||
|
+Thus, the
|
||||||
|
+.BI \-nc
|
||||||
|
+option can be used to prevent dhclient from dropping capabilities.
|
||||||
|
.SH SEE ALSO
|
||||||
|
dhclient(8), dhcpd(8), dhcrelay(8), dhclient.conf(5) and
|
||||||
|
dhclient.leases(5).
|
||||||
|
diff --git a/client/dhclient.8 b/client/dhclient.8
|
||||||
|
index aa2238d..005cda5 100644
|
||||||
|
--- a/client/dhclient.8
|
||||||
|
+++ b/client/dhclient.8
|
||||||
|
@@ -134,6 +134,9 @@ dhclient - Dynamic Host Configuration Protocol Client
|
||||||
|
.B -w
|
||||||
|
]
|
||||||
|
[
|
||||||
|
+.B -nc
|
||||||
|
+]
|
||||||
|
+[
|
||||||
|
.B -B
|
||||||
|
]
|
||||||
|
[
|
||||||
|
@@ -320,6 +323,32 @@ not to exit when it doesn't find any such interfaces. The
|
||||||
|
program can then be used to notify the client when a network interface
|
||||||
|
has been added or removed, so that the client can attempt to configure an IP
|
||||||
|
address on that interface.
|
||||||
|
+.TP
|
||||||
|
+.BI \-nc
|
||||||
|
+Do not drop capabilities.
|
||||||
|
+
|
||||||
|
+Normally, if
|
||||||
|
+.B dhclient
|
||||||
|
+was compiled with libcap-ng support,
|
||||||
|
+.B dhclient
|
||||||
|
+drops most capabilities immediately upon startup. While more secure,
|
||||||
|
+this greatly restricts the additional actions that hooks in
|
||||||
|
+.B dhclient-script (8)
|
||||||
|
+can take. (For example, any daemons that
|
||||||
|
+.B dhclient-script (8)
|
||||||
|
+starts or restarts will inherit the restricted capabilities as well,
|
||||||
|
+which may interfere with their correct operation.) Thus, the
|
||||||
|
+.BI \-nc
|
||||||
|
+option can be used to prevent
|
||||||
|
+.B dhclient
|
||||||
|
+from dropping capabilities.
|
||||||
|
+
|
||||||
|
+The
|
||||||
|
+.BI \-nc
|
||||||
|
+option is ignored if
|
||||||
|
+.B dhclient
|
||||||
|
+was not compiled with libcap-ng support.
|
||||||
|
+
|
||||||
|
.TP
|
||||||
|
.BI \-n
|
||||||
|
Do not configure any interfaces. This is most likely to be useful in
|
||||||
|
diff --git a/client/dhclient.c b/client/dhclient.c
|
||||||
|
index 09ae09b..2d564ff 100644
|
||||||
|
--- a/client/dhclient.c
|
||||||
|
+++ b/client/dhclient.c
|
||||||
|
@@ -40,6 +40,10 @@
|
||||||
|
#include <isc/file.h>
|
||||||
|
#include <dns/result.h>
|
||||||
|
|
||||||
|
+#ifdef HAVE_LIBCAP_NG
|
||||||
|
+#include <cap-ng.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Defined in stdio.h when _GNU_SOURCE is set, but we don't want to define
|
||||||
|
* that when building ISC code.
|
||||||
|
@@ -239,6 +243,9 @@ main(int argc, char **argv) {
|
||||||
|
int timeout_arg = 0;
|
||||||
|
char *arg_conf = NULL;
|
||||||
|
int arg_conf_len = 0;
|
||||||
|
+#ifdef HAVE_LIBCAP_NG
|
||||||
|
+ int keep_capabilities = 0;
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
/* Initialize client globals. */
|
||||||
|
memset(&default_duid, 0, sizeof(default_duid));
|
||||||
|
@@ -548,6 +555,10 @@ main(int argc, char **argv) {
|
||||||
|
}
|
||||||
|
|
||||||
|
dhclient_request_options = argv[i];
|
||||||
|
+ } else if (!strcmp(argv[i], "-nc")) {
|
||||||
|
+#ifdef HAVE_LIBCAP_NG
|
||||||
|
+ keep_capabilities = 1;
|
||||||
|
+#endif
|
||||||
|
} else if (argv[i][0] == '-') {
|
||||||
|
usage("Unknown command: %s", argv[i]);
|
||||||
|
} else if (interfaces_requested < 0) {
|
||||||
|
@@ -608,6 +619,19 @@ main(int argc, char **argv) {
|
||||||
|
path_dhclient_script = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef HAVE_LIBCAP_NG
|
||||||
|
+ /* Drop capabilities */
|
||||||
|
+ if (!keep_capabilities) {
|
||||||
|
+ capng_clear(CAPNG_SELECT_CAPS);
|
||||||
|
+ capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
|
||||||
|
+ CAP_DAC_OVERRIDE); // Drop this someday
|
||||||
|
+ capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
|
||||||
|
+ CAP_NET_ADMIN, CAP_NET_RAW,
|
||||||
|
+ CAP_NET_BIND_SERVICE, CAP_SYS_ADMIN, -1);
|
||||||
|
+ capng_apply(CAPNG_SELECT_CAPS);
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* Set up the initial dhcp option universe. */
|
||||||
|
initialize_common_option_spaces();
|
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index adc98a8..8bbe5ca 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -592,6 +592,41 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[void foo() __attribute__((noreturn));
|
||||||
|
# Look for optional headers.
|
||||||
|
AC_CHECK_HEADERS(sys/socket.h net/if_dl.h net/if6.h regex.h)
|
||||||
|
|
||||||
|
+# look for capabilities library
|
||||||
|
+AC_ARG_WITH(libcap-ng,
|
||||||
|
+ [ --with-libcap-ng=[auto/yes/no] Add Libcap-ng support [default=auto]],,
|
||||||
|
+ with_libcap_ng=auto)
|
||||||
|
+
|
||||||
|
+# Check for Libcap-ng API
|
||||||
|
+#
|
||||||
|
+# libcap-ng detection
|
||||||
|
+if test x$with_libcap_ng = xno ; then
|
||||||
|
+ have_libcap_ng=no;
|
||||||
|
+else
|
||||||
|
+ # Start by checking for header file
|
||||||
|
+ AC_CHECK_HEADER(cap-ng.h, capng_headers=yes, capng_headers=no)
|
||||||
|
+
|
||||||
|
+ # See if we have libcap-ng library
|
||||||
|
+ AC_CHECK_LIB(cap-ng, capng_clear,
|
||||||
|
+ CAPNG_LDADD=-lcap-ng,)
|
||||||
|
+
|
||||||
|
+ # Check results are usable
|
||||||
|
+ if test x$with_libcap_ng = xyes -a x$CAPNG_LDADD = x ; then
|
||||||
|
+ AC_MSG_ERROR(libcap-ng support was requested and the library was not found)
|
||||||
|
+ fi
|
||||||
|
+ if test x$CAPNG_LDADD != x -a $capng_headers = no ; then
|
||||||
|
+ AC_MSG_ERROR(libcap-ng libraries found but headers are missing)
|
||||||
|
+ fi
|
||||||
|
+fi
|
||||||
|
+AC_SUBST(CAPNG_LDADD)
|
||||||
|
+AC_MSG_CHECKING(whether to use libcap-ng)
|
||||||
|
+if test x$CAPNG_LDADD != x ; then
|
||||||
|
+ AC_DEFINE(HAVE_LIBCAP_NG,1,[libcap-ng support])
|
||||||
|
+ AC_MSG_RESULT(yes)
|
||||||
|
+else
|
||||||
|
+ AC_MSG_RESULT(no)
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
# Solaris needs some libraries for functions
|
||||||
|
AC_SEARCH_LIBS(socket, [socket])
|
||||||
|
AC_SEARCH_LIBS(inet_ntoa, [nsl])
|
||||||
|
diff --git a/relay/Makefile.am b/relay/Makefile.am
|
||||||
|
index 316a524..999e543 100644
|
||||||
|
--- a/relay/Makefile.am
|
||||||
|
+++ b/relay/Makefile.am
|
||||||
|
@@ -5,7 +5,7 @@ AM_CPPFLAGS = -DLOCALSTATEDIR='"@localstatedir@"'
|
||||||
|
sbin_PROGRAMS = dhcrelay
|
||||||
|
dhcrelay_SOURCES = dhcrelay.c
|
||||||
|
dhcrelay_LDADD = ../common/libdhcp.a ../omapip/libomapi.la \
|
||||||
|
- $(BIND_LIBS)
|
||||||
|
+ $(CAPNG_LDADD) $(BIND_LIBS)
|
||||||
|
man_MANS = dhcrelay.8
|
||||||
|
EXTRA_DIST = $(man_MANS)
|
||||||
|
|
||||||
|
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
|
||||||
|
index eac119c..d2ab448 100644
|
||||||
|
--- a/relay/dhcrelay.c
|
||||||
|
+++ b/relay/dhcrelay.c
|
||||||
|
@@ -32,6 +32,11 @@
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <isc/file.h>
|
||||||
|
|
||||||
|
+#ifdef HAVE_LIBCAP_NG
|
||||||
|
+# include <cap-ng.h>
|
||||||
|
+ int keep_capabilities = 0;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
TIME default_lease_time = 43200; /* 12 hours... */
|
||||||
|
TIME max_lease_time = 86400; /* 24 hours... */
|
||||||
|
struct tree_cache *global_options[256];
|
||||||
|
@@ -472,6 +477,10 @@ main(int argc, char **argv) {
|
||||||
|
if (++i == argc)
|
||||||
|
usage(use_noarg, argv[i-1]);
|
||||||
|
dhcrelay_sub_id = argv[i];
|
||||||
|
+#endif
|
||||||
|
+ } else if (!strcmp(argv[i], "-nc")) {
|
||||||
|
+#ifdef HAVE_LIBCAP_NG
|
||||||
|
+ keep_capabilities = 1;
|
||||||
|
#endif
|
||||||
|
} else if (!strcmp(argv[i], "-pf")) {
|
||||||
|
if (++i == argc)
|
||||||
|
@@ -547,6 +556,17 @@ main(int argc, char **argv) {
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef HAVE_LIBCAP_NG
|
||||||
|
+ /* Drop capabilities */
|
||||||
|
+ if (!keep_capabilities) {
|
||||||
|
+ capng_clear(CAPNG_SELECT_BOTH);
|
||||||
|
+ capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
|
||||||
|
+ CAP_NET_RAW, CAP_NET_BIND_SERVICE, -1);
|
||||||
|
+ capng_apply(CAPNG_SELECT_BOTH);
|
||||||
|
+ log_info ("Dropped all unnecessary capabilities.");
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
if (!quiet) {
|
||||||
|
log_info("%s %s", message, PACKAGE_VERSION);
|
||||||
|
log_info(copyright);
|
||||||
|
@@ -699,6 +719,15 @@ main(int argc, char **argv) {
|
||||||
|
signal(SIGTERM, dhcp_signal_handler); /* kill */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifdef HAVE_LIBCAP_NG
|
||||||
|
+ /* Drop all capabilities */
|
||||||
|
+ if (!keep_capabilities) {
|
||||||
|
+ capng_clear(CAPNG_SELECT_BOTH);
|
||||||
|
+ capng_apply(CAPNG_SELECT_BOTH);
|
||||||
|
+ log_info ("Dropped all capabilities.");
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* Start dispatching packets and timeouts... */
|
||||||
|
dispatch();
|
||||||
|
|
@ -0,0 +1,61 @@
|
|||||||
|
diff -up dhcp-4.3.4/client/dhclient.c.bind-iface dhcp-4.3.4/client/dhclient.c
|
||||||
|
--- dhcp-4.3.4/client/dhclient.c.bind-iface 2016-04-29 13:06:50.595257108 +0200
|
||||||
|
+++ dhcp-4.3.4/client/dhclient.c 2016-04-29 13:08:30.237281528 +0200
|
||||||
|
@@ -3023,6 +3023,14 @@ void send_request (cpp)
|
||||||
|
#endif
|
||||||
|
if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
|
||||||
|
fallback_interface) {
|
||||||
|
+#if defined(SO_BINDTODEVICE)
|
||||||
|
+ if (setsockopt(fallback_interface -> wfdesc, SOL_SOCKET,
|
||||||
|
+ SO_BINDTODEVICE, client->interface->name,
|
||||||
|
+ strlen(client->interface->name)) < 0) {
|
||||||
|
+ log_error("%s:%d: Failed to bind fallback interface"
|
||||||
|
+ " to %s: %m", MDL, client->interface->name);
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
result = send_packet(fallback_interface, NULL, &client->packet,
|
||||||
|
client->packet_length, from, &destination,
|
||||||
|
NULL);
|
||||||
|
@@ -3032,6 +3040,13 @@ void send_request (cpp)
|
||||||
|
client->packet_length,
|
||||||
|
fallback_interface->name);
|
||||||
|
}
|
||||||
|
+#if defined(SO_BINDTODEVICE)
|
||||||
|
+ if (setsockopt(fallback_interface -> wfdesc, SOL_SOCKET,
|
||||||
|
+ SO_BINDTODEVICE, NULL, 0) < 0) {
|
||||||
|
+ log_fatal("%s:%d: Failed to unbind fallback interface:"
|
||||||
|
+ " %m", MDL);
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Send out a packet. */
|
||||||
|
@@ -3144,6 +3159,14 @@ void send_release (cpp)
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
if (fallback_interface) {
|
||||||
|
+#if defined(SO_BINDTODEVICE)
|
||||||
|
+ if (setsockopt(fallback_interface -> wfdesc, SOL_SOCKET,
|
||||||
|
+ SO_BINDTODEVICE, client->interface->name,
|
||||||
|
+ strlen(client->interface->name)) < 0) {
|
||||||
|
+ log_error("%s:%d: Failed to bind fallback interface"
|
||||||
|
+ " to %s: %m", MDL, client->interface->name);
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
result = send_packet(fallback_interface, NULL, &client->packet,
|
||||||
|
client->packet_length, from, &destination,
|
||||||
|
NULL);
|
||||||
|
@@ -3153,6 +3176,13 @@ void send_release (cpp)
|
||||||
|
client->packet_length,
|
||||||
|
fallback_interface->name);
|
||||||
|
}
|
||||||
|
+#if defined(SO_BINDTODEVICE)
|
||||||
|
+ if (setsockopt(fallback_interface -> wfdesc, SOL_SOCKET,
|
||||||
|
+ SO_BINDTODEVICE, NULL, 0) < 0) {
|
||||||
|
+ log_fatal("%s:%d: Failed to unbind fallback interface:"
|
||||||
|
+ " %m", MDL);
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
} else {
|
||||||
|
/* Send out a packet. */
|
||||||
|
result = send_packet(client->interface, NULL, &client->packet,
|
@ -0,0 +1,44 @@
|
|||||||
|
diff -up dhcp-4.3.4/client/clparse.c.requested dhcp-4.3.4/client/clparse.c
|
||||||
|
--- dhcp-4.3.4/client/clparse.c.requested 2016-04-29 12:18:50.157151352 +0200
|
||||||
|
+++ dhcp-4.3.4/client/clparse.c 2016-04-29 12:19:22.235137243 +0200
|
||||||
|
@@ -31,7 +31,7 @@
|
||||||
|
|
||||||
|
struct client_config top_level_config;
|
||||||
|
|
||||||
|
-#define NUM_DEFAULT_REQUESTED_OPTS 9
|
||||||
|
+#define NUM_DEFAULT_REQUESTED_OPTS 14
|
||||||
|
/* There can be 2 extra requested options for DHCPv4-over-DHCPv6. */
|
||||||
|
struct option *default_requested_options[NUM_DEFAULT_REQUESTED_OPTS + 2 + 1];
|
||||||
|
|
||||||
|
@@ -116,6 +116,31 @@ isc_result_t read_client_conf ()
|
||||||
|
option_code_hash_lookup(&default_requested_options[8],
|
||||||
|
dhcpv6_universe.code_hash, &code, 0, MDL);
|
||||||
|
|
||||||
|
+ /* 10 */
|
||||||
|
+ code = DHO_NIS_DOMAIN;
|
||||||
|
+ option_code_hash_lookup(&default_requested_options[9],
|
||||||
|
+ dhcp_universe.code_hash, &code, 0, MDL);
|
||||||
|
+
|
||||||
|
+ /* 11 */
|
||||||
|
+ code = DHO_NIS_SERVERS;
|
||||||
|
+ option_code_hash_lookup(&default_requested_options[10],
|
||||||
|
+ dhcp_universe.code_hash, &code, 0, MDL);
|
||||||
|
+
|
||||||
|
+ /* 12 */
|
||||||
|
+ code = DHO_NTP_SERVERS;
|
||||||
|
+ option_code_hash_lookup(&default_requested_options[11],
|
||||||
|
+ dhcp_universe.code_hash, &code, 0, MDL);
|
||||||
|
+
|
||||||
|
+ /* 13 */
|
||||||
|
+ code = DHO_INTERFACE_MTU;
|
||||||
|
+ option_code_hash_lookup(&default_requested_options[12],
|
||||||
|
+ dhcp_universe.code_hash, &code, 0, MDL);
|
||||||
|
+
|
||||||
|
+ /* 14 */
|
||||||
|
+ code = DHO_DOMAIN_SEARCH;
|
||||||
|
+ option_code_hash_lookup(&default_requested_options[13],
|
||||||
|
+ dhcp_universe.code_hash, &code, 0, MDL);
|
||||||
|
+
|
||||||
|
for (code = 0 ; code < NUM_DEFAULT_REQUESTED_OPTS ; code++) {
|
||||||
|
if (default_requested_options[code] == NULL)
|
||||||
|
log_fatal("Unable to find option definition for "
|
@ -0,0 +1,93 @@
|
|||||||
|
From 41c6032ace65119e6a400365f7e90283c930afd4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavel Zhukov <pzhukov@redhat.com>
|
||||||
|
Date: Tue, 22 Oct 2019 16:23:01 +0200
|
||||||
|
Subject: [PATCH 24/26] Detect system time changes
|
||||||
|
Cc: pzhukov@redhat.com
|
||||||
|
|
||||||
|
---
|
||||||
|
client/dhclient.c | 6 ++++++
|
||||||
|
common/dispatch.c | 11 ++++++++++-
|
||||||
|
includes/dhcpd.h | 3 ++-
|
||||||
|
server/dhcpd.c | 6 ++++++
|
||||||
|
4 files changed, 24 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/client/dhclient.c b/client/dhclient.c
|
||||||
|
index 9b65438..44d508a 100644
|
||||||
|
--- a/client/dhclient.c
|
||||||
|
+++ b/client/dhclient.c
|
||||||
|
@@ -5408,6 +5408,12 @@ isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
|
||||||
|
case server_awaken:
|
||||||
|
state_reboot (client);
|
||||||
|
break;
|
||||||
|
+
|
||||||
|
+ case server_time_changed:
|
||||||
|
+ if (client->active){
|
||||||
|
+ state_reboot (client);
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/common/dispatch.c b/common/dispatch.c
|
||||||
|
index d7fe200..8a24499 100644
|
||||||
|
--- a/common/dispatch.c
|
||||||
|
+++ b/common/dispatch.c
|
||||||
|
@@ -118,7 +118,6 @@ dispatch(void)
|
||||||
|
* signal. It will return ISC_R_RELOAD in that
|
||||||
|
* case. That is a normal behavior.
|
||||||
|
*/
|
||||||
|
-
|
||||||
|
if (status == ISC_R_RELOAD) {
|
||||||
|
/*
|
||||||
|
* dhcp_set_control_state() will do the job.
|
||||||
|
@@ -129,6 +128,16 @@ dispatch(void)
|
||||||
|
if (status == ISC_R_SUCCESS)
|
||||||
|
status = ISC_R_RELOAD;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ if (status == ISC_R_TIMESHIFTED){
|
||||||
|
+ status = dhcp_set_control_state(server_time_changed,
|
||||||
|
+ server_time_changed);
|
||||||
|
+ status = ISC_R_RELOAD;
|
||||||
|
+ log_info ("System time has been changed. Unable to use existing leases. Restarting");
|
||||||
|
+ // do nothing, restart context
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
} while (status == ISC_R_RELOAD);
|
||||||
|
|
||||||
|
log_fatal ("Dispatch routine failed: %s -- exiting",
|
||||||
|
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
|
||||||
|
index 635c510..ec6c227 100644
|
||||||
|
--- a/includes/dhcpd.h
|
||||||
|
+++ b/includes/dhcpd.h
|
||||||
|
@@ -524,7 +524,8 @@ typedef enum {
|
||||||
|
server_running = 1,
|
||||||
|
server_shutdown = 2,
|
||||||
|
server_hibernate = 3,
|
||||||
|
- server_awaken = 4
|
||||||
|
+ server_awaken = 4,
|
||||||
|
+ server_time_changed = 5
|
||||||
|
} control_object_state_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
diff --git a/server/dhcpd.c b/server/dhcpd.c
|
||||||
|
index 530a923..4aef16b 100644
|
||||||
|
--- a/server/dhcpd.c
|
||||||
|
+++ b/server/dhcpd.c
|
||||||
|
@@ -1767,6 +1767,12 @@ isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
+ if (newstate == server_time_changed){
|
||||||
|
+ log_error ("System time has been changed. Leases information unreliable!");
|
||||||
|
+ return ISC_R_SUCCESS;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
if (newstate != server_shutdown)
|
||||||
|
return DHCP_R_INVALIDARG;
|
||||||
|
/* Re-entry. */
|
||||||
|
--
|
||||||
|
2.14.5
|
||||||
|
|
@ -0,0 +1,63 @@
|
|||||||
|
diff -up dhcp-4.3.4/client/dhclient.c.backoff dhcp-4.3.4/client/dhclient.c
|
||||||
|
--- dhcp-4.3.4/client/dhclient.c.backoff 2016-04-29 12:16:26.976245611 +0200
|
||||||
|
+++ dhcp-4.3.4/client/dhclient.c 2016-04-29 12:16:26.979245609 +0200
|
||||||
|
@@ -1423,6 +1423,8 @@ void state_init (cpp)
|
||||||
|
void *cpp;
|
||||||
|
{
|
||||||
|
struct client_state *client = cpp;
|
||||||
|
+ enum dhcp_state init_state = client->state;
|
||||||
|
+ struct timeval tv;
|
||||||
|
|
||||||
|
ASSERT_STATE(state, S_INIT);
|
||||||
|
|
||||||
|
@@ -1435,9 +1437,18 @@ void state_init (cpp)
|
||||||
|
client -> first_sending = cur_time;
|
||||||
|
client -> interval = client -> config -> initial_interval;
|
||||||
|
|
||||||
|
- /* Add an immediate timeout to cause the first DHCPDISCOVER packet
|
||||||
|
- to go out. */
|
||||||
|
- send_discover (client);
|
||||||
|
+ if (init_state != S_DECLINED) {
|
||||||
|
+ /* Add an immediate timeout to cause the first DHCPDISCOVER packet
|
||||||
|
+ to go out. */
|
||||||
|
+ send_discover(client);
|
||||||
|
+ } else {
|
||||||
|
+ /* We've received an OFFER and it has been DECLINEd by dhclient-script.
|
||||||
|
+ * wait for a random time between 1 and backoff_cutoff seconds before
|
||||||
|
+ * trying again. */
|
||||||
|
+ tv . tv_sec = cur_time + ((1 + (random() >> 2)) % client->config->backoff_cutoff);
|
||||||
|
+ tv . tv_usec = 0;
|
||||||
|
+ add_timeout(&tv, send_discover, client, 0, 0);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -1734,5 +1745,6 @@ void bind_lease (client)
|
||||||
|
#endif
|
||||||
|
exit(2);
|
||||||
|
} else {
|
||||||
|
+ client -> state = S_DECLINED;
|
||||||
|
state_init(client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@@ -4626,6 +4638,7 @@ void client_location_changed ()
|
||||||
|
case S_INIT:
|
||||||
|
case S_REBINDING:
|
||||||
|
case S_STOPPED:
|
||||||
|
+ case S_DECLINED:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
client -> state = S_INIT;
|
||||||
|
diff -up dhcp-4.3.4/includes/dhcpd.h.backoff dhcp-4.3.4/includes/dhcpd.h
|
||||||
|
--- dhcp-4.3.4/includes/dhcpd.h.backoff 2016-04-29 12:16:26.980245609 +0200
|
||||||
|
+++ dhcp-4.3.4/includes/dhcpd.h 2016-04-29 12:17:30.893203533 +0200
|
||||||
|
@@ -1171,7 +1171,8 @@ enum dhcp_state {
|
||||||
|
S_BOUND = 5,
|
||||||
|
S_RENEWING = 6,
|
||||||
|
S_REBINDING = 7,
|
||||||
|
- S_STOPPED = 8
|
||||||
|
+ S_STOPPED = 8,
|
||||||
|
+ S_DECLINED = 9
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Possible pending client operations. */
|
@ -0,0 +1,449 @@
|
|||||||
|
diff --git a/client/clparse.c b/client/clparse.c
|
||||||
|
index 03190c3..2033427 100644
|
||||||
|
--- a/client/clparse.c
|
||||||
|
+++ b/client/clparse.c
|
||||||
|
@@ -189,6 +189,7 @@ isc_result_t read_client_conf ()
|
||||||
|
/* Requested lease time, used by DHCPv6 (DHCPv4 uses the option cache)
|
||||||
|
*/
|
||||||
|
top_level_config.requested_lease = 7200;
|
||||||
|
+ top_level_config.bootp_broadcast_always = 0;
|
||||||
|
|
||||||
|
group_allocate (&top_level_config.on_receipt, MDL);
|
||||||
|
if (!top_level_config.on_receipt)
|
||||||
|
@@ -394,7 +395,8 @@ void read_client_leases ()
|
||||||
|
interface-declaration |
|
||||||
|
LEASE client-lease-statement |
|
||||||
|
ALIAS client-lease-statement |
|
||||||
|
- KEY key-definition */
|
||||||
|
+ KEY key-definition |
|
||||||
|
+ BOOTP_BROADCAST_ALWAYS */
|
||||||
|
|
||||||
|
void parse_client_statement (cfile, ip, config)
|
||||||
|
struct parse *cfile;
|
||||||
|
@@ -817,6 +819,12 @@ void parse_client_statement (cfile, ip, config)
|
||||||
|
parse_lease_id_format(cfile);
|
||||||
|
break;
|
||||||
|
|
||||||
|
+ case BOOTP_BROADCAST_ALWAYS:
|
||||||
|
+ token = next_token(&val, (unsigned*)0, cfile);
|
||||||
|
+ config -> bootp_broadcast_always = 1;
|
||||||
|
+ parse_semi (cfile);
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
|
||||||
|
default:
|
||||||
|
lose = 0;
|
||||||
|
diff --git a/client/dhclient.8 b/client/dhclient.8
|
||||||
|
index 24f8f12..aa2238d 100644
|
||||||
|
--- a/client/dhclient.8
|
||||||
|
+++ b/client/dhclient.8
|
||||||
|
@@ -134,6 +134,33 @@ dhclient - Dynamic Host Configuration Protocol Client
|
||||||
|
.B -w
|
||||||
|
]
|
||||||
|
[
|
||||||
|
+.B -B
|
||||||
|
+]
|
||||||
|
+[
|
||||||
|
+.B -C
|
||||||
|
+.I dhcp-client-identifier
|
||||||
|
+]
|
||||||
|
+[
|
||||||
|
+.B -H
|
||||||
|
+.I host-name
|
||||||
|
+]
|
||||||
|
+[
|
||||||
|
+.B -F
|
||||||
|
+.I fqdn.fqdn
|
||||||
|
+]
|
||||||
|
+[
|
||||||
|
+.B -V
|
||||||
|
+.I vendor-class-identifier
|
||||||
|
+]
|
||||||
|
+[
|
||||||
|
+.B --request-options
|
||||||
|
+.I request-option-list
|
||||||
|
+]
|
||||||
|
+[
|
||||||
|
+.B --timeout
|
||||||
|
+.I timeout
|
||||||
|
+]
|
||||||
|
+[
|
||||||
|
.B --dad-wait-time
|
||||||
|
.I seconds
|
||||||
|
]
|
||||||
|
diff --git a/client/dhclient.c b/client/dhclient.c
|
||||||
|
index dcf3f1a..270a960 100644
|
||||||
|
--- a/client/dhclient.c
|
||||||
|
+++ b/client/dhclient.c
|
||||||
|
@@ -40,6 +40,12 @@
|
||||||
|
#include <isc/file.h>
|
||||||
|
#include <dns/result.h>
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Defined in stdio.h when _GNU_SOURCE is set, but we don't want to define
|
||||||
|
+ * that when building ISC code.
|
||||||
|
+ */
|
||||||
|
+extern int asprintf(char **strp, const char *fmt, ...);
|
||||||
|
+
|
||||||
|
TIME default_lease_time = 43200; /* 12 hours... */
|
||||||
|
TIME max_lease_time = 86400; /* 24 hours... */
|
||||||
|
|
||||||
|
@@ -101,6 +107,10 @@ char *mockup_relay = NULL;
|
||||||
|
|
||||||
|
char *progname = NULL;
|
||||||
|
|
||||||
|
+int bootp_broadcast_always = 0;
|
||||||
|
+
|
||||||
|
+extern struct option *default_requested_options[];
|
||||||
|
+
|
||||||
|
void run_stateless(int exit_mode, u_int16_t port);
|
||||||
|
|
||||||
|
static isc_result_t write_duid(struct data_string *duid);
|
||||||
|
@@ -179,7 +189,11 @@ usage(const char *sfmt, const char *sarg)
|
||||||
|
" [-s server-addr] [-cf config-file]\n"
|
||||||
|
" [-df duid-file] [-lf lease-file]\n"
|
||||||
|
" [-pf pid-file] [--no-pid] [-e VAR=val]\n"
|
||||||
|
- " [-sf script-file] [interface]*",
|
||||||
|
+ " [-sf script-file] [interface]*\n"
|
||||||
|
+ " [-C <dhcp-client-identifier>] [-B]\n"
|
||||||
|
+ " [-H <host-name> | -F <fqdn.fqdn>] [--timeout <timeout>]\n"
|
||||||
|
+ " [-V <vendor-class-identifier>]\n"
|
||||||
|
+ " [--request-options <request option list>]",
|
||||||
|
isc_file_basename(progname));
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -216,6 +230,16 @@ main(int argc, char **argv) {
|
||||||
|
progname = argv[0];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+ char *dhcp_client_identifier_arg = NULL;
|
||||||
|
+ char *dhcp_host_name_arg = NULL;
|
||||||
|
+ char *dhcp_fqdn_arg = NULL;
|
||||||
|
+ char *dhcp_vendor_class_identifier_arg = NULL;
|
||||||
|
+ char *dhclient_request_options = NULL;
|
||||||
|
+
|
||||||
|
+ int timeout_arg = 0;
|
||||||
|
+ char *arg_conf = NULL;
|
||||||
|
+ int arg_conf_len = 0;
|
||||||
|
+
|
||||||
|
/* Initialize client globals. */
|
||||||
|
memset(&default_duid, 0, sizeof(default_duid));
|
||||||
|
|
||||||
|
@@ -442,6 +466,88 @@ main(int argc, char **argv) {
|
||||||
|
strlen(PACKAGE_VERSION)));
|
||||||
|
IGNORE_RET(write(STDERR_FILENO, "\n", 1));
|
||||||
|
exit(0);
|
||||||
|
+ } else if (!strcmp(argv[i], "-C")) {
|
||||||
|
+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
|
||||||
|
+ usage(use_noarg, argv[i-1]);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
|
||||||
|
+ log_error("-C option dhcp-client-identifier string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dhcp_client_identifier_arg = argv[i];
|
||||||
|
+ } else if (!strcmp(argv[i], "-B")) {
|
||||||
|
+ bootp_broadcast_always = 1;
|
||||||
|
+ } else if (!strcmp(argv[i], "-H")) {
|
||||||
|
+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
|
||||||
|
+ usage(use_noarg, argv[i-1]);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
|
||||||
|
+ log_error("-H option host-name string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (dhcp_host_name_arg != NULL) {
|
||||||
|
+ log_error("The -H <host-name> and -F <fqdn> arguments are mutually exclusive");
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dhcp_host_name_arg = argv[i];
|
||||||
|
+ } else if (!strcmp(argv[i], "-F")) {
|
||||||
|
+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
|
||||||
|
+ usage(use_noarg, argv[i-1]);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
|
||||||
|
+ log_error("-F option fqdn.fqdn string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (dhcp_fqdn_arg != NULL) {
|
||||||
|
+ log_error("Only one -F <fqdn> argument can be specified");
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (dhcp_host_name_arg != NULL) {
|
||||||
|
+ log_error("The -F <fqdn> and -H <host-name> arguments are mutually exclusive");
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dhcp_fqdn_arg = argv[i];
|
||||||
|
+ } else if (!strcmp(argv[i], "--timeout")) {
|
||||||
|
+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
|
||||||
|
+ usage(use_noarg, argv[i-1]);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((timeout_arg = atoi(argv[i])) <= 0) {
|
||||||
|
+ log_error("timeout option must be > 0 - bad value: %s",argv[i]);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+ } else if (!strcmp(argv[i], "-V")) {
|
||||||
|
+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
|
||||||
|
+ usage(use_noarg, argv[i-1]);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
|
||||||
|
+ log_error("-V option vendor-class-identifier string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dhcp_vendor_class_identifier_arg = argv[i];
|
||||||
|
+ } else if (!strcmp(argv[i], "--request-options")) {
|
||||||
|
+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
|
||||||
|
+ usage(use_noarg, argv[i-1]);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dhclient_request_options = argv[i];
|
||||||
|
} else if (argv[i][0] == '-') {
|
||||||
|
usage("Unknown command: %s", argv[i]);
|
||||||
|
} else if (interfaces_requested < 0) {
|
||||||
|
@@ -641,6 +747,156 @@ main(int argc, char **argv) {
|
||||||
|
/* Parse the dhclient.conf file. */
|
||||||
|
read_client_conf();
|
||||||
|
|
||||||
|
+ /* Parse any extra command line configuration arguments: */
|
||||||
|
+ if ((dhcp_client_identifier_arg != NULL) && (*dhcp_client_identifier_arg != '\0')) {
|
||||||
|
+ arg_conf_len = asprintf(&arg_conf, "send dhcp-client-identifier \"%s\";", dhcp_client_identifier_arg);
|
||||||
|
+
|
||||||
|
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||||
|
+ log_fatal("Unable to send -C option dhcp-client-identifier");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((dhcp_host_name_arg != NULL) && (*dhcp_host_name_arg != '\0')) {
|
||||||
|
+ if (arg_conf == 0) {
|
||||||
|
+ arg_conf_len = asprintf(&arg_conf, "send host-name \"%s\";", dhcp_host_name_arg);
|
||||||
|
+
|
||||||
|
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||||
|
+ log_fatal("Unable to send -H option host-name");
|
||||||
|
+ } else {
|
||||||
|
+ char *last_arg_conf = arg_conf;
|
||||||
|
+ arg_conf = NULL;
|
||||||
|
+ arg_conf_len = asprintf(&arg_conf, "%s\nsend host-name \"%s\";", last_arg_conf, dhcp_host_name_arg);
|
||||||
|
+
|
||||||
|
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||||
|
+ log_fatal("Unable to send -H option host-name");
|
||||||
|
+
|
||||||
|
+ free(last_arg_conf);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((dhcp_fqdn_arg != NULL) && (*dhcp_fqdn_arg != '\0')) {
|
||||||
|
+ if (arg_conf == 0) {
|
||||||
|
+ arg_conf_len = asprintf(&arg_conf, "send fqdn.fqdn \"%s\";", dhcp_fqdn_arg);
|
||||||
|
+
|
||||||
|
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||||
|
+ log_fatal("Unable to send -F option fqdn.fqdn");
|
||||||
|
+ } else {
|
||||||
|
+ char *last_arg_conf = arg_conf;
|
||||||
|
+ arg_conf = NULL;
|
||||||
|
+ arg_conf_len = asprintf(&arg_conf, "%s\nsend fqdn.fqdn \"%s\";", last_arg_conf, dhcp_fqdn_arg);
|
||||||
|
+
|
||||||
|
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||||
|
+ log_fatal("Unable to send -F option fqdn.fqdn");
|
||||||
|
+
|
||||||
|
+ free(last_arg_conf);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (timeout_arg) {
|
||||||
|
+ if (arg_conf == 0) {
|
||||||
|
+ arg_conf_len = asprintf(&arg_conf, "timeout %d;", timeout_arg);
|
||||||
|
+
|
||||||
|
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||||
|
+ log_fatal("Unable to process --timeout timeout argument");
|
||||||
|
+ } else {
|
||||||
|
+ char *last_arg_conf = arg_conf;
|
||||||
|
+ arg_conf = NULL;
|
||||||
|
+ arg_conf_len = asprintf(&arg_conf, "%s\ntimeout %d;", last_arg_conf, timeout_arg);
|
||||||
|
+
|
||||||
|
+ if ((arg_conf == 0) || (arg_conf_len == 0))
|
||||||
|
+ log_fatal("Unable to process --timeout timeout argument");
|
||||||
|
+
|
||||||
|
+ free(last_arg_conf);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((dhcp_vendor_class_identifier_arg != NULL) && (*dhcp_vendor_class_identifier_arg != '\0')) {
|
||||||
|
+ if (arg_conf == 0) {
|
||||||
|
+ arg_conf_len = asprintf(&arg_conf, "send vendor-class-identifier \"%s\";", dhcp_vendor_class_identifier_arg);
|
||||||
|
+
|
||||||
|
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||||
|
+ log_fatal("Unable to send -V option vendor-class-identifier");
|
||||||
|
+ } else {
|
||||||
|
+ char *last_arg_conf = arg_conf;
|
||||||
|
+ arg_conf = NULL;
|
||||||
|
+ arg_conf_len = asprintf(&arg_conf, "%s\nsend vendor-class-identifier \"%s\";", last_arg_conf, dhcp_vendor_class_identifier_arg);
|
||||||
|
+
|
||||||
|
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||||
|
+ log_fatal("Unable to send -V option vendor-class-identifier");
|
||||||
|
+
|
||||||
|
+ free(last_arg_conf);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (dhclient_request_options != NULL) {
|
||||||
|
+ if (arg_conf == 0) {
|
||||||
|
+ arg_conf_len = asprintf(&arg_conf, "request %s;", dhclient_request_options);
|
||||||
|
+
|
||||||
|
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||||
|
+ log_fatal("Unable to parse --request-options <request options list> argument");
|
||||||
|
+ } else {
|
||||||
|
+ char *last_arg_conf = arg_conf;
|
||||||
|
+ arg_conf = NULL;
|
||||||
|
+ arg_conf_len = asprintf(&arg_conf, "%s\nrequest %s;", last_arg_conf, dhclient_request_options);
|
||||||
|
+
|
||||||
|
+ if ((arg_conf == 0) || (arg_conf_len <= 0))
|
||||||
|
+ log_fatal("Unable to parse --request-options <request options list> argument");
|
||||||
|
+
|
||||||
|
+ free(last_arg_conf);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (arg_conf) {
|
||||||
|
+ if (arg_conf_len == 0)
|
||||||
|
+ if ((arg_conf_len = strlen(arg_conf)) == 0)
|
||||||
|
+ /* huh ? cannot happen ! */
|
||||||
|
+ log_fatal("Unable to process -C/-H/-F/--timeout/-V/--request-options configuration arguments");
|
||||||
|
+
|
||||||
|
+ /* parse the extra dhclient.conf configuration arguments
|
||||||
|
+ * into top level config: */
|
||||||
|
+ struct parse *cfile = (struct parse *)0;
|
||||||
|
+ const char *val = NULL;
|
||||||
|
+ int token;
|
||||||
|
+
|
||||||
|
+ status = new_parse(&cfile, -1, arg_conf, arg_conf_len, "extra dhclient -C/-H/-F/--timeout/-V/--request-options configuration arguments", 0);
|
||||||
|
+
|
||||||
|
+ if ((status != ISC_R_SUCCESS) || (cfile -> warnings_occurred))
|
||||||
|
+ log_fatal("Cannot parse -C/-H/-F/--timeout/-V/--request-options configuration arguments !");
|
||||||
|
+ /* more detailed parse failures will be logged */
|
||||||
|
+
|
||||||
|
+ do {
|
||||||
|
+ token = peek_token(&val, (unsigned *)0, cfile);
|
||||||
|
+ if (token == END_OF_FILE)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ parse_client_statement(cfile, (struct interface_info *)0, &top_level_config);
|
||||||
|
+ } while (1);
|
||||||
|
+
|
||||||
|
+ if (cfile -> warnings_occurred)
|
||||||
|
+ log_fatal("Cannot parse -C/-H/-F/--timeout/-V/--request-options configuration arguments !");
|
||||||
|
+ end_parse(&cfile);
|
||||||
|
+
|
||||||
|
+ if (timeout_arg) {
|
||||||
|
+ /* we just set the toplevel timeout, but per-client
|
||||||
|
+ * timeouts may still be at defaults.
|
||||||
|
+ */
|
||||||
|
+ for (ip=interfaces; ip; ip = ip->next) {
|
||||||
|
+ if (ip->client->config->timeout == 60)
|
||||||
|
+ ip->client->config->timeout = timeout_arg;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((dhclient_request_options != 0) && (top_level_config.requested_options != default_requested_options)) {
|
||||||
|
+ for (ip=interfaces; ip; ip = ip->next) {
|
||||||
|
+ if (ip->client->config->requested_options == default_requested_options)
|
||||||
|
+ ip->client->config->requested_options = top_level_config.requested_options;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ free(arg_conf);
|
||||||
|
+ arg_conf = NULL;
|
||||||
|
+ arg_conf_len = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* Parse the lease database. */
|
||||||
|
read_client_leases();
|
||||||
|
|
||||||
|
@@ -3092,7 +3348,8 @@ void make_discover (client, lease)
|
||||||
|
client -> packet.xid = random ();
|
||||||
|
client -> packet.secs = 0; /* filled in by send_discover. */
|
||||||
|
|
||||||
|
- if (can_receive_unicast_unconfigured (client -> interface))
|
||||||
|
+ if ((!(bootp_broadcast_always || client->config->bootp_broadcast_always))
|
||||||
|
+ && can_receive_unicast_unconfigured(client->interface))
|
||||||
|
client -> packet.flags = 0;
|
||||||
|
else
|
||||||
|
client -> packet.flags = htons (BOOTP_BROADCAST);
|
||||||
|
@@ -3177,7 +3434,9 @@ void make_request (client, lease)
|
||||||
|
} else {
|
||||||
|
memset (&client -> packet.ciaddr, 0,
|
||||||
|
sizeof client -> packet.ciaddr);
|
||||||
|
- if (can_receive_unicast_unconfigured (client -> interface))
|
||||||
|
+ if ((!(bootp_broadcast_always ||
|
||||||
|
+ client ->config->bootp_broadcast_always)) &&
|
||||||
|
+ can_receive_unicast_unconfigured (client -> interface))
|
||||||
|
client -> packet.flags = 0;
|
||||||
|
else
|
||||||
|
client -> packet.flags = htons (BOOTP_BROADCAST);
|
||||||
|
@@ -3240,7 +3499,8 @@ void make_decline (client, lease)
|
||||||
|
client -> packet.hops = 0;
|
||||||
|
client -> packet.xid = client -> xid;
|
||||||
|
client -> packet.secs = 0; /* Filled in by send_request. */
|
||||||
|
- if (can_receive_unicast_unconfigured (client -> interface))
|
||||||
|
+ if ((!(bootp_broadcast_always || client->config-> bootp_broadcast_always))
|
||||||
|
+ && can_receive_unicast_unconfigured (client->interface))
|
||||||
|
client -> packet.flags = 0;
|
||||||
|
else
|
||||||
|
client -> packet.flags = htons (BOOTP_BROADCAST);
|
||||||
|
diff --git a/common/conflex.c b/common/conflex.c
|
||||||
|
index fe994ac..bdb4a52 100644
|
||||||
|
--- a/common/conflex.c
|
||||||
|
+++ b/common/conflex.c
|
||||||
|
@@ -832,6 +832,8 @@ intern(char *atom, enum dhcp_token dfv) {
|
||||||
|
if (!strcasecmp(atom+1, "ig-endian")) {
|
||||||
|
return TOKEN_BIG_ENDIAN;
|
||||||
|
}
|
||||||
|
+ if (!strcasecmp (atom + 1, "ootp-broadcast-always"))
|
||||||
|
+ return BOOTP_BROADCAST_ALWAYS;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
if (!strcasecmp(atom + 1, "ase"))
|
||||||
|
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
|
||||||
|
index eab09a6..cfdac23 100644
|
||||||
|
--- a/includes/dhcpd.h
|
||||||
|
+++ b/includes/dhcpd.h
|
||||||
|
@@ -1251,6 +1251,9 @@ struct client_config {
|
||||||
|
|
||||||
|
int lease_id_format; /* format for IDs in lease file,
|
||||||
|
TOKEN_OCTAL or TOKEN_HEX */
|
||||||
|
+
|
||||||
|
+ int bootp_broadcast_always; /* If nonzero, always set the BOOTP_BROADCAST
|
||||||
|
+ flag in requests */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Per-interface state used in the dhcp client... */
|
||||||
|
diff --git a/includes/dhctoken.h b/includes/dhctoken.h
|
||||||
|
index 15bbd1c..b312e7a 100644
|
||||||
|
--- a/includes/dhctoken.h
|
||||||
|
+++ b/includes/dhctoken.h
|
||||||
|
@@ -373,7 +373,8 @@ enum dhcp_token {
|
||||||
|
TOKEN_BIG_ENDIAN = 675,
|
||||||
|
LEASE_ID_FORMAT = 676,
|
||||||
|
TOKEN_HEX = 677,
|
||||||
|
- TOKEN_OCTAL = 678
|
||||||
|
+ TOKEN_OCTAL = 678,
|
||||||
|
+ BOOTP_BROADCAST_ALWAYS = 679
|
||||||
|
};
|
||||||
|
|
||||||
|
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
|
@ -0,0 +1,64 @@
|
|||||||
|
diff -up dhcp-4.3.4/client/dhclient.c.preinit6s dhcp-4.3.4/client/dhclient.c
|
||||||
|
--- dhcp-4.3.4/client/dhclient.c.preinit6s 2016-04-29 13:15:10.361379493 +0200
|
||||||
|
+++ dhcp-4.3.4/client/dhclient.c 2016-04-29 13:17:43.622415423 +0200
|
||||||
|
@@ -812,6 +812,12 @@ main(int argc, char **argv) {
|
||||||
|
|
||||||
|
inaddr_any.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
|
+ /* Discover all the network interfaces. */
|
||||||
|
+ discover_interfaces(DISCOVER_UNCONFIGURED);
|
||||||
|
+
|
||||||
|
+ /* Parse the dhclient.conf file. */
|
||||||
|
+ read_client_conf();
|
||||||
|
+
|
||||||
|
/* Stateless special case. */
|
||||||
|
if (stateless) {
|
||||||
|
if (release_mode || (wanted_ia_na > 0) ||
|
||||||
|
@@ -828,12 +834,6 @@ main(int argc, char **argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Discover all the network interfaces. */
|
||||||
|
- discover_interfaces(DISCOVER_UNCONFIGURED);
|
||||||
|
-
|
||||||
|
- /* Parse the dhclient.conf file. */
|
||||||
|
- read_client_conf();
|
||||||
|
-
|
||||||
|
/* Parse any extra command line configuration arguments: */
|
||||||
|
if ((dhcp_client_identifier_arg != NULL) && (*dhcp_client_identifier_arg != '\0')) {
|
||||||
|
arg_conf_len = asprintf(&arg_conf, "send dhcp-client-identifier \"%s\";", dhcp_client_identifier_arg);
|
||||||
|
@@ -1288,20 +1288,30 @@ void run_stateless(int exit_mode, u_int1
|
||||||
|
IGNORE_UNUSED(port);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- /* Discover the network interface. */
|
||||||
|
- discover_interfaces(DISCOVER_REQUESTED);
|
||||||
|
+ struct interface_info *ip;
|
||||||
|
|
||||||
|
if (!interfaces)
|
||||||
|
usage("No interfaces available for stateless command: %s", "-S");
|
||||||
|
|
||||||
|
- /* Parse the dhclient.conf file. */
|
||||||
|
#ifdef DHCP4o6
|
||||||
|
if (dhcpv4_over_dhcpv6) {
|
||||||
|
/* Mark we want to request IRT too! */
|
||||||
|
dhcpv4_over_dhcpv6++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
- read_client_conf();
|
||||||
|
+
|
||||||
|
+ for (ip = interfaces; ip; ip = ip->next) {
|
||||||
|
+ if ((interfaces_requested > 0) &&
|
||||||
|
+ ((ip->flags & (INTERFACE_REQUESTED |
|
||||||
|
+ INTERFACE_AUTOMATIC)) !=
|
||||||
|
+ INTERFACE_REQUESTED))
|
||||||
|
+ continue;
|
||||||
|
+ script_init(ip->client, "PREINIT6", NULL);
|
||||||
|
+ script_go(ip->client);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Discover the network interface. */
|
||||||
|
+ discover_interfaces(DISCOVER_REQUESTED);
|
||||||
|
|
||||||
|
/* Parse the lease database. */
|
||||||
|
read_client_leases();
|
@ -0,0 +1,94 @@
|
|||||||
|
diff --git a/client/dhc6.c b/client/dhc6.c
|
||||||
|
index 5460ee1..fe0057c 100644
|
||||||
|
--- a/client/dhc6.c
|
||||||
|
+++ b/client/dhc6.c
|
||||||
|
@@ -148,6 +148,7 @@ static int dhc6_score_lease(struct client_state *client,
|
||||||
|
|
||||||
|
extern int onetry;
|
||||||
|
extern int stateless;
|
||||||
|
+extern int address_prefix_len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assign DHCPv6 port numbers as a client.
|
||||||
|
@@ -4364,7 +4365,7 @@ dhc6_marshall_values(const char *prefix, struct client_state *client,
|
||||||
|
(unsigned) addr->plen);
|
||||||
|
} else {
|
||||||
|
client_envadd(client, prefix, "ip6_prefixlen",
|
||||||
|
- "%d", DHCLIENT_DEFAULT_PREFIX_LEN);
|
||||||
|
+ "%d", address_prefix_len);
|
||||||
|
client_envadd(client, prefix, "ip6_address",
|
||||||
|
"%s", piaddr(addr->address));
|
||||||
|
}
|
||||||
|
diff --git a/client/dhclient.c b/client/dhclient.c
|
||||||
|
index b61da43..05bfc7e 100644
|
||||||
|
--- a/client/dhclient.c
|
||||||
|
+++ b/client/dhclient.c
|
||||||
|
@@ -114,6 +114,7 @@ char *progname = NULL;
|
||||||
|
|
||||||
|
int bootp_broadcast_always = 0;
|
||||||
|
|
||||||
|
+int address_prefix_len = DHCLIENT_DEFAULT_PREFIX_LEN;
|
||||||
|
extern struct option *default_requested_options[];
|
||||||
|
|
||||||
|
void run_stateless(int exit_mode, u_int16_t port);
|
||||||
|
@@ -192,6 +193,7 @@ usage(const char *sfmt, const char *sarg)
|
||||||
|
#endif
|
||||||
|
#else /* DHCPv6 */
|
||||||
|
"[-I1dvrxi] [-nw] [-p <port>] [-D LL|LLT] \n"
|
||||||
|
+ " [--address-prefix-len length]\n"
|
||||||
|
#endif /* DHCPv6 */
|
||||||
|
" [-s server-addr] [-cf config-file]\n"
|
||||||
|
" [-df duid-file] [-lf lease-file]\n"
|
||||||
|
@@ -392,6 +394,17 @@ main(int argc, char **argv) {
|
||||||
|
tmp->next = client_env;
|
||||||
|
client_env = tmp;
|
||||||
|
client_env_count++;
|
||||||
|
+ } else if (!strcmp(argv[i], "--address-prefix-len")) {
|
||||||
|
+ if (++i == argc) {
|
||||||
|
+ usage(use_noarg, argv[i-1]);
|
||||||
|
+ }
|
||||||
|
+ errno = 0;
|
||||||
|
+ address_prefix_len = (int)strtol(argv[i], &s, 10);
|
||||||
|
+ if (errno || (*s != '\0') ||
|
||||||
|
+ (address_prefix_len < 0)) {
|
||||||
|
+ usage("Invalid value for"
|
||||||
|
+ " --address-prefix-len: %s", argv[i]);
|
||||||
|
+ }
|
||||||
|
#ifdef DHCPv6
|
||||||
|
} else if (!strcmp(argv[i], "-S")) {
|
||||||
|
if (local_family_set && (local_family == AF_INET)) {
|
||||||
|
diff --git a/includes/site.h b/includes/site.h
|
||||||
|
index b2f7fd7..aad9711 100644
|
||||||
|
--- a/includes/site.h
|
||||||
|
+++ b/includes/site.h
|
||||||
|
@@ -286,7 +286,7 @@
|
||||||
|
is a host address and doesn't include any on-link information.
|
||||||
|
64 indicates that the first 64 bits are the subnet or on-link
|
||||||
|
prefix. */
|
||||||
|
-#define DHCLIENT_DEFAULT_PREFIX_LEN 64
|
||||||
|
+#define DHCLIENT_DEFAULT_PREFIX_LEN 128
|
||||||
|
|
||||||
|
/* Enable the gentle shutdown signal handling. Currently this
|
||||||
|
means that on SIGINT or SIGTERM a client will release its
|
||||||
|
diff --git a/client/dhclient.c b/client/dhclient.c
|
||||||
|
index 2f29591..6c8b145 100644
|
||||||
|
diff --git a/client/dhclient.c b/client/dhclient.c
|
||||||
|
index b0bf2bf..f7b1476 100644
|
||||||
|
--- a/client/dhclient.c
|
||||||
|
+++ b/client/dhclient.c
|
||||||
|
@@ -193,7 +193,6 @@ usage(const char *sfmt, const char *sarg)
|
||||||
|
#endif
|
||||||
|
#else /* DHCPv6 */
|
||||||
|
"[-I1dvrxi] [-nw] [-p <port>] [-D LL|LLT] \n"
|
||||||
|
- " [--address-prefix-len length]\n"
|
||||||
|
#endif /* DHCPv6 */
|
||||||
|
" [-s server-addr] [-cf config-file]\n"
|
||||||
|
" [-df duid-file] [-lf lease-file]\n"
|
||||||
|
@@ -202,6 +201,7 @@ usage(const char *sfmt, const char *sarg)
|
||||||
|
" [-C <dhcp-client-identifier>] [-B]\n"
|
||||||
|
" [-H <host-name> | -F <fqdn.fqdn>] [--timeout <timeout>]\n"
|
||||||
|
" [-V <vendor-class-identifier>]\n"
|
||||||
|
+ " [--address-prefix-len length]\n"
|
||||||
|
" [--request-options <request option list>]",
|
||||||
|
isc_file_basename(progname));
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
diff --git a/common/options.c b/common/options.c
|
||||||
|
index 3e6383a..9216ae4 100644
|
||||||
|
--- a/common/options.c
|
||||||
|
+++ b/common/options.c
|
||||||
|
@@ -1122,7 +1122,6 @@ store_options6(char *buf, int buflen,
|
||||||
|
*/
|
||||||
|
if (code == vsio_option_code) {
|
||||||
|
vsio_wanted = 1;
|
||||||
|
- continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
@ -0,0 +1,111 @@
|
|||||||
|
diff -up dhcp-4.3.4/client/dhclient.c.duid_uuid dhcp-4.3.4/client/dhclient.c
|
||||||
|
--- dhcp-4.3.4/client/dhclient.c.duid_uuid 2016-04-29 12:58:14.846150838 +0200
|
||||||
|
+++ dhcp-4.3.4/client/dhclient.c 2016-04-29 12:58:14.851150839 +0200
|
||||||
|
@@ -3868,6 +3868,59 @@ write_options(struct client_state *clien
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+int unhexchar(char c) {
|
||||||
|
+
|
||||||
|
+ if (c >= '0' && c <= '9')
|
||||||
|
+ return c - '0';
|
||||||
|
+
|
||||||
|
+ if (c >= 'a' && c <= 'f')
|
||||||
|
+ return c - 'a' + 10;
|
||||||
|
+
|
||||||
|
+ if (c >= 'A' && c <= 'F')
|
||||||
|
+ return c - 'A' + 10;
|
||||||
|
+
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+isc_result_t
|
||||||
|
+read_uuid(u_int8_t* uuid) {
|
||||||
|
+ const char *id_fname = "/etc/machine-id";
|
||||||
|
+ char id[32];
|
||||||
|
+ size_t nread;
|
||||||
|
+ FILE * file = fopen( id_fname , "r");
|
||||||
|
+ if (!file) {
|
||||||
|
+ log_debug("Cannot open %s", id_fname);
|
||||||
|
+ return ISC_R_IOERROR;
|
||||||
|
+ }
|
||||||
|
+ nread = fread(id, 1, sizeof id, file);
|
||||||
|
+ fclose(file);
|
||||||
|
+
|
||||||
|
+ if (nread < 32) {
|
||||||
|
+ log_debug("Not enough data in %s", id_fname);
|
||||||
|
+ return ISC_R_IOERROR;
|
||||||
|
+ }
|
||||||
|
+ int j;
|
||||||
|
+ for (j = 0; j < 16; j++) {
|
||||||
|
+ int a, b;
|
||||||
|
+
|
||||||
|
+ a = unhexchar(id[j*2]);
|
||||||
|
+ b = unhexchar(id[j*2+1]);
|
||||||
|
+
|
||||||
|
+ if (a < 0 || b < 0) {
|
||||||
|
+ log_debug("Wrong data in %s", id_fname);
|
||||||
|
+ return ISC_R_IOERROR;
|
||||||
|
+ }
|
||||||
|
+ uuid[j] = a << 4 | b;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Set UUID version to 4 --- truly random generation */
|
||||||
|
+ uuid[6] = (uuid[6] & 0x0F) | 0x40;
|
||||||
|
+ /* Set the UUID variant to DCE */
|
||||||
|
+ uuid[8] = (uuid[8] & 0x3F) | 0x80;
|
||||||
|
+
|
||||||
|
+ return ISC_R_SUCCESS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* The "best" default DUID, since we cannot predict any information
|
||||||
|
* about the system (such as whether or not the hardware addresses are
|
||||||
|
@@ -3888,6 +3941,7 @@ form_duid(struct data_string *duid, cons
|
||||||
|
struct interface_info *ip;
|
||||||
|
int len;
|
||||||
|
char *str;
|
||||||
|
+ u_int8_t uuid[16];
|
||||||
|
|
||||||
|
/* For now, just use the first interface on the list. */
|
||||||
|
ip = interfaces;
|
||||||
|
@@ -3908,9 +3962,16 @@ form_duid(struct data_string *duid, cons
|
||||||
|
(ip->hw_address.hlen > sizeof(ip->hw_address.hbuf)))
|
||||||
|
log_fatal("Impossible hardware address length at %s:%d.", MDL);
|
||||||
|
|
||||||
|
- if (duid_type == 0)
|
||||||
|
- duid_type = stateless ? DUID_LL : DUID_LLT;
|
||||||
|
-
|
||||||
|
+ if (duid_type == 0) {
|
||||||
|
+ if (read_uuid(uuid) == ISC_R_SUCCESS)
|
||||||
|
+ duid_type = DUID_UUID;
|
||||||
|
+ else
|
||||||
|
+ duid_type = stateless ? DUID_LL : DUID_LLT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (duid_type == DUID_UUID)
|
||||||
|
+ len = 2 + sizeof (uuid);
|
||||||
|
+ else {
|
||||||
|
/*
|
||||||
|
* 2 bytes for the 'duid type' field.
|
||||||
|
* 2 bytes for the 'htype' field.
|
||||||
|
@@ -3921,13 +3982,18 @@ form_duid(struct data_string *duid, cons
|
||||||
|
len = 4 + (ip->hw_address.hlen - 1);
|
||||||
|
if (duid_type == DUID_LLT)
|
||||||
|
len += 4;
|
||||||
|
+ }
|
||||||
|
if (!buffer_allocate(&duid->buffer, len, MDL))
|
||||||
|
log_fatal("no memory for default DUID!");
|
||||||
|
duid->data = duid->buffer->data;
|
||||||
|
duid->len = len;
|
||||||
|
|
||||||
|
+ if (duid_type == DUID_UUID) {
|
||||||
|
+ putUShort(duid->buffer->data, DUID_UUID);
|
||||||
|
+ memcpy(duid->buffer->data + 2, uuid, sizeof(uuid));
|
||||||
|
+ }
|
||||||
|
/* Basic Link Local Address type of DUID. */
|
||||||
|
- if (duid_type == DUID_LLT) {
|
||||||
|
+ else if (duid_type == DUID_LLT) {
|
||||||
|
putUShort(duid->buffer->data, DUID_LLT);
|
||||||
|
putUShort(duid->buffer->data + 2, ip->hw_address.hbuf[0]);
|
||||||
|
putULong(duid->buffer->data + 4, cur_time - DUID_TIME_EPOCH);
|
@ -0,0 +1,34 @@
|
|||||||
|
diff -up dhcp-4.3.1b1/client/dhclient.8.KrJcIv dhcp-4.3.1b1/client/dhclient.8
|
||||||
|
--- dhcp-4.3.1b1/client/dhclient.8.KrJcIv 2014-07-10 17:39:25.852763873 +0200
|
||||||
|
+++ dhcp-4.3.1b1/client/dhclient.8 2014-07-10 17:54:26.841012988 +0200
|
||||||
|
@@ -458,6 +458,9 @@ used to construct a RFC4361 style client
|
||||||
|
in the client's messages. This client id can be overridden by
|
||||||
|
setting a client id in the configuration file. Overridding the
|
||||||
|
client id in this fashion is discouraged.
|
||||||
|
+This option is turned on by default, if you want to redefine or turn off
|
||||||
|
+sending of client id, use send dhcp-client-identifier = "better identifier"
|
||||||
|
+or send dhcp-client-identifier = "" in /etc/dhcp/dhclient.conf.
|
||||||
|
.TP
|
||||||
|
.BI \-I
|
||||||
|
Use the standard DDNS scheme from RFCs 4701 & 4702.
|
||||||
|
diff -up dhcp-4.3.1b1/client/dhclient.c.KrJcIv dhcp-4.3.1b1/client/dhclient.c
|
||||||
|
--- dhcp-4.3.1b1/client/dhclient.c.KrJcIv 2014-07-10 17:54:26.829013157 +0200
|
||||||
|
+++ dhcp-4.3.1b1/client/dhclient.c 2014-07-10 17:55:50.155835918 +0200
|
||||||
|
@@ -73,7 +73,7 @@ struct sockaddr_in sockaddr_broadcast;
|
||||||
|
struct in_addr giaddr;
|
||||||
|
struct data_string default_duid;
|
||||||
|
int duid_type = 0;
|
||||||
|
-int duid_v4 = 0;
|
||||||
|
+int duid_v4 = 1;
|
||||||
|
int std_dhcid = 0;
|
||||||
|
|
||||||
|
/* ASSERT_STATE() does nothing now; it used to be
|
||||||
|
@@ -1301,7 +1301,7 @@ static void setup_ib_interface(struct in
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No client ID specified */
|
||||||
|
- log_fatal("dhcp-client-identifier must be specified for InfiniBand");
|
||||||
|
+ //log_fatal("dhcp-client-identifier must be specified for InfiniBand");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Individual States:
|
@ -0,0 +1,64 @@
|
|||||||
|
diff -up dhcp-4.3.5/omapip/errwarn.c.errwarn dhcp-4.3.5/omapip/errwarn.c
|
||||||
|
--- dhcp-4.3.5/omapip/errwarn.c.errwarn 2016-09-27 21:16:50.000000000 +0200
|
||||||
|
+++ dhcp-4.3.5/omapip/errwarn.c 2016-11-29 19:44:03.515031147 +0100
|
||||||
|
@@ -49,6 +49,41 @@ void (*log_cleanup) (void);
|
||||||
|
static char mbuf [CVT_BUF_MAX + 1];
|
||||||
|
static char fbuf [CVT_BUF_MAX + 1];
|
||||||
|
|
||||||
|
+// get BUG_REPORT_URL from /etc/os-release
|
||||||
|
+char * bug_report_url(void) {
|
||||||
|
+ FILE * file = fopen("/etc/os-release", "r");
|
||||||
|
+ size_t len;
|
||||||
|
+ char * line = NULL;
|
||||||
|
+ char * url = NULL;
|
||||||
|
+ size_t url_len = 256;
|
||||||
|
+
|
||||||
|
+ url = (char *) malloc(url_len * sizeof(char));
|
||||||
|
+ strcpy(url, "https://bugzilla.redhat.com/");
|
||||||
|
+
|
||||||
|
+ if (!file)
|
||||||
|
+ return url;
|
||||||
|
+
|
||||||
|
+ while ((getline(&line, &len, file)) != -1) {
|
||||||
|
+ if (strstr(line, "BUG_REPORT_URL") != NULL) {
|
||||||
|
+ char * start = strchr(line, '=');
|
||||||
|
+ char * rquotes = strrchr(line, '"');
|
||||||
|
+
|
||||||
|
+ if (rquotes != NULL) {
|
||||||
|
+ *rquotes = '\0';
|
||||||
|
+ strncpy(url, start+2, url_len);
|
||||||
|
+ } else {
|
||||||
|
+ strncpy(url, start+1, url_len);
|
||||||
|
+ }
|
||||||
|
+ url[url_len-1] = '\0';
|
||||||
|
+ fclose(file);
|
||||||
|
+ return url;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ fclose(file);
|
||||||
|
+ return url;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
/* Log an error message, then exit... */
|
||||||
|
|
||||||
|
void log_fatal (const char * fmt, ... )
|
||||||
|
@@ -75,11 +110,13 @@ void log_fatal (const char * fmt, ... )
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error ("%s", "");
|
||||||
|
- log_error ("If you think you have received this message due to a bug rather");
|
||||||
|
- log_error ("than a configuration issue please read the section on submitting");
|
||||||
|
- log_error ("bugs on either our web page at www.isc.org or in the README file");
|
||||||
|
- log_error ("before submitting a bug. These pages explain the proper");
|
||||||
|
- log_error ("process and the information we find helpful for debugging.");
|
||||||
|
+ log_error ("This version of ISC DHCP is based on the release available");
|
||||||
|
+ log_error ("on ftp.isc.org. Features have been added and other changes");
|
||||||
|
+ log_error ("have been made to the base software release in order to make");
|
||||||
|
+ log_error ("it work better with this distribution.");
|
||||||
|
+ log_error ("%s", "");
|
||||||
|
+ log_error ("Please report issues with this software via: ");
|
||||||
|
+ log_error ("%s", bug_report_url());
|
||||||
|
log_error ("%s", "");
|
||||||
|
log_error ("exiting.");
|
||||||
|
|
@ -0,0 +1,12 @@
|
|||||||
|
diff -up dhcp-4.3.0rc1/common/tables.c.garbage dhcp-4.3.0rc1/common/tables.c
|
||||||
|
--- dhcp-4.3.0rc1/common/tables.c.garbage 2014-01-29 10:03:52.132624677 +0100
|
||||||
|
+++ dhcp-4.3.0rc1/common/tables.c 2014-01-29 10:04:51.413875343 +0100
|
||||||
|
@@ -213,7 +213,7 @@ static struct option dhcp_options[] = {
|
||||||
|
{ "name-service-search", "Sa", &dhcp_universe, 117, 1 },
|
||||||
|
#endif
|
||||||
|
{ "subnet-selection", "I", &dhcp_universe, 118, 1 },
|
||||||
|
- { "domain-search", "Dc", &dhcp_universe, 119, 1 },
|
||||||
|
+ { "domain-search", "D", &dhcp_universe, 119, 1 },
|
||||||
|
{ "vivco", "Evendor-class.", &dhcp_universe, 124, 1 },
|
||||||
|
{ "vivso", "Evendor.", &dhcp_universe, 125, 1 },
|
||||||
|
#if 0
|
@ -0,0 +1,44 @@
|
|||||||
|
diff --git a/omapip/isclib.c b/omapip/isclib.c
|
||||||
|
index 9ec1a0f..42d82ff 100644
|
||||||
|
--- a/omapip/isclib.c
|
||||||
|
+++ b/omapip/isclib.c
|
||||||
|
@@ -185,16 +185,6 @@ dhcp_context_create(int flags,
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
- result = isc_app_ctxstart(dhcp_gbl_ctx.actx);
|
||||||
|
- if (result != ISC_R_SUCCESS)
|
||||||
|
- return (result);
|
||||||
|
- dhcp_gbl_ctx.actx_started = ISC_TRUE;
|
||||||
|
-
|
||||||
|
- /* Not all OSs support suppressing SIGPIPE through socket
|
||||||
|
- * options, so set the sigal action to be ignore. This allows
|
||||||
|
- * broken connections to fail gracefully with EPIPE on writes */
|
||||||
|
- handle_signal(SIGPIPE, SIG_IGN);
|
||||||
|
-
|
||||||
|
result = isc_taskmgr_createinctx(dhcp_gbl_ctx.mctx,
|
||||||
|
dhcp_gbl_ctx.actx,
|
||||||
|
1, 0,
|
||||||
|
@@ -217,6 +207,21 @@ dhcp_context_create(int flags,
|
||||||
|
result = isc_task_create(dhcp_gbl_ctx.taskmgr, 0, &dhcp_gbl_ctx.task);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
goto cleanup;
|
||||||
|
+
|
||||||
|
+ result = isc_app_ctxstart(dhcp_gbl_ctx.actx);
|
||||||
|
+ if (result != ISC_R_SUCCESS)
|
||||||
|
+ return (result);
|
||||||
|
+ dhcp_gbl_ctx.actx_started = ISC_TRUE;
|
||||||
|
+
|
||||||
|
+ /* Not all OSs support suppressing SIGPIPE through socket
|
||||||
|
+ * options, so set the sigal action to be ignore. This allows
|
||||||
|
+ * broken connections to fail gracefully with EPIPE on writes */
|
||||||
|
+ handle_signal(SIGPIPE, SIG_IGN);
|
||||||
|
+
|
||||||
|
+ /* Reset handlers installed by isc_app_ctxstart()
|
||||||
|
+ * to default for control-c and kill */
|
||||||
|
+ handle_signal(SIGINT, SIG_DFL);
|
||||||
|
+ handle_signal(SIGTERM, SIG_DFL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (NSUPDATE)
|
||||||
|
|
@ -0,0 +1,49 @@
|
|||||||
|
diff -up dhcp-4.3.0a1/client/dhc6.c.honor-expired dhcp-4.3.0a1/client/dhc6.c
|
||||||
|
--- dhcp-4.3.0a1/client/dhc6.c.honor-expired 2013-12-19 16:00:28.062183037 +0100
|
||||||
|
+++ dhcp-4.3.0a1/client/dhc6.c 2013-12-19 16:00:28.076182842 +0100
|
||||||
|
@@ -1351,6 +1351,32 @@ start_info_request6(struct client_state
|
||||||
|
go_daemon();
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Run through the addresses in lease and return true if there's any unexpired.
|
||||||
|
+ * Return false otherwise.
|
||||||
|
+ */
|
||||||
|
+isc_boolean_t
|
||||||
|
+unexpired_address_in_lease(struct dhc6_lease *lease)
|
||||||
|
+{
|
||||||
|
+ struct dhc6_ia *ia;
|
||||||
|
+ struct dhc6_addr *addr;
|
||||||
|
+
|
||||||
|
+ for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
|
||||||
|
+ for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
|
||||||
|
+ if (addr->flags & DHC6_ADDR_EXPIRED)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (addr->starts + addr->max_life > cur_time) {
|
||||||
|
+ return ISC_TRUE;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ log_info("PRC: Previous lease is devoid of active addresses."
|
||||||
|
+ " Re-initializing.");
|
||||||
|
+
|
||||||
|
+ return ISC_FALSE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* start_confirm6() kicks off an "init-reboot" version of the process, at
|
||||||
|
* startup to find out if old bindings are 'fair' and at runtime whenever
|
||||||
|
@@ -1363,8 +1389,10 @@ start_confirm6(struct client_state *clie
|
||||||
|
|
||||||
|
/* If there is no active lease, there is nothing to check. */
|
||||||
|
if ((client->active_lease == NULL) ||
|
||||||
|
- !active_prefix(client) ||
|
||||||
|
- client->active_lease->released) {
|
||||||
|
+ !active_prefix(client) ||
|
||||||
|
+ client->active_lease->released ||
|
||||||
|
+ !unexpired_address_in_lease(client->active_lease)) {
|
||||||
|
+ dhc6_lease_destroy(&client->active_lease, MDL);
|
||||||
|
start_init6(client);
|
||||||
|
return;
|
||||||
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
diff -up dhcp-4.3.4/client/dhclient.c.improved-xid dhcp-4.3.4/client/dhclient.c
|
||||||
|
--- dhcp-4.3.4/client/dhclient.c.improved-xid 2016-04-29 12:54:55.997102182 +0200
|
||||||
|
+++ dhcp-4.3.4/client/dhclient.c 2016-04-29 12:57:25.123139587 +0200
|
||||||
|
@@ -1045,6 +1045,26 @@ main(int argc, char **argv) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* We create a backup seed before rediscovering interfaces in order to
|
||||||
|
+ have a seed built using all of the available interfaces
|
||||||
|
+ It's interesting if required interfaces doesn't let us defined
|
||||||
|
+ a really unique seed due to a lack of valid HW addr later
|
||||||
|
+ (this is the case with DHCP over IB)
|
||||||
|
+ We only use the last device as using a sum could broke the
|
||||||
|
+ uniqueness of the seed among multiple nodes
|
||||||
|
+ */
|
||||||
|
+ unsigned backup_seed = 0;
|
||||||
|
+ for (ip = interfaces; ip; ip = ip -> next) {
|
||||||
|
+ int junk;
|
||||||
|
+ if ( ip -> hw_address.hlen <= sizeof seed )
|
||||||
|
+ continue;
|
||||||
|
+ memcpy (&junk,
|
||||||
|
+ &ip -> hw_address.hbuf [ip -> hw_address.hlen -
|
||||||
|
+ sizeof seed], sizeof seed);
|
||||||
|
+ backup_seed = junk;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
/* At this point, all the interfaces that the script thinks
|
||||||
|
are relevant should be running, so now we once again call
|
||||||
|
discover_interfaces(), and this time ask it to actually set
|
||||||
|
@@ -1059,14 +1079,36 @@ main(int argc, char **argv) {
|
||||||
|
Not much entropy, but we're booting, so we're not likely to
|
||||||
|
find anything better. */
|
||||||
|
seed = 0;
|
||||||
|
+ int seed_flag = 0;
|
||||||
|
for (ip = interfaces; ip; ip = ip->next) {
|
||||||
|
int junk;
|
||||||
|
+ if ( ip -> hw_address.hlen <= sizeof seed )
|
||||||
|
+ continue;
|
||||||
|
memcpy(&junk,
|
||||||
|
&ip->hw_address.hbuf[ip->hw_address.hlen -
|
||||||
|
sizeof seed], sizeof seed);
|
||||||
|
seed += junk;
|
||||||
|
+ seed_flag = 1;
|
||||||
|
}
|
||||||
|
- srandom(seed + cur_time + (unsigned)getpid());
|
||||||
|
+ if ( seed_flag == 0 ) {
|
||||||
|
+ if ( backup_seed != 0 ) {
|
||||||
|
+ seed = backup_seed;
|
||||||
|
+ log_info ("xid: rand init seed (0x%x) built using all"
|
||||||
|
+ " available interfaces",seed);
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ seed = cur_time^((unsigned) gethostid()) ;
|
||||||
|
+ log_info ("xid: warning: no netdev with useable HWADDR found"
|
||||||
|
+ " for seed's uniqueness enforcement");
|
||||||
|
+ log_info ("xid: rand init seed (0x%x) built using gethostid",
|
||||||
|
+ seed);
|
||||||
|
+ }
|
||||||
|
+ /* we only use seed and no current time as a broadcast reply */
|
||||||
|
+ /* will certainly be used by the hwaddrless interface */
|
||||||
|
+ srandom(seed + ((unsigned)(cur_tv.tv_usec * 1000000)) + (unsigned)getpid());
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ srandom(seed + ((unsigned)(cur_tv.tv_usec * 1000000)) + (unsigned)getpid());
|
||||||
|
|
||||||
|
/* Setup specific Infiniband options */
|
||||||
|
for (ip = interfaces; ip; ip = ip->next) {
|
||||||
|
@@ -1633,7 +1675,7 @@ void dhcpack (packet)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- log_info ("DHCPACK from %s", piaddr (packet -> client_addr));
|
||||||
|
+ log_info ("DHCPACK from %s (xid=0x%x)", piaddr (packet -> client_addr), ntohl(client -> xid));
|
||||||
|
|
||||||
|
lease = packet_to_lease (packet, client);
|
||||||
|
if (!lease) {
|
||||||
|
@@ -2541,7 +2583,7 @@ void dhcpnak (packet)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));
|
||||||
|
+ log_info ("DHCPNAK from %s (xid=0x%x)", piaddr (packet -> client_addr), ntohl(client -> xid));
|
||||||
|
|
||||||
|
if (!client -> active) {
|
||||||
|
#if defined (DEBUG)
|
||||||
|
@@ -2674,10 +2716,10 @@ void send_discover (cpp)
|
||||||
|
(long)(client -> interval));
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
- log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
|
||||||
|
+ log_info ("DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)",
|
||||||
|
client -> name ? client -> name : client -> interface -> name,
|
||||||
|
inet_ntoa (sockaddr_broadcast.sin_addr),
|
||||||
|
- ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));
|
||||||
|
+ ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval), ntohl(client -> xid));
|
||||||
|
|
||||||
|
/* Send out a packet. */
|
||||||
|
#if defined(DHCPv6) && defined(DHCP4o6)
|
||||||
|
@@ -2962,10 +3004,10 @@ void send_request (cpp)
|
||||||
|
log_info ("DHCPREQUEST");
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
- log_info ("DHCPREQUEST on %s to %s port %d",
|
||||||
|
+ log_info ("DHCPREQUEST on %s to %s port %d (xid=0x%x)",
|
||||||
|
client -> name ? client -> name : client -> interface -> name,
|
||||||
|
inet_ntoa (destination.sin_addr),
|
||||||
|
- ntohs (destination.sin_port));
|
||||||
|
+ ntohs (destination.sin_port), ntohl(client -> xid));
|
||||||
|
|
||||||
|
#if defined(DHCPv6) && defined(DHCP4o6)
|
||||||
|
if (dhcpv4_over_dhcpv6) {
|
||||||
|
@@ -3022,10 +3064,10 @@ void send_decline (cpp)
|
||||||
|
log_info ("DHCPDECLINE");
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
- log_info ("DHCPDECLINE on %s to %s port %d",
|
||||||
|
+ log_info ("DHCPDECLINE on %s to %s port %d (xid=0x%x)",
|
||||||
|
client->name ? client->name : client->interface->name,
|
||||||
|
inet_ntoa(sockaddr_broadcast.sin_addr),
|
||||||
|
- ntohs(sockaddr_broadcast.sin_port));
|
||||||
|
+ ntohs(sockaddr_broadcast.sin_port), ntohl(client -> xid));
|
||||||
|
|
||||||
|
/* Send out a packet. */
|
||||||
|
#if defined(DHCPv6) && defined(DHCP4o6)
|
||||||
|
@@ -3084,10 +3126,10 @@ void send_release (cpp)
|
||||||
|
log_info ("DHCPRELEASE");
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
- log_info ("DHCPRELEASE on %s to %s port %d",
|
||||||
|
+ log_info ("DHCPRELEASE on %s to %s port %d (xid=0x%x)",
|
||||||
|
client -> name ? client -> name : client -> interface -> name,
|
||||||
|
inet_ntoa (destination.sin_addr),
|
||||||
|
- ntohs (destination.sin_port));
|
||||||
|
+ ntohs (destination.sin_port), ntohl(client -> xid));
|
||||||
|
|
||||||
|
#if defined(DHCPv6) && defined(DHCP4o6)
|
||||||
|
if (dhcpv4_over_dhcpv6) {
|
@ -0,0 +1,164 @@
|
|||||||
|
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
|
||||||
|
index aac2c108..c83dc9a6 100644
|
||||||
|
--- a/includes/dhcpd.h
|
||||||
|
+++ b/includes/dhcpd.h
|
||||||
|
@@ -1622,8 +1622,9 @@ struct iasubopt {
|
||||||
|
*/
|
||||||
|
#define EXPIRED_IPV6_CLEANUP_TIME (60*60)
|
||||||
|
|
||||||
|
- int heap_index; /* index into heap, or -1
|
||||||
|
- (internal use only) */
|
||||||
|
+ /* index into heaps, or -1 (internal use only) */
|
||||||
|
+ int active_index;
|
||||||
|
+ int inactive_index;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A pointer to the state of the ddns update for this lease.
|
||||||
|
diff --git a/server/mdb6.c b/server/mdb6.c
|
||||||
|
index 1a728eb3..418ff606 100644
|
||||||
|
--- a/server/mdb6.c
|
||||||
|
+++ b/server/mdb6.c
|
||||||
|
@@ -216,7 +216,8 @@ iasubopt_allocate(struct iasubopt **iasubopt, const char *file, int line) {
|
||||||
|
|
||||||
|
tmp->refcnt = 1;
|
||||||
|
tmp->state = FTS_FREE;
|
||||||
|
- tmp->heap_index = -1;
|
||||||
|
+ tmp->active_index = -1;
|
||||||
|
+ tmp->inactive_index = -1;
|
||||||
|
tmp->plen = 255;
|
||||||
|
|
||||||
|
*iasubopt = tmp;
|
||||||
|
@@ -604,10 +605,14 @@ lease_older(void *a, void *b) {
|
||||||
|
* Callback when an address's position in the heap changes.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
-lease_index_changed(void *iasubopt, unsigned int new_heap_index) {
|
||||||
|
- ((struct iasubopt *)iasubopt)-> heap_index = new_heap_index;
|
||||||
|
+active_changed(void *iasubopt, unsigned int new_heap_index) {
|
||||||
|
+ ((struct iasubopt *)iasubopt)-> active_index = new_heap_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+inactive_changed(void *iasubopt, unsigned int new_heap_index) {
|
||||||
|
+ ((struct iasubopt *)iasubopt)-> inactive_index = new_heap_index;
|
||||||
|
+}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
@@ -660,13 +665,13 @@ ipv6_pool_allocate(struct ipv6_pool **pool, u_int16_t type,
|
||||||
|
dfree(tmp, file, line);
|
||||||
|
return ISC_R_NOMEMORY;
|
||||||
|
}
|
||||||
|
- if (isc_heap_create(dhcp_gbl_ctx.mctx, lease_older, lease_index_changed,
|
||||||
|
+ if (isc_heap_create(dhcp_gbl_ctx.mctx, lease_older, active_changed,
|
||||||
|
0, &(tmp->active_timeouts)) != ISC_R_SUCCESS) {
|
||||||
|
iasubopt_free_hash_table(&(tmp->leases), file, line);
|
||||||
|
dfree(tmp, file, line);
|
||||||
|
return ISC_R_NOMEMORY;
|
||||||
|
}
|
||||||
|
- if (isc_heap_create(dhcp_gbl_ctx.mctx, lease_older, lease_index_changed,
|
||||||
|
+ if (isc_heap_create(dhcp_gbl_ctx.mctx, lease_older, inactive_changed,
|
||||||
|
0, &(tmp->inactive_timeouts)) != ISC_R_SUCCESS) {
|
||||||
|
isc_heap_destroy(&(tmp->active_timeouts));
|
||||||
|
iasubopt_free_hash_table(&(tmp->leases), file, line);
|
||||||
|
@@ -1361,7 +1366,7 @@ cleanup_lease6(ia_hash_t *ia_table,
|
||||||
|
* Remove the old lease from the active heap and from the hash table
|
||||||
|
* then remove the lease from the IA and clean up the IA if necessary.
|
||||||
|
*/
|
||||||
|
- isc_heap_delete(pool->active_timeouts, test_iasubopt->heap_index);
|
||||||
|
+ isc_heap_delete(pool->active_timeouts, test_iasubopt->active_index);
|
||||||
|
pool->num_active--;
|
||||||
|
if (pool->ipv6_pond)
|
||||||
|
pool->ipv6_pond->num_active--;
|
||||||
|
@@ -1434,7 +1439,7 @@ add_lease6(struct ipv6_pool *pool, struct iasubopt *lease,
|
||||||
|
if ((test_iasubopt->state == FTS_ACTIVE) ||
|
||||||
|
(test_iasubopt->state == FTS_ABANDONED)) {
|
||||||
|
isc_heap_delete(pool->active_timeouts,
|
||||||
|
- test_iasubopt->heap_index);
|
||||||
|
+ test_iasubopt->active_index);
|
||||||
|
pool->num_active--;
|
||||||
|
if (pool->ipv6_pond)
|
||||||
|
pool->ipv6_pond->num_active--;
|
||||||
|
@@ -1446,7 +1451,7 @@ add_lease6(struct ipv6_pool *pool, struct iasubopt *lease,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
isc_heap_delete(pool->inactive_timeouts,
|
||||||
|
- test_iasubopt->heap_index);
|
||||||
|
+ test_iasubopt->inactive_index);
|
||||||
|
pool->num_inactive--;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1567,14 +1572,13 @@ lease6_usable(struct iasubopt *lease) {
|
||||||
|
static isc_result_t
|
||||||
|
move_lease_to_active(struct ipv6_pool *pool, struct iasubopt *lease) {
|
||||||
|
isc_result_t insert_result;
|
||||||
|
- int old_heap_index;
|
||||||
|
|
||||||
|
- old_heap_index = lease->heap_index;
|
||||||
|
insert_result = isc_heap_insert(pool->active_timeouts, lease);
|
||||||
|
if (insert_result == ISC_R_SUCCESS) {
|
||||||
|
iasubopt_hash_add(pool->leases, &lease->addr,
|
||||||
|
sizeof(lease->addr), lease, MDL);
|
||||||
|
- isc_heap_delete(pool->inactive_timeouts, old_heap_index);
|
||||||
|
+ isc_heap_delete(pool->inactive_timeouts,
|
||||||
|
+ lease->inactive_index);
|
||||||
|
pool->num_active++;
|
||||||
|
pool->num_inactive--;
|
||||||
|
lease->state = FTS_ACTIVE;
|
||||||
|
@@ -1624,16 +1628,16 @@ renew_lease6(struct ipv6_pool *pool, struct iasubopt *lease) {
|
||||||
|
if (lease->state == FTS_ACTIVE) {
|
||||||
|
if (old_end_time <= lease->hard_lifetime_end_time) {
|
||||||
|
isc_heap_decreased(pool->active_timeouts,
|
||||||
|
- lease->heap_index);
|
||||||
|
+ lease->active_index);
|
||||||
|
} else {
|
||||||
|
isc_heap_increased(pool->active_timeouts,
|
||||||
|
- lease->heap_index);
|
||||||
|
+ lease->active_index);
|
||||||
|
}
|
||||||
|
return ISC_R_SUCCESS;
|
||||||
|
} else if (lease->state == FTS_ABANDONED) {
|
||||||
|
char tmp_addr[INET6_ADDRSTRLEN];
|
||||||
|
lease->state = FTS_ACTIVE;
|
||||||
|
- isc_heap_increased(pool->active_timeouts, lease->heap_index);
|
||||||
|
+ isc_heap_increased(pool->active_timeouts, lease->active_index);
|
||||||
|
log_info("Reclaiming previously abandoned address %s",
|
||||||
|
inet_ntop(AF_INET6, &(lease->addr), tmp_addr,
|
||||||
|
sizeof(tmp_addr)));
|
||||||
|
@@ -1655,9 +1659,7 @@ static isc_result_t
|
||||||
|
move_lease_to_inactive(struct ipv6_pool *pool, struct iasubopt *lease,
|
||||||
|
binding_state_t state) {
|
||||||
|
isc_result_t insert_result;
|
||||||
|
- int old_heap_index;
|
||||||
|
|
||||||
|
- old_heap_index = lease->heap_index;
|
||||||
|
insert_result = isc_heap_insert(pool->inactive_timeouts, lease);
|
||||||
|
if (insert_result == ISC_R_SUCCESS) {
|
||||||
|
/*
|
||||||
|
@@ -1708,7 +1710,7 @@ move_lease_to_inactive(struct ipv6_pool *pool, struct iasubopt *lease,
|
||||||
|
|
||||||
|
iasubopt_hash_delete(pool->leases,
|
||||||
|
&lease->addr, sizeof(lease->addr), MDL);
|
||||||
|
- isc_heap_delete(pool->active_timeouts, old_heap_index);
|
||||||
|
+ isc_heap_delete(pool->active_timeouts, lease->active_index);
|
||||||
|
lease->state = state;
|
||||||
|
pool->num_active--;
|
||||||
|
pool->num_inactive++;
|
||||||
|
@@ -1786,7 +1788,7 @@ decline_lease6(struct ipv6_pool *pool, struct iasubopt *lease) {
|
||||||
|
pool->ipv6_pond->num_abandoned++;
|
||||||
|
|
||||||
|
lease->hard_lifetime_end_time = MAX_TIME;
|
||||||
|
- isc_heap_decreased(pool->active_timeouts, lease->heap_index);
|
||||||
|
+ isc_heap_decreased(pool->active_timeouts, lease->active_index);
|
||||||
|
return ISC_R_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2059,7 +2061,7 @@ cleanup_old_expired(struct ipv6_pool *pool) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- isc_heap_delete(pool->inactive_timeouts, tmp->heap_index);
|
||||||
|
+ isc_heap_delete(pool->inactive_timeouts, tmp->inactive_index);
|
||||||
|
pool->num_inactive--;
|
||||||
|
|
||||||
|
if (tmp->ia != NULL) {
|
@ -0,0 +1,200 @@
|
|||||||
|
From e6ffc27f24321017a5ad9af3707f4e2e54bbac74 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Markwalder <tmark@isc.org>
|
||||||
|
Date: Mon, 11 Dec 2017 07:19:43 -0500
|
||||||
|
Subject: [PATCH] [master] Adds key-algorithm statement to omshell
|
||||||
|
|
||||||
|
Merges in rt46771.
|
||||||
|
---
|
||||||
|
RELNOTES | 7 +++++++
|
||||||
|
common/conflex.c | 2 ++
|
||||||
|
dhcpctl/omshell.1 | 32 ++++++++++++++++++++++++--------
|
||||||
|
dhcpctl/omshell.c | 38 +++++++++++++++++++++++++++++++++++---
|
||||||
|
includes/dhctoken.h | 3 ++-
|
||||||
|
5 files changed, 70 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/common/conflex.c b/common/conflex.c
|
||||||
|
index 8ce024af..045b655d 100644
|
||||||
|
--- a/common/conflex.c
|
||||||
|
+++ b/common/conflex.c
|
||||||
|
@@ -1104,6 +1104,8 @@ intern(char *atom, enum dhcp_token dfv) {
|
||||||
|
}
|
||||||
|
if (!strcasecmp (atom + 1, "ey"))
|
||||||
|
return KEY;
|
||||||
|
+ if (!strcasecmp (atom + 1, "ey-algorithm"))
|
||||||
|
+ return KEY_ALGORITHM;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
if (!strcasecmp (atom + 1, "case"))
|
||||||
|
diff --git a/dhcpctl/omshell.1 b/dhcpctl/omshell.1
|
||||||
|
index 4846272a..2f55e965 100644
|
||||||
|
--- a/dhcpctl/omshell.1
|
||||||
|
+++ b/dhcpctl/omshell.1
|
||||||
|
@@ -1,7 +1,6 @@
|
||||||
|
.\" $Id: omshell.1,v 1.6 2009/11/24 02:06:56 sar Exp $
|
||||||
|
.\"
|
||||||
|
-.\" Copyright (c) 2012,2014 by Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
-.\" Copyright (c) 2004,2009 by Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
+.\" Copyright (c) 2004-2017 by Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
.\" Copyright (c) 2001-2003 by Internet Software Consortium
|
||||||
|
.\"
|
||||||
|
.\" Permission to use, copy, modify, and distribute this software for any
|
||||||
|
@@ -81,7 +80,24 @@ where number is the port that OMAPI listens on. By default, this is 7911.
|
||||||
|
This specifies the TSIG key to use to authenticate the OMAPI transactions.
|
||||||
|
\fIname\fR is the name of a key defined in \fIdhcpd.conf\fR with the
|
||||||
|
\fBomapi-key\fR statement. The \fIsecret\fR is the secret key generated from
|
||||||
|
-\fBdnssec-keygen\fR or another key generation program.
|
||||||
|
+\fBdnssec-keygen\fR or another key generation program. The key algorithm is
|
||||||
|
+assumed to be HMAC-MD5 key. If a different algorithm was specified in dhcpd.conf
|
||||||
|
+file for the key, then it must be specified via the \fIkey-algorithm\fR statement.
|
||||||
|
+.RE
|
||||||
|
+.PP
|
||||||
|
+.B key-algorithm \fIalgorithm\fR
|
||||||
|
+.RS 0.5i
|
||||||
|
+This specifies the cryptographic algorithm for the key used when authenticating OMAPI
|
||||||
|
+transactions. Supported values for \fIalgorithm\fR are:
|
||||||
|
+.nf
|
||||||
|
+ HMAC-MD5
|
||||||
|
+ HMAC-SHA1
|
||||||
|
+ HMAC-SHA224
|
||||||
|
+ HMAC-SHA256
|
||||||
|
+ HMAC-SHA384
|
||||||
|
+ HMAC-SHA512
|
||||||
|
+fi
|
||||||
|
+The default is HMAC-MD5. (Value is not case sensitive).
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
.B connect
|
||||||
|
@@ -253,7 +269,7 @@ name = "some-host"
|
||||||
|
hardware-address = 00:80:c7:84:b1:94
|
||||||
|
hardware-type = 00:00:00:01
|
||||||
|
ip-address = c0:a8:04:28
|
||||||
|
->
|
||||||
|
+>
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
Your dhcpd.leases file would then have an entry like this in it:
|
||||||
|
@@ -267,7 +283,7 @@ host some-host {
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
The \fIdynamic;\fR line is to denote that this host entry did not come from
|
||||||
|
-dhcpd.conf, but was created dynamically via OMAPI.
|
||||||
|
+dhcpd.conf, but was created dynamically via OMAPI.
|
||||||
|
.SH RESETTING ATTRIBUTES
|
||||||
|
.PP
|
||||||
|
If you want to remove an attribute from an object, you can do this with the
|
||||||
|
@@ -288,7 +304,7 @@ name = "some-host"
|
||||||
|
hardware-address = 00:80:c7:84:b1:94
|
||||||
|
hardware-type = 00:00:00:01
|
||||||
|
ip-address = <null>
|
||||||
|
->
|
||||||
|
+>
|
||||||
|
.fi
|
||||||
|
.SH REFRESHING OBJECTS
|
||||||
|
.PP
|
||||||
|
@@ -300,7 +316,7 @@ particularly useful for hosts.
|
||||||
|
.PP
|
||||||
|
Any remote object that can be created can also be destroyed. This is done by
|
||||||
|
creating a new local object, setting attributes, associating the local and
|
||||||
|
-remote object using \fBopen\fR, and then using the \fBremove\fR command.
|
||||||
|
+remote object using \fBopen\fR, and then using the \fBremove\fR command.
|
||||||
|
If the host "some-host" from before was created in error, this could be
|
||||||
|
corrected as follows:
|
||||||
|
.nf
|
||||||
|
@@ -312,7 +328,7 @@ hardware-type = 00:00:00:01
|
||||||
|
ip-address = c0:a8:04:28
|
||||||
|
> remove
|
||||||
|
obj: <null>
|
||||||
|
->
|
||||||
|
+>
|
||||||
|
.fi
|
||||||
|
.SH HELP
|
||||||
|
.PP
|
||||||
|
diff --git a/dhcpctl/omshell.c b/dhcpctl/omshell.c
|
||||||
|
index c42bab1a..9233f50e 100644
|
||||||
|
--- a/dhcpctl/omshell.c
|
||||||
|
+++ b/dhcpctl/omshell.c
|
||||||
|
@@ -321,12 +321,42 @@ main(int argc, char **argv) {
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
+ case KEY_ALGORITHM:
|
||||||
|
+ /* Algorithm is optional */
|
||||||
|
+ token = next_token (&val, (unsigned *)0, cfile);
|
||||||
|
+ if (token != NAME || !is_identifier(token)) {
|
||||||
|
+ printf ("missing or invalid algorithm name\n");
|
||||||
|
+ printf ("usage: key-algoritm <algorithm name>\n");
|
||||||
|
+ skip_to_semi (cfile);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ s = dmalloc (strlen (val) + 1, MDL);
|
||||||
|
+ if (!s) {
|
||||||
|
+ printf ("no memory for algorithm name.\n");
|
||||||
|
+ skip_to_semi (cfile);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ strcpy (s, val);
|
||||||
|
+ algorithm = s;
|
||||||
|
+
|
||||||
|
+ token = next_token (&val, (unsigned *)0, cfile);
|
||||||
|
+ if (token != END_OF_FILE && token != EOL) {
|
||||||
|
+ printf ("extra information after %s\n", algorithm);
|
||||||
|
+ printf ("usage: key-algorithm <algorithm name>\n");
|
||||||
|
+ skip_to_semi (cfile);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
case KEY:
|
||||||
|
token = peek_token(&val, (unsigned *)0, cfile);
|
||||||
|
if (token == STRING) {
|
||||||
|
token = next_token (&val, (unsigned *)0, cfile);
|
||||||
|
if (!is_identifier (token)) {
|
||||||
|
- printf ("usage: key <name> <value>\n");
|
||||||
|
+ printf ("usage: key <name> <value>\n");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -340,7 +370,7 @@ main(int argc, char **argv) {
|
||||||
|
} else {
|
||||||
|
s = parse_host_name(cfile);
|
||||||
|
if (s == NULL) {
|
||||||
|
- printf ("usage: key <name> <value>\n");
|
||||||
|
+ printf ("usage: key <name> <value>\n");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -352,12 +382,14 @@ main(int argc, char **argv) {
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
token = next_token (&val, (unsigned *)0, cfile);
|
||||||
|
if (token != END_OF_FILE && token != EOL) {
|
||||||
|
- printf ("usage: key <name> <secret>\n");
|
||||||
|
+ printf ("usage: key <name> <value> {algorithm}\n");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CONNECT:
|
||||||
|
diff --git a/includes/dhctoken.h b/includes/dhctoken.h
|
||||||
|
index 6fc4df3..ca24d4c 100644
|
||||||
|
--- a/includes/dhctoken.h
|
||||||
|
+++ b/includes/dhctoken.h
|
||||||
|
@@ -374,8 +374,9 @@ enum dhcp_token {
|
||||||
|
LEASE_ID_FORMAT = 676,
|
||||||
|
TOKEN_HEX = 677,
|
||||||
|
TOKEN_OCTAL = 678,
|
||||||
|
- BOOTP_BROADCAST_ALWAYS = 679,
|
||||||
|
- DESTINATION_DESCRIPTOR = 680
|
||||||
|
+ KEY_ALGORITHM = 679,
|
||||||
|
+ BOOTP_BROADCAST_ALWAYS = 680,
|
||||||
|
+ DESTINATION_DESCRIPTOR = 681
|
||||||
|
};
|
||||||
|
|
||||||
|
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
|
@ -0,0 +1,614 @@
|
|||||||
|
diff -up dhcp-4.3.4/client/dhclient.c.lpf-ib dhcp-4.3.4/client/dhclient.c
|
||||||
|
--- dhcp-4.3.4/client/dhclient.c.lpf-ib 2016-05-02 14:37:36.945128001 +0200
|
||||||
|
+++ dhcp-4.3.4/client/dhclient.c 2016-05-02 14:37:36.952128005 +0200
|
||||||
|
@@ -163,6 +163,8 @@ static const char use_noarg[] = "No argu
|
||||||
|
static const char use_v6command[] = "Command not used for DHCPv4: %s";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+static void setup_ib_interface(struct interface_info *ip);
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
usage(const char *sfmt, const char *sarg)
|
||||||
|
{
|
||||||
|
@@ -1066,6 +1068,13 @@ main(int argc, char **argv) {
|
||||||
|
}
|
||||||
|
srandom(seed + cur_time + (unsigned)getpid());
|
||||||
|
|
||||||
|
+ /* Setup specific Infiniband options */
|
||||||
|
+ for (ip = interfaces; ip; ip = ip->next) {
|
||||||
|
+ if (ip->client &&
|
||||||
|
+ (ip->hw_address.hbuf[0] == HTYPE_INFINIBAND)) {
|
||||||
|
+ setup_ib_interface(ip);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Establish a default DUID. We always do so for v6 and
|
||||||
|
@@ -1361,6 +1370,29 @@ int find_subnet (struct subnet **sp,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void setup_ib_interface(struct interface_info *ip)
|
||||||
|
+{
|
||||||
|
+ struct group *g;
|
||||||
|
+
|
||||||
|
+ /* Set the broadcast flag */
|
||||||
|
+ ip->client->config->bootp_broadcast_always = 1;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Find out if a dhcp-client-identifier option was specified either
|
||||||
|
+ * in the config file or on the command line
|
||||||
|
+ */
|
||||||
|
+ for (g = ip->client->config->on_transmission; g != NULL; g = g->next) {
|
||||||
|
+ if ((g->statements != NULL) &&
|
||||||
|
+ (strcmp(g->statements->data.option->option->name,
|
||||||
|
+ "dhcp-client-identifier") == 0)) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* No client ID specified */
|
||||||
|
+ log_fatal("dhcp-client-identifier must be specified for InfiniBand");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Individual States:
|
||||||
|
*
|
||||||
|
* Each routine is called from the dhclient_state_machine() in one of
|
||||||
|
diff -up dhcp-4.3.4/common/bpf.c.lpf-ib dhcp-4.3.4/common/bpf.c
|
||||||
|
--- dhcp-4.3.4/common/bpf.c.lpf-ib 2016-05-02 14:37:36.946128001 +0200
|
||||||
|
+++ dhcp-4.3.4/common/bpf.c 2016-05-02 14:37:36.952128005 +0200
|
||||||
|
@@ -198,11 +198,43 @@ struct bpf_insn dhcp_bpf_filter [] = {
|
||||||
|
BPF_STMT(BPF_RET+BPF_K, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
+/* Packet filter program for DHCP over Infiniband.
|
||||||
|
+ *
|
||||||
|
+ * XXX
|
||||||
|
+ * Changes to the filter program may require changes to the constant offsets
|
||||||
|
+ * used in lpf_gen_filter_setup to patch the port in the BPF program!
|
||||||
|
+ * XXX
|
||||||
|
+ */
|
||||||
|
+struct bpf_insn dhcp_ib_bpf_filter [] = {
|
||||||
|
+ /* Packet filter for Infiniband */
|
||||||
|
+ /* Make sure it's a UDP packet... */
|
||||||
|
+ BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 9),
|
||||||
|
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
|
||||||
|
+
|
||||||
|
+ /* Make sure this isn't a fragment... */
|
||||||
|
+ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 6),
|
||||||
|
+ BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
|
||||||
|
+
|
||||||
|
+ /* Get the IP header length... */
|
||||||
|
+ BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 0),
|
||||||
|
+
|
||||||
|
+ /* Make sure it's to the right port... */
|
||||||
|
+ BPF_STMT(BPF_LD + BPF_H + BPF_IND, 2),
|
||||||
|
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),
|
||||||
|
+
|
||||||
|
+ /* If we passed all the tests, ask for the whole packet. */
|
||||||
|
+ BPF_STMT(BPF_RET + BPF_K, (u_int)-1),
|
||||||
|
+
|
||||||
|
+ /* Otherwise, drop it. */
|
||||||
|
+ BPF_STMT(BPF_RET + BPF_K, 0),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
#if defined (DEC_FDDI)
|
||||||
|
struct bpf_insn *bpf_fddi_filter = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
|
||||||
|
+int dhcp_ib_bpf_filter_len = sizeof dhcp_ib_bpf_filter / sizeof (struct bpf_insn);
|
||||||
|
#if defined (HAVE_TR_SUPPORT)
|
||||||
|
struct bpf_insn dhcp_bpf_tr_filter [] = {
|
||||||
|
/* accept all token ring packets due to variable length header */
|
||||||
|
diff -up dhcp-4.3.4/common/discover.c.lpf-ib dhcp-4.3.4/common/discover.c
|
||||||
|
--- dhcp-4.3.4/common/discover.c.lpf-ib 2016-03-22 14:16:51.000000000 +0100
|
||||||
|
+++ dhcp-4.3.4/common/discover.c 2016-05-02 14:38:08.257147982 +0200
|
||||||
|
@@ -1235,7 +1235,7 @@ discover_interfaces(int state) {
|
||||||
|
if_register_send(tmp);
|
||||||
|
} else {
|
||||||
|
/* get_hw_addr() was called by register. */
|
||||||
|
- get_hw_addr(tmp->name, &tmp->hw_address);
|
||||||
|
+ get_hw_addr(tmp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#ifdef DHCPv6
|
||||||
|
@@ -1248,7 +1248,7 @@ discover_interfaces(int state) {
|
||||||
|
so now we have to call it explicitly
|
||||||
|
to not leave the hardware address unknown
|
||||||
|
(some code expects it cannot be. */
|
||||||
|
- get_hw_addr(tmp->name, &tmp->hw_address);
|
||||||
|
+ get_hw_addr(tmp);
|
||||||
|
} else {
|
||||||
|
if_register_linklocal6(tmp);
|
||||||
|
}
|
||||||
|
diff -up dhcp-4.3.4/common/lpf.c.lpf-ib dhcp-4.3.4/common/lpf.c
|
||||||
|
--- dhcp-4.3.4/common/lpf.c.lpf-ib 2016-05-02 14:37:36.947128002 +0200
|
||||||
|
+++ dhcp-4.3.4/common/lpf.c 2016-05-02 14:37:36.953128006 +0200
|
||||||
|
@@ -47,6 +47,17 @@
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
+#include <ifaddrs.h>
|
||||||
|
+
|
||||||
|
+/* Default broadcast address for IPoIB */
|
||||||
|
+static unsigned char default_ib_bcast_addr[20] = {
|
||||||
|
+ 0x00, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0x12, 0x40, 0x1b,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)
|
||||||
|
@@ -80,10 +91,20 @@ int if_register_lpf (info)
|
||||||
|
struct sockaddr common;
|
||||||
|
} sa;
|
||||||
|
struct ifreq ifr;
|
||||||
|
+ int type;
|
||||||
|
+ int protocol;
|
||||||
|
+
|
||||||
|
+ get_hw_addr(info);
|
||||||
|
+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
|
||||||
|
+ type = SOCK_DGRAM;
|
||||||
|
+ protocol = ETHERTYPE_IP;
|
||||||
|
+ } else {
|
||||||
|
+ type = SOCK_RAW;
|
||||||
|
+ protocol = ETH_P_ALL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* Make an LPF socket. */
|
||||||
|
- if ((sock = socket(PF_PACKET, SOCK_RAW,
|
||||||
|
- htons((short)ETH_P_ALL))) < 0) {
|
||||||
|
+ if ((sock = socket(PF_PACKET, type, htons((short)protocol))) < 0) {
|
||||||
|
if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
|
||||||
|
errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
|
||||||
|
errno == EAFNOSUPPORT || errno == EINVAL) {
|
||||||
|
@@ -106,6 +127,7 @@ int if_register_lpf (info)
|
||||||
|
/* Bind to the interface name */
|
||||||
|
memset (&sa, 0, sizeof sa);
|
||||||
|
sa.ll.sll_family = AF_PACKET;
|
||||||
|
+ sa.ll.sll_protocol = htons(protocol);
|
||||||
|
sa.ll.sll_ifindex = ifr.ifr_ifindex;
|
||||||
|
if (bind (sock, &sa.common, sizeof sa)) {
|
||||||
|
if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
|
||||||
|
@@ -122,8 +144,6 @@ int if_register_lpf (info)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- get_hw_addr(info->name, &info->hw_address);
|
||||||
|
-
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
|
#endif /* USE_LPF_SEND || USE_LPF_RECEIVE */
|
||||||
|
@@ -178,6 +198,8 @@ void if_deregister_send (info)
|
||||||
|
in bpf includes... */
|
||||||
|
extern struct sock_filter dhcp_bpf_filter [];
|
||||||
|
extern int dhcp_bpf_filter_len;
|
||||||
|
+extern struct sock_filter dhcp_ib_bpf_filter [];
|
||||||
|
+extern int dhcp_ib_bpf_filter_len;
|
||||||
|
|
||||||
|
#if defined (HAVE_TR_SUPPORT)
|
||||||
|
extern struct sock_filter dhcp_bpf_tr_filter [];
|
||||||
|
@@ -196,11 +218,12 @@ void if_register_receive (info)
|
||||||
|
#ifdef PACKET_AUXDATA
|
||||||
|
{
|
||||||
|
int val = 1;
|
||||||
|
-
|
||||||
|
- if (setsockopt(info->rfdesc, SOL_PACKET, PACKET_AUXDATA,
|
||||||
|
- &val, sizeof(val)) < 0) {
|
||||||
|
- if (errno != ENOPROTOOPT) {
|
||||||
|
- log_fatal ("Failed to set auxiliary packet data: %m");
|
||||||
|
+ if (info->hw_address.hbuf[0] != HTYPE_INFINIBAND) {
|
||||||
|
+ if (setsockopt(info->rfdesc, SOL_PACKET, PACKET_AUXDATA,
|
||||||
|
+ &val, sizeof(val)) < 0) {
|
||||||
|
+ if (errno != ENOPROTOOPT) {
|
||||||
|
+ log_fatal ("Failed to set auxiliary packet data: %m");
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -250,15 +273,28 @@ static void lpf_gen_filter_setup (info)
|
||||||
|
|
||||||
|
memset(&p, 0, sizeof(p));
|
||||||
|
|
||||||
|
- /* Set up the bpf filter program structure. This is defined in
|
||||||
|
- bpf.c */
|
||||||
|
- p.len = dhcp_bpf_filter_len;
|
||||||
|
- p.filter = dhcp_bpf_filter;
|
||||||
|
-
|
||||||
|
- /* Patch the server port into the LPF program...
|
||||||
|
- XXX changes to filter program may require changes
|
||||||
|
- to the insn number(s) used below! XXX */
|
||||||
|
- dhcp_bpf_filter [8].k = ntohs ((short)local_port);
|
||||||
|
+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
|
||||||
|
+ /* Set up the bpf filter program structure. */
|
||||||
|
+ p.len = dhcp_ib_bpf_filter_len;
|
||||||
|
+ p.filter = dhcp_ib_bpf_filter;
|
||||||
|
+
|
||||||
|
+ /* Patch the server port into the LPF program...
|
||||||
|
+ XXX
|
||||||
|
+ changes to filter program may require changes
|
||||||
|
+ to the insn number(s) used below!
|
||||||
|
+ XXX */
|
||||||
|
+ dhcp_ib_bpf_filter[6].k = ntohs ((short)local_port);
|
||||||
|
+ } else {
|
||||||
|
+ /* Set up the bpf filter program structure.
|
||||||
|
+ This is defined in bpf.c */
|
||||||
|
+ p.len = dhcp_bpf_filter_len;
|
||||||
|
+ p.filter = dhcp_bpf_filter;
|
||||||
|
+
|
||||||
|
+ /* Patch the server port into the LPF program...
|
||||||
|
+ XXX changes to filter program may require changes
|
||||||
|
+ to the insn number(s) used below! XXX */
|
||||||
|
+ dhcp_bpf_filter [8].k = ntohs ((short)local_port);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
|
||||||
|
sizeof p) < 0) {
|
||||||
|
@@ -315,6 +351,54 @@ static void lpf_tr_filter_setup (info)
|
||||||
|
#endif /* USE_LPF_RECEIVE */
|
||||||
|
|
||||||
|
#ifdef USE_LPF_SEND
|
||||||
|
+ssize_t send_packet_ib(interface, packet, raw, len, from, to, hto)
|
||||||
|
+ struct interface_info *interface;
|
||||||
|
+ struct packet *packet;
|
||||||
|
+ struct dhcp_packet *raw;
|
||||||
|
+ size_t len;
|
||||||
|
+ struct in_addr from;
|
||||||
|
+ struct sockaddr_in *to;
|
||||||
|
+ struct hardware *hto;
|
||||||
|
+{
|
||||||
|
+ unsigned ibufp = 0;
|
||||||
|
+ double ih [1536 / sizeof (double)];
|
||||||
|
+ unsigned char *buf = (unsigned char *)ih;
|
||||||
|
+ ssize_t result;
|
||||||
|
+
|
||||||
|
+ union sockunion {
|
||||||
|
+ struct sockaddr sa;
|
||||||
|
+ struct sockaddr_ll sll;
|
||||||
|
+ struct sockaddr_storage ss;
|
||||||
|
+ } su;
|
||||||
|
+
|
||||||
|
+ assemble_udp_ip_header (interface, buf, &ibufp, from.s_addr,
|
||||||
|
+ to->sin_addr.s_addr, to->sin_port,
|
||||||
|
+ (unsigned char *)raw, len);
|
||||||
|
+ memcpy (buf + ibufp, raw, len);
|
||||||
|
+
|
||||||
|
+ memset(&su, 0, sizeof(su));
|
||||||
|
+ su.sll.sll_family = AF_PACKET;
|
||||||
|
+ su.sll.sll_protocol = htons(ETHERTYPE_IP);
|
||||||
|
+
|
||||||
|
+ if (!(su.sll.sll_ifindex = if_nametoindex(interface->name))) {
|
||||||
|
+ errno = ENOENT;
|
||||||
|
+ log_error ("send_packet_ib: %m - failed to get if index");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ su.sll.sll_hatype = htons(HTYPE_INFINIBAND);
|
||||||
|
+ su.sll.sll_halen = sizeof(interface->bcast_addr);
|
||||||
|
+ memcpy(&su.sll.sll_addr, interface->bcast_addr, 20);
|
||||||
|
+
|
||||||
|
+ result = sendto(interface->wfdesc, buf, ibufp + len, 0,
|
||||||
|
+ &su.sa, sizeof(su));
|
||||||
|
+
|
||||||
|
+ if (result < 0)
|
||||||
|
+ log_error ("send_packet_ib: %m");
|
||||||
|
+
|
||||||
|
+ return result;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
ssize_t send_packet (interface, packet, raw, len, from, to, hto)
|
||||||
|
struct interface_info *interface;
|
||||||
|
struct packet *packet;
|
||||||
|
@@ -335,6 +419,11 @@ ssize_t send_packet (interface, packet,
|
||||||
|
return send_fallback (interface, packet, raw,
|
||||||
|
len, from, to, hto);
|
||||||
|
|
||||||
|
+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
|
||||||
|
+ return send_packet_ib(interface, packet, raw, len, from,
|
||||||
|
+ to, hto);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (hto == NULL && interface->anycast_mac_addr.hlen)
|
||||||
|
hto = &interface->anycast_mac_addr;
|
||||||
|
|
||||||
|
@@ -355,6 +444,42 @@ ssize_t send_packet (interface, packet,
|
||||||
|
#endif /* USE_LPF_SEND */
|
||||||
|
|
||||||
|
#ifdef USE_LPF_RECEIVE
|
||||||
|
+ssize_t receive_packet_ib (interface, buf, len, from, hfrom)
|
||||||
|
+ struct interface_info *interface;
|
||||||
|
+ unsigned char *buf;
|
||||||
|
+ size_t len;
|
||||||
|
+ struct sockaddr_in *from;
|
||||||
|
+ struct hardware *hfrom;
|
||||||
|
+{
|
||||||
|
+ int length = 0;
|
||||||
|
+ int offset = 0;
|
||||||
|
+ unsigned char ibuf [1536];
|
||||||
|
+ unsigned bufix = 0;
|
||||||
|
+ unsigned paylen;
|
||||||
|
+
|
||||||
|
+ length = read(interface->rfdesc, ibuf, sizeof(ibuf));
|
||||||
|
+
|
||||||
|
+ if (length <= 0)
|
||||||
|
+ return length;
|
||||||
|
+
|
||||||
|
+ offset = decode_udp_ip_header(interface, ibuf, bufix, from,
|
||||||
|
+ (unsigned)length, &paylen, 0);
|
||||||
|
+
|
||||||
|
+ if (offset < 0)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ bufix += offset;
|
||||||
|
+ length -= offset;
|
||||||
|
+
|
||||||
|
+ if (length < paylen)
|
||||||
|
+ log_fatal("Internal inconsistency at %s:%d.", MDL);
|
||||||
|
+
|
||||||
|
+ /* Copy out the data in the packet... */
|
||||||
|
+ memcpy(buf, &ibuf[bufix], paylen);
|
||||||
|
+
|
||||||
|
+ return (ssize_t)paylen;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
ssize_t receive_packet (interface, buf, len, from, hfrom)
|
||||||
|
struct interface_info *interface;
|
||||||
|
unsigned char *buf;
|
||||||
|
@@ -393,6 +518,10 @@ ssize_t receive_packet (interface, buf,
|
||||||
|
};
|
||||||
|
#endif /* PACKET_AUXDATA */
|
||||||
|
|
||||||
|
+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
|
||||||
|
+ return receive_packet_ib(interface, buf, len, from, hfrom);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
length = recvmsg (interface->rfdesc, &msg, 0);
|
||||||
|
if (length <= 0)
|
||||||
|
return length;
|
||||||
|
@@ -506,11 +635,33 @@ void maybe_setup_fallback ()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (USE_LPF_RECEIVE) || defined (USE_LPF_HWADDR)
|
||||||
|
-void
|
||||||
|
-get_hw_addr(const char *name, struct hardware *hw) {
|
||||||
|
+struct sockaddr_ll *
|
||||||
|
+get_ll (struct ifaddrs *ifaddrs, struct ifaddrs **ifa, char *name)
|
||||||
|
+{
|
||||||
|
+ for (*ifa = ifaddrs; *ifa != NULL; *ifa = (*ifa)->ifa_next) {
|
||||||
|
+ if ((*ifa)->ifa_addr == NULL)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if ((*ifa)->ifa_addr->sa_family != AF_PACKET)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if ((*ifa)->ifa_flags & IFF_LOOPBACK)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (strcmp((*ifa)->ifa_name, name) == 0)
|
||||||
|
+ return (struct sockaddr_ll *)(void *)(*ifa)->ifa_addr;
|
||||||
|
+ }
|
||||||
|
+ *ifa = NULL;
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct sockaddr_ll *
|
||||||
|
+ioctl_get_ll(char *name)
|
||||||
|
+{
|
||||||
|
int sock;
|
||||||
|
struct ifreq tmp;
|
||||||
|
- struct sockaddr *sa;
|
||||||
|
+ struct sockaddr *sa = NULL;
|
||||||
|
+ struct sockaddr_ll *sll = NULL;
|
||||||
|
|
||||||
|
if (strlen(name) >= sizeof(tmp.ifr_name)) {
|
||||||
|
log_fatal("Device name too long: \"%s\"", name);
|
||||||
|
@@ -524,16 +675,61 @@ get_hw_addr(const char *name, struct har
|
||||||
|
memset(&tmp, 0, sizeof(tmp));
|
||||||
|
strcpy(tmp.ifr_name, name);
|
||||||
|
if (ioctl(sock, SIOCGIFHWADDR, &tmp) < 0) {
|
||||||
|
- log_fatal("Error getting hardware address for \"%s\": %m",
|
||||||
|
+ log_fatal("Error getting hardware address for \"%s\": %m",
|
||||||
|
name);
|
||||||
|
}
|
||||||
|
+ close(sock);
|
||||||
|
|
||||||
|
sa = &tmp.ifr_hwaddr;
|
||||||
|
- switch (sa->sa_family) {
|
||||||
|
+ // needs to be freed outside this function
|
||||||
|
+ sll = dmalloc (sizeof (struct sockaddr_ll), MDL);
|
||||||
|
+ if (!sll)
|
||||||
|
+ log_fatal("Unable to allocate memory for link layer address");
|
||||||
|
+ memcpy(&sll->sll_hatype, &sa->sa_family, sizeof (sll->sll_hatype));
|
||||||
|
+ memcpy(sll->sll_addr, sa->sa_data, sizeof (sll->sll_addr));
|
||||||
|
+ switch (sll->sll_hatype) {
|
||||||
|
+ case ARPHRD_INFINIBAND:
|
||||||
|
+ sll->sll_halen = HARDWARE_ADDR_LEN_IOCTL;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ return sll;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+get_hw_addr(struct interface_info *info)
|
||||||
|
+{
|
||||||
|
+ struct hardware *hw = &info->hw_address;
|
||||||
|
+ char *name = info->name;
|
||||||
|
+ struct ifaddrs *ifaddrs = NULL;
|
||||||
|
+ struct ifaddrs *ifa = NULL;
|
||||||
|
+ struct sockaddr_ll *sll = NULL;
|
||||||
|
+ int sll_allocated = 0;
|
||||||
|
+ char *dup = NULL;
|
||||||
|
+ char *colon = NULL;
|
||||||
|
+
|
||||||
|
+ if (getifaddrs(&ifaddrs) == -1)
|
||||||
|
+ log_fatal("Failed to get interfaces");
|
||||||
|
+
|
||||||
|
+ if ((sll = get_ll(ifaddrs, &ifa, name)) == NULL) {
|
||||||
|
+ /*
|
||||||
|
+ * We were unable to get link-layer address for name.
|
||||||
|
+ * Fall back to ioctl(SIOCGIFHWADDR).
|
||||||
|
+ */
|
||||||
|
+ sll = ioctl_get_ll(name);
|
||||||
|
+ if (sll != NULL)
|
||||||
|
+ sll_allocated = 1;
|
||||||
|
+ else
|
||||||
|
+ // shouldn't happen
|
||||||
|
+ log_fatal("Unexpected internal error");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ switch (sll->sll_hatype) {
|
||||||
|
case ARPHRD_ETHER:
|
||||||
|
hw->hlen = 7;
|
||||||
|
hw->hbuf[0] = HTYPE_ETHER;
|
||||||
|
- memcpy(&hw->hbuf[1], sa->sa_data, 6);
|
||||||
|
+ memcpy(&hw->hbuf[1], sll->sll_addr, 6);
|
||||||
|
break;
|
||||||
|
case ARPHRD_IEEE802:
|
||||||
|
#ifdef ARPHRD_IEEE802_TR
|
||||||
|
@@ -541,18 +737,50 @@ get_hw_addr(const char *name, struct har
|
||||||
|
#endif /* ARPHRD_IEEE802_TR */
|
||||||
|
hw->hlen = 7;
|
||||||
|
hw->hbuf[0] = HTYPE_IEEE802;
|
||||||
|
- memcpy(&hw->hbuf[1], sa->sa_data, 6);
|
||||||
|
+ memcpy(&hw->hbuf[1], sll->sll_addr, 6);
|
||||||
|
break;
|
||||||
|
case ARPHRD_FDDI:
|
||||||
|
hw->hlen = 7;
|
||||||
|
hw->hbuf[0] = HTYPE_FDDI;
|
||||||
|
- memcpy(&hw->hbuf[1], sa->sa_data, 6);
|
||||||
|
+ memcpy(&hw->hbuf[1], sll->sll_addr, 6);
|
||||||
|
+ break;
|
||||||
|
+ case ARPHRD_INFINIBAND:
|
||||||
|
+ dup = strdup(name);
|
||||||
|
+ /* Aliased infiniband interface is special case where
|
||||||
|
+ * neither get_ll() nor ioctl_get_ll() get's correct hw
|
||||||
|
+ * address, so we have to truncate the :0 and run
|
||||||
|
+ * get_ll() again for the rest.
|
||||||
|
+ */
|
||||||
|
+ if ((colon = strchr(dup, ':')) != NULL) {
|
||||||
|
+ *colon = '\0';
|
||||||
|
+ if ((sll = get_ll(ifaddrs, &ifa, dup)) == NULL)
|
||||||
|
+ log_fatal("Error getting hardware address for \"%s\": %m", name);
|
||||||
|
+ }
|
||||||
|
+ free (dup);
|
||||||
|
+ /* For Infiniband, save the broadcast address and store
|
||||||
|
+ * the port GUID into the hardware address.
|
||||||
|
+ */
|
||||||
|
+ if (ifa && (ifa->ifa_flags & IFF_BROADCAST)) {
|
||||||
|
+ struct sockaddr_ll *bll;
|
||||||
|
+
|
||||||
|
+ bll = (struct sockaddr_ll *)ifa->ifa_broadaddr;
|
||||||
|
+ memcpy(&info->bcast_addr, bll->sll_addr, 20);
|
||||||
|
+ } else {
|
||||||
|
+ memcpy(&info->bcast_addr, default_ib_bcast_addr,
|
||||||
|
+ 20);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ hw->hlen = HARDWARE_ADDR_LEN_IOCTL + 1;
|
||||||
|
+ hw->hbuf[0] = HTYPE_INFINIBAND;
|
||||||
|
+ memcpy(&hw->hbuf[1],
|
||||||
|
+ &sll->sll_addr[sll->sll_halen - HARDWARE_ADDR_LEN_IOCTL],
|
||||||
|
+ HARDWARE_ADDR_LEN_IOCTL);
|
||||||
|
break;
|
||||||
|
#if defined(ARPHRD_PPP)
|
||||||
|
case ARPHRD_PPP:
|
||||||
|
if (local_family != AF_INET6)
|
||||||
|
- log_fatal("Unsupported device type %d for \"%s\"",
|
||||||
|
- sa->sa_family, name);
|
||||||
|
+ log_fatal("local_family != AF_INET6 for \"%s\"",
|
||||||
|
+ name);
|
||||||
|
hw->hlen = 0;
|
||||||
|
hw->hbuf[0] = HTYPE_RESERVED;
|
||||||
|
/* 0xdeadbeef should never occur on the wire,
|
||||||
|
@@ -565,10 +793,13 @@ get_hw_addr(const char *name, struct har
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
- log_fatal("Unsupported device type %ld for \"%s\"",
|
||||||
|
- (long int)sa->sa_family, name);
|
||||||
|
+ freeifaddrs(ifaddrs);
|
||||||
|
+ log_fatal("Unsupported device type %hu for \"%s\"",
|
||||||
|
+ sll->sll_hatype, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
- close(sock);
|
||||||
|
+ if (sll_allocated)
|
||||||
|
+ dfree(sll, MDL);
|
||||||
|
+ freeifaddrs(ifaddrs);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
diff -up dhcp-4.3.4/common/socket.c.lpf-ib dhcp-4.3.4/common/socket.c
|
||||||
|
--- dhcp-4.3.4/common/socket.c.lpf-ib 2016-03-22 14:16:51.000000000 +0100
|
||||||
|
+++ dhcp-4.3.4/common/socket.c 2016-05-02 14:37:36.953128006 +0200
|
||||||
|
@@ -328,7 +328,7 @@ void if_register_send (info)
|
||||||
|
info->wfdesc = if_register_socket(info, AF_INET, 0, NULL);
|
||||||
|
/* If this is a normal IPv4 address, get the hardware address. */
|
||||||
|
if (strcmp(info->name, "fallback") != 0)
|
||||||
|
- get_hw_addr(info->name, &info->hw_address);
|
||||||
|
+ get_hw_addr(info);
|
||||||
|
#if defined (USE_SOCKET_FALLBACK)
|
||||||
|
/* Fallback only registers for send, but may need to receive as
|
||||||
|
well. */
|
||||||
|
@@ -391,7 +391,7 @@ void if_register_receive (info)
|
||||||
|
#endif /* IP_PKTINFO... */
|
||||||
|
/* If this is a normal IPv4 address, get the hardware address. */
|
||||||
|
if (strcmp(info->name, "fallback") != 0)
|
||||||
|
- get_hw_addr(info->name, &info->hw_address);
|
||||||
|
+ get_hw_addr(info);
|
||||||
|
|
||||||
|
if (!quiet_interface_discovery)
|
||||||
|
log_info ("Listening on Socket/%s%s%s",
|
||||||
|
@@ -505,7 +505,7 @@ if_register6(struct interface_info *info
|
||||||
|
if (req_multi)
|
||||||
|
if_register_multicast(info);
|
||||||
|
|
||||||
|
- get_hw_addr(info->name, &info->hw_address);
|
||||||
|
+ get_hw_addr(info);
|
||||||
|
|
||||||
|
if (!quiet_interface_discovery) {
|
||||||
|
if (info->shared_network != NULL) {
|
||||||
|
@@ -561,7 +561,7 @@ if_register_linklocal6(struct interface_
|
||||||
|
info->rfdesc = sock;
|
||||||
|
info->wfdesc = sock;
|
||||||
|
|
||||||
|
- get_hw_addr(info->name, &info->hw_address);
|
||||||
|
+ get_hw_addr(info);
|
||||||
|
|
||||||
|
if (!quiet_interface_discovery) {
|
||||||
|
if (info->shared_network != NULL) {
|
||||||
|
diff -up dhcp-4.3.4/includes/dhcpd.h.lpf-ib dhcp-4.3.4/includes/dhcpd.h
|
||||||
|
--- dhcp-4.3.4/includes/dhcpd.h.lpf-ib 2016-05-02 14:37:36.948128002 +0200
|
||||||
|
+++ dhcp-4.3.4/includes/dhcpd.h 2016-05-02 14:37:36.954128006 +0200
|
||||||
|
@@ -482,6 +482,9 @@ struct packet {
|
||||||
|
|
||||||
|
#define HARDWARE_ADDR_LEN 20
|
||||||
|
|
||||||
|
+/* ioctl limits hardware addresses to 8 bytes */
|
||||||
|
+#define HARDWARE_ADDR_LEN_IOCTL 8
|
||||||
|
+
|
||||||
|
struct hardware {
|
||||||
|
u_int8_t hlen;
|
||||||
|
u_int8_t hbuf[HARDWARE_ADDR_LEN + 1];
|
||||||
|
@@ -1343,6 +1346,7 @@ struct interface_info {
|
||||||
|
struct shared_network *shared_network;
|
||||||
|
/* Networks connected to this interface. */
|
||||||
|
struct hardware hw_address; /* Its physical address. */
|
||||||
|
+ u_int8_t bcast_addr[20]; /* Infiniband broadcast address */
|
||||||
|
struct in_addr *addresses; /* Addresses associated with this
|
||||||
|
* interface.
|
||||||
|
*/
|
||||||
|
@@ -2580,7 +2584,7 @@ void print_dns_status (int, struct dhcp_
|
||||||
|
#endif
|
||||||
|
const char *print_time(TIME);
|
||||||
|
|
||||||
|
-void get_hw_addr(const char *name, struct hardware *hw);
|
||||||
|
+void get_hw_addr(struct interface_info *info);
|
||||||
|
char *buf_to_hex (const unsigned char *s, unsigned len,
|
||||||
|
const char *file, int line);
|
||||||
|
char *format_lease_id(const unsigned char *s, unsigned len, int format,
|
@ -0,0 +1,148 @@
|
|||||||
|
diff -up dhcp-4.3.5b1/client/dhclient.conf.5.man dhcp-4.3.5b1/client/dhclient.conf.5
|
||||||
|
--- dhcp-4.3.5b1/client/dhclient.conf.5.man 2016-08-26 20:19:53.000000000 +0200
|
||||||
|
+++ dhcp-4.3.5b1/client/dhclient.conf.5 2016-09-12 17:09:23.243313514 +0200
|
||||||
|
@@ -228,7 +228,8 @@ responding to the client send the client
|
||||||
|
options. Only the option names should be specified in the request
|
||||||
|
statement - not option parameters. By default, the DHCPv4 client
|
||||||
|
requests the subnet-mask, broadcast-address, time-offset, routers,
|
||||||
|
-domain-name, domain-name-servers and host-name options while the DHCPv6
|
||||||
|
+domain-search, domain-name, domain-name-servers, host-name, nis-domain,
|
||||||
|
+nis-servers, ntp-servers and interface-mtu options while the DHCPv6
|
||||||
|
client requests the dhcp6 name-servers and domain-search options. Note
|
||||||
|
that if you enter a \'request\' statement, you over-ride these defaults
|
||||||
|
and these options will not be requested.
|
||||||
|
@@ -736,6 +737,17 @@ know the DHCP service(s) anycast MAC add
|
||||||
|
client. The \fIlink-type\fR and \fImac-address\fR parameters are configured
|
||||||
|
in a similar manner to the \fBhardware\fR statement.
|
||||||
|
.PP
|
||||||
|
+ \fBbootp-broadcast-always;\fR
|
||||||
|
+.PP
|
||||||
|
+The
|
||||||
|
+.B bootp-broadcast-always
|
||||||
|
+statement instructs dhclient to always set the bootp broadcast flag in
|
||||||
|
+request packets, so that servers will always broadcast replies.
|
||||||
|
+This is equivalent to supplying the dhclient -B argument, and has
|
||||||
|
+the same effect as specifying 'always-broadcast' in the server's dhcpd.conf.
|
||||||
|
+This option is provided as an extension to enable dhclient to work
|
||||||
|
+on IBM s390 Linux guests.
|
||||||
|
+.PP
|
||||||
|
.SH SAMPLE
|
||||||
|
The following configuration file was used on a laptop running NetBSD
|
||||||
|
1.3, though the domains have been modified.
|
||||||
|
diff -up dhcp-4.3.5b1/client/dhclient-script.8.man dhcp-4.3.5b1/client/dhclient-script.8
|
||||||
|
--- dhcp-4.3.5b1/client/dhclient-script.8.man 2016-08-26 20:19:53.000000000 +0200
|
||||||
|
+++ dhcp-4.3.5b1/client/dhclient-script.8 2016-09-12 17:08:09.516254385 +0200
|
||||||
|
@@ -45,7 +45,7 @@ customizations are needed, they should b
|
||||||
|
exit hooks provided (see HOOKS for details). These hooks will allow the
|
||||||
|
user to override the default behaviour of the client in creating a
|
||||||
|
.B /etc/resolv.conf
|
||||||
|
-file.
|
||||||
|
+file, and to handle DHCP options not handled by default.
|
||||||
|
.PP
|
||||||
|
No standard client script exists for some operating systems, even though
|
||||||
|
the actual client may work, so a pioneering user may well need to create
|
||||||
|
@@ -89,6 +89,26 @@ present. The
|
||||||
|
.B ETCDIR/dhclient-exit-hooks
|
||||||
|
script can modify the valid of exit_status to change the exit status
|
||||||
|
of dhclient-script.
|
||||||
|
+.PP
|
||||||
|
+Immediately after dhclient brings an interface UP with a new IP address,
|
||||||
|
+subnet mask, and routes, in the REBOOT/BOUND states, it will check for the
|
||||||
|
+existence of an executable
|
||||||
|
+.B ETCDIR/dhclient-up-hooks
|
||||||
|
+script, and source it if found. This script can handle DHCP options in
|
||||||
|
+the environment that are not handled by default. A per-interface.
|
||||||
|
+.B ETCDIR/dhclient-${IF}-up-hooks
|
||||||
|
+script will override the generic script and be sourced when interface
|
||||||
|
+$IF has been brought up.
|
||||||
|
+.PP
|
||||||
|
+Immediately before dhclient brings an interface DOWN, removing its IP
|
||||||
|
+address, subnet mask, and routes, in the STOP/RELEASE states, it will
|
||||||
|
+check for the existence of an executable
|
||||||
|
+.B ETCDIR/dhclient-down-hooks
|
||||||
|
+script, and source it if found. This script can handle DHCP options in
|
||||||
|
+the environment that are not handled by default. A per-interface
|
||||||
|
+.B ETCDIR/dhclient-${IF}-down-hooks
|
||||||
|
+script will override the generic script and be sourced when interface
|
||||||
|
+$IF is about to be brought down.
|
||||||
|
.SH OPERATION
|
||||||
|
When dhclient needs to invoke the client configuration script, it
|
||||||
|
defines a set of variables in the environment, and then invokes
|
||||||
|
diff -up dhcp-4.3.5b1/common/dhcp-options.5.man dhcp-4.3.5b1/common/dhcp-options.5
|
||||||
|
--- dhcp-4.3.5b1/common/dhcp-options.5.man 2016-08-26 20:19:53.000000000 +0200
|
||||||
|
+++ dhcp-4.3.5b1/common/dhcp-options.5 2016-09-12 17:08:09.517254386 +0200
|
||||||
|
@@ -1013,6 +1013,21 @@ classless IP routing - it does not inclu
|
||||||
|
classless IP routing is now the most widely deployed routing standard,
|
||||||
|
this option is virtually useless, and is not implemented by any of the
|
||||||
|
popular DHCP clients, for example the Microsoft DHCP client.
|
||||||
|
+.PP
|
||||||
|
+NOTE to Fedora dhclient users:
|
||||||
|
+.br
|
||||||
|
+dhclient-script interprets trailing 0 octets of the target as indicating
|
||||||
|
+the subnet class of the route, so for the following static-routes value:
|
||||||
|
+.br
|
||||||
|
+ option static-routes 172.0.0.0 172.16.2.254,
|
||||||
|
+.br
|
||||||
|
+ 192.168.0.0 192.168.2.254;
|
||||||
|
+.br
|
||||||
|
+dhclient-script will create routes:
|
||||||
|
+.br
|
||||||
|
+ 172/8 via 172.16.2.254 dev $interface
|
||||||
|
+.br
|
||||||
|
+ 192.168/16 via 192.168.2.254 dev $interface
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
.nf
|
||||||
|
diff -up dhcp-4.3.5b1/server/dhcpd.conf.5.man dhcp-4.3.5b1/server/dhcpd.conf.5
|
||||||
|
--- dhcp-4.3.5b1/server/dhcpd.conf.5.man 2016-08-26 20:19:53.000000000 +0200
|
||||||
|
+++ dhcp-4.3.5b1/server/dhcpd.conf.5 2016-09-12 17:10:11.205351980 +0200
|
||||||
|
@@ -528,6 +528,9 @@ pool {
|
||||||
|
};
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
+Dynamic BOOTP leases are not compatible with failover, and, as such,
|
||||||
|
+you need to disallow BOOTP in pools that you are using failover for.
|
||||||
|
+.PP
|
||||||
|
The server currently does very little sanity checking, so if you
|
||||||
|
configure it wrong, it will just fail in odd ways. I would recommend
|
||||||
|
therefore that you either do failover or don't do failover, but don't
|
||||||
|
@@ -542,9 +545,9 @@ primary server might look like this:
|
||||||
|
failover peer "foo" {
|
||||||
|
primary;
|
||||||
|
address anthrax.rc.example.com;
|
||||||
|
- port 519;
|
||||||
|
+ port 647;
|
||||||
|
peer address trantor.rc.example.com;
|
||||||
|
- peer port 520;
|
||||||
|
+ peer port 847;
|
||||||
|
max-response-delay 60;
|
||||||
|
max-unacked-updates 10;
|
||||||
|
mclt 3600;
|
||||||
|
@@ -1246,7 +1249,7 @@ the zone containing PTR records - for IS
|
||||||
|
.PP
|
||||||
|
.nf
|
||||||
|
key DHCP_UPDATER {
|
||||||
|
- algorithm HMAC-MD5.SIG-ALG.REG.INT;
|
||||||
|
+ algorithm hmac-md5;
|
||||||
|
secret pRP5FapFoJ95JEL06sv4PQ==;
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -1269,7 +1272,7 @@ dhcpd.conf file:
|
||||||
|
.PP
|
||||||
|
.nf
|
||||||
|
key DHCP_UPDATER {
|
||||||
|
- algorithm HMAC-MD5.SIG-ALG.REG.INT;
|
||||||
|
+ algorithm hmac-md5;
|
||||||
|
secret pRP5FapFoJ95JEL06sv4PQ==;
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -2742,7 +2745,8 @@ statement
|
||||||
|
The \fInext-server\fR statement is used to specify the host address of
|
||||||
|
the server from which the initial boot file (specified in the
|
||||||
|
\fIfilename\fR statement) is to be loaded. \fIServer-name\fR should
|
||||||
|
-be a numeric IP address or a domain name.
|
||||||
|
+be a numeric IP address or a domain name. If no \fInext-server\fR statement
|
||||||
|
+applies to a given client, the address 0.0.0.0 is used.
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
The
|
@ -0,0 +1,48 @@
|
|||||||
|
diff -up dhcp-4.3.0a1/common/discover.c.error2info dhcp-4.3.0a1/common/discover.c
|
||||||
|
--- dhcp-4.3.0a1/common/discover.c.error2info 2013-12-20 13:59:15.148553898 +0100
|
||||||
|
+++ dhcp-4.3.0a1/common/discover.c 2013-12-20 13:59:15.181553438 +0100
|
||||||
|
@@ -779,9 +779,9 @@ discover_interfaces(int state) {
|
||||||
|
|
||||||
|
/* We must have a subnet declaration for each interface. */
|
||||||
|
if (!tmp->shared_network && (state == DISCOVER_SERVER)) {
|
||||||
|
- log_error("%s", "");
|
||||||
|
+ log_info("%s", "");
|
||||||
|
if (local_family == AF_INET) {
|
||||||
|
- log_error("No subnet declaration for %s (%s).",
|
||||||
|
+ log_info("No subnet declaration for %s (%s).",
|
||||||
|
tmp->name,
|
||||||
|
(tmp->addresses == NULL) ?
|
||||||
|
"no IPv4 addresses" :
|
||||||
|
@@ -796,26 +796,26 @@ discover_interfaces(int state) {
|
||||||
|
} else {
|
||||||
|
strcpy(abuf, "no IPv6 addresses");
|
||||||
|
}
|
||||||
|
- log_error("No subnet6 declaration for %s (%s).",
|
||||||
|
+ log_info("No subnet6 declaration for %s (%s).",
|
||||||
|
tmp->name,
|
||||||
|
abuf);
|
||||||
|
#endif /* DHCPv6 */
|
||||||
|
}
|
||||||
|
if (supports_multiple_interfaces(tmp)) {
|
||||||
|
- log_error ("** Ignoring requests on %s. %s",
|
||||||
|
+ log_info ("** Ignoring requests on %s. %s",
|
||||||
|
tmp -> name, "If this is not what");
|
||||||
|
- log_error (" you want, please write %s",
|
||||||
|
+ log_info (" you want, please write %s",
|
||||||
|
#ifdef DHCPv6
|
||||||
|
(local_family != AF_INET) ?
|
||||||
|
"a subnet6 declaration" :
|
||||||
|
#endif
|
||||||
|
"a subnet declaration");
|
||||||
|
- log_error (" in your dhcpd.conf file %s",
|
||||||
|
+ log_info (" in your dhcpd.conf file %s",
|
||||||
|
"for the network segment");
|
||||||
|
- log_error (" to %s %s %s",
|
||||||
|
+ log_info (" to %s %s %s",
|
||||||
|
"which interface",
|
||||||
|
tmp -> name, "is attached. **");
|
||||||
|
- log_error ("%s", "");
|
||||||
|
+ log_info ("%s", "");
|
||||||
|
goto next;
|
||||||
|
} else {
|
||||||
|
log_error ("You must write a %s",
|
@ -0,0 +1,155 @@
|
|||||||
|
diff --git a/omapip/connection.c b/omapip/connection.c
|
||||||
|
index a74becc..56826a5 100644
|
||||||
|
--- a/omapip/connection.c
|
||||||
|
+++ b/omapip/connection.c
|
||||||
|
@@ -46,6 +46,9 @@ extern omapi_array_t *trace_listeners;
|
||||||
|
#endif
|
||||||
|
static isc_result_t omapi_connection_connect_internal (omapi_object_t *);
|
||||||
|
|
||||||
|
+static isc_result_t ctring_from_attribute(omapi_object_t *obj, char *attr_name,
|
||||||
|
+ char **cstr);
|
||||||
|
+
|
||||||
|
OMAPI_OBJECT_ALLOC (omapi_connection,
|
||||||
|
omapi_connection_object_t, omapi_type_connection)
|
||||||
|
|
||||||
|
@@ -765,64 +768,41 @@ isc_result_t omapi_connection_reaper (omapi_object_t *h)
|
||||||
|
}
|
||||||
|
|
||||||
|
static isc_result_t make_dst_key (dst_key_t **dst_key, omapi_object_t *a) {
|
||||||
|
- omapi_value_t *name = (omapi_value_t *)0;
|
||||||
|
- omapi_value_t *algorithm = (omapi_value_t *)0;
|
||||||
|
- omapi_value_t *key = (omapi_value_t *)0;
|
||||||
|
- char *name_str = NULL;
|
||||||
|
+ omapi_value_t *key = 0;
|
||||||
|
+ char *name_str = 0;
|
||||||
|
+ char *algorithm_str = 0;
|
||||||
|
isc_result_t status = ISC_R_SUCCESS;
|
||||||
|
|
||||||
|
- if (status == ISC_R_SUCCESS)
|
||||||
|
- status = omapi_get_value_str
|
||||||
|
- (a, (omapi_object_t *)0, "name", &name);
|
||||||
|
-
|
||||||
|
- if (status == ISC_R_SUCCESS)
|
||||||
|
- status = omapi_get_value_str
|
||||||
|
- (a, (omapi_object_t *)0, "algorithm", &algorithm);
|
||||||
|
-
|
||||||
|
- if (status == ISC_R_SUCCESS)
|
||||||
|
- status = omapi_get_value_str
|
||||||
|
- (a, (omapi_object_t *)0, "key", &key);
|
||||||
|
-
|
||||||
|
+ /* Get the key name as a C string. */
|
||||||
|
+ status = ctring_from_attribute(a, "name", &name_str);
|
||||||
|
if (status == ISC_R_SUCCESS) {
|
||||||
|
- if ((algorithm->value->type != omapi_datatype_data &&
|
||||||
|
- algorithm->value->type != omapi_datatype_string) ||
|
||||||
|
- strncasecmp((char *)algorithm->value->u.buffer.value,
|
||||||
|
- NS_TSIG_ALG_HMAC_MD5 ".",
|
||||||
|
- algorithm->value->u.buffer.len) != 0) {
|
||||||
|
- status = DHCP_R_INVALIDARG;
|
||||||
|
+ /* Get the algorithm name as a C string. */
|
||||||
|
+ status = ctring_from_attribute(a, "algorithm", &algorithm_str);
|
||||||
|
+ if (status == ISC_R_SUCCESS) {
|
||||||
|
+ /* Get the key secret value */
|
||||||
|
+ status = omapi_get_value_str(a, 0, "key", &key);
|
||||||
|
+ if (status == ISC_R_SUCCESS) {
|
||||||
|
+ /* Now let's try and create the key */
|
||||||
|
+ status = isclib_make_dst_key(
|
||||||
|
+ name_str,
|
||||||
|
+ algorithm_str,
|
||||||
|
+ key->value->u.buffer.value,
|
||||||
|
+ key->value->u.buffer.len,
|
||||||
|
+ dst_key);
|
||||||
|
+
|
||||||
|
+ if (*dst_key == NULL) {
|
||||||
|
+ status = ISC_R_NOMEMORY;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (status == ISC_R_SUCCESS) {
|
||||||
|
- name_str = dmalloc (name -> value -> u.buffer.len + 1, MDL);
|
||||||
|
- if (!name_str)
|
||||||
|
- status = ISC_R_NOMEMORY;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (status == ISC_R_SUCCESS) {
|
||||||
|
- memcpy (name_str,
|
||||||
|
- name -> value -> u.buffer.value,
|
||||||
|
- name -> value -> u.buffer.len);
|
||||||
|
- name_str [name -> value -> u.buffer.len] = 0;
|
||||||
|
-
|
||||||
|
- status = isclib_make_dst_key(name_str,
|
||||||
|
- DHCP_HMAC_MD5_NAME,
|
||||||
|
- key->value->u.buffer.value,
|
||||||
|
- key->value->u.buffer.len,
|
||||||
|
- dst_key);
|
||||||
|
-
|
||||||
|
- if (*dst_key == NULL)
|
||||||
|
- status = ISC_R_NOMEMORY;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
if (name_str)
|
||||||
|
dfree (name_str, MDL);
|
||||||
|
+ if (algorithm_str)
|
||||||
|
+ dfree (algorithm_str, MDL);
|
||||||
|
if (key)
|
||||||
|
omapi_value_dereference (&key, MDL);
|
||||||
|
- if (algorithm)
|
||||||
|
- omapi_value_dereference (&algorithm, MDL);
|
||||||
|
- if (name)
|
||||||
|
- omapi_value_dereference (&name, MDL);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
@@ -1105,3 +1085,50 @@ isc_result_t omapi_connection_stuff_values (omapi_object_t *c,
|
||||||
|
m -> inner);
|
||||||
|
return ISC_R_SUCCESS;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/* @brief Fetches the value of an attribute in an object as an allocated
|
||||||
|
+ * C string
|
||||||
|
+ *
|
||||||
|
+ * @param obj ompapi object containing the desire attribute
|
||||||
|
+ * @param attr_name name of the desired attribute
|
||||||
|
+ * @param[out] cstr pointer in which to place the allocated C string's address
|
||||||
|
+ *
|
||||||
|
+ * Caller is responsible for freeing (via dfree) the allocated string.
|
||||||
|
+ *
|
||||||
|
+ * @return ISC_R_SUCCESS if successful, otherwise indicates the type of failure
|
||||||
|
+*/
|
||||||
|
+static isc_result_t ctring_from_attribute(omapi_object_t *obj, char *attr_name,
|
||||||
|
+ char **cstr) {
|
||||||
|
+ isc_result_t status = ISC_R_SUCCESS;
|
||||||
|
+ omapi_value_t *attr = 0;
|
||||||
|
+
|
||||||
|
+ /* Find the attribute in the object. */
|
||||||
|
+ status = omapi_get_value_str(obj, (omapi_object_t *)0, attr_name,
|
||||||
|
+ &attr);
|
||||||
|
+ if (status != ISC_R_SUCCESS) {
|
||||||
|
+ return (status);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Got it, let's make sure it's either data or string type. */
|
||||||
|
+ if (attr->value->type != omapi_datatype_data &&
|
||||||
|
+ attr->value->type != omapi_datatype_string) {
|
||||||
|
+ return (DHCP_R_INVALIDARG);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Make a C string from the attribute value. */
|
||||||
|
+ *cstr = dmalloc (attr->value->u.buffer.len + 1, MDL);
|
||||||
|
+ if (!(*cstr)) {
|
||||||
|
+ status = ISC_R_NOMEMORY;
|
||||||
|
+ } else {
|
||||||
|
+ memcpy (*cstr, attr->value->u.buffer.value,
|
||||||
|
+ attr->value->u.buffer.len);
|
||||||
|
+ (*cstr)[attr->value->u.buffer.len] = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Get rid of the attribute reference */
|
||||||
|
+ if (attr) {
|
||||||
|
+ omapi_value_dereference (&attr, MDL);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return (status);
|
||||||
|
+}
|
@ -0,0 +1,217 @@
|
|||||||
|
diff -up dhcp-4.3.5b1/common/options.c.option97 dhcp-4.3.5b1/common/options.c
|
||||||
|
--- dhcp-4.3.5b1/common/options.c.option97 2016-09-12 17:17:13.972691041 +0200
|
||||||
|
+++ dhcp-4.3.5b1/common/options.c 2016-09-12 17:19:17.706790276 +0200
|
||||||
|
@@ -4434,13 +4434,26 @@ int validate_packet(struct packet *packe
|
||||||
|
"a future version of ISC DHCP will reject this");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
- /*
|
||||||
|
- * If hlen is 0 we don't have any identifier, we warn the user
|
||||||
|
- * but continue processing the packet as we can.
|
||||||
|
- */
|
||||||
|
- if (packet->raw->hlen == 0) {
|
||||||
|
- log_debug("Received DHCPv4 packet without client-id"
|
||||||
|
- " option and empty hlen field.");
|
||||||
|
+ oc = lookup_option (&dhcp_universe, packet->options,
|
||||||
|
+ DHO_PXE_CLIENT_ID);
|
||||||
|
+ if (oc) {
|
||||||
|
+ /* Let's check if pxe-client-id is sane */
|
||||||
|
+ if ((oc->data.len < 2) ||
|
||||||
|
+ (oc->data.data[0] == '\0' &&
|
||||||
|
+ oc->data.len != 17)) {
|
||||||
|
+ log_debug("Dropped DHCPv4 packet with wrong "
|
||||||
|
+ "(len == %d) pxe-client-id", oc->data.len);
|
||||||
|
+ return (0);
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ /*
|
||||||
|
+ * If hlen is 0 we don't have any identifier, we warn the user
|
||||||
|
+ * but continue processing the packet as we can.
|
||||||
|
+ */
|
||||||
|
+ if (packet->raw->hlen == 0) {
|
||||||
|
+ log_debug("Received DHCPv4 packet without client-id"
|
||||||
|
+ " option and empty hlen field.");
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff -up dhcp-4.3.5b1/common/tables.c.option97 dhcp-4.3.5b1/common/tables.c
|
||||||
|
--- dhcp-4.3.5b1/common/tables.c.option97 2016-09-12 17:17:13.927691005 +0200
|
||||||
|
+++ dhcp-4.3.5b1/common/tables.c 2016-09-12 17:17:13.972691041 +0200
|
||||||
|
@@ -196,8 +196,9 @@ static struct option dhcp_options[] = {
|
||||||
|
/* Defined by RFC 4578 */
|
||||||
|
{ "pxe-system-type", "S", &dhcp_universe, 93, 1 },
|
||||||
|
{ "pxe-interface-id", "BBB", &dhcp_universe, 94, 1 },
|
||||||
|
- { "pxe-client-id", "BX", &dhcp_universe, 97, 1 },
|
||||||
|
#endif
|
||||||
|
+ { "pxe-client-id", "BX", &dhcp_universe, 97, 1 },
|
||||||
|
+
|
||||||
|
{ "uap-servers", "t", &dhcp_universe, 98, 1 },
|
||||||
|
#if defined(RFC4776_OPTIONS)
|
||||||
|
{ "geoconf-civic", "X", &dhcp_universe, 99, 1 },
|
||||||
|
diff -up dhcp-4.3.5b1/includes/dhcp.h.option97 dhcp-4.3.5b1/includes/dhcp.h
|
||||||
|
--- dhcp-4.3.5b1/includes/dhcp.h.option97 2016-09-12 17:17:13.936691013 +0200
|
||||||
|
+++ dhcp-4.3.5b1/includes/dhcp.h 2016-09-12 17:17:13.972691041 +0200
|
||||||
|
@@ -159,6 +159,7 @@ struct dhcp_packet {
|
||||||
|
#define DHO_AUTHENTICATE 90 /* RFC3118, was 210 */
|
||||||
|
#define DHO_CLIENT_LAST_TRANSACTION_TIME 91
|
||||||
|
#define DHO_ASSOCIATED_IP 92
|
||||||
|
+#define DHO_PXE_CLIENT_ID 97 /* RFC4578 */
|
||||||
|
#define DHO_SUBNET_SELECTION 118 /* RFC3011! */
|
||||||
|
#define DHO_DOMAIN_SEARCH 119 /* RFC3397 */
|
||||||
|
#define DHO_CLASSLESS_STATIC_ROUTES 121 /* RFC3442 */
|
||||||
|
diff -up dhcp-4.3.5b1/server/dhcp.c.option97 dhcp-4.3.5b1/server/dhcp.c
|
||||||
|
--- dhcp-4.3.5b1/server/dhcp.c.option97 2016-09-12 17:17:13.947691021 +0200
|
||||||
|
+++ dhcp-4.3.5b1/server/dhcp.c 2016-09-12 17:17:13.973691042 +0200
|
||||||
|
@@ -221,6 +221,10 @@ dhcp (struct packet *packet) {
|
||||||
|
oc = lookup_option (&dhcp_universe, packet -> options,
|
||||||
|
DHO_DHCP_CLIENT_IDENTIFIER);
|
||||||
|
if (!oc)
|
||||||
|
+ oc = lookup_option (&dhcp_universe,
|
||||||
|
+ packet -> options,
|
||||||
|
+ DHO_PXE_CLIENT_ID);
|
||||||
|
+ if (!oc)
|
||||||
|
goto nolease;
|
||||||
|
|
||||||
|
memset (&data, 0, sizeof data);
|
||||||
|
@@ -818,6 +822,9 @@ void dhcprelease (packet, ms_nulltp)
|
||||||
|
|
||||||
|
oc = lookup_option (&dhcp_universe, packet -> options,
|
||||||
|
DHO_DHCP_CLIENT_IDENTIFIER);
|
||||||
|
+ if (!oc)
|
||||||
|
+ oc = lookup_option (&dhcp_universe, packet -> options,
|
||||||
|
+ DHO_PXE_CLIENT_ID);
|
||||||
|
memset (&data, 0, sizeof data);
|
||||||
|
if (oc &&
|
||||||
|
evaluate_option_cache (&data, packet, (struct lease *)0,
|
||||||
|
@@ -1286,6 +1293,9 @@ void dhcpinform (packet, ms_nulltp)
|
||||||
|
*/
|
||||||
|
oc = lookup_option(&dhcp_universe, packet->options,
|
||||||
|
DHO_DHCP_CLIENT_IDENTIFIER);
|
||||||
|
+ if (!oc)
|
||||||
|
+ oc = lookup_option (&dhcp_universe, packet -> options,
|
||||||
|
+ DHO_PXE_CLIENT_ID);
|
||||||
|
memset(&d1, 0, sizeof(d1));
|
||||||
|
if (oc &&
|
||||||
|
evaluate_option_cache(&d1, packet, NULL, NULL,
|
||||||
|
@@ -2381,6 +2391,9 @@ void ack_lease (packet, lease, offer, wh
|
||||||
|
can be used. */
|
||||||
|
oc = lookup_option (&dhcp_universe, packet -> options,
|
||||||
|
DHO_DHCP_CLIENT_IDENTIFIER);
|
||||||
|
+ if (!oc)
|
||||||
|
+ oc = lookup_option (&dhcp_universe, packet -> options,
|
||||||
|
+ DHO_PXE_CLIENT_ID);
|
||||||
|
if (oc &&
|
||||||
|
evaluate_option_cache (&d1, packet, lease,
|
||||||
|
(struct client_state *)0,
|
||||||
|
@@ -2962,6 +2975,9 @@ void ack_lease (packet, lease, offer, wh
|
||||||
|
/* Record the uid, if given... */
|
||||||
|
oc = lookup_option (&dhcp_universe, packet -> options,
|
||||||
|
DHO_DHCP_CLIENT_IDENTIFIER);
|
||||||
|
+ if (!oc)
|
||||||
|
+ oc = lookup_option (&dhcp_universe, packet -> options,
|
||||||
|
+ DHO_PXE_CLIENT_ID);
|
||||||
|
if (oc &&
|
||||||
|
evaluate_option_cache(&d1, packet, lease, NULL,
|
||||||
|
packet->options, state->options,
|
||||||
|
@@ -4068,6 +4084,9 @@ int find_lease (struct lease **lp,
|
||||||
|
specified unique client identifier. */
|
||||||
|
oc = lookup_option (&dhcp_universe, packet -> options,
|
||||||
|
DHO_DHCP_CLIENT_IDENTIFIER);
|
||||||
|
+ if (!oc)
|
||||||
|
+ oc = lookup_option (&dhcp_universe, packet -> options,
|
||||||
|
+ DHO_PXE_CLIENT_ID);
|
||||||
|
memset (&client_identifier, 0, sizeof client_identifier);
|
||||||
|
if (oc &&
|
||||||
|
evaluate_option_cache (&client_identifier,
|
||||||
|
diff -up dhcp-4.3.5b1/server/dhcpd.conf.5.option97 dhcp-4.3.5b1/server/dhcpd.conf.5
|
||||||
|
--- dhcp-4.3.5b1/server/dhcpd.conf.5.option97 2016-09-12 17:17:13.885690972 +0200
|
||||||
|
+++ dhcp-4.3.5b1/server/dhcpd.conf.5 2016-09-12 17:17:13.974691043 +0200
|
||||||
|
@@ -1587,10 +1587,12 @@ should be a name identifying the host.
|
||||||
|
not specified for the host, \fIhostname\fR is used.
|
||||||
|
.PP
|
||||||
|
\fIHost\fR declarations are matched to actual DHCP or BOOTP clients
|
||||||
|
-by matching the \fRdhcp-client-identifier\fR option specified in the
|
||||||
|
+by matching the \fIdhcp-client-identifier\fR or \fIpxe-client-id\fR
|
||||||
|
+options specified in the
|
||||||
|
\fIhost\fR declaration to the one supplied by the client, or, if the
|
||||||
|
\fIhost\fR declaration or the client does not provide a
|
||||||
|
-\fRdhcp-client-identifier\fR option, by matching the \fIhardware\fR
|
||||||
|
+\fIdhcp-client-identifier\fR or \fIpxe-client-id\fR options,
|
||||||
|
+by matching the \fIhardware\fR
|
||||||
|
parameter in the \fIhost\fR declaration to the network hardware
|
||||||
|
address supplied by the client. BOOTP clients do not normally
|
||||||
|
provide a \fIdhcp-client-identifier\fR, so the hardware address must
|
||||||
|
@@ -1602,7 +1604,8 @@ to identify hosts.
|
||||||
|
.PP
|
||||||
|
Please be aware that
|
||||||
|
.B only
|
||||||
|
-the \fIdhcp-client-identifier\fR option and the hardware address can be
|
||||||
|
+the \fIdhcp-client-identifier\fR and \fIpxe-client-id\fR
|
||||||
|
+options and the hardware address can be
|
||||||
|
used to match a host declaration, or the \fIhost-identifier option\fR
|
||||||
|
parameter for DHCPv6 servers. For example, it is not possible to
|
||||||
|
match a host declaration to a \fIhost-name\fR option. This is
|
||||||
|
diff -up dhcp-4.3.5b1/server/dhcpleasequery.c.option97 dhcp-4.3.5b1/server/dhcpleasequery.c
|
||||||
|
--- dhcp-4.3.5b1/server/dhcpleasequery.c.option97 2016-08-26 20:19:53.000000000 +0200
|
||||||
|
+++ dhcp-4.3.5b1/server/dhcpleasequery.c 2016-09-12 17:17:13.974691043 +0200
|
||||||
|
@@ -273,7 +273,7 @@ dhcpleasequery(struct packet *packet, in
|
||||||
|
*/
|
||||||
|
|
||||||
|
memset(&uid, 0, sizeof(uid));
|
||||||
|
- if (get_option(&uid,
|
||||||
|
+ i = get_option(&uid,
|
||||||
|
&dhcp_universe,
|
||||||
|
packet,
|
||||||
|
NULL,
|
||||||
|
@@ -283,8 +283,20 @@ dhcpleasequery(struct packet *packet, in
|
||||||
|
packet->options,
|
||||||
|
&global_scope,
|
||||||
|
DHO_DHCP_CLIENT_IDENTIFIER,
|
||||||
|
- MDL)) {
|
||||||
|
-
|
||||||
|
+ MDL);
|
||||||
|
+ if (!i)
|
||||||
|
+ i = get_option(&uid,
|
||||||
|
+ &dhcp_universe,
|
||||||
|
+ packet,
|
||||||
|
+ NULL,
|
||||||
|
+ NULL,
|
||||||
|
+ packet->options,
|
||||||
|
+ NULL,
|
||||||
|
+ packet->options,
|
||||||
|
+ &global_scope,
|
||||||
|
+ DHO_PXE_CLIENT_ID,
|
||||||
|
+ MDL);
|
||||||
|
+ if (i) {
|
||||||
|
snprintf(dbg_info,
|
||||||
|
sizeof(dbg_info),
|
||||||
|
"client-id %s",
|
||||||
|
diff -up dhcp-4.3.5b1/server/failover.c.option97 dhcp-4.3.5b1/server/failover.c
|
||||||
|
--- dhcp-4.3.5b1/server/failover.c.option97 2016-08-26 20:19:53.000000000 +0200
|
||||||
|
+++ dhcp-4.3.5b1/server/failover.c 2016-09-12 17:17:13.975691044 +0200
|
||||||
|
@@ -5957,6 +5957,9 @@ int load_balance_mine (struct packet *pa
|
||||||
|
|
||||||
|
oc = lookup_option(&dhcp_universe, packet->options,
|
||||||
|
DHO_DHCP_CLIENT_IDENTIFIER);
|
||||||
|
+ if (!oc)
|
||||||
|
+ oc = lookup_option(&dhcp_universe, packet -> options,
|
||||||
|
+ DHO_PXE_CLIENT_ID);
|
||||||
|
memset(&ds, 0, sizeof ds);
|
||||||
|
if (oc &&
|
||||||
|
evaluate_option_cache(&ds, packet, NULL, NULL,
|
||||||
|
diff -up dhcp-4.3.5b1/server/mdb.c.option97 dhcp-4.3.5b1/server/mdb.c
|
||||||
|
--- dhcp-4.3.5b1/server/mdb.c.option97 2016-08-26 20:19:53.000000000 +0200
|
||||||
|
+++ dhcp-4.3.5b1/server/mdb.c 2016-09-12 17:17:13.975691044 +0200
|
||||||
|
@@ -129,8 +129,9 @@ static int find_uid_statement (struct ex
|
||||||
|
esp -> data.option &&
|
||||||
|
(esp -> data.option -> option -> universe ==
|
||||||
|
&dhcp_universe) &&
|
||||||
|
- (esp -> data.option -> option -> code ==
|
||||||
|
- DHO_DHCP_CLIENT_IDENTIFIER)) {
|
||||||
|
+ ((esp -> data.option -> option -> code ==
|
||||||
|
+ DHO_DHCP_CLIENT_IDENTIFIER) ||
|
||||||
|
+ (esp -> data.option -> option -> code == DHO_PXE_CLIENT_ID))) {
|
||||||
|
if (condp) {
|
||||||
|
log_error ("dhcp client identifier may not be %s",
|
||||||
|
"specified conditionally.");
|
@ -0,0 +1,38 @@
|
|||||||
|
diff -up dhcp-4.3.0a1/doc/examples/dhcpd-dhcpv6.conf.paths dhcp-4.3.0a1/doc/examples/dhcpd-dhcpv6.conf
|
||||||
|
--- dhcp-4.3.0a1/doc/examples/dhcpd-dhcpv6.conf.paths 2013-11-07 20:15:08.000000000 +0100
|
||||||
|
+++ dhcp-4.3.0a1/doc/examples/dhcpd-dhcpv6.conf 2013-12-19 15:34:16.262247711 +0100
|
||||||
|
@@ -42,7 +42,7 @@ option dhcp6.domain-search "test.example
|
||||||
|
option dhcp6.info-refresh-time 21600;
|
||||||
|
|
||||||
|
# The path of the lease file
|
||||||
|
-dhcpv6-lease-file-name "/usr/local/var/db/dhcpd6.leases";
|
||||||
|
+dhcpv6-lease-file-name "/var/lib/dhcpd/dhcpd6.leases";
|
||||||
|
|
||||||
|
# Static definition (must be global)
|
||||||
|
host myclient {
|
||||||
|
diff -up dhcp-4.3.0a1/includes/dhcpd.h.paths dhcp-4.3.0a1/includes/dhcpd.h
|
||||||
|
--- dhcp-4.3.0a1/includes/dhcpd.h.paths 2013-12-19 15:34:16.253247840 +0100
|
||||||
|
+++ dhcp-4.3.0a1/includes/dhcpd.h 2013-12-19 15:34:16.263247697 +0100
|
||||||
|
@@ -1429,7 +1429,7 @@ typedef unsigned char option_mask [16];
|
||||||
|
#else /* !DEBUG */
|
||||||
|
|
||||||
|
#ifndef _PATH_DHCPD_CONF
|
||||||
|
-#define _PATH_DHCPD_CONF "/etc/dhcpd.conf"
|
||||||
|
+#define _PATH_DHCPD_CONF "/etc/dhcp/dhcpd.conf"
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
#ifndef _PATH_DHCPD_DB
|
||||||
|
@@ -1451,11 +1451,11 @@ typedef unsigned char option_mask [16];
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
#ifndef _PATH_DHCLIENT_CONF
|
||||||
|
-#define _PATH_DHCLIENT_CONF "/etc/dhclient.conf"
|
||||||
|
+#define _PATH_DHCLIENT_CONF "/etc/dhcp/dhclient.conf"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _PATH_DHCLIENT_SCRIPT
|
||||||
|
-#define _PATH_DHCLIENT_SCRIPT "/sbin/dhclient-script"
|
||||||
|
+#define _PATH_DHCLIENT_SCRIPT "/usr/sbin/dhclient-script"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _PATH_DHCLIENT_PID
|
@ -0,0 +1,85 @@
|
|||||||
|
diff -up dhcp-4.3.0a1/client/dhclient.c.ifup dhcp-4.3.0a1/client/dhclient.c
|
||||||
|
--- dhcp-4.3.0a1/client/dhclient.c.ifup 2013-12-19 14:53:08.817760677 +0100
|
||||||
|
+++ dhcp-4.3.0a1/client/dhclient.c 2013-12-19 15:05:16.290518574 +0100
|
||||||
|
@@ -521,9 +521,81 @@ main(int argc, char **argv) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(pidfd);
|
||||||
|
+ } else {
|
||||||
|
+ /* handle release for interfaces requested with Red Hat
|
||||||
|
+ * /sbin/ifup - pidfile will be /var/run/dhclient-$interface.pid
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ if ((path_dhclient_pid == NULL) || (*path_dhclient_pid == '\0'))
|
||||||
|
+ path_dhclient_pid = "/var/run/dhclient.pid";
|
||||||
|
+
|
||||||
|
+ char *new_path_dhclient_pid;
|
||||||
|
+ struct interface_info *ip;
|
||||||
|
+ int pdp_len = strlen(path_dhclient_pid), pfx, dpfx;
|
||||||
|
+
|
||||||
|
+ /* find append point: beginning of any trailing '.pid'
|
||||||
|
+ * or '-$IF.pid' */
|
||||||
|
+ for (pfx=pdp_len; (pfx >= 0) && (path_dhclient_pid[pfx] != '.') && (path_dhclient_pid[pfx] != '/'); pfx--);
|
||||||
|
+ if (pfx == -1)
|
||||||
|
+ pfx = pdp_len;
|
||||||
|
+
|
||||||
|
+ if (path_dhclient_pid[pfx] == '/')
|
||||||
|
+ pfx += 1;
|
||||||
|
+
|
||||||
|
+ for (dpfx=pfx; (dpfx >= 0) && (path_dhclient_pid[dpfx] != '-') && (path_dhclient_pid[dpfx] != '/'); dpfx--);
|
||||||
|
+ if ((dpfx > -1) && (path_dhclient_pid[dpfx] != '/'))
|
||||||
|
+ pfx = dpfx;
|
||||||
|
+
|
||||||
|
+ for (ip = interfaces; ip; ip = ip->next) {
|
||||||
|
+ if (interfaces_requested && (ip->flags & (INTERFACE_REQUESTED))) {
|
||||||
|
+ int n_len = strlen(ip->name);
|
||||||
|
+
|
||||||
|
+ new_path_dhclient_pid = (char*) malloc(pfx + n_len + 6);
|
||||||
|
+ strncpy(new_path_dhclient_pid, path_dhclient_pid, pfx);
|
||||||
|
+ sprintf(new_path_dhclient_pid + pfx, "-%s.pid", ip->name);
|
||||||
|
+
|
||||||
|
+ if ((pidfd = fopen(new_path_dhclient_pid, "r")) != NULL) {
|
||||||
|
+ e = fscanf(pidfd, "%ld\n", &temp);
|
||||||
|
+ oldpid = (pid_t)temp;
|
||||||
|
+
|
||||||
|
+ if (e != 0 && e != EOF) {
|
||||||
|
+ if (oldpid) {
|
||||||
|
+ if (kill(oldpid, SIGTERM) == 0)
|
||||||
|
+ unlink(path_dhclient_pid);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ fclose(pidfd);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ free(new_path_dhclient_pid);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ FILE *pidfp = NULL;
|
||||||
|
+ long temp = 0;
|
||||||
|
+ pid_t dhcpid = 0;
|
||||||
|
+ int dhc_running = 0;
|
||||||
|
+ char procfn[256] = "";
|
||||||
|
+
|
||||||
|
+ if ((pidfp = fopen(path_dhclient_pid, "r")) != NULL) {
|
||||||
|
+ if ((fscanf(pidfp, "%ld", &temp)==1) && ((dhcpid=(pid_t)temp) > 0)) {
|
||||||
|
+ snprintf(procfn,256,"/proc/%u",dhcpid);
|
||||||
|
+ dhc_running = (access(procfn, F_OK) == 0);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ fclose(pidfp);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (dhc_running) {
|
||||||
|
+ log_fatal("dhclient(%u) is already running - exiting. ", dhcpid);
|
||||||
|
+ return(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ write_client_pid_file();
|
||||||
|
+
|
||||||
|
if (!quiet) {
|
||||||
|
log_info("%s %s", message, PACKAGE_VERSION);
|
||||||
|
log_info(copyright);
|
@ -0,0 +1,351 @@
|
|||||||
|
From 2698385647a6ebd58b5d25147333e494c3da2409 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Petr Mensik <pemensik@redhat.com>
|
||||||
|
Date: Fri, 9 Feb 2018 15:24:53 +0100
|
||||||
|
Subject: [PATCH] Support for isc-config.sh script on --with-libbind parameter
|
||||||
|
|
||||||
|
Move checks only to isc-config section
|
||||||
|
|
||||||
|
Fix detection of bind flags from config
|
||||||
|
|
||||||
|
Add support for with-libbind=config, Improve help message
|
||||||
|
---
|
||||||
|
client/Makefile.am | 5 ++-
|
||||||
|
client/tests/Makefile.am | 8 ++---
|
||||||
|
common/tests/Makefile.am | 14 +++-----
|
||||||
|
configure.ac | 84 ++++++++++++++++++++++++++++++++++++++++++------
|
||||||
|
dhcpctl/Makefile.am | 8 ++---
|
||||||
|
omapip/Makefile.am | 5 ++-
|
||||||
|
relay/Makefile.am | 5 ++-
|
||||||
|
server/Makefile.am | 6 ++--
|
||||||
|
server/tests/Makefile.am | 9 +++---
|
||||||
|
9 files changed, 98 insertions(+), 46 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/client/Makefile.am b/client/Makefile.am
|
||||||
|
index 2cb83d8..b85f5d2 100644
|
||||||
|
--- a/client/Makefile.am
|
||||||
|
+++ b/client/Makefile.am
|
||||||
|
@@ -4,7 +4,7 @@
|
||||||
|
# production code. Sadly, we are not there yet.
|
||||||
|
SUBDIRS = . tests
|
||||||
|
|
||||||
|
-BINDLIBDIR = @BINDDIR@/lib
|
||||||
|
+BIND_LIBS = @BIND_LIBS@
|
||||||
|
|
||||||
|
AM_CPPFLAGS = -DCLIENT_PATH='"PATH=$(sbindir):/sbin:/bin:/usr/sbin:/usr/bin"' \
|
||||||
|
-DLOCALSTATEDIR='"$(localstatedir)"'
|
||||||
|
@@ -15,7 +15,6 @@ dhclient_SOURCES = clparse.c dhclient.c dhc6.c \
|
||||||
|
scripts/bsdos scripts/freebsd scripts/linux scripts/macos \
|
||||||
|
scripts/netbsd scripts/nextstep scripts/openbsd \
|
||||||
|
scripts/solaris scripts/openwrt
|
||||||
|
-dhclient_LDADD = ../common/libdhcp.a ../omapip/libomapi.a $(BINDLIBDIR)/libirs.a \
|
||||||
|
- $(BINDLIBDIR)/libdns.a $(BINDLIBDIR)/libisccfg.a $(BINDLIBDIR)/libisc.a
|
||||||
|
+dhclient_LDADD = ../common/libdhcp.a ../omapip/libomapi.a $(BIND_LIBS)
|
||||||
|
man_MANS = dhclient.8 dhclient-script.8 dhclient.conf.5 dhclient.leases.5
|
||||||
|
EXTRA_DIST = $(man_MANS)
|
||||||
|
diff --git a/client/tests/Makefile.am b/client/tests/Makefile.am
|
||||||
|
index 5031d0c..bb1fda4 100644
|
||||||
|
--- a/client/tests/Makefile.am
|
||||||
|
+++ b/client/tests/Makefile.am
|
||||||
|
@@ -1,9 +1,9 @@
|
||||||
|
SUBDIRS = .
|
||||||
|
|
||||||
|
-BINDLIBDIR = @BINDDIR@/lib
|
||||||
|
+BIND_LIBS = @BIND_LIBS@
|
||||||
|
|
||||||
|
AM_CPPFLAGS = $(ATF_CFLAGS) -DUNIT_TEST -I$(top_srcdir)/includes
|
||||||
|
-AM_CPPFLAGS += -I@BINDDIR@/include -I$(top_srcdir)
|
||||||
|
+AM_CPPFLAGS += @BIND_CPPFLAGS@ -I$(top_srcdir)
|
||||||
|
AM_CPPFLAGS += -DLOCALSTATEDIR='"."'
|
||||||
|
AM_CPPFLAGS += -DCLIENT_PATH='"."'
|
||||||
|
|
||||||
|
@@ -18,9 +18,7 @@ info:
|
||||||
|
DHCPSRC = ../clparse.c ../dhc6.c ../dhclient.c
|
||||||
|
|
||||||
|
DHCPLIBS = $(top_builddir)/common/libdhcp.a $(top_builddir)/omapip/libomapi.a \
|
||||||
|
- $(top_builddir)/dhcpctl/libdhcpctl.a $(BINDLIBDIR)/libirs.a \
|
||||||
|
- $(BINDLIBDIR)/libdns.a $(BINDLIBDIR)/libisccfg.a \
|
||||||
|
- $(BINDLIBDIR)/libisc.a
|
||||||
|
+ $(top_builddir)/dhcpctl/libdhcpctl.a $(BIND_LIBS)
|
||||||
|
|
||||||
|
ATF_TESTS =
|
||||||
|
if HAVE_ATF
|
||||||
|
diff --git a/common/tests/Makefile.am b/common/tests/Makefile.am
|
||||||
|
index f6a43e4..196aa44 100644
|
||||||
|
--- a/common/tests/Makefile.am
|
||||||
|
+++ b/common/tests/Makefile.am
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
SUBDIRS = .
|
||||||
|
|
||||||
|
-BINDLIBDIR = @BINDDIR@/lib
|
||||||
|
+BIND_LIBS = @BIND_LIBS@
|
||||||
|
|
||||||
|
AM_CPPFLAGS = $(ATF_CFLAGS) -I$(top_srcdir)/includes
|
||||||
|
|
||||||
|
@@ -15,26 +15,22 @@ ATF_TESTS += alloc_unittest dns_unittest misc_unittest ns_name_unittest
|
||||||
|
alloc_unittest_SOURCES = test_alloc.c $(top_srcdir)/tests/t_api_dhcp.c
|
||||||
|
alloc_unittest_LDADD = $(ATF_LDFLAGS)
|
||||||
|
alloc_unittest_LDADD += ../libdhcp.a \
|
||||||
|
- ../../omapip/libomapi.a $(BINDLIBDIR)/libirs.a \
|
||||||
|
- $(BINDLIBDIR)/libdns.a $(BINDLIBDIR)/libisccfg.a $(BINDLIBDIR)/libisc.a
|
||||||
|
+ ../../omapip/libomapi.a $(BIND_LIBS)
|
||||||
|
|
||||||
|
dns_unittest_SOURCES = dns_unittest.c $(top_srcdir)/tests/t_api_dhcp.c
|
||||||
|
dns_unittest_LDADD = $(ATF_LDFLAGS)
|
||||||
|
dns_unittest_LDADD += ../libdhcp.a \
|
||||||
|
- ../../omapip/libomapi.a $(BINDLIBDIR)/libirs.a \
|
||||||
|
- $(BINDLIBDIR)/libdns.a $(BINDLIBDIR)/libisccfg.a $(BINDLIBDIR)/libisc.a
|
||||||
|
+ ../../omapip/libomapi.a $(BIND_LIBS)
|
||||||
|
|
||||||
|
misc_unittest_SOURCES = misc_unittest.c $(top_srcdir)/tests/t_api_dhcp.c
|
||||||
|
misc_unittest_LDADD = $(ATF_LDFLAGS)
|
||||||
|
misc_unittest_LDADD += ../libdhcp.a \
|
||||||
|
- ../../omapip/libomapi.a $(BINDLIBDIR)/libirs.a \
|
||||||
|
- $(BINDLIBDIR)/libdns.a $(BINDLIBDIR)/libisccfg.a $(BINDLIBDIR)/libisc.a
|
||||||
|
+ ../../omapip/libomapi.a $(BIND_LIBS)
|
||||||
|
|
||||||
|
ns_name_unittest_SOURCES = ns_name_test.c $(top_srcdir)/tests/t_api_dhcp.c
|
||||||
|
ns_name_unittest_LDADD = $(ATF_LDFLAGS)
|
||||||
|
ns_name_unittest_LDADD += ../libdhcp.a \
|
||||||
|
- ../../omapip/libomapi.a $(BINDLIBDIR)/libirs.a \
|
||||||
|
- $(BINDLIBDIR)/libdns.a $(BINDLIBDIR)/libisccfg.a $(BINDLIBDIR)/libisc.a
|
||||||
|
+ ../../omapip/libomapi.a $(BIND_LIBS)
|
||||||
|
|
||||||
|
check: $(ATF_TESTS)
|
||||||
|
@if test $(top_srcdir) != ${top_builddir}; then \
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index cdfa352..ef55f8d 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -688,8 +688,12 @@ AC_CHECK_MEMBER(struct tpacket_auxdata.tp_vlan_tci,
|
||||||
|
|
||||||
|
BINDDIR=
|
||||||
|
BINDSRCDIR=
|
||||||
|
+BIND_CONFIG=
|
||||||
|
+BIND_CPPFLAGS=
|
||||||
|
+BIND_LIBS=
|
||||||
|
AC_ARG_WITH(libbind,
|
||||||
|
- AS_HELP_STRING([--with-libbind=PATH],[bind includes and libraries are in PATH
|
||||||
|
+ AS_HELP_STRING([--with-libbind=PATH|config],[bind includes and libraries are in PATH.
|
||||||
|
+ Use config to obtain libraries from isc-config.sh.
|
||||||
|
(default is ./bind)]),
|
||||||
|
use_libbind="$withval", use_libbind="no")
|
||||||
|
case "$use_libbind" in
|
||||||
|
@@ -701,23 +705,85 @@ no)
|
||||||
|
BINDDIR="\${top_srcdir}/bind"
|
||||||
|
BINDSRCDIR="\${top_srcdir}/bind"
|
||||||
|
;;
|
||||||
|
+config)
|
||||||
|
+ AC_PATH_PROG(BIND_CONFIG, [isc-config.sh bind9-config])
|
||||||
|
+ ;;
|
||||||
|
*)
|
||||||
|
- BINDDIR="$use_libbind"
|
||||||
|
- if test ! -d "$srcdir/bind"; then
|
||||||
|
- # no bind directory, create it with a fake Makefile.in
|
||||||
|
- # (AC_CONFIG_FILES and top Makefile refer to it so
|
||||||
|
- # it must exits)
|
||||||
|
- mkdir $srcdir/bind
|
||||||
|
- cat > $srcdir/bind/Makefile.in << EOF
|
||||||
|
+ if test -f "$use_libbind" -a -x "$use_libbind"; then
|
||||||
|
+ # passed full path of isc-config.sh
|
||||||
|
+ BIND_CONFIG="$use_libbind"
|
||||||
|
+ else
|
||||||
|
+ BINDDIR="$use_libbind"
|
||||||
|
+ if test ! -d "$srcdir/bind"; then
|
||||||
|
+ # no bind directory, create it with a fake Makefile.in
|
||||||
|
+ # (AC_CONFIG_FILES and top Makefile refer to it so
|
||||||
|
+ # it must exits)
|
||||||
|
+ mkdir $srcdir/bind
|
||||||
|
+ cat > $srcdir/bind/Makefile.in << EOF
|
||||||
|
# placeholder
|
||||||
|
all check clean distclean distdir install uninstall:
|
||||||
|
|
||||||
|
EOF
|
||||||
|
+ fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
+if test -z "$BIND_CONFIG"; then
|
||||||
|
+ BIND_CPPFLAGS="-I${BINDDIR}/include"
|
||||||
|
+ BIND_LIBDIR="${BINDDIR}/lib"
|
||||||
|
+ BIND_LIBS="$(BINDLIBDIR)/libirs.a $(BINDLIBDIR)/libdns.a $(BINDLIBDIR)/libisccfg.a $(BINDLIBDIR)/libisc.a"
|
||||||
|
+else
|
||||||
|
+ BIND_CPPFLAGS=`$BIND_CONFIG --cflags`
|
||||||
|
+ BIND_LIBS=`$BIND_CONFIG --libs irs dns isccfg isc`
|
||||||
|
+
|
||||||
|
+ # bind is already built
|
||||||
|
+ AC_CHECKING([Checking bind libraries have no thread support])
|
||||||
|
+ saved_libs="$LIBS"
|
||||||
|
+ saved_CPPFLAGS="$CPPFLAGS"
|
||||||
|
+ CPPFLAGS="${CPPFLAGS} ${BIND_CPPFLAGS}"
|
||||||
|
+ LIBS="${LIBS} ${BIND_LIBS}"
|
||||||
|
+AC_TRY_LINK([
|
||||||
|
+#include <isc/bind9.h>
|
||||||
|
+#include <isc/lib.h>
|
||||||
|
+],[
|
||||||
|
+#ifdef BIND9
|
||||||
|
+#error Export BIND library has to be used with BIND version up to 9.9
|
||||||
|
+#endif
|
||||||
|
+isc_lib_register();
|
||||||
|
+], [AC_MSG_RESULT(Bind export library found)
|
||||||
|
+ BIND_EXPORT=yes], [BIND_EXPORT=no]
|
||||||
|
+)
|
||||||
|
+
|
||||||
|
+# Allow build with disabled threads for dhcp
|
||||||
|
+AC_TRY_LINK([
|
||||||
|
+#include <isc/platform.h>
|
||||||
|
+#include <isc/bind9.h>
|
||||||
|
+#include <isc/lib.h>
|
||||||
|
+],[
|
||||||
|
+#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
+#error Bind library must not be compiled with threads
|
||||||
|
+#endif
|
||||||
|
+isc_lib_register();
|
||||||
|
+if (isc_bind9 != 0) {}
|
||||||
|
+], [AC_MSG_RESULT(Bind single thread library found)
|
||||||
|
+ BIND_SINGLETHREAD=yes], [BIND_SINGLETHREAD=no]
|
||||||
|
+)
|
||||||
|
+
|
||||||
|
+ if test "x$BIND_EXPORT" != xyes -a "x$BIND_SINGLETHREADED" != xyes
|
||||||
|
+ then
|
||||||
|
+ AC_MSG_RESULT([BIND_CONFIG=${BIND_CONFIG}])
|
||||||
|
+ AC_MSG_RESULT([BIND_CPPFLAGS=${BIND_CPPFLAGS}])
|
||||||
|
+ AC_MSG_RESULT([BIND_LIBS=${BIND_LIBS}])
|
||||||
|
+ AC_MSG_ERROR([Bind libraries are not useable for dhcp])
|
||||||
|
+ fi
|
||||||
|
+ CPPFLAGS="$saved_CPPFLAGS"
|
||||||
|
+ LIBS="$saved_LIBS"
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
AC_SUBST(BINDDIR)
|
||||||
|
AC_SUBST(BINDSRCDIR)
|
||||||
|
+AC_SUBST(BIND_CPPFLAGS)
|
||||||
|
+AC_SUBST(BIND_LIBS)
|
||||||
|
|
||||||
|
# OpenLDAP support.
|
||||||
|
AC_ARG_WITH(ldap,
|
||||||
|
@@ -795,7 +861,7 @@ fi
|
||||||
|
CFLAGS="$CFLAGS $STD_CWARNINGS"
|
||||||
|
|
||||||
|
# Try to add the bind and dhcp include directories
|
||||||
|
-CFLAGS="$CFLAGS -I\$(top_srcdir)/includes -I$BINDDIR/include"
|
||||||
|
+CFLAGS="$CFLAGS -I\$(top_srcdir)/includes $BIND_CPPFLAGS"
|
||||||
|
|
||||||
|
case "$host" in
|
||||||
|
*-darwin*)
|
||||||
|
diff --git a/dhcpctl/Makefile.am b/dhcpctl/Makefile.am
|
||||||
|
index ceb0de1..fa20a78 100644
|
||||||
|
--- a/dhcpctl/Makefile.am
|
||||||
|
+++ b/dhcpctl/Makefile.am
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-BINDLIBDIR = @BINDDIR@/lib
|
||||||
|
+BIND_LIBS = @BIND_LIBS@
|
||||||
|
|
||||||
|
bin_PROGRAMS = omshell
|
||||||
|
lib_LIBRARIES = libdhcpctl.a
|
||||||
|
@@ -8,12 +8,10 @@ EXTRA_DIST = $(man_MANS)
|
||||||
|
|
||||||
|
omshell_SOURCES = omshell.c
|
||||||
|
omshell_LDADD = libdhcpctl.a ../common/libdhcp.a ../omapip/libomapi.a \
|
||||||
|
- $(BINDLIBDIR)/libirs.a $(BINDLIBDIR)/libdns.a \
|
||||||
|
- $(BINDLIBDIR)/libisccfg.a $(BINDLIBDIR)/libisc.a
|
||||||
|
+ $(BIND_LIBS)
|
||||||
|
|
||||||
|
libdhcpctl_a_SOURCES = dhcpctl.c callback.c remote.c
|
||||||
|
|
||||||
|
cltest_SOURCES = cltest.c
|
||||||
|
cltest_LDADD = libdhcpctl.a ../common/libdhcp.a ../omapip/libomapi.a \
|
||||||
|
- $(BINDLIBDIR)/libirs.a $(BINDLIBDIR)/libdns.a \
|
||||||
|
- $(BINDLIBDIR)/libisccfg.a $(BINDLIBDIR)/libisc.a
|
||||||
|
+ $(BIND_LIBS)
|
||||||
|
diff --git a/omapip/Makefile.am b/omapip/Makefile.am
|
||||||
|
index 446a594..b0d2680 100644
|
||||||
|
--- a/omapip/Makefile.am
|
||||||
|
+++ b/omapip/Makefile.am
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-BINDLIBDIR = @BINDDIR@/lib
|
||||||
|
+BIND_LIBS = @BIND_LIBS@
|
||||||
|
|
||||||
|
lib_LIBRARIES = libomapi.a
|
||||||
|
noinst_PROGRAMS = svtest
|
||||||
|
@@ -12,6 +12,5 @@ man_MANS = omapi.3
|
||||||
|
EXTRA_DIST = $(man_MANS)
|
||||||
|
|
||||||
|
svtest_SOURCES = test.c
|
||||||
|
-svtest_LDADD = libomapi.a $(BINDLIBDIR)/libirs.a $(BINDLIBDIR)/libdns.a \
|
||||||
|
- $(BINDLIBDIR)/libisccfg.a $(BINDLIBDIR)/libisc.a
|
||||||
|
+svtest_LDADD = libomapi.a $(BIND_LIBS)
|
||||||
|
|
||||||
|
diff --git a/relay/Makefile.am b/relay/Makefile.am
|
||||||
|
index 3060eca..c9a1cba 100644
|
||||||
|
--- a/relay/Makefile.am
|
||||||
|
+++ b/relay/Makefile.am
|
||||||
|
@@ -1,12 +1,11 @@
|
||||||
|
-BINDLIBDIR = @BINDDIR@/lib
|
||||||
|
+BIND_LIBS = @BIND_LIBS@
|
||||||
|
|
||||||
|
AM_CPPFLAGS = -DLOCALSTATEDIR='"@localstatedir@"'
|
||||||
|
|
||||||
|
sbin_PROGRAMS = dhcrelay
|
||||||
|
dhcrelay_SOURCES = dhcrelay.c
|
||||||
|
dhcrelay_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \
|
||||||
|
- $(BINDLIBDIR)/libirs.a $(BINDLIBDIR)/libdns.a \
|
||||||
|
- $(BINDLIBDIR)/libisccfg.a $(BINDLIBDIR)/libisc.a
|
||||||
|
+ $(BIND_LIBS)
|
||||||
|
man_MANS = dhcrelay.8
|
||||||
|
EXTRA_DIST = $(man_MANS)
|
||||||
|
|
||||||
|
diff --git a/server/Makefile.am b/server/Makefile.am
|
||||||
|
index 54feedf..30cf2b1 100644
|
||||||
|
--- a/server/Makefile.am
|
||||||
|
+++ b/server/Makefile.am
|
||||||
|
@@ -4,7 +4,7 @@
|
||||||
|
# production code. Sadly, we are not there yet.
|
||||||
|
SUBDIRS = . tests
|
||||||
|
|
||||||
|
-BINDLIBDIR = @BINDDIR@/lib
|
||||||
|
+BIND_LIBS = @BIND_LIBS@
|
||||||
|
|
||||||
|
AM_CPPFLAGS = -I.. -DLOCALSTATEDIR='"@localstatedir@"'
|
||||||
|
|
||||||
|
@@ -16,9 +16,7 @@ dhcpd_SOURCES = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \
|
||||||
|
|
||||||
|
dhcpd_CFLAGS = $(LDAP_CFLAGS)
|
||||||
|
dhcpd_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \
|
||||||
|
- ../dhcpctl/libdhcpctl.a $(BINDLIBDIR)/libirs.a \
|
||||||
|
- $(BINDLIBDIR)/libdns.a $(BINDLIBDIR)/libisccfg.a \
|
||||||
|
- $(BINDLIBDIR)/libisc.a $(LDAP_LIBS)
|
||||||
|
+ ../dhcpctl/libdhcpctl.a $(BIND_LIBS) $(LDAP_LIBS)
|
||||||
|
|
||||||
|
man_MANS = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5
|
||||||
|
EXTRA_DIST = $(man_MANS)
|
||||||
|
diff --git a/server/tests/Makefile.am b/server/tests/Makefile.am
|
||||||
|
index a87c5e7..771de06 100644
|
||||||
|
--- a/server/tests/Makefile.am
|
||||||
|
+++ b/server/tests/Makefile.am
|
||||||
|
@@ -1,9 +1,10 @@
|
||||||
|
SUBDIRS = .
|
||||||
|
|
||||||
|
-BINDLIBDIR = @BINDDIR@/lib
|
||||||
|
+BIND_LIBS = @BIND_LIBS@
|
||||||
|
+
|
||||||
|
|
||||||
|
AM_CPPFLAGS = $(ATF_CFLAGS) -DUNIT_TEST -I$(top_srcdir)/includes
|
||||||
|
-AM_CPPFLAGS += -I@BINDDIR@/include -I$(top_srcdir)
|
||||||
|
+AM_CPPFLAGS += $(BIND_CPPFLAGS) -I$(top_srcdir)
|
||||||
|
AM_CPPFLAGS += -DLOCALSTATEDIR='"."'
|
||||||
|
|
||||||
|
EXTRA_DIST = Atffile
|
||||||
|
@@ -20,9 +21,7 @@ DHCPSRC = ../dhcp.c ../bootp.c ../confpars.c ../db.c ../class.c \
|
||||||
|
../ldap.c ../ldap_casa.c ../dhcpd.c ../leasechain.c
|
||||||
|
|
||||||
|
DHCPLIBS = $(top_builddir)/common/libdhcp.a $(top_builddir)/omapip/libomapi.a \
|
||||||
|
- $(top_builddir)/dhcpctl/libdhcpctl.a $(BINDLIBDIR)/libirs.a \
|
||||||
|
- $(BINDLIBDIR)/libdns.a $(BINDLIBDIR)/libisccfg.a \
|
||||||
|
- $(BINDLIBDIR)/libisc.a
|
||||||
|
+ $(top_builddir)/dhcpctl/libdhcpctl.a $(BIND_LIBS)
|
||||||
|
|
||||||
|
ATF_TESTS =
|
||||||
|
if HAVE_ATF
|
||||||
|
--
|
||||||
|
2.14.3
|
||||||
|
|
@ -0,0 +1,44 @@
|
|||||||
|
diff --git a/server/confpars.c b/server/confpars.c
|
||||||
|
index d79489b..2b1e393 100644
|
||||||
|
--- a/server/confpars.c
|
||||||
|
+++ b/server/confpars.c
|
||||||
|
@@ -134,6 +134,11 @@ isc_result_t read_conf_file (const char *filename, struct group *group,
|
||||||
|
|
||||||
|
cfile = (struct parse *)0;
|
||||||
|
#if defined (TRACING)
|
||||||
|
+ // No need to dmalloc huge memory region if we're not going to re-play
|
||||||
|
+ if (!trace_record()){
|
||||||
|
+ status = new_parse(&cfile, file, NULL, 0, filename, 0);
|
||||||
|
+ goto noreplay;
|
||||||
|
+ };
|
||||||
|
flen = lseek (file, (off_t)0, SEEK_END);
|
||||||
|
if (flen < 0) {
|
||||||
|
boom:
|
||||||
|
@@ -165,7 +170,6 @@ isc_result_t read_conf_file (const char *filename, struct group *group,
|
||||||
|
if (result != ulen)
|
||||||
|
log_fatal ("%s: short read of %d bytes instead of %d.",
|
||||||
|
filename, ulen, result);
|
||||||
|
- close (file);
|
||||||
|
memfile:
|
||||||
|
/* If we're recording, write out the filename and file contents. */
|
||||||
|
if (trace_record ())
|
||||||
|
@@ -174,6 +178,9 @@ isc_result_t read_conf_file (const char *filename, struct group *group,
|
||||||
|
#else
|
||||||
|
status = new_parse(&cfile, file, NULL, 0, filename, 0);
|
||||||
|
#endif
|
||||||
|
+ noreplay:
|
||||||
|
+ if (!trace_playback())
|
||||||
|
+ close (file);
|
||||||
|
if (status != ISC_R_SUCCESS || cfile == NULL)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
@@ -183,7 +190,8 @@ isc_result_t read_conf_file (const char *filename, struct group *group,
|
||||||
|
status = conf_file_subparse (cfile, group, group_type);
|
||||||
|
end_parse (&cfile);
|
||||||
|
#if defined (TRACING)
|
||||||
|
- dfree (dbuf, MDL);
|
||||||
|
+ if (trace_record())
|
||||||
|
+ dfree (dbuf, MDL);
|
||||||
|
#endif
|
||||||
|
return status;
|
||||||
|
}
|
@ -0,0 +1,405 @@
|
|||||||
|
diff -up dhcp-4.3.4/client/clparse.c.rfc3442 dhcp-4.3.4/client/clparse.c
|
||||||
|
--- dhcp-4.3.4/client/clparse.c.rfc3442 2016-04-29 12:23:34.192032714 +0200
|
||||||
|
+++ dhcp-4.3.4/client/clparse.c 2016-04-29 12:24:37.531016317 +0200
|
||||||
|
@@ -31,7 +31,7 @@
|
||||||
|
|
||||||
|
struct client_config top_level_config;
|
||||||
|
|
||||||
|
-#define NUM_DEFAULT_REQUESTED_OPTS 14
|
||||||
|
+#define NUM_DEFAULT_REQUESTED_OPTS 15
|
||||||
|
/* There can be 2 extra requested options for DHCPv4-over-DHCPv6. */
|
||||||
|
struct option *default_requested_options[NUM_DEFAULT_REQUESTED_OPTS + 2 + 1];
|
||||||
|
|
||||||
|
@@ -87,7 +87,11 @@ isc_result_t read_client_conf ()
|
||||||
|
dhcp_universe.code_hash, &code, 0, MDL);
|
||||||
|
|
||||||
|
/* 4 */
|
||||||
|
- code = DHO_ROUTERS;
|
||||||
|
+ /* The Classless Static Routes option code MUST appear in the parameter
|
||||||
|
+ * request list prior to both the Router option code and the Static
|
||||||
|
+ * Routes option code, if present. (RFC3442)
|
||||||
|
+ */
|
||||||
|
+ code = DHO_CLASSLESS_STATIC_ROUTES;
|
||||||
|
option_code_hash_lookup(&default_requested_options[3],
|
||||||
|
dhcp_universe.code_hash, &code, 0, MDL);
|
||||||
|
|
||||||
|
@@ -141,6 +145,11 @@ isc_result_t read_client_conf ()
|
||||||
|
option_code_hash_lookup(&default_requested_options[13],
|
||||||
|
dhcp_universe.code_hash, &code, 0, MDL);
|
||||||
|
|
||||||
|
+ /* 15 */
|
||||||
|
+ code = DHO_ROUTERS;
|
||||||
|
+ option_code_hash_lookup(&default_requested_options[14],
|
||||||
|
+ dhcp_universe.code_hash, &code, 0, MDL);
|
||||||
|
+
|
||||||
|
for (code = 0 ; code < NUM_DEFAULT_REQUESTED_OPTS ; code++) {
|
||||||
|
if (default_requested_options[code] == NULL)
|
||||||
|
log_fatal("Unable to find option definition for "
|
||||||
|
diff -up dhcp-4.3.4/common/dhcp-options.5.rfc3442 dhcp-4.3.4/common/dhcp-options.5
|
||||||
|
--- dhcp-4.3.4/common/dhcp-options.5.rfc3442 2016-04-29 12:23:34.183032716 +0200
|
||||||
|
+++ dhcp-4.3.4/common/dhcp-options.5 2016-04-29 12:23:34.237032703 +0200
|
||||||
|
@@ -111,6 +111,26 @@ hexadecimal, separated by colons. For e
|
||||||
|
or
|
||||||
|
option dhcp-client-identifier 43:4c:49:45:54:2d:46:4f:4f;
|
||||||
|
.fi
|
||||||
|
+.PP
|
||||||
|
+The
|
||||||
|
+.B destination-descriptor
|
||||||
|
+describe the IP subnet number and subnet mask
|
||||||
|
+of a particular destination using a compact encoding. This encoding
|
||||||
|
+consists of one octet describing the width of the subnet mask,
|
||||||
|
+followed by all the significant octets of the subnet number.
|
||||||
|
+The following table contains some examples of how various subnet
|
||||||
|
+number/mask combinations can be encoded:
|
||||||
|
+.nf
|
||||||
|
+.sp 1
|
||||||
|
+Subnet number Subnet mask Destination descriptor
|
||||||
|
+0 0 0
|
||||||
|
+10.0.0.0 255.0.0.0 8.10
|
||||||
|
+10.0.0.0 255.255.255.0 24.10.0.0
|
||||||
|
+10.17.0.0 255.255.0.0 16.10.17
|
||||||
|
+10.27.129.0 255.255.255.0 24.10.27.129
|
||||||
|
+10.229.0.128 255.255.255.128 25.10.229.0.128
|
||||||
|
+10.198.122.47 255.255.255.255 32.10.198.122.47
|
||||||
|
+.fi
|
||||||
|
.SH SETTING OPTION VALUES USING EXPRESSIONS
|
||||||
|
Sometimes it's helpful to be able to set the value of a DHCP option
|
||||||
|
based on some value that the client has sent. To do this, you can
|
||||||
|
@@ -1031,6 +1051,29 @@ dhclient-script will create routes:
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
.nf
|
||||||
|
+.B option \fBclassless-static-routes\fR \fIdestination-descriptor ip-address\fR
|
||||||
|
+ [\fB,\fR \fIdestination-descriptor ip-address\fR...]\fB;\fR
|
||||||
|
+.fi
|
||||||
|
+.RS 0.25i
|
||||||
|
+.PP
|
||||||
|
+This option (see RFC3442) specifies a list of classless static routes
|
||||||
|
+that the client should install in its routing cache.
|
||||||
|
+.PP
|
||||||
|
+This option can contain one or more static routes, each of which
|
||||||
|
+consists of a destination descriptor and the IP address of the router
|
||||||
|
+that should be used to reach that destination.
|
||||||
|
+.PP
|
||||||
|
+Many clients may not implement the Classless Static Routes option.
|
||||||
|
+DHCP server administrators should therefore configure their DHCP
|
||||||
|
+servers to send both a Router option and a Classless Static Routes
|
||||||
|
+option, and should specify the default router(s) both in the Router
|
||||||
|
+option and in the Classless Static Routes option.
|
||||||
|
+.PP
|
||||||
|
+If the DHCP server returns both a Classless Static Routes option and
|
||||||
|
+a Router option, the DHCP client ignores the Router option.
|
||||||
|
+.RE
|
||||||
|
+.PP
|
||||||
|
+.nf
|
||||||
|
.B option \fBstreettalk-directory-assistance-server\fR \fIip-address\fR
|
||||||
|
[\fB,\fR \fIip-address\fR...]\fB;\fR
|
||||||
|
.fi
|
||||||
|
diff -up dhcp-4.3.4/common/inet.c.rfc3442 dhcp-4.3.4/common/inet.c
|
||||||
|
--- dhcp-4.3.4/common/inet.c.rfc3442 2016-03-22 14:16:51.000000000 +0100
|
||||||
|
+++ dhcp-4.3.4/common/inet.c 2016-04-29 12:23:34.237032703 +0200
|
||||||
|
@@ -519,6 +519,60 @@ free_iaddrcidrnetlist(struct iaddrcidrne
|
||||||
|
return ISC_R_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static const char *
|
||||||
|
+inet_ntopdd(const unsigned char *src, unsigned srclen, char *dst, size_t size)
|
||||||
|
+{
|
||||||
|
+ char tmp[sizeof("32.255.255.255.255")];
|
||||||
|
+ int len;
|
||||||
|
+
|
||||||
|
+ switch (srclen) {
|
||||||
|
+ case 2:
|
||||||
|
+ len = sprintf (tmp, "%u.%u", src[0], src[1]);
|
||||||
|
+ break;
|
||||||
|
+ case 3:
|
||||||
|
+ len = sprintf (tmp, "%u.%u.%u", src[0], src[1], src[2]);
|
||||||
|
+ break;
|
||||||
|
+ case 4:
|
||||||
|
+ len = sprintf (tmp, "%u.%u.%u.%u", src[0], src[1], src[2], src[3]);
|
||||||
|
+ break;
|
||||||
|
+ case 5:
|
||||||
|
+ len = sprintf (tmp, "%u.%u.%u.%u.%u", src[0], src[1], src[2], src[3], src[4]);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ if (len < 0)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ if (len > size) {
|
||||||
|
+ errno = ENOSPC;
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return strcpy (dst, tmp);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* pdestdesc() turns an iaddr structure into a printable dest. descriptor */
|
||||||
|
+const char *
|
||||||
|
+pdestdesc(const struct iaddr addr) {
|
||||||
|
+ static char pbuf[sizeof("255.255.255.255.255")];
|
||||||
|
+
|
||||||
|
+ if (addr.len == 0) {
|
||||||
|
+ return "<null destination descriptor>";
|
||||||
|
+ }
|
||||||
|
+ if (addr.len == 1) {
|
||||||
|
+ return "0";
|
||||||
|
+ }
|
||||||
|
+ if ((addr.len >= 2) && (addr.len <= 5)) {
|
||||||
|
+ return inet_ntopdd(addr.iabuf, addr.len, pbuf, sizeof(pbuf));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ log_fatal("pdestdesc():%s:%d: Invalid destination descriptor length %d.",
|
||||||
|
+ MDL, addr.len);
|
||||||
|
+ /* quell compiler warnings */
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* piaddr() turns an iaddr structure into a printable address. */
|
||||||
|
/* XXX: should use a const pointer rather than passing the structure */
|
||||||
|
const char *
|
||||||
|
diff -up dhcp-4.3.4/common/options.c.rfc3442 dhcp-4.3.4/common/options.c
|
||||||
|
--- dhcp-4.3.4/common/options.c.rfc3442 2016-03-22 14:16:51.000000000 +0100
|
||||||
|
+++ dhcp-4.3.4/common/options.c 2016-04-29 12:23:34.237032703 +0200
|
||||||
|
@@ -713,7 +713,11 @@ cons_options(struct packet *inpacket, st
|
||||||
|
* packet.
|
||||||
|
*/
|
||||||
|
priority_list[priority_len++] = DHO_SUBNET_MASK;
|
||||||
|
- priority_list[priority_len++] = DHO_ROUTERS;
|
||||||
|
+ if (lookup_option(&dhcp_universe, cfg_options,
|
||||||
|
+ DHO_CLASSLESS_STATIC_ROUTES))
|
||||||
|
+ priority_list[priority_len++] = DHO_CLASSLESS_STATIC_ROUTES;
|
||||||
|
+ else
|
||||||
|
+ priority_list[priority_len++] = DHO_ROUTERS;
|
||||||
|
priority_list[priority_len++] = DHO_DOMAIN_NAME_SERVERS;
|
||||||
|
priority_list[priority_len++] = DHO_HOST_NAME;
|
||||||
|
priority_list[priority_len++] = DHO_FQDN;
|
||||||
|
@@ -1694,6 +1698,7 @@ const char *pretty_print_option (option,
|
||||||
|
unsigned long tval;
|
||||||
|
isc_boolean_t a_array = ISC_FALSE;
|
||||||
|
int len_used;
|
||||||
|
+ unsigned int octets = 0;
|
||||||
|
|
||||||
|
if (emit_commas)
|
||||||
|
comma = ',';
|
||||||
|
@@ -1702,6 +1707,7 @@ const char *pretty_print_option (option,
|
||||||
|
|
||||||
|
memset (enumbuf, 0, sizeof enumbuf);
|
||||||
|
|
||||||
|
+ if (option->format[0] != 'R') { /* see explanation lower */
|
||||||
|
/* Figure out the size of the data. */
|
||||||
|
for (l = i = 0; option -> format [i]; i++, l++) {
|
||||||
|
if (l >= sizeof(fmtbuf) - 1)
|
||||||
|
@@ -1894,6 +1900,33 @@ const char *pretty_print_option (option,
|
||||||
|
if (numhunk < 0)
|
||||||
|
numhunk = 1;
|
||||||
|
|
||||||
|
+ } else { /* option->format[i] == 'R') */
|
||||||
|
+ /* R (destination descriptor) has variable length.
|
||||||
|
+ * We can find it only in classless static route option,
|
||||||
|
+ * so we are for sure parsing classless static route option now.
|
||||||
|
+ * We go through whole the option to check whether there are no
|
||||||
|
+ * missing/extra bytes.
|
||||||
|
+ * I didn't find out how to improve the existing code and that's the
|
||||||
|
+ * reason for this separate 'else' where I do my own checkings.
|
||||||
|
+ * I know it's little bit unsystematic, but it works.
|
||||||
|
+ */
|
||||||
|
+ numhunk = 0;
|
||||||
|
+ numelem = 2; /* RI */
|
||||||
|
+ fmtbuf[0]='R'; fmtbuf[1]='I'; fmtbuf[2]=0;
|
||||||
|
+ for (i =0; i < len; i = i + octets + 5) {
|
||||||
|
+ if (data[i] > 32) { /* subnet mask width */
|
||||||
|
+ log_error ("wrong subnet mask width in destination descriptor");
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ numhunk++;
|
||||||
|
+ octets = ((data[i]+7) / 8);
|
||||||
|
+ }
|
||||||
|
+ if (i != len) {
|
||||||
|
+ log_error ("classless static routes option has wrong size or "
|
||||||
|
+ "there's some garbage in format");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* Cycle through the array (or hunk) printing the data. */
|
||||||
|
for (i = 0; i < numhunk; i++) {
|
||||||
|
if ((a_array == ISC_TRUE) && (i != 0) && (numelem > 0)) {
|
||||||
|
@@ -2049,6 +2082,20 @@ const char *pretty_print_option (option,
|
||||||
|
strcpy(op, piaddr(iaddr));
|
||||||
|
dp += 4;
|
||||||
|
break;
|
||||||
|
+
|
||||||
|
+ case 'R':
|
||||||
|
+ if (dp[0] <= 32)
|
||||||
|
+ iaddr.len = (((dp[0]+7)/8)+1);
|
||||||
|
+ else {
|
||||||
|
+ log_error ("wrong subnet mask width in destination descriptor");
|
||||||
|
+ return "<error>";
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ memcpy(iaddr.iabuf, dp, iaddr.len);
|
||||||
|
+ strcpy(op, pdestdesc(iaddr));
|
||||||
|
+ dp += iaddr.len;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
case '6':
|
||||||
|
iaddr.len = 16;
|
||||||
|
memcpy(iaddr.iabuf, dp, 16);
|
||||||
|
diff -up dhcp-4.3.4/common/parse.c.rfc3442 dhcp-4.3.4/common/parse.c
|
||||||
|
--- dhcp-4.3.4/common/parse.c.rfc3442 2016-04-29 12:23:34.220032707 +0200
|
||||||
|
+++ dhcp-4.3.4/common/parse.c 2016-04-29 12:23:34.238032702 +0200
|
||||||
|
@@ -341,6 +341,39 @@ int parse_ip_addr (cfile, addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
+ * destination-descriptor :== NUMBER DOT NUMBER |
|
||||||
|
+ * NUMBER DOT NUMBER DOT NUMBER |
|
||||||
|
+ * NUMBER DOT NUMBER DOT NUMBER DOT NUMBER |
|
||||||
|
+ * NUMBER DOT NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+int parse_destination_descriptor (cfile, addr)
|
||||||
|
+ struct parse *cfile;
|
||||||
|
+ struct iaddr *addr;
|
||||||
|
+{
|
||||||
|
+ unsigned int mask_width, dest_dest_len;
|
||||||
|
+ addr -> len = 0;
|
||||||
|
+ if (parse_numeric_aggregate (cfile, addr -> iabuf,
|
||||||
|
+ &addr -> len, DOT, 10, 8)) {
|
||||||
|
+ mask_width = (unsigned int)addr->iabuf[0];
|
||||||
|
+ dest_dest_len = (((mask_width+7)/8)+1);
|
||||||
|
+ if (mask_width > 32) {
|
||||||
|
+ parse_warn (cfile,
|
||||||
|
+ "subnet mask width (%u) greater than 32.", mask_width);
|
||||||
|
+ }
|
||||||
|
+ else if (dest_dest_len != addr->len) {
|
||||||
|
+ parse_warn (cfile,
|
||||||
|
+ "destination descriptor with subnet mask width %u "
|
||||||
|
+ "should have %u octets, but has %u octets.",
|
||||||
|
+ mask_width, dest_dest_len, addr->len);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
* Return true if every character in the string is hexadecimal.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
@@ -720,8 +753,10 @@ unsigned char *parse_numeric_aggregate (
|
||||||
|
if (count) {
|
||||||
|
token = peek_token (&val, (unsigned *)0, cfile);
|
||||||
|
if (token != separator) {
|
||||||
|
- if (!*max)
|
||||||
|
+ if (!*max) {
|
||||||
|
+ *max = count;
|
||||||
|
break;
|
||||||
|
+ }
|
||||||
|
if (token != RBRACE && token != LBRACE)
|
||||||
|
token = next_token (&val,
|
||||||
|
(unsigned *)0,
|
||||||
|
@@ -1668,6 +1703,9 @@ int parse_option_code_definition (cfile,
|
||||||
|
case IP_ADDRESS:
|
||||||
|
type = 'I';
|
||||||
|
break;
|
||||||
|
+ case DESTINATION_DESCRIPTOR:
|
||||||
|
+ type = 'R';
|
||||||
|
+ break;
|
||||||
|
case IP6_ADDRESS:
|
||||||
|
type = '6';
|
||||||
|
break;
|
||||||
|
@@ -5097,6 +5135,15 @@ int parse_option_token (rv, cfile, fmt,
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
+ case 'R': /* destination descriptor */
|
||||||
|
+ if (!parse_destination_descriptor (cfile, &addr)) {
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ if (!make_const_data (&t, addr.iabuf, addr.len, 0, 1, MDL)) {
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
case '6': /* IPv6 address. */
|
||||||
|
if (!parse_ip6_addr(cfile, &addr)) {
|
||||||
|
return 0;
|
||||||
|
@@ -5374,6 +5421,13 @@ int parse_option_decl (oc, cfile)
|
||||||
|
goto exit;
|
||||||
|
len = ip_addr.len;
|
||||||
|
dp = ip_addr.iabuf;
|
||||||
|
+ goto alloc;
|
||||||
|
+
|
||||||
|
+ case 'R': /* destination descriptor */
|
||||||
|
+ if (!parse_destination_descriptor (cfile, &ip_addr))
|
||||||
|
+ goto exit;
|
||||||
|
+ len = ip_addr.len;
|
||||||
|
+ dp = ip_addr.iabuf;
|
||||||
|
|
||||||
|
alloc:
|
||||||
|
if (hunkix + len > sizeof hunkbuf) {
|
||||||
|
diff -up dhcp-4.3.4/common/tables.c.rfc3442 dhcp-4.3.4/common/tables.c
|
||||||
|
--- dhcp-4.3.4/common/tables.c.rfc3442 2016-04-29 12:23:34.209032710 +0200
|
||||||
|
+++ dhcp-4.3.4/common/tables.c 2016-04-29 12:23:34.238032702 +0200
|
||||||
|
@@ -45,6 +45,7 @@ HASH_FUNCTIONS (option_code, const unsig
|
||||||
|
Format codes:
|
||||||
|
|
||||||
|
I - IPv4 address
|
||||||
|
+ R - destination descriptor (RFC3442)
|
||||||
|
6 - IPv6 address
|
||||||
|
l - 32-bit signed integer
|
||||||
|
L - 32-bit unsigned integer
|
||||||
|
@@ -216,6 +217,7 @@ static struct option dhcp_options[] = {
|
||||||
|
#endif
|
||||||
|
{ "subnet-selection", "I", &dhcp_universe, 118, 1 },
|
||||||
|
{ "domain-search", "D", &dhcp_universe, 119, 1 },
|
||||||
|
+ { "classless-static-routes", "RIA", &dhcp_universe, 121, 1 },
|
||||||
|
{ "vivco", "Evendor-class.", &dhcp_universe, 124, 1 },
|
||||||
|
{ "vivso", "Evendor.", &dhcp_universe, 125, 1 },
|
||||||
|
#if 0
|
||||||
|
diff -up dhcp-4.3.4/includes/dhcpd.h.rfc3442 dhcp-4.3.4/includes/dhcpd.h
|
||||||
|
--- dhcp-4.3.4/includes/dhcpd.h.rfc3442 2016-04-29 12:23:34.186032716 +0200
|
||||||
|
+++ dhcp-4.3.4/includes/dhcpd.h 2016-04-29 12:23:34.239032702 +0200
|
||||||
|
@@ -2894,6 +2894,7 @@ isc_result_t range2cidr(struct iaddrcidr
|
||||||
|
const struct iaddr *lo, const struct iaddr *hi);
|
||||||
|
isc_result_t free_iaddrcidrnetlist(struct iaddrcidrnetlist **result);
|
||||||
|
const char *piaddr (struct iaddr);
|
||||||
|
+const char *pdestdesc (struct iaddr);
|
||||||
|
char *piaddrmask(struct iaddr *, struct iaddr *);
|
||||||
|
char *piaddrcidr(const struct iaddr *, unsigned int);
|
||||||
|
u_int16_t validate_port(char *);
|
||||||
|
@@ -3108,6 +3109,7 @@ void parse_client_lease_declaration (str
|
||||||
|
int parse_option_decl (struct option_cache **, struct parse *);
|
||||||
|
void parse_string_list (struct parse *, struct string_list **, int);
|
||||||
|
int parse_ip_addr (struct parse *, struct iaddr *);
|
||||||
|
+int parse_destination_descriptor (struct parse *, struct iaddr *);
|
||||||
|
int parse_ip_addr_with_subnet(struct parse *, struct iaddrmatch *);
|
||||||
|
void parse_reject_statement (struct parse *, struct client_config *);
|
||||||
|
|
||||||
|
diff -up dhcp-4.3.4/includes/dhcp.h.rfc3442 dhcp-4.3.4/includes/dhcp.h
|
||||||
|
--- dhcp-4.3.4/includes/dhcp.h.rfc3442 2016-03-22 14:16:51.000000000 +0100
|
||||||
|
+++ dhcp-4.3.4/includes/dhcp.h 2016-04-29 12:23:34.239032702 +0200
|
||||||
|
@@ -159,6 +159,7 @@ struct dhcp_packet {
|
||||||
|
#define DHO_ASSOCIATED_IP 92
|
||||||
|
#define DHO_SUBNET_SELECTION 118 /* RFC3011! */
|
||||||
|
#define DHO_DOMAIN_SEARCH 119 /* RFC3397 */
|
||||||
|
+#define DHO_CLASSLESS_STATIC_ROUTES 121 /* RFC3442 */
|
||||||
|
#define DHO_VIVCO_SUBOPTIONS 124
|
||||||
|
#define DHO_VIVSO_SUBOPTIONS 125
|
||||||
|
|
||||||
|
diff -up dhcp-4.3.4/includes/dhctoken.h.rfc3442 dhcp-4.3.4/includes/dhctoken.h
|
||||||
|
--- dhcp-4.3.4/includes/dhctoken.h.rfc3442 2016-04-29 12:23:34.239032702 +0200
|
||||||
|
+++ dhcp-4.3.4/includes/dhctoken.h 2016-04-29 12:25:07.236008628 +0200
|
||||||
|
@@ -374,7 +374,8 @@ enum dhcp_token {
|
||||||
|
LEASE_ID_FORMAT = 676,
|
||||||
|
TOKEN_HEX = 677,
|
||||||
|
TOKEN_OCTAL = 678,
|
||||||
|
- BOOTP_BROADCAST_ALWAYS = 679
|
||||||
|
+ BOOTP_BROADCAST_ALWAYS = 679,
|
||||||
|
+ DESTINATION_DESCRIPTOR = 680
|
||||||
|
};
|
||||||
|
|
||||||
|
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
|
@ -0,0 +1,79 @@
|
|||||||
|
diff -up dhcp-4.3.4/configure.ac.sd_notify dhcp-4.3.4/configure.ac
|
||||||
|
--- dhcp-4.3.4/configure.ac.sd_notify 2016-04-29 13:08:52.813287060 +0200
|
||||||
|
+++ dhcp-4.3.4/configure.ac 2016-04-29 13:08:52.872287075 +0200
|
||||||
|
@@ -832,6 +832,17 @@ if test x$ldap = xyes || test x$ldapcryp
|
||||||
|
AC_SUBST(LDAP_CFLAGS, [$LDAP_CFLAGS])
|
||||||
|
fi
|
||||||
|
|
||||||
|
+AC_ARG_WITH(systemd,
|
||||||
|
+ AC_HELP_STRING([--with-systemd],
|
||||||
|
+ [enable sending status notifications to systemd daemon (default is no)]),
|
||||||
|
+ [systemd=$withval],
|
||||||
|
+ [systemd=no])
|
||||||
|
+
|
||||||
|
+if test x$systemd = xyes ; then
|
||||||
|
+ AC_CHECK_LIB(systemd, sd_notifyf, ,
|
||||||
|
+ AC_MSG_FAILURE([*** systemd library not present - do you need to install systemd-libs package?]))
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
# Append selected warning levels to CFLAGS before substitution (but after
|
||||||
|
# AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[],[]) & etc).
|
||||||
|
CFLAGS="$CFLAGS $STD_CWARNINGS"
|
||||||
|
diff -up dhcp-4.3.4/relay/dhcrelay.c.sd_notify dhcp-4.3.4/relay/dhcrelay.c
|
||||||
|
--- dhcp-4.3.4/relay/dhcrelay.c.sd_notify 2016-04-29 13:08:52.814287061 +0200
|
||||||
|
+++ dhcp-4.3.4/relay/dhcrelay.c 2016-04-29 13:08:52.872287075 +0200
|
||||||
|
@@ -37,6 +37,10 @@
|
||||||
|
int keep_capabilities = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifdef HAVE_LIBSYSTEMD
|
||||||
|
+#include <systemd/sd-daemon.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
TIME default_lease_time = 43200; /* 12 hours... */
|
||||||
|
TIME max_lease_time = 86400; /* 24 hours... */
|
||||||
|
struct tree_cache *global_options[256];
|
||||||
|
@@ -709,6 +713,14 @@ main(int argc, char **argv) {
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifdef HAVE_LIBSYSTEMD
|
||||||
|
+ /* We are ready to process incomming packets. Let's notify systemd */
|
||||||
|
+ sd_notifyf(0, "READY=1\n"
|
||||||
|
+ "STATUS=Dispatching packets...\n"
|
||||||
|
+ "MAINPID=%lu",
|
||||||
|
+ (unsigned long) getpid());
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* Start dispatching packets and timeouts... */
|
||||||
|
dispatch();
|
||||||
|
|
||||||
|
diff -up dhcp-4.3.4/server/dhcpd.c.sd_notify dhcp-4.3.4/server/dhcpd.c
|
||||||
|
--- dhcp-4.3.4/server/dhcpd.c.sd_notify 2016-04-29 13:08:52.873287075 +0200
|
||||||
|
+++ dhcp-4.3.4/server/dhcpd.c 2016-04-29 13:12:00.655333096 +0200
|
||||||
|
@@ -57,6 +57,10 @@ uid_t set_uid = 0;
|
||||||
|
gid_t set_gid = 0;
|
||||||
|
#endif /* PARANOIA */
|
||||||
|
|
||||||
|
+#ifdef HAVE_LIBSYSTEMD
|
||||||
|
+#include <systemd/sd-daemon.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
struct iaddr server_identifier;
|
||||||
|
int server_identifier_matched;
|
||||||
|
|
||||||
|
@@ -931,6 +935,14 @@ main(int argc, char **argv) {
|
||||||
|
/* Log that we are about to start working */
|
||||||
|
log_info("Server starting service.");
|
||||||
|
|
||||||
|
+#ifdef HAVE_LIBSYSTEMD
|
||||||
|
+ /* We are ready to process incomming packets. Let's notify systemd */
|
||||||
|
+ sd_notifyf(0, "READY=1\n"
|
||||||
|
+ "STATUS=Dispatching packets...\n"
|
||||||
|
+ "MAINPID=%lu",
|
||||||
|
+ (unsigned long) getpid());
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Receive packets and dispatch them...
|
||||||
|
* dispatch() will never return.
|
@ -0,0 +1,231 @@
|
|||||||
|
diff -up dhcp-4.3.4/client/dhc6.c.sendDecline dhcp-4.3.4/client/dhc6.c
|
||||||
|
--- dhcp-4.3.4/client/dhc6.c.sendDecline 2016-03-22 14:16:51.000000000 +0100
|
||||||
|
+++ dhcp-4.3.4/client/dhc6.c 2016-05-02 14:51:57.916578401 +0200
|
||||||
|
@@ -115,6 +115,8 @@ void do_select6(void *input);
|
||||||
|
void do_refresh6(void *input);
|
||||||
|
static void do_release6(void *input);
|
||||||
|
static void start_bound(struct client_state *client);
|
||||||
|
+static void start_decline6(struct client_state *client);
|
||||||
|
+static void do_decline6(void *input);
|
||||||
|
static void start_informed(struct client_state *client);
|
||||||
|
void informed_handler(struct packet *packet, struct client_state *client);
|
||||||
|
void bound_handler(struct packet *packet, struct client_state *client);
|
||||||
|
@@ -2314,6 +2316,7 @@ start_release6(struct client_state *clie
|
||||||
|
cancel_timeout(do_select6, client);
|
||||||
|
cancel_timeout(do_refresh6, client);
|
||||||
|
cancel_timeout(do_release6, client);
|
||||||
|
+ cancel_timeout(do_decline6, client);
|
||||||
|
client->state = S_STOPPED;
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -2968,6 +2971,7 @@ dhc6_check_reply(struct client_state *cl
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_STOPPED:
|
||||||
|
+ case S_DECLINED:
|
||||||
|
action = dhc6_stop_action;
|
||||||
|
break;
|
||||||
|
|
||||||
|
@@ -3084,6 +3088,7 @@ dhc6_check_reply(struct client_state *cl
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_STOPPED:
|
||||||
|
+ case S_DECLINED:
|
||||||
|
/* Nothing critical to do at this stage. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
@@ -4214,17 +4219,23 @@ reply_handler(struct packet *packet, str
|
||||||
|
cancel_timeout(do_select6, client);
|
||||||
|
cancel_timeout(do_refresh6, client);
|
||||||
|
cancel_timeout(do_release6, client);
|
||||||
|
+ cancel_timeout(do_decline6, client);
|
||||||
|
|
||||||
|
/* If this is in response to a Release/Decline, clean up and return. */
|
||||||
|
- if (client->state == S_STOPPED) {
|
||||||
|
- if (client->active_lease == NULL)
|
||||||
|
- return;
|
||||||
|
+ if ((client->state == S_STOPPED) ||
|
||||||
|
+ (client->state == S_DECLINED)) {
|
||||||
|
+
|
||||||
|
+ if (client->active_lease != NULL) {
|
||||||
|
+ dhc6_lease_destroy(&client->active_lease, MDL);
|
||||||
|
+ client->active_lease = NULL;
|
||||||
|
+ /* We should never wait for nothing!? */
|
||||||
|
+ if (stopping_finished())
|
||||||
|
+ exit(0);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (client->state == S_DECLINED)
|
||||||
|
+ start_init6(client);
|
||||||
|
|
||||||
|
- dhc6_lease_destroy(&client->active_lease, MDL);
|
||||||
|
- client->active_lease = NULL;
|
||||||
|
- /* We should never wait for nothing!? */
|
||||||
|
- if (stopping_finished())
|
||||||
|
- exit(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -4798,7 +4809,11 @@ start_bound(struct client_state *client)
|
||||||
|
dhc6_marshall_values("new_", client, lease, ia, addr);
|
||||||
|
script_write_requested6(client);
|
||||||
|
|
||||||
|
- script_go(client);
|
||||||
|
+ // when script returns 3, DAD failed
|
||||||
|
+ if (script_go(client) == 3) {
|
||||||
|
+ start_decline6(client);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX: maybe we should loop on the old values instead? */
|
||||||
|
@@ -4851,6 +4866,149 @@ start_bound(struct client_state *client)
|
||||||
|
dhc6_check_times(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Decline addresses.
|
||||||
|
+ */
|
||||||
|
+void
|
||||||
|
+start_decline6(struct client_state *client)
|
||||||
|
+{
|
||||||
|
+ /* Cancel any pending transmissions */
|
||||||
|
+ cancel_timeout(do_confirm6, client);
|
||||||
|
+ cancel_timeout(do_select6, client);
|
||||||
|
+ cancel_timeout(do_refresh6, client);
|
||||||
|
+ cancel_timeout(do_release6, client);
|
||||||
|
+ cancel_timeout(do_decline6, client);
|
||||||
|
+ client->state = S_DECLINED;
|
||||||
|
+
|
||||||
|
+ if (client->active_lease == NULL)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /* Set timers per RFC3315 section 18.1.7. */
|
||||||
|
+ client->IRT = DEC_TIMEOUT * 100;
|
||||||
|
+ client->MRT = 0;
|
||||||
|
+ client->MRC = DEC_MAX_RC;
|
||||||
|
+ client->MRD = 0;
|
||||||
|
+
|
||||||
|
+ dhc6_retrans_init(client);
|
||||||
|
+ client->v6_handler = reply_handler;
|
||||||
|
+
|
||||||
|
+ client->refresh_type = DHCPV6_DECLINE;
|
||||||
|
+ do_decline6(client);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * do_decline6() creates a Decline packet and transmits it.
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+do_decline6(void *input)
|
||||||
|
+{
|
||||||
|
+ struct client_state *client;
|
||||||
|
+ struct data_string ds;
|
||||||
|
+ struct timeval elapsed, tv;
|
||||||
|
+ int send_ret, added;
|
||||||
|
+
|
||||||
|
+ client = input;
|
||||||
|
+
|
||||||
|
+ if ((client->active_lease == NULL) || !active_prefix(client))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if ((client->MRC != 0) && (client->txcount > client->MRC)) {
|
||||||
|
+ log_info("Max retransmission count exceeded.");
|
||||||
|
+ goto decline_done;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Start_time starts at the first transmission.
|
||||||
|
+ */
|
||||||
|
+ if (client->txcount == 0) {
|
||||||
|
+ client->start_time.tv_sec = cur_tv.tv_sec;
|
||||||
|
+ client->start_time.tv_usec = cur_tv.tv_usec;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* elapsed = cur - start */
|
||||||
|
+ elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
|
||||||
|
+ elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
|
||||||
|
+ if (elapsed.tv_usec < 0) {
|
||||||
|
+ elapsed.tv_sec -= 1;
|
||||||
|
+ elapsed.tv_usec += 1000000;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ memset(&ds, 0, sizeof(ds));
|
||||||
|
+ if (!buffer_allocate(&ds.buffer, 4, MDL)) {
|
||||||
|
+ log_error("Unable to allocate memory for Decline.");
|
||||||
|
+ goto decline_done;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ds.data = ds.buffer->data;
|
||||||
|
+ ds.len = 4;
|
||||||
|
+ ds.buffer->data[0] = DHCPV6_DECLINE;
|
||||||
|
+ memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
|
||||||
|
+
|
||||||
|
+ /* Form an elapsed option. */
|
||||||
|
+ /* Maximum value is 65535 1/100s coded as 0xffff. */
|
||||||
|
+ if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
|
||||||
|
+ ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
|
||||||
|
+ client->elapsed = 0xffff;
|
||||||
|
+ } else {
|
||||||
|
+ client->elapsed = elapsed.tv_sec * 100;
|
||||||
|
+ client->elapsed += elapsed.tv_usec / 10000;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ client->elapsed = htons(client->elapsed);
|
||||||
|
+
|
||||||
|
+ log_debug("XMT: Forming Decline.");
|
||||||
|
+ make_client6_options(client, &client->sent_options,
|
||||||
|
+ client->active_lease, DHCPV6_DECLINE);
|
||||||
|
+ dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL,
|
||||||
|
+ client->sent_options, &global_scope,
|
||||||
|
+ &dhcpv6_universe);
|
||||||
|
+
|
||||||
|
+ /* Append IA's (but don't release temporary addresses). */
|
||||||
|
+ if (wanted_ia_na &&
|
||||||
|
+ dhc6_add_ia_na(client, &ds, client->active_lease,
|
||||||
|
+ DHCPV6_DECLINE, 0, &added) != ISC_R_SUCCESS) {
|
||||||
|
+ data_string_forget(&ds, MDL);
|
||||||
|
+ goto decline_done;
|
||||||
|
+ }
|
||||||
|
+ if (wanted_ia_pd &&
|
||||||
|
+ dhc6_add_ia_pd(client, &ds, client->active_lease,
|
||||||
|
+ DHCPV6_DECLINE, 0, &added) != ISC_R_SUCCESS) {
|
||||||
|
+ data_string_forget(&ds, MDL);
|
||||||
|
+ goto decline_done;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Transmit and wait. */
|
||||||
|
+ log_info("XMT: Decline on %s, interval %ld0ms.",
|
||||||
|
+ client->name ? client->name : client->interface->name,
|
||||||
|
+ (long int)client->RT);
|
||||||
|
+
|
||||||
|
+ send_ret = send_packet6(client->interface, ds.data, ds.len,
|
||||||
|
+ &DHCPv6DestAddr);
|
||||||
|
+ if (send_ret != ds.len) {
|
||||||
|
+ log_error("dhc6: sendpacket6() sent %d of %d bytes",
|
||||||
|
+ send_ret, ds.len);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ data_string_forget(&ds, MDL);
|
||||||
|
+
|
||||||
|
+ /* Wait RT */
|
||||||
|
+ tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
|
||||||
|
+ tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
|
||||||
|
+ if (tv.tv_usec >= 1000000) {
|
||||||
|
+ tv.tv_sec += 1;
|
||||||
|
+ tv.tv_usec -= 1000000;
|
||||||
|
+ }
|
||||||
|
+ add_timeout(&tv, do_decline6, client, NULL, NULL);
|
||||||
|
+ dhc6_retrans_advance(client);
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+decline_done:
|
||||||
|
+ dhc6_lease_destroy(&client->active_lease, MDL);
|
||||||
|
+ client->active_lease = NULL;
|
||||||
|
+ start_init6(client);
|
||||||
|
+ return;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* While bound, ignore packets. In the future we'll want to answer
|
||||||
|
* Reconfigure-Request messages and the like.
|
||||||
|
*/
|
@ -0,0 +1,149 @@
|
|||||||
|
diff --git a/client/Makefile.am b/client/Makefile.am
|
||||||
|
index b85f5d2..b1ecf82 100644
|
||||||
|
--- a/client/Makefile.am
|
||||||
|
+++ b/client/Makefile.am
|
||||||
|
@@ -15,6 +15,6 @@ dhclient_SOURCES = clparse.c dhclient.c dhc6.c \
|
||||||
|
scripts/bsdos scripts/freebsd scripts/linux scripts/macos \
|
||||||
|
scripts/netbsd scripts/nextstep scripts/openbsd \
|
||||||
|
scripts/solaris scripts/openwrt
|
||||||
|
-dhclient_LDADD = ../common/libdhcp.a ../omapip/libomapi.a $(BIND_LIBS)
|
||||||
|
+dhclient_LDADD = ../common/libdhcp.a ../omapip/libomapi.la $(BIND_LIBS)
|
||||||
|
man_MANS = dhclient.8 dhclient-script.8 dhclient.conf.5 dhclient.leases.5
|
||||||
|
EXTRA_DIST = $(man_MANS)
|
||||||
|
diff --git a/common/tests/Makefile.am b/common/tests/Makefile.am
|
||||||
|
index 196aa44..1ccaa05 100644
|
||||||
|
--- a/common/tests/Makefile.am
|
||||||
|
+++ b/common/tests/Makefile.am
|
||||||
|
@@ -15,22 +15,22 @@ ATF_TESTS += alloc_unittest dns_unittest misc_unittest ns_name_unittest
|
||||||
|
alloc_unittest_SOURCES = test_alloc.c $(top_srcdir)/tests/t_api_dhcp.c
|
||||||
|
alloc_unittest_LDADD = $(ATF_LDFLAGS)
|
||||||
|
alloc_unittest_LDADD += ../libdhcp.a \
|
||||||
|
- ../../omapip/libomapi.a $(BIND_LIBS)
|
||||||
|
+ ../../omapip/libomapi.la $(BIND_LIBS)
|
||||||
|
|
||||||
|
dns_unittest_SOURCES = dns_unittest.c $(top_srcdir)/tests/t_api_dhcp.c
|
||||||
|
dns_unittest_LDADD = $(ATF_LDFLAGS)
|
||||||
|
dns_unittest_LDADD += ../libdhcp.a \
|
||||||
|
- ../../omapip/libomapi.a $(BIND_LIBS)
|
||||||
|
+ ../../omapip/libomapi.la $(BIND_LIBS)
|
||||||
|
|
||||||
|
misc_unittest_SOURCES = misc_unittest.c $(top_srcdir)/tests/t_api_dhcp.c
|
||||||
|
misc_unittest_LDADD = $(ATF_LDFLAGS)
|
||||||
|
misc_unittest_LDADD += ../libdhcp.a \
|
||||||
|
- ../../omapip/libomapi.a $(BIND_LIBS)
|
||||||
|
+ ../../omapip/libomapi.la $(BIND_LIBS)
|
||||||
|
|
||||||
|
ns_name_unittest_SOURCES = ns_name_test.c $(top_srcdir)/tests/t_api_dhcp.c
|
||||||
|
ns_name_unittest_LDADD = $(ATF_LDFLAGS)
|
||||||
|
ns_name_unittest_LDADD += ../libdhcp.a \
|
||||||
|
- ../../omapip/libomapi.a $(BIND_LIBS)
|
||||||
|
+ ../../omapip/libomapi.la $(BIND_LIBS)
|
||||||
|
|
||||||
|
check: $(ATF_TESTS)
|
||||||
|
@if test $(top_srcdir) != ${top_builddir}; then \
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index f594cfa..adc98a8 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -47,7 +47,8 @@ AM_CONDITIONAL(CROSS_COMPILING, test "$cross_compiling" = "yes")
|
||||||
|
# Use this to define _GNU_SOURCE to pull in the IPv6 Advanced Socket API.
|
||||||
|
AC_USE_SYSTEM_EXTENSIONS
|
||||||
|
|
||||||
|
-AC_PROG_RANLIB
|
||||||
|
+# Use libtool to simplify building of shared libraries
|
||||||
|
+AC_PROG_LIBTOOL
|
||||||
|
|
||||||
|
AC_PATH_PROG(AR, ar)
|
||||||
|
AC_SUBST(AR)
|
||||||
|
diff --git a/dhcpctl/Makefile.am b/dhcpctl/Makefile.am
|
||||||
|
index fa20a78..dd016e4 100644
|
||||||
|
--- a/dhcpctl/Makefile.am
|
||||||
|
+++ b/dhcpctl/Makefile.am
|
||||||
|
@@ -1,17 +1,17 @@
|
||||||
|
BIND_LIBS = @BIND_LIBS@
|
||||||
|
|
||||||
|
bin_PROGRAMS = omshell
|
||||||
|
-lib_LIBRARIES = libdhcpctl.a
|
||||||
|
+lib_LTLIBRARIES = libdhcpctl.la
|
||||||
|
noinst_PROGRAMS = cltest
|
||||||
|
man_MANS = omshell.1 dhcpctl.3
|
||||||
|
EXTRA_DIST = $(man_MANS)
|
||||||
|
|
||||||
|
omshell_SOURCES = omshell.c
|
||||||
|
-omshell_LDADD = libdhcpctl.a ../common/libdhcp.a ../omapip/libomapi.a \
|
||||||
|
+omshell_LDADD = libdhcpctl.la ../common/libdhcp.a ../omapip/libomapi.la \
|
||||||
|
$(BIND_LIBS)
|
||||||
|
|
||||||
|
-libdhcpctl_a_SOURCES = dhcpctl.c callback.c remote.c
|
||||||
|
+libdhcpctl_la_SOURCES = dhcpctl.c callback.c remote.c
|
||||||
|
|
||||||
|
cltest_SOURCES = cltest.c
|
||||||
|
-cltest_LDADD = libdhcpctl.a ../common/libdhcp.a ../omapip/libomapi.a \
|
||||||
|
+cltest_LDADD = libdhcpctl.la ../common/libdhcp.a ../omapip/libomapi.la \
|
||||||
|
$(BIND_LIBS)
|
||||||
|
diff --git a/omapip/Makefile.am b/omapip/Makefile.am
|
||||||
|
index b0d2680..265bcef 100644
|
||||||
|
--- a/omapip/Makefile.am
|
||||||
|
+++ b/omapip/Makefile.am
|
||||||
|
@@ -1,9 +1,9 @@
|
||||||
|
BIND_LIBS = @BIND_LIBS@
|
||||||
|
|
||||||
|
-lib_LIBRARIES = libomapi.a
|
||||||
|
+lib_LTLIBRARIES = libomapi.la
|
||||||
|
noinst_PROGRAMS = svtest
|
||||||
|
|
||||||
|
-libomapi_a_SOURCES = protocol.c buffer.c alloc.c result.c connection.c \
|
||||||
|
+libomapi_la_SOURCES = protocol.c buffer.c alloc.c result.c connection.c \
|
||||||
|
errwarn.c listener.c dispatch.c generic.c support.c \
|
||||||
|
handle.c message.c convert.c hash.c auth.c inet_addr.c \
|
||||||
|
array.c trace.c toisc.c iscprint.c isclib.c
|
||||||
|
@@ -12,5 +12,5 @@ man_MANS = omapi.3
|
||||||
|
EXTRA_DIST = $(man_MANS)
|
||||||
|
|
||||||
|
svtest_SOURCES = test.c
|
||||||
|
-svtest_LDADD = libomapi.a $(BIND_LIBS)
|
||||||
|
+svtest_LDADD = libomapi.la $(BIND_LIBS)
|
||||||
|
|
||||||
|
diff --git a/relay/Makefile.am b/relay/Makefile.am
|
||||||
|
index c9a1cba..316a524 100644
|
||||||
|
--- a/relay/Makefile.am
|
||||||
|
+++ b/relay/Makefile.am
|
||||||
|
@@ -4,7 +4,7 @@ AM_CPPFLAGS = -DLOCALSTATEDIR='"@localstatedir@"'
|
||||||
|
|
||||||
|
sbin_PROGRAMS = dhcrelay
|
||||||
|
dhcrelay_SOURCES = dhcrelay.c
|
||||||
|
-dhcrelay_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \
|
||||||
|
+dhcrelay_LDADD = ../common/libdhcp.a ../omapip/libomapi.la \
|
||||||
|
$(BIND_LIBS)
|
||||||
|
man_MANS = dhcrelay.8
|
||||||
|
EXTRA_DIST = $(man_MANS)
|
||||||
|
diff --git a/server/Makefile.am b/server/Makefile.am
|
||||||
|
index 30cf2b1..f56f310 100644
|
||||||
|
--- a/server/Makefile.am
|
||||||
|
+++ b/server/Makefile.am
|
||||||
|
@@ -15,8 +15,8 @@ dhcpd_SOURCES = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \
|
||||||
|
dhcpv6.c mdb6.c ldap.c ldap_casa.c leasechain.c ldap_krb_helper.c
|
||||||
|
|
||||||
|
dhcpd_CFLAGS = $(LDAP_CFLAGS)
|
||||||
|
-dhcpd_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \
|
||||||
|
- ../dhcpctl/libdhcpctl.a $(BIND_LIBS) $(LDAP_LIBS)
|
||||||
|
+dhcpd_LDADD = ../common/libdhcp.a ../omapip/libomapi.la \
|
||||||
|
+ ../dhcpctl/libdhcpctl.la $(BIND_LIBS) $(LDAP_LIBS)
|
||||||
|
|
||||||
|
man_MANS = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5
|
||||||
|
EXTRA_DIST = $(man_MANS)
|
||||||
|
diff --git a/server/tests/Makefile.am b/server/tests/Makefile.am
|
||||||
|
index 771de06..8d8a2c1 100644
|
||||||
|
--- a/server/tests/Makefile.am
|
||||||
|
+++ b/server/tests/Makefile.am
|
||||||
|
@@ -20,8 +20,8 @@ DHCPSRC = ../dhcp.c ../bootp.c ../confpars.c ../db.c ../class.c \
|
||||||
|
../ddns.c ../dhcpleasequery.c ../dhcpv6.c ../mdb6.c \
|
||||||
|
../ldap.c ../ldap_casa.c ../dhcpd.c ../leasechain.c
|
||||||
|
|
||||||
|
-DHCPLIBS = $(top_builddir)/common/libdhcp.a $(top_builddir)/omapip/libomapi.a \
|
||||||
|
- $(top_builddir)/dhcpctl/libdhcpctl.a $(BIND_LIBS)
|
||||||
|
+DHCPLIBS = $(top_builddir)/common/libdhcp.a $(top_builddir)/omapip/libomapi.la \
|
||||||
|
+ $(top_builddir)/dhcpctl/libdhcpctl.la $(BIND_LIBS)
|
||||||
|
|
||||||
|
ATF_TESTS =
|
||||||
|
if HAVE_ATF
|
@ -0,0 +1,13 @@
|
|||||||
|
diff -up dhcp-4.3.4/client/dhclient.c.stateless-DUID-LLT dhcp-4.3.4/client/dhclient.c
|
||||||
|
--- dhcp-4.3.4/client/dhclient.c.stateless-DUID-LLT 2016-04-29 13:13:50.467360008 +0200
|
||||||
|
+++ dhcp-4.3.4/client/dhclient.c 2016-04-29 13:14:53.389375428 +0200
|
||||||
|
@@ -1317,6 +1317,9 @@ void run_stateless(int exit_mode, u_int1
|
||||||
|
data_string_forget(&default_duid, MDL);
|
||||||
|
|
||||||
|
form_duid(&default_duid, MDL);
|
||||||
|
+ if (form_duid(&default_duid, MDL) == ISC_R_SUCCESS &&
|
||||||
|
+ duid_type == DUID_LLT)
|
||||||
|
+ write_duid(&default_duid);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DHCP4o6
|
@ -0,0 +1,21 @@
|
|||||||
|
diff --git a/common/parse.c b/common/parse.c
|
||||||
|
index e78223c2..656b378b 100644
|
||||||
|
--- a/common/parse.c
|
||||||
|
+++ b/common/parse.c
|
||||||
|
@@ -5790,13 +5790,14 @@ int parse_X (cfile, buf, max)
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
- convert_num (cfile, &buf [len], val, 16, 8);
|
||||||
|
- if (len++ > max) {
|
||||||
|
+ if (len >= max) {
|
||||||
|
parse_warn (cfile,
|
||||||
|
"hexadecimal constant too long.");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+ convert_num (cfile, &buf [len], val, 16, 8);
|
||||||
|
+ len++;
|
||||||
|
token = peek_token (&val, (unsigned *)0, cfile);
|
||||||
|
if (token == COLON)
|
||||||
|
token = next_token (&val,
|
@ -0,0 +1,101 @@
|
|||||||
|
diff -up dhcp-4.3.4/server/bootp.c.unicast dhcp-4.3.4/server/bootp.c
|
||||||
|
--- dhcp-4.3.4/server/bootp.c.unicast 2016-03-22 14:16:51.000000000 +0100
|
||||||
|
+++ dhcp-4.3.4/server/bootp.c 2016-05-02 15:09:40.023243008 +0200
|
||||||
|
@@ -52,6 +52,7 @@ void bootp (packet)
|
||||||
|
char msgbuf [1024];
|
||||||
|
int ignorep;
|
||||||
|
int peer_has_leases = 0;
|
||||||
|
+ int norelay = 0;
|
||||||
|
|
||||||
|
if (packet -> raw -> op != BOOTREQUEST)
|
||||||
|
return;
|
||||||
|
@@ -67,7 +68,7 @@ void bootp (packet)
|
||||||
|
? inet_ntoa (packet -> raw -> giaddr)
|
||||||
|
: packet -> interface -> name);
|
||||||
|
|
||||||
|
- if (!locate_network (packet)) {
|
||||||
|
+ if ((norelay = locate_network (packet)) == 0) {
|
||||||
|
log_info ("%s: network unknown", msgbuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@@ -428,6 +429,15 @@ void bootp (packet)
|
||||||
|
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
+ } else if (norelay == 2) {
|
||||||
|
+ to.sin_addr = raw.ciaddr;
|
||||||
|
+ to.sin_port = remote_port;
|
||||||
|
+ if (fallback_interface) {
|
||||||
|
+ result = send_packet (fallback_interface, NULL, &raw,
|
||||||
|
+ outgoing.packet_length, from,
|
||||||
|
+ &to, &hto);
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* If it comes from a client that already knows its address
|
||||||
|
and is not requesting a broadcast response, and we can
|
||||||
|
diff -up dhcp-4.3.4/server/dhcp.c.unicast dhcp-4.3.4/server/dhcp.c
|
||||||
|
--- dhcp-4.3.4/server/dhcp.c.unicast 2016-03-22 14:16:51.000000000 +0100
|
||||||
|
+++ dhcp-4.3.4/server/dhcp.c 2016-05-02 15:10:13.255267511 +0200
|
||||||
|
@@ -5132,6 +5132,7 @@ int locate_network (packet)
|
||||||
|
struct data_string data;
|
||||||
|
struct subnet *subnet = (struct subnet *)0;
|
||||||
|
struct option_cache *oc;
|
||||||
|
+ int norelay = 0;
|
||||||
|
|
||||||
|
#if defined(DHCPv6) && defined(DHCP4o6)
|
||||||
|
if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
|
||||||
|
@@ -5153,12 +5154,24 @@ int locate_network (packet)
|
||||||
|
from the interface, if there is one. If not, fail. */
|
||||||
|
if (!oc && !packet -> raw -> giaddr.s_addr) {
|
||||||
|
if (packet -> interface -> shared_network) {
|
||||||
|
- shared_network_reference
|
||||||
|
- (&packet -> shared_network,
|
||||||
|
- packet -> interface -> shared_network, MDL);
|
||||||
|
- return 1;
|
||||||
|
+ struct in_addr any_addr;
|
||||||
|
+ any_addr.s_addr = INADDR_ANY;
|
||||||
|
+
|
||||||
|
+ if (!packet -> packet_type && memcmp(&packet -> raw -> ciaddr, &any_addr, 4)) {
|
||||||
|
+ struct iaddr cip;
|
||||||
|
+ memcpy(cip.iabuf, &packet -> raw -> ciaddr, 4);
|
||||||
|
+ cip.len = 4;
|
||||||
|
+ if (!find_grouped_subnet(&subnet, packet->interface->shared_network, cip, MDL))
|
||||||
|
+ norelay = 2;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!norelay) {
|
||||||
|
+ shared_network_reference(&packet -> shared_network, packet -> interface -> shared_network, MDL);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
- return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If there's an option indicating link connection, and it's valid,
|
||||||
|
@@ -5185,7 +5198,10 @@ int locate_network (packet)
|
||||||
|
data_string_forget (&data, MDL);
|
||||||
|
} else {
|
||||||
|
ia.len = 4;
|
||||||
|
- memcpy (ia.iabuf, &packet -> raw -> giaddr, 4);
|
||||||
|
+ if (norelay)
|
||||||
|
+ memcpy (ia.iabuf, &packet->raw->ciaddr, 4);
|
||||||
|
+ else
|
||||||
|
+ memcpy (ia.iabuf, &packet->raw->giaddr, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we know the subnet on which the IP address lives, use it. */
|
||||||
|
@@ -5193,7 +5209,10 @@ int locate_network (packet)
|
||||||
|
shared_network_reference (&packet -> shared_network,
|
||||||
|
subnet -> shared_network, MDL);
|
||||||
|
subnet_dereference (&subnet, MDL);
|
||||||
|
- return 1;
|
||||||
|
+ if (norelay)
|
||||||
|
+ return norelay;
|
||||||
|
+ else
|
||||||
|
+ return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, fail. */
|
@ -0,0 +1,15 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=DHCPv4 Server Daemon
|
||||||
|
Documentation=man:dhcpd(8) man:dhcpd.conf(5)
|
||||||
|
Wants=network-online.target
|
||||||
|
After=network-online.target
|
||||||
|
After=time-sync.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=notify
|
||||||
|
EnvironmentFile=-/etc/sysconfig/dhcpd
|
||||||
|
ExecStart=/usr/sbin/dhcpd -f -cf /etc/dhcp/dhcpd.conf -user dhcpd -group dhcpd --no-pid $DHCPDARGS
|
||||||
|
StandardError=null
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
@ -0,0 +1,15 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=DHCPv6 Server Daemon
|
||||||
|
Documentation=man:dhcpd(8) man:dhcpd.conf(5)
|
||||||
|
Wants=network-online.target
|
||||||
|
After=network-online.target
|
||||||
|
After=time-sync.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=notify
|
||||||
|
EnvironmentFile=-/etc/sysconfig/dhcpd6
|
||||||
|
ExecStart=/usr/sbin/dhcpd -f -6 -cf /etc/dhcp/dhcpd6.conf -user dhcpd -group dhcpd --no-pid $DHCPDARGS
|
||||||
|
StandardError=null
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
@ -0,0 +1,13 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=DHCP Relay Agent Daemon
|
||||||
|
Documentation=man:dhcrelay(8)
|
||||||
|
Wants=network-online.target
|
||||||
|
After=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=notify
|
||||||
|
ExecStart=/usr/sbin/dhcrelay -d --no-pid
|
||||||
|
StandardError=null
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue