#!/bin/sh
#
#	$Id: IPaddr.in,v 1.52.2.11 2005/09/08 16:49:25 alan Exp $
#
#	This script manages IP alias IP addresses
#
#	It can add an IP alias, or remove one.
#
#	usage: $0 ip-address {start|stop|status|monitor}
#
#	The "start" arg adds an IP alias.
#
#	Surprisingly, the "stop" arg removes one.	:-)
#
#

unset LC_ALL; export LC_ALL # Make ifconfig work in France for David Jules :-)
unset LANGUAGE; export LANGUAGE # Make ifconfig work in France for Fabrice :-)
#	make ifconfig work in Austria for Gregor Gstl
#	I have no idea why the previous fix didn't fix it for him.
LC_MESSAGES=C
export LC_MESSAGES

prefix=/usr
exec_prefix=/usr
HA_D=/etc/ha.d
. ${HA_D}/shellfuncs

IFCONFIG=/sbin/ifconfig
IFCONFIG_A_OPT=
VARLIB=/var/lib/heartbeat
VLDIR=$VARLIB/rsctmp/IPaddr
SENDARPPIDDIR=$VARLIB/rsctmp/send_arp
ROUTE=/sbin/route
SENDARP=$HA_BIN/send_arp
FINDIF=$HA_BIN/findif
USAGE="usage: $0 ip-address {start|stop|status|monitor}";
SYSTYPE="`uname -s`"
case "$SYSTYPE" in
    SunOS)
        # `uname -r` = 5.9 -> SYSVERSION = 9
        SYSVERSION="`uname -r | cut -d. -f 2`"
	;;
    *)
        ;;
esac

#
#      Find out which alias serves the given IP address
#      The argument is an IP address, and its output
#      is an aliased interface name (e.g., "eth0:0").
#
find_interface_solaris() {

  ipaddr="$1";

  $IFCONFIG $IFCONFIG_A_OPT | nawk '{if ($0 ~ /.*: / && NR > 1) {print "\n"$0} else {print}}' |
  while read ifname linkstuff
  do
    : ifname = $ifname
    read inet addr junk
    : inet = $inet addr = $addr
    while
      read line && [ "X$line" != "X" ]
    do
      : Nothing
    done

    #  This doesn't look right for a box with multiple NICs.
    #  It looks like it always selects the first interface on
    #  a machine.  Yet, we appear to use the results for this case too...
    ifname=`echo "$ifname" | sed s'%:$%%'`

    case $addr in
      addr:$ipaddr)	echo $ifname; return 0;;
      $ipaddr)	echo $ifname; return 0;;
    esac
  done
  return 1
}

#
#	Find out which alias serves the given IP address
#	The argument is an IP address, and its output
#	is an aliased interface name (e.g., "eth0:0").
#
find_interface_generic() {

  ipaddr="$1";

  $IFCONFIG $IFCONFIG_A_OPT  |
  while read ifname linkstuff
  do
    : Read gave us ifname = $ifname

    read inet addr junk
    : Read gave us inet = $inet addr = $addr

    while
      read line && [ "X$line" != "X" ]
    do
      : Nothing
    done


    case $SYSTYPE in
      *BSD)
		$IFCONFIG | grep "$ipaddr" -B4 | grep "UP," | cut -d ":" -f 1
		return 0;;
      *)
    		: "comparing $ipaddr to $addr (from ifconfig)"
		case $addr in
		  addr:$ipaddr)	echo $ifname; return 0;;
		  $ipaddr)	echo $ifname; return 0;;
    		esac
		continue;;
    esac


  done
  return 1
}

#
#       Find out which alias serves the given IP address
#       The argument is an IP address, and its output
#       is an aliased interface name (e.g., "eth0:0").
#
find_interface() {
    case $SYSTYPE in
	SunOS)
	 	IF=`find_interface_solaris $BASEIP`
        ;;
      *)
	 	IF=`find_interface_generic $BASEIP`
       ;;
       esac

  echo $IF
  return 0;
}

#
# This routine should handle any type of interface, but has only been
# tested on ethernet-type NICs.
#
ifconfig2sendarp() {
	echo "$1" | sed "s%:%%g"
}

#add_route () {
#  ipaddr="$1"
#  iface="$2"
#
#  case $SYSTYPE in
#    	SunOS)	
#		dev_intf="-interface"
#		;;
#    	*BSD)	
#		dev_intf="-ifp"
#		;;
#    	*)	
#		dev_intf="dev"
#		;;
#  esac
#
#  ha_log "info: $ROUTE -n -add host $ipaddr $dev_intf $iface"
#  $ROUTE -n add -host $ipaddr $dev_intf $iface
#
#  return $?
#}

delete_route () {
  ipaddr="$1"

  case $SYSTYPE in
	SunOS)
		CMD=""
		;;
	*BSD)
		CMD="$ROUTE -n delete -host $ipaddr"
		;;

	*)	
		CMD="$ROUTE -n del -host $ipaddr"
		;;
  esac

  ha_log "info: $CMD"
  $CMD

  return $?
}

delete_interface () {
  ipaddr="$1"
  ifname="$2"

  case $SYSTYPE in
	SunOS)
		if [ "$SYSVERSION" -ge 8 ] ; then
		    CMD="$IFCONFIG $ifname unplumb"
		else
		    CMD="$IFCONFIG $ifname 0 down"
		fi
		;;
	*BSD)
		CMD="$IFCONFIG $ifname inet $ipaddr -alias"
		;;

	*)
		CMD="$IFCONFIG $ifname down"
		;;
  esac

  ha_log "info: $CMD"
  $CMD

  return $?
}


add_interface () {
  ipaddr="$1"
  ifinfo="$2"
  iface="$3"

  #
  #	On Linux the Alias is named ethx:y
  #	This will remove the "extra" interface Data 
  #	leaving us with just ethx
  #
  case $SYSTYPE in
    *BSD)
		IFEXTRA=""
		;;
    *)
		IFEXTRA=`echo "$ifinfo" | cut -f2-`
		;;
  esac

  case $SYSTYPE in
    SunOS)
		if [ "$SYSVERSION" -ge 8 ] ; then
		    $IFCONFIG $iface plumb
		    rc=$?
		    if [ $rc -ne 0 ] ; then
			echo "ERROR: '$IFCONFIG $iface plumb' failed."
			return $rc
		    fi
		fi
		CMD="$IFCONFIG $iface inet $ipaddr $IFEXTRA up"
		;;

    *BSD)
		CMD="$IFCONFIG $iface inet $ipaddr netmask 255.255.255.255 alias"
		;;
    *)		
    		CMD="$IFCONFIG $iface $ipaddr $IFEXTRA"	
		;;
  esac

  ha_log "info: $CMD"
  $CMD
  rc=$?

  case $rc in
    0)
    		;;
    *)
    		echo "ERROR: $CMD failed."
		;;
  esac

  return $rc
}

#      On Linux systems the (hidden) loopback interface may
#      conflict with the requested IP address. If so, this
#      unoriginal code will remove the offending loopback address
#      and save it in VLDIR so it can be added back in later
#      when the IPaddr is released.
#
remove_conflicting_loopback() {
	ipaddr="$1"
	ifname="$2"

	ha_log "info: Removing conflicting loopback $ifname."
	if
	  [ -d "$VLDIR/" ] || mkdir -p "$VLDIR/"
	then
	  : Directory $VLDIR now exists
	else
	  ha_log "ERROR: Could not create \"$VLDIR/\" conflicting" \
	  " loopback $ifname cannot be restored."
	fi
	if 
	  echo $ifname > "$VLDIR/$ipaddr"
	then
	  : Saved loopback information in $VLDIR/$ipaddr
	else
	  ha_log "ERROR: Could not save conflicting loopback $ifname." \
	  "it will not be restored."
	fi
	delete_interface "$ipaddr" "$ifname"
	# Forcibly remove the route (if it exists) to the loopback.
	delete_route "$ipaddr"
}

#      On Linux systems the (hidden) loopback interface may
#      need to be restored if it has been taken down previously
#      by remove_conflicting_loopback()
#
restore_loopback() {
	ipaddr="$1"

	if [ -s "$VLDIR/$ipaddr" ]; then
		ifname=`cat "$VLDIR/$ipaddr"`
		ha_log "info: Restoring loopback IP Address " \
			"$ipaddr on $ifname."
		add_interface "$ipaddr" "netmask 255.255.255.255" "$ifname"
		#add_route "$ipaddr" "$ifname"
		rm -f "$VLDIR/$ipaddr"
	fi
}

#
#	Remove the IP alias for the requested IP address...
#
ip_stop() {
  BASEIP=`echo $1 | sed s'%/.*%%'`
  SENDARPPIDFILE="$SENDARPPIDDIR/send_arp-$BASEIP"
  IF=`find_interface $BASEIP`
  case $SYSTYPE in
	*BSD)
		;;
	Linux|SunOS)
  		case $IF in
    				*:*)	;; 	# Linux style alias DEVICE:#
     				?*)	ha_log "ERROR: non-aliased Interface [$IF] is active. Nothing stopped."
				        exit 0;; # This is to keep the machine from rebooting...
  		esac
  esac

  if test -f "$SENDARPPIDFILE"
  then
  	cat "$SENDARPPIDFILE" | xargs kill
	rm -f "$SENDARPPIDFILE"
  fi

  case $SYSTYPE in
	*BSD)
		if $IFCONFIG $IFCONFIG_A_OPT | \
			grep "inet.*[: ]$BASEIP " >/dev/null 2>&1; then
			continue;
		else
			exit 0
		fi;;

	Linux|SunOS)
		if [ -z "$IF" ]; then
    			: Requested interface not in use
    			exit 0
		else
			case $IF in
			  lo*)
				: Requested interface is on loopback
				exit 0
				;;
			esac
  		fi;;
	*)
		if [ -z "$IF" ]; then
    			: Requested interface not in use
    			exit 0
  		fi;;
  esac

  if
    [ -x $HA_RCDIR/local_giveip ]
  then
    $HA_RCDIR/local_giveip $*
  fi

  delete_route "$BASEIP"
  delete_interface "$BASEIP" "$IF"
  rc=$?

  case $SYSTYPE in
	*BSD)	;;
	Linux|SunOS)
		restore_loopback "$BASEIP"
		# remove lock file...
		rm -f "$VLDIR/$IF";;
	
	*)	# remove lock file...
		rm -f "$VLDIR/$IF";;
  esac

  case $rc in
    	0) 
		ha_log "info: IP Address $BASEIP released"
		;;
    	*) 	
		ha_log "WARN: IP Address $BASEIP NOT released"
		;;
  esac
  return $rc
}


#
#	Find an unused interface/alias name for us to use for new IP alias
#	The argument is an IP address, and the output
#	is an aliased interface name (e.g., "eth0:0", "dc0", "le0:0").
#
find_free_interface() {
  if
    [ ! -d $VLDIR ]
  then
    mkdir -p $VLDIR
  fi

  BASEIP=`echo $1 | sed s'%/.*%%'`
  if
    NICINFO=`$FINDIF $1`
  then
    : OK
  else
    lrc=$?
    ha_log "ERROR: unable to find an interface for $BASEIP"
    return $lrc
  fi

  nicname=`echo "$NICINFO" | cut -f1`
  nicinfo=`echo "$NICINFO" | cut -f2-`
  if
    [ "X$nicname" = "X" ]
  then
    ha_log "ERROR: no interface found for $BASEIP"
    return 1;
  fi

  NICBASE="$VLDIR/$nicname"
  touch "$NICBASE"

  case $SYSTYPE in
	SunOS)
		IFLIST=`$IFCONFIG $IFCONFIG_A_OPT | \
			grep "^$nicname:[0-9]" | sed 's%: .*%%'`
		;;
	*)
		IFLIST=`$IFCONFIG $IFCONFIG_A_OPT | \
			grep "^$nicname:[0-9]" | sed 's% .*%%'`
		;;
  esac

  IFLIST=" `echo $IFLIST` "

  case $SYSTYPE in
       SunOS)
		j=1
		;;
	*)
		j=0
                TRYADRCNT=`ls "${NICBASE}:"* | wc -l | tr -d ' ' 2>/dev/null`
		if 
		  [ -f "${NICBASE}:${TRYADRCNT}" ]
		then
		  : OK
		else
		  j="${TRYADRCNT}"
		fi
		;;
  esac

  case $SYSTYPE in
	*BSD)
		echo $nicname;
		return 0;;

	*)
  	while
    	  [ $j -lt 512 ]
  	do
    	    case $IFLIST in
	      *" "$nicname:$j" "*)	;;
	      *)			
		NICLINK="$NICBASE:$j"
		if
		  ln "$NICBASE" "$NICLINK" 2>/dev/null
		then
		  echo "$nicname:$j	$nicinfo"
		  return 0
		fi;;
	    esac
            j=`expr $j + 1`
	done;;
  esac
  return 1
}


#
#	Add an IP alias for the requested IP address...
#
#	It could be that we already have taken it, in which case it should
#	do nothing.
#

ip_start() {
  #
  #	Do we already service this IP address?
  #
  case `ip_status $1` in
    *unning*)   exit 0;
  esac

  BASEIP=`echo $1 | sed s'%/.*%%'`
  SENDARPPIDFILE="$SENDARPPIDDIR/send_arp-$BASEIP"

  case $SYSTYPE in
    Linux|SunOS)
		CURRENTIF=`find_interface "$BASEIP"`
       		case $CURRENTIF in
         	  lo*)
            		remove_conflicting_loopback "$BASEIP" "$CURRENTIF"
            		;;
      		  *:*)	;;
            	  ?*)	ha_log "ERROR: non-aliased Interface [$CURRENTIF] is active"
			exit 1
			;;
    		esac ;;
    *)		;;
  esac

  if IFINFO=`find_free_interface $1`; then
  	: OK got interface [$IFINFO] for $1
  else
  	exit 1
  fi
  IF=`echo "$IFINFO" | cut -f1`

  if
    [ -x $HA_RCDIR/local_takeip ]
  then
    $HA_RCDIR/local_takeip $*
  fi

  add_interface "$BASEIP" "$IFINFO" "$IF"
  rc=$?
  case $rc in
    0)
    		;;
    *)
		return $rc
		;;
  esac

  # add_route $BASEIP $IF

  TARGET_INTERFACE=`echo $IF | sed 's%:.*%%'`

  ha_log "info: Sending Gratuitous Arp for $BASEIP on $IF [$TARGET_INTERFACE]"

  [ -r ${HA_CONFDIR}/arp_config ] && . ${HA_CONFDIR}/arp_config
  [ -r "${HA_CONFDIR}/arp_config:${TARGET_INTERFACE}" ] && . "${HA_CONFDIR}/arp_config:${TARGET_INTERFACE}"

  # Set default values (can be overridden as described above)

  : ${ARP_INTERVAL_MS=1010}	# milliseconds between ARPs
  : ${ARP_REPEAT=5}		# repeat count
  : ${ARP_BACKGROUND=yes}	# no to run in foreground (no longer any reason to do this)
  : ${ARP_NETMASK=ffffffffffff}	# netmask for ARP
  

  ARGS="-i $ARP_INTERVAL_MS -r $ARP_REPEAT -p $SENDARPPIDFILE $TARGET_INTERFACE $BASEIP auto $BASEIP $ARP_NETMASK"
  ha_log "$SENDARP $ARGS"
  case $ARP_BACKGROUND in
    yes) ($SENDARP $ARGS || ha_log "ERROR: Could not send gratuitous arps")&;;
    *)	  $SENDARP $ARGS || ha_log "ERROR: Could not send gratuitous arps";;
  esac
}

ip_status() {
  BASEIP=`echo $1 | sed -e s'%/.*%%'`
  IF=`find_interface $BASEIP`

  case $SYSTYPE in
    *BSD)
	if
		$IFCONFIG $IFCONFIG_A_OPT | grep "inet.*[: ]$BASEIP " >/dev/null 2>&1
	then
		echo "running"
	else
		echo "stopped"; return 3
	fi;;

    Linux|SunOS)		
	if
		[ -z "$IF" ]
	then
		echo "stopped"; return 3
	else
		case $IF in
		  lo*)
			echo "loopback"
			;;
		  *)
			echo "running"
			;;
		esac
	fi;;
    *)		
	if
		[ -z "$IF" ]
	then
		echo "stopped"; return 3
	else
		echo "running"
	fi;;
  esac
}

#
#	Determine if this IP address is really being served, or not.
#	Note that we must distinguish if *we're* serving it locally...
#
ip_monitor() {
  BASEIP=`echo $1 | sed s'%/.*%%'`
  TIMEOUT=1 # seconds
  case $SYSTYPE in
        Linux)
            # -c count -t timetolive -q(uiet) -n(umeric) -W timeout
            PINGARGS="-c 1 -q -n $BASEIP"
            ;;
        SunOS)
            PINGARGS="$BASEIP $TIMEOUT"
            ;;
        *)
            PINGARGS="-c 1 -q $BASEIP"
            ;;
  esac
  for j in 1 2 3
  do
    # for R1 style clusters, CTS runs this on the test monitor node
    # so we cannot check to see if the IP address is served locally
    # This means that the ARP spoofing is also tested
    # But we can't tell for sure which node is serving the IP

    if
      /bin/ping $PINGARGS >/dev/null 2>&1
    then
      echo "OK"
      return 0
    fi
  done
  echo "down"
  return 1
}

usage() {
  echo $USAGE >&2
  echo "$Id: IPaddr.in,v 1.52.2.11 2005/09/08 16:49:25 alan Exp $"
}

#
#	Add or remove IP alias for the given IP address...
#

if
  [ $# -eq 1 ]
then
  case $1 in
    info)	cat <<-!INFO
	Abstract=IP address takeover
	Argument=IP address OR IP address/broadcast address OR IP address/broadcast address/netmaskbits
	Description:
	An IPaddr resource is an IP address which is to be taken over by \\
	the owning node.  An argument is required, and is of this form:
	    nnn.nnn.nnn.nnn/bbb.bbb.bbb.bbb
	Where nnn.nnn.nnn.nnn is the IP address to be taken over, and\\
	bbb.bbb.bbb.bbb is the broadcast address to be used with this address.

	Since IPaddr is the "default" resource type, it is not necessary\\
	to prefix the IP address by "IPaddr::".
	This allows IPaddr::192.2.4.63 to be abbreviated as 192.2.4.63.
	!INFO
	exit 0;;
  esac
fi
if
  [ $# -ne 2 ]
then
  usage
  exit 1
fi

case $2 in
  start)	ip_start $1;;
  stop)		ip_stop $1;;
  status)	ip_status $1;;
  monitor)	ip_monitor $1;;
  *)		usage
 		exit 1
		;;
esac
#
#
# $Log: IPaddr.in,v $
# Revision 1.52.2.11  2005/09/08 16:49:25  alan
# Undid an erroneous fix by Sun Jiang Dong.
# It sounds good, but it breaks CTS.
#
# Revision 1.52.2.10  2005/08/19 14:56:03  sunjd
# add missed arguments
#
# Revision 1.52.2.9  2005/08/19 10:33:04  sunjd
# resolve the issue that ping timeout option may be invalid, found&resovled by Horms and Sun Xun
#
# Revision 1.52.2.8  2005/08/17 09:10:17  horms
# Merge confdir changes from HEAD
#
# Revision 1.52.2.7  2004/09/12 00:06:10  msoffen
# Fixed to handle device properly for FreeBSD.
#
# Revision 1.52.2.6  2004/05/12 01:38:24  alan
# Continued (hopefully) finished previous IPaddr fix...
#
# Revision 1.52.2.5  2004/05/12 01:25:59  alan
# Fixed a bug in the last IPaddr fix ;-)
#
# Revision 1.52.2.4  2004/05/12 00:16:57  alan
# Fixed an error message in IPaddr to print the interface name instead
# of the command name where it meant to print the interface name.
#
# Revision 1.52.2.3  2004/05/12 00:14:01  alan
# Fixed a bug in IPaddr where it would not declare an interface as running
# because it had a non-aliased interface name.
#
# Revision 1.52.2.2  2004/05/11 03:27:15  alan
# Discovered Linux ignores ARPs closer together than 1 second - so
# raised the default ARP interval to 1.01 seconds
#
# Revision 1.52.2.1  2004/04/20 05:05:29  alan
# Backported everything from 1.3.0 to 1.2.1
#
# Revision 1.53  2004/04/19 18:09:39  alan
# Some Solaris patches from Dominique Petitpierre <Dominique.Petitpierre@adm.unige.ch> to MailTo and IPaddr.
#
# Revision 1.52  2004/02/05 05:12:30  alan
# Doubled the number of ARPs (10), over a period of 5 seconds
#
# Revision 1.51  2004/01/30 22:49:54  alan
# Changed IPaddr so it exits with proper LSB exit codes
# for status.
#
# Revision 1.50  2003/10/29 11:40:50  horms
# Send arp  creates a driectory to store its pid file in on-the-fly. IPaddr does likewise for state files.
#
# Revision 1.49  2003/10/29 05:38:59  horms
# Need to create these directories on-the-fly after all.
#
# Revision 1.48  2003/10/24 07:07:44  horms
# remove send arps pid file on stop if it exists
#
# Revision 1.47  2003/10/23 08:03:17  horms
# IPaddr and IPaddr2 both kill send_arp on stop
# IPaddr defaults to running send_arp in the background
# IPaddr2 used arp_config in the same way as IPaddr
#
# Revision 1.46  2003/10/23 05:34:03  horms
# create state directories for resources at install time instead of run time.
#
# Revision 1.45  2003/10/15 17:04:40  horms
# Merged  get_hw_addr into and send_arp
#
# Revision 1.44  2003/07/16 13:43:30  alan
# Redirected some irrelevant error messages from ls to /dev/null
#
# Revision 1.43  2003/07/12 16:19:54  alan
# Fixed a bug in the new send_arp options and their invocation...
#
# Revision 1.42  2003/07/12 14:27:21  alan
# Changed IPaddr to not go into background for ARPs, and greatly shortened
# the inter-ARP-interval by using a new send_arp option.
# These behaviors be overridden by setting parameters in /etc/ha.d/conf/arp_config
# and/or /etc/ha.d/conf/arp_config:${TARGET_INTERFACE}
#
# Revision 1.41  2003/05/21 09:02:32  horms
# Free alias search optimisation by Sean Reifschneider
#
# Revision 1.40  2003/05/21 08:42:57  horms
# Free alias search optimisation by Sean Reifschneider
#
# Revision 1.39  2003/03/24 08:17:05  horms
# merged in changes from stable branch
#
# Revision 1.38  2003/03/15 02:18:54  horms
# Fixed mkdir logic and removed bash-isms. Alan
#
# Revision 1.37  2003/03/14 12:29:56  horms
# Restore of loopback device requires a tmp directory.
# This is now autocreated as necessary.
#
# Revision 1.36  2003/02/12 05:40:22  alan
# Put in a bug fix from Gregor Gstl of Austria to fix the language
# of the ifconfig command to English/C.
# I have no idea why it's necessary in addition to the fix that's already
# there.
#
# Revision 1.35  2003/02/03 15:40:35  msoffen
# Splitting the ifconfig onto 2 lines failed miserably. Put back on one.
#
# Revision 1.34  2002/12/10 22:42:00  horms
# ipaddri -> ipaddr
#
# Revision 1.33  2002/12/10 22:18:39  horms
# If IPaddr is running on Linux, and a VIP is obtained that
# is on a loopback alias, then the loopback alias and the associated
# route if it exists, is removed before the alias, usually on an ethernet
# interface, is brought up.
#
# When the VIP is relinquished the alias on the loopback is restored.
#
# This is intended for use in conjunction with the LVS, where the
# same host may be a Linux Director and a Real Server.
#
# This feature explictly only works on Linux, as LVS only works on Linux.
#
# Thanks to Lorn Kay who did a lot of the ground work to get this fix working.
#
# Revision 1.32  2002/11/20 09:16:01  horms
# do not fail if an interface is already configured
#
# Revision 1.31  2002/10/22 02:48:04  msoffen
# Replaced find_interface_generic BSD code with more robust code.
#
# Revision 1.30  2002/10/21 10:17:18  horms
# hb api clients may now be built outside of the heartbeat tree
#
# Revision 1.29  2002/09/04 15:23:36  msoffen
# Changed for Solaris.  Removed "Add Route" and moved to subroutine (Left commented out call to subroutine though).
# Corrected comment (added monitor as allowd parameter).
#
# Revision 1.28  2002/08/17 14:35:58  alan
# Changed BasicSanityCheck to assign the dummy IP address to the dead machine.
#
# Fixed IPaddr.in so that it works again on Linux.
#
# Revision 1.27  2002/08/16 14:18:42  msoffen
# Changes to get IP takeover working properly on OpenBSD
# Changed how *BSD deletes an alias.
# Create get_hw_addr (uses libnet package).
#
# Revision 1.26  2002/08/15 16:15:35  msoffen
# Corrected so that BSD will properly get the status/etc. since it has
# a single device for both IP's (not device:n).
#
# Revision 1.25  2002/08/02 22:50:43  alan
# Put in a minor Solaris bug fix for IPaddr.
# If we get a MAC address that is missing a leading zero, then we add
# it back in.
#
# Revision 1.24  2002/08/02 03:29:16  horms
# Reworked Lorn Kay's loopback interface patch for Linux.
#
# Notes:
#
# This script assumes that an IP address can only belong
# to one interface. This is _wrong_. However, it works for
# almost all cases so I'm happy to leave it as is for now.
#
# In the mean time, this work arround allows us to have
# manages addresses on the loopback interface on Linux,
# which is very useful when heartbeat is used in conjunction
# with the Linux Virtual Server, and a node is both
# a Real Server and a Linux Director.
#
# Revision 1.23  2002/07/30 17:33:34  horms
# The old checking for an empty string without putting the suspect
# variable in quotes trick. Gets 'em every time.
#
# Revision 1.22  2002/07/27 06:02:21  horms
# Lorn Kay's patch for IPaddr to better handle the presance of
# managed IP addresses being present on a loopback interface.
# Designed for use in conjunction with LVS Direct Routing.
# Should be fully backwards compatible.
#
# Revision 1.21  2002/07/09 16:42:22  msoffen
# Deleted extra "debugging" lines .
#
# Revision 1.20  2002/05/28 18:25:48  msoffen
# Changes to replace send_arp with a libnet based version.  This works accross
# all operating systems we currently "support" (Linux, FreeBSD, Solaris).
#
# Revision 1.19  2002/05/15 04:25:47  msoffen
# Corrected Ping problem so that it would work in FreeBSD (using parameters from configure.in).
#
# Revision 1.18  2002/04/29 07:32:44  alan
# Solaris extensions/enhancements from Thomas Hepper for Solaris 2.8
#
# Revision 1.17  2002/03/21 02:03:00  alan
# Added locking to the assignment of interfaces in IPaddr.
#
# Revision 1.16  2002/03/14 04:28:51  alan
# Changed all the resource scripts to have ID strings in them
#
# Revision 1.15  2002/02/15 06:53:16  horms
# Small changes to allow heartbeat to work on Solaris 8
# * use unset LC_ALL and unset LANGUAGE instead of LC_ALL=en and LANGUAGE=en
# * provide LOG_PERROR, as Solaris doesn't
# -- Horms
#
# Revision 1.14  2002/01/18 18:55:49  alan
# Put in a generalization suggested by Matt Soffen to allow us
# to handle BSD and Solaris network interfaces.
#
# Revision 1.13  2001/10/24 20:23:09  alan
# Changed INFO: to info: for consistency.
#
# Revision 1.12  2001/10/12 04:54:22  alan
# Changed IPaddr to be more BSD/Solaris compatible
#
# Revision 1.11  2001/10/08 14:04:18  alan
# Put a fix into IPaddr.in to make it work on Solaris as well as Linux.
#
# Revision 1.10  2001/10/07 04:18:20  alan
# Added some more portability patches from David Lee.
#
# Revision 1.9  2001/10/07 04:00:56  alan
# Got rid of a non-portable shell construct in IPaddr.in
#
# Revision 1.8  2001/10/03 15:00:26  alan
# Patch from Matt Soffen to add a comment about the IFEXTRA logic in the
# IPaddr resource script.
# Matt also replaced an errant echo with an ha_log() call.
#
# Revision 1.7  2001/10/03 13:54:16  alan
# Merged in Matt Soffen's changes and added some of my own for IPaddr...
#
# CVg: Committing in .
#
# Revision 1.6  2001/10/02 20:04:09  alan
# I added wehat should be a redundnat fix for Fabrice of France.
# He says it isn't redundant.  It's clearly harmless.
#
# Revision 1.5  2001/07/19 15:59:55  alan
# Put in Matt Soffen's pathname patch...
#
# Revision 1.4  2001/07/02 17:23:23  alan
# Changed the order of the ifdown and route del commands...
#
# Revision 1.3  2001/06/29 21:23:47  alan
# Put in a modified version of Matt Soffen's patch to make
# IPaddr work under FreeBSD.
# Don't know if it works under FreeBSD, but it works on Linux.
#
# Revision 1.2  2001/06/28 20:35:00  alan
# Patch from Juri to install our scripts with paths patched appropriately.
#
# Revision 1.1  2001/06/28 12:16:44  alan
# Committed the *rest* of Juri Haberland's script patch that I thought I
# had already applied :-(.
#
# Revision 1.9  2001/05/17 18:45:55  alan
# Applied two patches for IPaddr from Emily Ratliff <emilyr@us.ibm.com>
#
# Revision 1.8  2001/02/05 21:43:38  alan
# Added "monitor" action to IPaddr.
#
# Revision 1.7  2000/11/07 14:15:04  alan
# Made the takeover of IP addresses go faster.
# Removed the limit on 8 aliases per interface.
#
# Revision 1.6  2000/06/12 06:11:09  alan
# Changed resource takeover order to left-to-right
# Added new version of nice_failback.  Hopefully it works wonderfully!
# Regularized some error messages
# Print the version of heartbeat when starting
# Hosts now have three statuses {down, up, active}
# SuSE compatability due to Friedrich Lobenstock and alanr
# Other minor tweaks, too numerous to mention.
#
# Revision 1.5  1999/12/30 03:18:50  alan
# Put Stefan Salzer's fix on the place he put it in :-)  The same bug appeared
# twice in the code.  I fixed it in one place, and so did he.  Now
# it looks like they're both fixed.
#
# Revision 1.4  1999/12/23 03:28:21  alan
# Put in Stefan Salzer's fix to IPaddr to make it not confuse
# x.y.z.1 with x.y.z.11 or similar...
#
# Revision 1.3  1999/11/16 04:36:53  alan
# Added fix from David Jules to make IPaddr work in France.
# The problem is that various commands that IPaddr invokes (notably ifconfig)
# produce different output in other locales than they do in LC_ALL=en
# so the output wasn't recognized by IPaddr.  The fix is much simpler than
# this explanation :-)
#
# Revision 1.2  1999/11/10 20:33:04  alan
# Deleted /proc/ha directory from build list
# Added #!/bin/sh to lots (all?) of the scripts...
#
# Revision 1.1.1.1  1999/09/23 15:31:24  alanr
# High-Availability Linux
#
# Revision 1.11  1999/09/12 06:56:53  alanr
# Fixed the bugs that kept addresses w/netmasks and broadcast addresses from working.
#
# Revision 1.10  1999/09/08 03:47:18  alanr
# fixed things up so that send_arp doesn't just assume eth0 as the ethernet interface...
#
# Revision 1.9  1999/08/22 04:49:42  alanr
# Fixed a stupid syntax error.  Wonder how it got in here?
#
# Revision 1.8  1999/08/21 05:43:38  alanr
# added "info" argument to support GUI help screens, etc.
#
# Revision 1.7  1999/08/17 18:09:16  alanr
# More message changes.
#
# Revision 1.6  1999/08/17 18:04:31  alanr
# Minor message changes for Thomas' code.
#
# Revision 1.5  1999/08/17 17:57:07  alanr
# Put in Thomas Hepper's fix to make it obey netmasks and broadcast addrs
# from base interface.
#
# Revision 1.4  1999/08/17 05:00:44  alanr
# added a dumb extra #
#
# Revision 1.3  1999/08/17 04:57:57  alanr
# Added RCS keywords, and bug fix from Thomas Hepper
# th@ant.han.de to fix some kind of problem associated with PPP configs.
#
#
#
