This file is indexed.

/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