#!/bin/bash #Todo: IPv6 #Todo: Other service types than gnudip (generic update URL) #Todo: GET WAN IP from Router via UPnP if supported PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin #static values EMPTYSTRING="none" NOIP="0.0.0.0" #how often do we poll for IP changes if we are behind a NAT? UPDATEMINUTES=5 #if we do not have a IP check URL, how often should we do a "blind" update UPDATEMINUTESUNKNOWN=3600 TOOLNAME=ez-ipupdate UPDATE_TOOL=$(which ${TOOLNAME}) #Dirs and filenames CFGDIR="/etc/${TOOLNAME}/" CFG="${CFGDIR}${TOOLNAME}.conf" CFG_disabled="${CFGDIR}${TOOLNAME}.inactive" IPFILE="${CFGDIR}${TOOLNAME}.currentIP" STATUSFILE="${CFGDIR}${TOOLNAME}.status" LASTUPDATE="${CFGDIR}/last-update" HELPERCFG="${CFGDIR}${TOOLNAME}-plinth.cfg" CRONJOB="/etc/cron.d/${TOOLNAME}" doReadCFG() { host="" server="" user="" pass="" IPURL="" FILE="" [ -f $CFG_disabled ] && FILE=$CFG_disabled [ -f $CFG ] && FILE=$CFG if [ ! -z $FILE ];then host=`cat $FILE 2> /dev/null |grep host |cut -d = -f 2` server=`cat $FILE 2> /dev/null |grep server |cut -d = -f 2` user=`cat $FILE 2> /dev/null |grep user |cut -d = -f 2 |cut -d : -f 1` pass=`cat $FILE 2> /dev/null |grep user |cut -d = -f 2 |cut -d : -f 2` fi if [ ! -z $HELPERCFG ];then IPURL=`cat $HELPERCFG 2> /dev/null |grep URL |awk '{print $2}'` fi } doGetOpt() { while getopts ":s:d:u:p:I:" opt; do case $opt in s) server=$OPTARG ;; d) host=$OPTARG ;; u) user=$OPTARG ;; p) pass=$OPTARG ;; I) if [ "$OPTARG" != "$EMPTYSTRING" ];then IPURL=$OPTARG else IPURL="" fi ;; \?) echo "Invalid option: -$OPTARG" >&2 exit 1 ;; :) echo "Option -$OPTARG requires an argument." >&2 exit 1 ;; esac done } doWriteCFG() { #always write to the inactive config - needs to be enabled vi "start" command later FILE=$CFG_disabled #reset the last update time echo 0 > $LASTUPDATE #reset the last updated IP echo "0.0.0.0" > $IPFILE #reset last update rm $STATUSFILE #find the interface (always the default gateway interface) DEFAULT=`ip route |grep default |awk '{print $5}'` #store the given options in ez-ipupdate compatible config file echo "host=$host" > $FILE echo "server=$server" >> $FILE echo "user=${user}:${pass}" >> $FILE echo "service-type=gnudip" >> $FILE echo "retrys=5" >> $FILE echo "execute=$0 success" >> $FILE echo "wildcard" >> $FILE #check if we are behind a NAT Router echo "IPURL $IPURL" > $HELPERCFG if [ -z $IPURL ];then echo "NAT unknown" >> $HELPERCFG else doGetWANIP ISGLOBAL=`ip addr ls $DEFAULT | grep $WANIP` if [ -z $ISGLOBAL ];then #we are behind NAT echo "NAT yes" >> $HELPERCFG else #we are directly connected echo "NAT no" >> $HELPERCFG #if this file is added ez-ipupdate will take ip form this interface echo "interface=$DEFAULT" >> $FILE #if this line is added to config file, ez-ipupdate will be launched on startup via init.d echo "daemon" >> $FILE fi fi } doGetWANIP() { if [ $IPURL ];then OUTFILE=`mktemp` wget -4 -o /dev/null -O $OUTFILE $IPURL WANIP=`cat $OUTFILE` rm $OUTFILE else #no WAN IP found because of missing check URL WANIP=${NOIP} fi echo $WANIP > $IPFILE } cmd=$1 shift case $cmd in configure) doGetOpt $@ doWriteCFG ;; start) if [ "$(cat $HELPERCFG |grep ^NAT | awk '{print $2}')" = "no" ];then mv $CFG_disabled $CFG /etc/init.d/${TOOLNAME} start else echo "*/${UPDATEMINUTES} * * * * root $0 update" > $CRONJOB $0 update fi ;; get-nat) NAT=`cat $HELPERCFG 2> /dev/null |grep ^NAT | awk '{print $2}'` [ -z $NAT ] && NAT="unknown" echo $NAT ;; update) doReadCFG OLDIP=`cat $IPFILE` doGetWANIP [ -f $CFG_disabled ] && FILE=$CFG_disabled [ -f $CFG ] && FILE=$CFG RESULT=0 #if we know our WAN IP, only update if IP changes if [ "$OLDIP" != "$WANIP" -a "${WANIP}" != ${NOIP} ];then ${UPDATE_TOOL} -c $FILE RESULT=$? cat /proc/uptime |awk '{print $1}' > $LASTUPDATE fi #if we don't know our WAN IP do a blind update once a hour if [ "${WANIP}" = ${NOIP} ];then UPTIME=`cat /proc/uptime` LAST=`cat $LASTUPDATE` DIFF=`expr $UPTIME - $LAST` if [ $DIFF -gt $UPDATEMINUTESUNKNOWN ];then ${UPDATE_TOOL} -c $FILE RESULT=$? cat /proc/uptime |awk '{print $1}' > $LASTUPDATE fi fi if [ $RESULT -eq 0 ];then $0 success else $0 failed fi ;; stop) rm $CRONJOB 2> /dev/null /etc/init.d/${TOOLNAME} stop mv $CFG $CFG_disabled ;; success) DATE=`date` echo "last update done ($DATE)" > $STATUSFILE ;; failed) DATE=`date` echo "last update failed ($DATE)" > $STATUSFILE ;; get-last-success) if [ -f $STATUSFILE ];then cat $STATUSFILE else echo "no update recorded since last config change" fi ;; get-installed) if [ ! -z ${UPDATE_TOOL} ];then echo "installed" fi ;; status) doReadCFG PROC=`pgrep ${TOOLNAME}` if [ -f $CRONJOB ];then echo enabled elif [ ! -z $PROC ];then echo enabled else echo disabled fi echo $server echo $host echo $user echo $pass echo $IPURL ;; get-timer) echo $UPDATEMINUTES ;; clean) rm ${CFGDIR}/* ;; *) echo "usage: get-installed|status|configure |start|stop|update|get-nat|clean|success|failed" echo "" echo "options are:" echo "-s Gnudip Server address" echo "-d Domain to be updated" echo "-u Account username" echo "-p Account Password" echo "-I A URL which returns the IP of the client who is requesting" echo "" echo "update do a one time update" echo "clean delete configuration" echo "success store update success" echo "failed store update failure" ;; esac exit 0