#!/bin/sh -u


    LastCheckFile=/var/cache/nagios/check_dyndnsip.last
    CurlHttpProxy=


    if [[ "$1" == "" ]]
    then
	text="Usage: $0 dyndns-host-to-check [update-credentials]"
	rc=3
    else
	rc=-1
	text=
	diags=
	DdnsHost=$1
	if [[ $# -ge 2 ]]
	then
	    DynDnsCredentials=$2
	    diags="$diags [update:yes]"
	else
	    DynDnsCredentials=
	fi
	
	#
	#  Since DynDNS says, we should not check more often than every
	#  ten minutes, the result of the last check is remembered and
	#  re-used, if younger!
	#

	if [[ -r $LastCheckFile  ]]
	then
	    Now=`date "+%s"`
	    LastChecked=`stat -c "%Y" $LastCheckFile`
	    LastCheckAge=$(( $Now - $LastChecked ))
	    diags="$diags [cache: ${LastCheckAge}s]"
	else
	    LastCheckAge=999999999
	    diags="$diags [cache: no file]"
	fi

	#
	#  Now determine our external address. We ask checkip.dyndns.org
	#  what address it sees in our request and parse the resulting
	#  numeric address from the HTML output...
	#

	if [[ $LastCheckAge -ge 600 ]]
	then
	    diags="$diags [query: yes]"
	    CurlResult=`curl --proxy "$CurlHttpProxy" -s -S checkip.dyndns.org 2>&1`
	    ExpectedIP=`expr "$CurlResult" : '^.*<body>Current IP Address: \([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)</body>.*$'`
	    if [[ $? -ne 0 ]]
	    then
		text="Cannot parse result from checkip.dyndns.org: $CurlResult"
		rc=2
	    else
		rm -f $LastCheckFile
		echo >$LastCheckFile "$ExpectedIP"
	    fi
	else
	    diags="$diags [query: no]"
	    ExpectedIP=`cat $LastCheckFile`
	fi

	#
	#  Next, get the IP address currently known to DNS (but
	#  only, if we're still in the game!) There might be better
	#  ways to do that, but it works.
	#

	if [[ $rc -le 0 ]]
	then
	    HostResult=`host $DdnsHost`
	    if [[ $? -eq 0 ]]
	    then
		DefinedIP=`expr "$HostResult" : '.* has address \([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)$'`
		if [[ $? -ne 0 ]]
		then
		    text="Address not found in output from host command: $HostResult"
		    rc=2
		fi
	    else
		text="Could not resolve current address of host '$DdnsHost': $HostResult"
		rc=2
	    fi
	fi

	#
	#  OK, we have the expected and the defined IP addresses now.
	#  So let's check, whether they match.
	#

	if [[ $rc -le 0 ]]
	then
	    if [[ "$ExpectedIP" == "$DefinedIP" ]]
	    then
		text="$DdnsHost has address $ExpectedIP"
		rc=0
	    else
		#
		#  OOPS! The external address is not what we expected! Of course,
		#  we could just return a CRITICAL condition, but let's play clever!
		#  Why not try and currect the problem right away? This function is
		#  only available, however, if credentials are given!
		#

		if [[ "$DynDnsCredentials" != "" ]]
		then
		    Query="http://$DynDnsCredentials@members.dyndns.org/nic/update?system=dyndns&hostname=$DdnsHost&myip=$ExpectedIP&wildcard=on&offline=no"
		    Result=`curl --connect-timeout 60 --proxy "$CurlHttpProxy" -s -S "$Query" 2>&1`
		    if [[ $? -eq 0 ]]
		    then
			if expr "$Result" : "^good $ExpectedIP" >/dev/null
			then
			    diag="$diag [update: $Result]"
			    text="$DdnsHost has been updated to $ExpectedIP (was: $DefinedIP)"
			    rc=1
			else
			    text="Update of $DdnsHost from: $DefinedIP to: $ExpectedIP failed: $Result"
			    rc=2
			fi
		    else
			text="Update of $DdnsHost failed in curl: $Result"
			rc=2
		    fi
		else
		    text="$DdnsHost in DNS is: $DefinedIP, but should have: $ExpectedIP"
		    rc=2
		fi
	    fi
	fi
    fi

    #
    #  Finally, prepare the result for Nagios. The status strings
    #  are properly prepended and given back...
    #

    case $rc in
	0)
	    text="OK - $text"
	    ;;
	1)
	    text="WARNING - $text"
	    ;;
	2)
	    text="CRITICAL - $text"
	    ;;
	3)
	    text="UNKNOWN - $text"
	    ;;
	*)
	    text="INTERNAL ERROR: Status code not properly set!"
	    rc=3
	    ;;
    esac

    echo "$text $diags"
    exit $rc

