/etc/network/if-up.d/10check-duplicate-ip is in ifupdown-extra 0.28.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | #!/bin/sh
#
# Check if an IPv4 ddress we are going to assign to an Ethernet interface is
# already in use by another system.
#
# This script should be installed in /etc/network/if-up.d/
# if you want it to be used whenever an interface is configured.
#
# It can also be used as a standalone script by setting up
# its environment:
# IFACE=eth0 IF_ADDRESS=192.168.0.1 check-duplicate-ip
#
# NOTE: IF_ADDRESS is optional, if not provided it will be determined
# by using the ip tools
#
# This script only works with IPv4 addresses, it does not work
# for IPv6 since arping does not work there. Use the check-duplicate-ip6
# script instead.
#
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# You can also find a copy of the GNU General Public License at
# http://www.gnu.org/licenses/licenses.html#TOCLGPL
# Check if an IP we are going to assign to an Ethernet interface
# is already in use by another system.
#
DEFAULT=/etc/default/network-test
# Read system default file
[ -r "$DEFAULT" ] && . $DEFAULT
# Do not continue if the user has told us to not do arpings
[ "$DO_ARPING" = "no" ] && exit 0
# Defaults
ETHTOOL=/sbin/ethtool
[ ! -x "$ETHTOOL" ] && [ -x "/usr/sbin/ethtool" ] && ETHTOOL=/usr/sbin/ethtool
DO_SYSLOG=${DO_SYSLOG:-yes}
VERBOSITY=${VERBOSITY:-0}
# Set up our environment
LC_ALL=C
export LC_ALL
if [ "$DO_SYSLOG" = "yes" ] ; then
OUTPUT="logger -i -p daemon.err -s"
else
OUTPUT="echo"
fi
do_arping() {
# Send ARP pings to detect if there is a duplicate address "out there"
# Curiously enough, the script will return faster if there *is* a system
# with the same IP address and will take ${ARP_TIMEOUT}*${ARP_COUNT} seconds
# to return if there is none.
# Do not do the check if ethtool (if installed) tells us the interface
# does not have link, notice that ARPING will try to send the ARP requests
# even if there is no link so we use this to speed things up
# First determine physical interface in case aliased interfaces are used
real_iface=$(echo "$IFACE" | sed -e 's|:[[:digit:]]\+||')
if [ -x "$ETHTOOL" ] ; then
LINK="`$ETHTOOL $real_iface 2>&1| grep \"Link[[:blank:]]\+detected:\"`"
if ! echo $LINK | grep -q "yes$" ; then
return
fi
fi
for ADDR in $IF_ADDRESS; do
# Skip interface is address is IPv6, arping only works for IPv4
if ! echo ${ADDR} | grep -q ":" ; then
[ "$VERBOSITY" -eq 1 ] && $OUTPUT "DEBUG: Sending arp pings through $real_iface (for $IFACE) to detect other systems using $ADDR"
$ARPING -c $ARP_COUNT -w $ARP_TIMEOUT -D -I $real_iface $ADDR $ARPING_EXTRAOPTS >$ARPING_REDIR
if [ $? -ne 0 ] ; then
$OUTPUT "ERROR: Duplicate address $ADDR assigned in the network where $real_iface is connected to."
fi
fi
done
}
find_ip() {
# Try to obtain our IP address (DHCP case)
export IF_ADDRESS
IF_ADDRESS=$(ip addr show "$IFACE" | sed -rne 's|^[[:blank:]]*inet[[:blank:]]+([^/]+)/.*|\1|p')
return 0
}
if [ -z "$IFACE" ] ; then
echo "ERROR: Do not know what interface to check. IFACE environment variable is not defined!" >&2
exit 0
fi
# For arping:
# Two possible arpings: iputils-arping or arping, with different
# interpretation of the '-w' value
if [ -x /usr/bin/arping ] ; then
# We are going to use iputils-arping
ARPING=/usr/bin/arping
ARP_TIMEOUT=${ARP_TIMEOUT:-3} # Time here is measured in seconds
ARPING_EXTRAOPTS="-q" # Use -q(uiet) in iputil's arping
ARPING_REDIR="/dev/stdout" # Do not redirect output
else
if [ -x /usr/sbin/arping ] ; then
ARPING=/usr/sbin/arping
ARP_TIMEOUT=${ARP_TIMEOUT:-1500} # Time here is measures in milliseconds
# experiments show anything less than 1500 is unreliable.
ARPING_EXTRAOPTS="" # No '-q' option in arping
ARPING_REDIR=">/dev/null" # Send output to /dev/null if using this program
else
# Do not continue if ARPING is not available
echo "WARNING: Cannot check for duplicate IP address in the network. The script cannot find the 'arping' program (tried /usr/bin/arping and /usr/sbin/arping. Please either install the iputils-arping or arping packages or disable this test by setting DO_ARPING to 'no' in $DEFAULT ." >&2
exit 0
fi
fi
ARP_COUNT=${ARP_COUNT:-2}
# Check our IFACE name, if it does not start with eth, bail out
case "$IFACE" in
eth*)
[ -z "$IF_ADDRESS" ] && find_ip
# Still no IP? Bail out
if [ -z "$IF_ADDRESS" ] ; then
echo "WARNING: Cannot check for duplicate IP address in the network as the script could not find the ip address of $IFACE. You can disable this test by setting DO_ARPING to 'no' in $DEFAULT ." >&2
exit 0
fi
do_arping ;;
*) ;;
esac
exit 0
|