#!/bin/bash # # Script Name: ipwatch # # Homepage: http://www.scrounge.org/ipwatch/ # # Email: ipwatch@scrounge.org # # Version: 1.1b # # Date: 11/20/2000 # # Copyright (C) 1999, 2000 Bruce Buhler, Wayne Larmon # # 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. # # 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. # # Purpose: Monitor connection to your ISP and restart your network, # firewall, and renew dynamic hostnames when it goes down # # Usage: This script should really be run on a cron by root. If you haven't lost your IP # it will only send 1 nslookup to the server, so there shouldn't be much overhead. # You should modify the variables below to suit your system before running this # script. See http://www.scrounge.org/ipwatch/ for full instructions # on how to install and configure this script. # # Optional. If you have ipcheck.sh then invoke ipwatch.sh with # the following options. Do NOT run ipcheck.sh directly. # # -c Displays status on console # -c -m Sends status message to address defined with MAILTO # -c -l Writes status to log file # -c -n Suppresses display on console # -c -v Display all variable settings # -c -s Show ipwatch log file # # Can also specify options verbosely: # # -c or --check # -m or --mail # -l or --log # -n or --noecho # -v or --variable # -s or --show #################################################### # Configure the stuff below to suit your machine # #################################################### # Identity of your machine. # Arbitrary name used in status messages to identify this machine MACHIDENT="Mymachine" # External ethernet interface EXTIF="eth0" # IP address of a local server # This should be set to the IP address of a machine local to your ISP # that is up all the time (like a DHCP server, name server, web server, etc.) SERVER="xxx.xxx.xxx.xxx" # Location of your firewall script and command to restart your firewall # If you don't have a command to restart your firewall, you can stop it and then # start it again. In that case, set this to # "/etc/rc.d/init.d/rc.firewall stop; /etc/rc.d/init.d/rc.firewall start" #FIREWALL="/etc/rc.d/init.d/rc.firewall restart" # Dynamic DNS - uncomment the service you use # Currently yi.org, homepc.org, dyndns.org, dyndns.com, justLinux, and dhs.org (static IP's only) # are supported. If you don't use any of these services, leave # them commented. # # IMPORTANT NOTE: dyndns.org and dyndns.com are completely untested. # We would appreciate any feedback on the functionallity of these services with # this script. # #DYNDNS="yi" #DYNDNS="homepc" #DYNDNS="dyndns_com" #DYNDNS="dyndns_org" #DYNDNS="justLinux" #DYNDNS="dhs" # Only static hostnames are supported at dhs.org # If you use dyndns.org or dhs.org you need to specify your hostname # used with these services. Enter your hostname used with these services here: #DYNHOSTNAME="yourhostname" # If you use justLinux you need to set your DNS ID. This is a number assigned # by justLinux and is *required* to update your hostname. See IPWatch's homepage # (http://www.scrounge.org/ipwatch/) for instructions on how to obtain your DNS ID #DNSID="your dnsid number goes here" # User ID and password used for updating Dynamic DNS hostname. # Again, if you don't use this service, it's safe to leave these commented. #USER_ID="enter your user ID here" #PASSWORD="enter your password here" # Do you want the script to update your hostname when your IP changes? # Setting this to "yes" will change your system's hostname to the hostname # your ISP assigns to you (something like cm-24-92-34-156) when your IP # updates. Any other value will not set your machine's hostname. UPDATEHOST="yes" # This is the maximum amount of time (in seconds) you want the script to # spend trying to renew your IP. Setting this value to 0 is equivalent to # setting no time limit (i.e. the script will keep running until it renews your # IP or is manually stopped). The default is 300 seconds which will abort # the script if it hasn't successfully renewed your IP within five minutes. TIMELIMIT=300 # This is the e-mail address where the output of the script and your new # IP address will be sent to. MAILTO="root@localhost" ############################### # End of user configuration # ############################### # Logfile for script LOGFILE="/var/log/ipwatch" # To store previous "current" IP (to detect an IP change.) IPFILE="/tmp/currentIP" # Set some environment variables export PATH="/sbin:/bin:/usr/bin" export BOOTUP="nocolor" export TERM="vt100" ##################### # Begin Functions # ##################### # Function to generate a timestamp timestamp() { DATE="["`date +%D" "%T`"]" echo $DATE } # Function to update dynamic hostnames dynupdate() { local SLEEPTIME local DYN_STATUS local TMPOUTPUT1 local TMPOUTPUT2 DYN_STATUS=1 SLEEPTIME=0 while [ $DYN_STATUS -ne 0 ]; do sleep $SLEEPTIME if [ ! -z "$URL1" ]; then TMPOUTPUT1=`lynx -dump $URL1` fi TMPOUTPUT2=`lynx -dump $URL2` DYN_STATUS=$? SLEEPTIME=60 if [ $SECONDS -gt $TIMELIMIT ] && [ $TIMELIMIT -ne 0 ]; then echo -e "\n`timestamp` Dynamic hostname renewal FAILED\n" | tee -a $MSGFILE | sed -e '/^$/d' >> $LOGFILE break fi if [ $DYN_STATUS -eq 0 ]; then echo -e "\n`timestamp` Dynamic hostname renewal SUCCESSFUL\n" | tee -a $MSGFILE | sed -e '/^$/d' >> $LOGFILE if [ ! -z "$TMPOUTPUT1" ]; then echo "$TMPOUTPUT1" >> $MSGFILE fi echo "$TMPOUTPUT2" >> $MSGFILE fi done } # Is Network up? 0 if up, non-zero if down isnetup() { local VAR VAR=`nslookup -retry=1 -timeout=2 $SERVER > /dev/null; echo $?` # Let's make sure we've really lost our connection if [ $VAR -ne 0 ]; then VAR=`nslookup -retry=4 -timeout=5 $SERVER > /dev/null; echo $?` fi return $VAR } # Function to set the hostname and restart the logging daemon hostnameset() { local HOSTNAME if [ $UPDATEHOST = "yes" ]; then HOSTNAME=`nslookup $IPADDR | grep "Name:" | awk '{ print $2 }'` hostname $HOSTNAME echo $HOSTNAME > /etc/HOSTNAME echo -e "\n`timestamp` Setting new hostname to $HOSTNAME\n" | tee -a $MSGFILE | sed -e '/^$/d' >> $LOGFILE echo -e "\n`timestamp` Restarting logging daemon\n" | tee -a $MSGFILE | sed -e '/^$/d' >> $LOGFILE /etc/rc.d/init.d/syslog restart >> $MSGFILE fi } # Function to restart the firewall firewallinit() { if [ ! -z "$FIREWALL" ]; then echo -e "\n`timestamp` Restarting the firewall\n" | tee -a $MSGFILE | sed -e '/^$/d' >> $LOGFILE $FIREWALL >> $MSGFILE fi } # Funtion to restart the network netinit() { local SLEEPTIME local TMPOUTPUT SLEEPTIME=0 while ! isnetup; do sleep $SLEEPTIME TMPOUTPUT=`ifdown $EXTIF; ifup $EXTIF` SLEEPTIME=60 if [ $SECONDS -gt $TIMELIMIT ] && [ $TIMELIMIT -ne 0 ]; then echo -e "\n`timestamp` Network initialization FAILED\n" | tee -a $MSGFILE | sed -e '/^$/d' >> $LOGFILE break fi if isnetup; then IPADDR=`ifconfig | grep -A 4 $EXTIF | awk '/inet/ { print $2 }' | sed -e s/addr://` echo -e "\n`timestamp` Network initialization SUCCESSFUL. Your current IP is $IPADDR\n" | tee -a $MSGFILE | sed -e '/^$/d' >> $LOGFILE echo "$TMPOUTPUT" >> $MSGFILE fi done } # Function to get the old IP address getoldip() { if [ -f $IPFILE ]; then OLDIP=`cat $IPFILE` else OLDIP= fi } checkpid() { local CHKPID CHKPID=`ps -hp $OLDPID > /dev/null; echo $?` # Returns 0 if OLDPID is found, 1 if it's not return $CHKPID } ################### # End Functions # ################### # Get current pid PID=$$ # Exit the script if we're already running another instance of it if [ -f /var/lock/subsys/ipwatch ]; then OLDPID=`cat /var/lock/subsys/ipwatch` if checkpid; then echo -e "\a\nA previous instance of IPWatch is still running.\n" echo "Check 'ps ax | grep ipwatch', and for the existance" echo "of the /var/lock/subsys/ipwatch \"lock\" file." exit fi fi # Do we want to execute ipcheck.sh? if [ "$1" = "-c" ] || [ "$1" = "--check" ]; then # Yes we do. shift FILE=`basename $0`; DIRECTORY=`echo $0 | sed -e s/'\/'$FILE//` # DIRECTORY is the directory that this script is running in. # ipcheck.sh should be in the same directory. if [ -f $DIRECTORY/ipcheck.sh ]; then . $DIRECTORY/ipcheck.sh $* exit else echo -e "\a\n$DIRECTORY/ipcheck is MISSING! Aborting..." exit 1 fi fi MSGFILE="/tmp/ipwatch.msg" # Let's not proceed if SERVER was not configured. Just give it up. if [ "$SERVER" = "xxx.xxx.xxx.xxx" ]; then echo -e "\a\nYou must configure the SERVER variable.\n" echo -e "It is currently defined as $SERVER. No, no, no.\n" exit 1 fi # Check to see if the network is up and if the IP has changed. # This is just a quick check so we can exit if everything's okay. if isnetup; then IPADDR=`ifconfig | grep -A 4 $EXTIF | awk '/inet/ { print $2 }' | sed -e s/addr://` getoldip if [ "$OLDIP" = "$IPADDR" ]; then if [ -f /var/lock/subsys/ipwatch ]; then rm -f /var/lock/subsys/ipwatch fi exit fi fi # The network is down or the IP address has changed. Create # a lock file to make sure no other instances of the script are started # until we're done here. The lock file will contain our pid. echo $PID > /var/lock/subsys/ipwatch # Determine if the network is down; if it is, restart it if ! isnetup; then echo -e "\n`timestamp` Network connectivity LOST\n" | tee -a $MSGFILE | sed -e '/^$/d' >> $LOGFILE netinit getoldip SUBJECT="$MACHIDENT has been restarted" fi # If the network is up, check to see if the IP has changed. if isnetup; then if [ -z "$IPADDR" ]; then IPADDR=`ifconfig | grep -A 4 $EXTIF | awk '/inet/ { print $2 }' | sed -e s/addr://` fi if [ "$OLDIP" != "$IPADDR" ] && [ ! -z $OLDIP ]; then firewallinit hostnameset echo $IPADDR > $IPFILE echo -e "\n`timestamp` IP address has changed from $OLDIP to $IPADDR\n" | tee -a $MSGFILE | sed -e '/^$/d' >> $LOGFILE case "$DYNDNS" in yi) URL2="-auth=$USER_ID:$PASSWORD http://www.yi.org/bin/dyndns.fcgi?ipaddr=$IPADDR" dynupdate ;; homepc) URL2="http://homepc.homepc.org/cgi-bin/changeip_now?passwd=$PASSWORD&subdomain=$USER_ID" dynupdate ;; dyndns_com) URL2="http://master.dyndns.com/cgi/DynDNSWeb.cgi?name=$USER_ID&passwd=$PASSWORD&domain=dyndns.com&IP=$IPADDR" dynupdate ;; dyndns_org) URL2="-auth=$USER_ID:$PASSWORD \ http://members.dyndns.org/nic/update?hostname=$DYNHOSTNAME&myip=$IPADDR" dynupdate ;; justLinux) URL1="-accept_all_cookies http://www.justlinux.com/bin/dologin?username=$USER_ID&password=$PASSWORD" URL2="http://www.justlinux.com/bin/controlpanel/dyndns/update.pl?dnsid=$DNSID&ip=$IPADDR" dynupdate ;; dhs) URL2="-auth=$USER_ID:$PASSWORD \ http://members.dhs.org/nic/hosts?domain=dhs.org&hostname=$DYNHOSTNAME&hostscmd=edit&hostscmdstage=2&type=1&ip=$IPADDR" dynupdate ;; esac if [ -z "$SUBJECT" ]; then SUBJECT="$MACHIDENT's IP address has changed to $IPADDR" else SUBJECT="$SUBJECT and your new IP address is $IPADDR" fi elif [ -z $OLDIP ]; then echo $IPADDR > $IPFILE fi # Send mail to the user if [ -f $MSGFILE ]; then mail -s "$SUBJECT" $MAILTO < $MSGFILE fi fi # Clean up temp files rm -f /var/lock/subsys/ipwatch; rm -f $MSGFILE # # End of script #