ddns-scripts: Copied from previous repository
authorNikos Mavrogiannopoulos <[email protected]>
Sun, 8 Jun 2014 12:03:31 +0000 (14:03 +0200)
committerNikos Mavrogiannopoulos <[email protected]>
Sun, 8 Jun 2014 12:03:36 +0000 (14:03 +0200)
Signed-off-by: Nikos Mavrogiannopoulos <[email protected]>
net/ddns-scripts/Makefile [new file with mode: 0644]
net/ddns-scripts/files/etc/config/ddns [new file with mode: 0644]
net/ddns-scripts/files/etc/hotplug.d/iface/25-ddns [new file with mode: 0644]
net/ddns-scripts/files/etc/init.d/ddns [new file with mode: 0644]
net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_functions.sh [new file with mode: 0644]
net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_updater.sh [new file with mode: 0755]
net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_updater.sh~ [new file with mode: 0755]
net/ddns-scripts/files/usr/lib/ddns/services [new file with mode: 0644]
net/ddns-scripts/files/usr/lib/ddns/url_escape.sed [new file with mode: 0644]

diff --git a/net/ddns-scripts/Makefile b/net/ddns-scripts/Makefile
new file mode 100644 (file)
index 0000000..4b50e8d
--- /dev/null
@@ -0,0 +1,44 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ddns-scripts
+PKG_VERSION:=1.0.0
+PKG_RELEASE:=22
+
+PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ddns-scripts
+       SECTION:=net
+       CATEGORY:=Network
+        SUBMENU:=IP Addresses and Names
+       TITLE:=Dynamic DNS Scripts
+       PKGARCH:=all
+endef
+
+define Package/ddns-scripts/description
+       A highly configurable set of scripts for doing
+       dynamic dns updates
+endef
+
+define Build/Prepare
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+endef
+
+define Package/ddns-scripts/conffiles
+/etc/config/ddns
+endef
+
+define Package/ddns-scripts/install
+       $(INSTALL_DIR) $(1)
+       $(CP) ./files/* $(1)/
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/etc/init.d/ddns $(1)/etc/init.d/
+endef
+
+$(eval $(call BuildPackage,ddns-scripts))
diff --git a/net/ddns-scripts/files/etc/config/ddns b/net/ddns-scripts/files/etc/config/ddns
new file mode 100644 (file)
index 0000000..e7337b5
--- /dev/null
@@ -0,0 +1,97 @@
+#################################################################
+# In order to enable dynamic dns you need at least one section,
+# and in that seciton the "enabled" option must be set to one
+# 
+# Each section represents an update to a different service
+#
+# You specify your domain name, your username and your password
+# with the optins "domain", "username" and "password" respectively
+#
+# Next you need to specify the name of the service you are 
+# connecting to "eg. dyndns.org".  The format of the update
+# urls for several different dynamic dns services is specified
+# in the /usr/lib/ddns/services file.  This list is hardly complete
+# as there are many, many different dynamic dns services.  If your
+# service is on the list you can merely specify it with the 
+# "service_name" option.  Otherwise you will need to determine
+# the format of the url to update with.  You can either add an
+# entry to the /usr/lib/ddns/services file or specify this with
+# the "update_url" option.
+#
+# We also need to specify the source of the ip address to associate with
+# your domain.  The "ip_source" option can be "network", "interface"
+# or "web", with "network" as the default.  
+#
+# If "ip_source" is "network" you specify a network section in your 
+# /etc/network config file (e.g. "wan", which is the default) with
+# the "ip_network" option.  If you specify "wan", you will update
+# with whatever the ip for your wan is.
+# 
+# If "ip_source" is "interface" you specify a hardware interface 
+# (e.g. "eth1") and whatever the current ip of this interface is
+# will be associated with the domain when an update is performed.
+#
+# If "ip_source" is "script" you specify a script to obtain ip address.
+# The "ip_script" option should contain path to your script.
+#
+# The last possibility is that "ip_source" is "web", which means
+# that in order to obtain our ip address we will connect to a 
+# website, and the first valid ip address listed on that page
+# will be assumed to be ours.  If you are behind another firewall
+# this is the best option since none of the local networks or 
+# interfaces will have the external ip.  The website to connect
+# to is specified by the "ip_url" option.  You may specify multiple
+# urls in the option, separated by whitespace.
+#
+# Finally we need to specify how often to check whether we need
+# to check whether the ip address has changed (and if so update
+# it) and how often we need to force an update ( many services
+# will expire your domain if you don't connect and do an update
+# every so often).  Use the "check_interval" to specify how
+# often to check whether an update is necessary, the "retry_interval"
+# to specify how often to retry in case the update has failed, and
+# the "force_interval" option to specify how often to force an
+# update.  Specify the units for these values with the "check_unit",
+# the "retry_init" and the "force_unit" options.  Units can be
+# "days", "hours", "minutes" or "seconds".  The default force_unit
+# is hours, the default retry_unit is seconds and the default
+# check_unit is seconds.  The default check_interval is 600 seconds,
+# or ten minutes.  The default retry_interval is 60 seconds, or one
+# minute. The default force_interval is 72 hours or 3 days.
+#
+#
+#########################################################
+
+config service "myddns"
+       option enabled          "0"
+       option interface        "wan"
+       option use_syslog       "1"
+
+       option service_name     "dyndns.org"
+       option domain           "mypersonaldomain.dyndns.org"
+       option username         "myusername"
+       option password         "mypassword"    
+       option use_https        "0"
+
+       option force_interval   "72"
+       option force_unit       "hours"
+       option check_interval   "10"
+       option check_unit       "minutes"
+       option retry_interval   "60"
+       option retry_unit       "seconds"
+
+       #option ip_source       "network" 
+       #option ip_network      "wan"
+
+       #option ip_source       "interface"
+       #option ip_interface    "eth0.1"
+
+       #option ip_source       "script"
+       #option ip_script       "path to your scrip"
+
+       option ip_source        "web"
+       option ip_url           "http://checkip.dyndns.com/"
+
+       #option update_url      "http://[USERNAME]:[PASSWORD]@members.dyndns.org/nic/update?hostname=[DOMAIN]&myip=[IP]"
+
+
diff --git a/net/ddns-scripts/files/etc/hotplug.d/iface/25-ddns b/net/ddns-scripts/files/etc/hotplug.d/iface/25-ddns
new file mode 100644 (file)
index 0000000..4495b5d
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+. /usr/lib/ddns/dynamic_dns_functions.sh
+
+if [ "$ACTION" = "ifup" ]; then
+       start_daemon_for_all_ddns_sections "$INTERFACE"
+fi
+
+
diff --git a/net/ddns-scripts/files/etc/init.d/ddns b/net/ddns-scripts/files/etc/init.d/ddns
new file mode 100644 (file)
index 0000000..3171d5a
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh /etc/rc.common
+START=95
+
+start() {
+       . /usr/lib/ddns/dynamic_dns_functions.sh
+       start_daemon_for_all_ddns_sections
+}
+
+stop() {
+       killall -9 dynamic_dns_updater.sh
+}
+
diff --git a/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_functions.sh b/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_functions.sh
new file mode 100644 (file)
index 0000000..a596932
--- /dev/null
@@ -0,0 +1,144 @@
+# /usr/lib/dynamic_dns/dynamic_dns_functions.sh
+#
+# Written by Eric Paul Bishop, Janary 2008
+# Distributed under the terms of the GNU General Public License (GPL) version 2.0
+#
+# This script is (loosely) based on the one posted by exobyte in the forums here:
+# http://forum.openwrt.org/viewtopic.php?id=14040
+
+
+
+. /lib/functions.sh
+. /lib/functions/network.sh
+
+
+#loads all options for a given package and section
+#also, sets all_option_variables to a list of the variable names
+load_all_config_options()
+{
+       pkg_name="$1"
+       section_id="$2"
+
+       ALL_OPTION_VARIABLES=""
+       # this callback loads all the variables
+       # in the section_id section when we do
+       # config_load. We need to redefine
+       # the option_cb for different sections
+       # so that the active one isn't still active
+       # after we're done with it.  For reference
+       # the $1 variable is the name of the option
+       # and $2 is the name of the section
+       config_cb()
+       {
+               if [ ."$2" = ."$section_id" ]; then
+                       option_cb()
+                       {
+                               ALL_OPTION_VARIABLES="$ALL_OPTION_VARIABLES $1"
+                       }
+               else
+                       option_cb() { return 0; }
+               fi
+       }
+
+
+       config_load "$pkg_name"
+       for var in $ALL_OPTION_VARIABLES
+       do
+               config_get "$var" "$section_id" "$var"
+       done
+}
+
+
+get_current_ip()
+{
+
+       #if ip source is not defined, assume we want to get ip from wan 
+       if [ "$ip_source" != "interface" ] && [ "$ip_source" != "web" ] && [ "$ip_source" != "script" ]
+       then
+               ip_source="network"
+       fi
+
+       if [ "$ip_source" = "network" ]
+       then
+               if [ -z "$ip_network" ]
+               then
+                       ip_network="wan"
+               fi
+       fi
+
+       current_ip='';
+       if [ "$ip_source" = "network" ]
+       then
+               network_get_ipaddr current_ip "$ip_network" || return
+       elif [ "$ip_source" = "interface" ]
+       then
+               current_ip=$(ifconfig $ip_interface | grep -o 'inet addr:[0-9.]*' | grep -o "$ip_regex")
+       elif [ "$ip_source" = "script" ]
+       then
+               # get ip from script
+               current_ip=$($ip_script)
+       else
+               # get ip from web
+               # we check each url in order in ip_url variable, and if no ips are found we use dyndns ip checker
+               # ip is set to FIRST expression in page that matches the ip_regex regular expression
+               for addr in $ip_url
+               do
+                       if [ -z "$current_ip" ]
+                       then
+                               current_ip=$(echo $( wget -O - $addr 2>/dev/null) | grep -o "$ip_regex")
+                       fi
+               done
+
+               #here we hard-code the dyndns checkip url in case no url was specified
+               if [ -z "$current_ip" ]
+               then
+                       current_ip=$(echo $( wget -O - http://checkip.dyndns.org 2>/dev/null) | grep -o "$ip_regex")
+               fi
+       fi
+
+       echo "$current_ip"
+}
+
+
+verbose_echo()
+{
+       if [ "$verbose_mode" = 1 ]
+       then
+               echo $1
+       fi
+}
+
+syslog_echo()
+{
+       if [ "$use_syslog" = 1 ]
+       then
+               echo $1|logger -t ddns-scripts-$service_id
+       fi
+}
+
+start_daemon_for_all_ddns_sections()
+{
+       local event_interface="$1"
+
+       SECTIONS=""
+       config_cb() 
+       {
+               SECTIONS="$SECTIONS $2"
+       }
+       config_load "ddns"
+
+       for section in $SECTIONS
+       do
+               local iface
+               config_get iface "$section" interface "wan"
+               [ "$iface" = "$event_interface" ] || continue
+               /usr/lib/ddns/dynamic_dns_updater.sh $section 0 > /dev/null 2>&1 &
+       done
+}
+
+monotonic_time()
+{
+       local uptime
+       read uptime < /proc/uptime
+       echo "${uptime%%.*}"
+}
diff --git a/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_updater.sh b/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_updater.sh
new file mode 100755 (executable)
index 0000000..e6d2987
--- /dev/null
@@ -0,0 +1,360 @@
+#!/bin/sh
+# /usr/lib/dynamic_dns/dynamic_dns_updater.sh
+#
+# Written by Eric Paul Bishop, Janary 2008
+# Distributed under the terms of the GNU General Public License (GPL) version 2.0
+#
+# This script is (loosely) based on the one posted by exobyte in the forums here:
+# http://forum.openwrt.org/viewtopic.php?id=14040
+#
+
+. /usr/lib/ddns/dynamic_dns_functions.sh
+
+
+service_id=$1
+if [ -z "$service_id" ]
+then
+       echo "ERRROR: You must specify a service id (the section name in the /etc/config/ddns file) to initialize dynamic DNS."
+       return 1
+fi
+
+#default mode is verbose_mode, but easily turned off with second parameter
+verbose_mode="1"
+if [ -n "$2" ]
+then
+       verbose_mode="$2"
+fi
+
+###############################################################
+# Leave this comment here, to clearly document variable names
+# that are expected/possible
+#
+# Now use load_all_config_options to load config
+# options, which is a much more flexible solution.
+#
+#
+#config_load "ddns"
+#
+#config_get enabled $service_id enabled
+#config_get service_name $service_id service_name
+#config_get update_url $service_id update_url
+#
+#
+#config_get username $service_id username
+#config_get password $service_id password
+#config_get domain $service_id domain
+#
+#
+#config_get use_https $service_id use_https
+#config_get use_syslog $service_id use_syslog
+#config_get cacert $service_id cacert
+#
+#config_get ip_source $service_id ip_source
+#config_get ip_interface $service_id ip_interface
+#config_get ip_network $service_id ip_network
+#config_get ip_url $service_id ip_url
+#
+#config_get force_interval $service_id force_interval
+#config_get force_unit $service_id force_unit
+#
+#config_get check_interval $service_id check_interval
+#config_get check_unit $service_id check_unit
+#########################################################
+load_all_config_options "ddns" "$service_id"
+
+
+#some defaults
+if [ -z "$check_interval" ]
+then
+       check_interval=600
+fi
+
+if [ -z "$retry_interval" ]
+then
+       retry_interval=60
+fi
+
+if [ -z "$check_unit" ]
+then
+       check_unit="seconds"
+fi
+
+if [ -z "$force_interval" ]
+then
+       force_interval=72
+fi
+
+if [ -z "$force_unit" ]
+then
+       force_unit="hours"
+fi
+
+if [ -z $use_syslog ]
+then
+       use_syslog=0
+fi
+
+if [ -z "$use_https" ]
+then
+       use_https=0
+fi
+
+
+#some constants
+
+retrieve_prog="/usr/bin/wget -O - ";
+if [ "x$use_https" = "x1" ]
+then
+       /usr/bin/wget --version 2>&1 |grep -q "\+ssl"
+       if [ $? -eq 0 ]
+       then
+               if [ -f "$cacert" ]
+               then
+                       retrieve_prog="${retrieve_prog}--ca-certificate=${cacert} "
+               elif [ -d "$cacert" ]
+               then
+                       retrieve_prog="${retrieve_prog}--ca-directory=${cacert} "
+               fi
+       else
+               retrieve_prog="/usr/bin/curl "
+               if [ -f "$cacert" ]
+               then
+                       retrieve_prog="${retrieve_prog}--cacert $cacert "
+               elif [ -d "$cacert" ]
+               then
+                       retrieve_prog="${retrieve_prog}--capath $cacert "
+               fi
+       fi
+fi
+
+
+service_file="/usr/lib/ddns/services"
+
+ip_regex="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
+
+NEWLINE_IFS='
+'
+
+#determine what update url we're using if the service_name is supplied
+if [ -n "$service_name" ]
+then
+       #remove any lines not containing data, and then make sure fields are enclosed in double quotes
+       quoted_services=$(cat $service_file |  grep "^[\t ]*[^#]" |  awk ' gsub("\x27", "\"") { if ($1~/^[^\"]*$/) $1="\""$1"\"" }; { if ( $NF~/^[^\"]*$/) $NF="\""$NF"\""  }; { print $0 }' )
+
+
+       #echo "quoted_services = $quoted_services"
+       OLD_IFS=$IFS
+       IFS=$NEWLINE_IFS
+       for service_line in $quoted_services
+       do
+               #grep out proper parts of data and use echo to remove quotes
+               next_name=$(echo $service_line | grep -o "^[\t ]*\"[^\"]*\"" | xargs -r -n1 echo)
+               next_url=$(echo $service_line | grep -o "\"[^\"]*\"[\t ]*$" | xargs -r -n1 echo)
+
+               if [ "$next_name" = "$service_name" ]
+               then
+                       update_url=$next_url
+               fi
+       done
+       IFS=$OLD_IFS
+fi
+
+if [ "x$use_https" = x1 ]
+then
+       update_url=$(echo $update_url | sed -e 's/^http:/https:/')
+fi
+
+verbose_echo "update_url=$update_url"
+
+#if this service isn't enabled then quit
+if [ "$enabled" != "1" ] 
+then
+       return 0
+fi
+
+#compute update interval in seconds
+case "$force_unit" in
+       "days" )
+               force_interval_seconds=$(($force_interval*60*60*24))
+               ;;
+       "hours" )
+               force_interval_seconds=$(($force_interval*60*60))
+               ;;
+       "minutes" )
+               force_interval_seconds=$(($force_interval*60))
+               ;;
+       "seconds" )
+               force_interval_seconds=$force_interval
+               ;;
+       * )
+               #default is hours
+               force_interval_seconds=$(($force_interval*60*60))
+               ;;
+esac
+
+
+#compute check interval in seconds
+case "$check_unit" in
+       "days" )
+               check_interval_seconds=$(($check_interval*60*60*24))
+               ;;
+       "hours" )
+               check_interval_seconds=$(($check_interval*60*60))
+               ;;
+       "minutes" )
+               check_interval_seconds=$(($check_interval*60))
+               ;;
+       "seconds" )
+               check_interval_seconds=$check_interval
+               ;;
+       * )
+               #default is seconds
+               check_interval_seconds=$check_interval
+               ;;
+esac
+
+
+#compute retry interval in seconds
+case "$retry_unit" in
+       "days" )
+               retry_interval_seconds=$(($retry_interval*60*60*24))
+               ;;
+       "hours" )
+               retry_interval_seconds=$(($retry_interval*60*60))
+               ;;
+       "minutes" )
+               retry_interval_seconds=$(($retry_interval*60))
+               ;;
+       "seconds" )
+               retry_interval_seconds=$retry_interval
+               ;;
+       * )
+               #default is seconds
+               retry_interval_seconds=$retry_interval
+               ;;
+esac
+
+
+verbose_echo "force seconds = $force_interval_seconds"
+verbose_echo "check seconds = $check_interval_seconds"
+
+#kill old process if it exists & set new pid file
+if [ -d /var/run/dynamic_dns ]
+then
+       #if process is already running, stop it
+       if [ -e "/var/run/dynamic_dns/$service_id.pid" ]
+       then
+               old_pid=$(cat /var/run/dynamic_dns/$service_id.pid)
+               test_match=$(ps | grep "^[\t ]*$old_pid")
+               verbose_echo "old process id (if it exists) = \"$test_match\""
+               if [ -n  "$test_match" ]
+               then
+                       kill $old_pid
+               fi
+       fi
+
+else
+       #make dir since it doesn't exist
+       mkdir /var/run/dynamic_dns
+fi
+echo $$ > /var/run/dynamic_dns/$service_id.pid
+
+
+
+
+#determine when the last update was
+current_time=$(monotonic_time)
+last_update=$(( $current_time - (2*$force_interval_seconds) ))
+if [ -e "/var/run/dynamic_dns/$service_id.update" ]
+then
+       last_update=$(cat /var/run/dynamic_dns/$service_id.update)
+fi
+time_since_update=$(($current_time - $last_update))
+
+
+human_time_since_update=$(( $time_since_update / ( 60 * 60 ) ))
+verbose_echo "time_since_update = $human_time_since_update hours"
+
+
+
+#do update and then loop endlessly, checking ip every check_interval and forcing an updating once every force_interval
+
+while [ true ]
+do
+       registered_ip=$(echo $(nslookup "$domain" 2>/dev/null) |  grep -o "Name:.*" | grep -o "$ip_regex")
+       current_ip=$(get_current_ip)
+
+
+       current_time=$(monotonic_time)
+       time_since_update=$(($current_time - $last_update))
+
+       syslog_echo "Running IP check ..."
+       verbose_echo "Running IP check..."
+       verbose_echo "current system ip = $current_ip"
+       verbose_echo "registered domain ip = $registered_ip"
+
+
+       if [ "$current_ip" != "$registered_ip" ]  || [ $force_interval_seconds -lt $time_since_update ]
+       then
+               verbose_echo "update necessary, performing update ..."
+
+               #do replacement
+               final_url=$update_url
+               for option_var in $ALL_OPTION_VARIABLES
+               do
+                       if [ "$option_var" != "update_url" ]
+                       then
+                               replace_name=$(echo "\[$option_var\]" | tr 'a-z' 'A-Z')
+                               replace_value=$(eval echo "\$$option_var")
+                               replace_value=$(echo $replace_value | sed -f /usr/lib/ddns/url_escape.sed)
+                               final_url=$(echo $final_url | sed s^"$replace_name"^"$replace_value"^g )
+                       fi
+               done
+               final_url=$(echo $final_url | sed s^"\[HTTPAUTH\]"^"${username//^/\\^}${password:+:${password//^/\\^}}"^g )
+               final_url=$(echo $final_url | sed s/"\[IP\]"/"$current_ip"/g )
+
+
+               verbose_echo "updating with url=\"$final_url\""
+
+               #here we actually connect, and perform the update
+               update_output=$( $retrieve_prog "$final_url" )
+               if [ $? -gt 0 ]
+               then
+                       syslog_echo "update failed, retrying in $retry_interval_seconds seconds"
+                       verbose_echo "update failed"
+                       sleep $retry_interval_seconds
+                       continue
+               fi
+               syslog_echo "Update successful"
+               verbose_echo "Update Output:"
+               verbose_echo "$update_output"
+               verbose_echo ""
+
+               #save the time of the update
+               current_time=$(monotonic_time)
+               last_update=$current_time
+               time_since_update='0'
+               registered_ip=$current_ip
+
+               human_time=$(date)
+               verbose_echo "update complete, time is: $human_time"
+
+               echo "$last_update" > "/var/run/dynamic_dns/$service_id.update"
+       else
+               human_time=$(date)
+               human_time_since_update=$(( $time_since_update / ( 60 * 60 ) ))
+               verbose_echo "update unnecessary"
+               verbose_echo "time since last update = $human_time_since_update hours"
+               verbose_echo "the time is now $human_time"
+       fi
+
+       #sleep for 10 minutes, then re-check ip && time since last update
+       sleep $check_interval_seconds
+done
+
+#should never get here since we're a daemon, but I'll throw it in anyway
+return 0
+
+
+
+
diff --git a/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_updater.sh~ b/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_updater.sh~
new file mode 100755 (executable)
index 0000000..e6d2987
--- /dev/null
@@ -0,0 +1,360 @@
+#!/bin/sh
+# /usr/lib/dynamic_dns/dynamic_dns_updater.sh
+#
+# Written by Eric Paul Bishop, Janary 2008
+# Distributed under the terms of the GNU General Public License (GPL) version 2.0
+#
+# This script is (loosely) based on the one posted by exobyte in the forums here:
+# http://forum.openwrt.org/viewtopic.php?id=14040
+#
+
+. /usr/lib/ddns/dynamic_dns_functions.sh
+
+
+service_id=$1
+if [ -z "$service_id" ]
+then
+       echo "ERRROR: You must specify a service id (the section name in the /etc/config/ddns file) to initialize dynamic DNS."
+       return 1
+fi
+
+#default mode is verbose_mode, but easily turned off with second parameter
+verbose_mode="1"
+if [ -n "$2" ]
+then
+       verbose_mode="$2"
+fi
+
+###############################################################
+# Leave this comment here, to clearly document variable names
+# that are expected/possible
+#
+# Now use load_all_config_options to load config
+# options, which is a much more flexible solution.
+#
+#
+#config_load "ddns"
+#
+#config_get enabled $service_id enabled
+#config_get service_name $service_id service_name
+#config_get update_url $service_id update_url
+#
+#
+#config_get username $service_id username
+#config_get password $service_id password
+#config_get domain $service_id domain
+#
+#
+#config_get use_https $service_id use_https
+#config_get use_syslog $service_id use_syslog
+#config_get cacert $service_id cacert
+#
+#config_get ip_source $service_id ip_source
+#config_get ip_interface $service_id ip_interface
+#config_get ip_network $service_id ip_network
+#config_get ip_url $service_id ip_url
+#
+#config_get force_interval $service_id force_interval
+#config_get force_unit $service_id force_unit
+#
+#config_get check_interval $service_id check_interval
+#config_get check_unit $service_id check_unit
+#########################################################
+load_all_config_options "ddns" "$service_id"
+
+
+#some defaults
+if [ -z "$check_interval" ]
+then
+       check_interval=600
+fi
+
+if [ -z "$retry_interval" ]
+then
+       retry_interval=60
+fi
+
+if [ -z "$check_unit" ]
+then
+       check_unit="seconds"
+fi
+
+if [ -z "$force_interval" ]
+then
+       force_interval=72
+fi
+
+if [ -z "$force_unit" ]
+then
+       force_unit="hours"
+fi
+
+if [ -z $use_syslog ]
+then
+       use_syslog=0
+fi
+
+if [ -z "$use_https" ]
+then
+       use_https=0
+fi
+
+
+#some constants
+
+retrieve_prog="/usr/bin/wget -O - ";
+if [ "x$use_https" = "x1" ]
+then
+       /usr/bin/wget --version 2>&1 |grep -q "\+ssl"
+       if [ $? -eq 0 ]
+       then
+               if [ -f "$cacert" ]
+               then
+                       retrieve_prog="${retrieve_prog}--ca-certificate=${cacert} "
+               elif [ -d "$cacert" ]
+               then
+                       retrieve_prog="${retrieve_prog}--ca-directory=${cacert} "
+               fi
+       else
+               retrieve_prog="/usr/bin/curl "
+               if [ -f "$cacert" ]
+               then
+                       retrieve_prog="${retrieve_prog}--cacert $cacert "
+               elif [ -d "$cacert" ]
+               then
+                       retrieve_prog="${retrieve_prog}--capath $cacert "
+               fi
+       fi
+fi
+
+
+service_file="/usr/lib/ddns/services"
+
+ip_regex="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
+
+NEWLINE_IFS='
+'
+
+#determine what update url we're using if the service_name is supplied
+if [ -n "$service_name" ]
+then
+       #remove any lines not containing data, and then make sure fields are enclosed in double quotes
+       quoted_services=$(cat $service_file |  grep "^[\t ]*[^#]" |  awk ' gsub("\x27", "\"") { if ($1~/^[^\"]*$/) $1="\""$1"\"" }; { if ( $NF~/^[^\"]*$/) $NF="\""$NF"\""  }; { print $0 }' )
+
+
+       #echo "quoted_services = $quoted_services"
+       OLD_IFS=$IFS
+       IFS=$NEWLINE_IFS
+       for service_line in $quoted_services
+       do
+               #grep out proper parts of data and use echo to remove quotes
+               next_name=$(echo $service_line | grep -o "^[\t ]*\"[^\"]*\"" | xargs -r -n1 echo)
+               next_url=$(echo $service_line | grep -o "\"[^\"]*\"[\t ]*$" | xargs -r -n1 echo)
+
+               if [ "$next_name" = "$service_name" ]
+               then
+                       update_url=$next_url
+               fi
+       done
+       IFS=$OLD_IFS
+fi
+
+if [ "x$use_https" = x1 ]
+then
+       update_url=$(echo $update_url | sed -e 's/^http:/https:/')
+fi
+
+verbose_echo "update_url=$update_url"
+
+#if this service isn't enabled then quit
+if [ "$enabled" != "1" ] 
+then
+       return 0
+fi
+
+#compute update interval in seconds
+case "$force_unit" in
+       "days" )
+               force_interval_seconds=$(($force_interval*60*60*24))
+               ;;
+       "hours" )
+               force_interval_seconds=$(($force_interval*60*60))
+               ;;
+       "minutes" )
+               force_interval_seconds=$(($force_interval*60))
+               ;;
+       "seconds" )
+               force_interval_seconds=$force_interval
+               ;;
+       * )
+               #default is hours
+               force_interval_seconds=$(($force_interval*60*60))
+               ;;
+esac
+
+
+#compute check interval in seconds
+case "$check_unit" in
+       "days" )
+               check_interval_seconds=$(($check_interval*60*60*24))
+               ;;
+       "hours" )
+               check_interval_seconds=$(($check_interval*60*60))
+               ;;
+       "minutes" )
+               check_interval_seconds=$(($check_interval*60))
+               ;;
+       "seconds" )
+               check_interval_seconds=$check_interval
+               ;;
+       * )
+               #default is seconds
+               check_interval_seconds=$check_interval
+               ;;
+esac
+
+
+#compute retry interval in seconds
+case "$retry_unit" in
+       "days" )
+               retry_interval_seconds=$(($retry_interval*60*60*24))
+               ;;
+       "hours" )
+               retry_interval_seconds=$(($retry_interval*60*60))
+               ;;
+       "minutes" )
+               retry_interval_seconds=$(($retry_interval*60))
+               ;;
+       "seconds" )
+               retry_interval_seconds=$retry_interval
+               ;;
+       * )
+               #default is seconds
+               retry_interval_seconds=$retry_interval
+               ;;
+esac
+
+
+verbose_echo "force seconds = $force_interval_seconds"
+verbose_echo "check seconds = $check_interval_seconds"
+
+#kill old process if it exists & set new pid file
+if [ -d /var/run/dynamic_dns ]
+then
+       #if process is already running, stop it
+       if [ -e "/var/run/dynamic_dns/$service_id.pid" ]
+       then
+               old_pid=$(cat /var/run/dynamic_dns/$service_id.pid)
+               test_match=$(ps | grep "^[\t ]*$old_pid")
+               verbose_echo "old process id (if it exists) = \"$test_match\""
+               if [ -n  "$test_match" ]
+               then
+                       kill $old_pid
+               fi
+       fi
+
+else
+       #make dir since it doesn't exist
+       mkdir /var/run/dynamic_dns
+fi
+echo $$ > /var/run/dynamic_dns/$service_id.pid
+
+
+
+
+#determine when the last update was
+current_time=$(monotonic_time)
+last_update=$(( $current_time - (2*$force_interval_seconds) ))
+if [ -e "/var/run/dynamic_dns/$service_id.update" ]
+then
+       last_update=$(cat /var/run/dynamic_dns/$service_id.update)
+fi
+time_since_update=$(($current_time - $last_update))
+
+
+human_time_since_update=$(( $time_since_update / ( 60 * 60 ) ))
+verbose_echo "time_since_update = $human_time_since_update hours"
+
+
+
+#do update and then loop endlessly, checking ip every check_interval and forcing an updating once every force_interval
+
+while [ true ]
+do
+       registered_ip=$(echo $(nslookup "$domain" 2>/dev/null) |  grep -o "Name:.*" | grep -o "$ip_regex")
+       current_ip=$(get_current_ip)
+
+
+       current_time=$(monotonic_time)
+       time_since_update=$(($current_time - $last_update))
+
+       syslog_echo "Running IP check ..."
+       verbose_echo "Running IP check..."
+       verbose_echo "current system ip = $current_ip"
+       verbose_echo "registered domain ip = $registered_ip"
+
+
+       if [ "$current_ip" != "$registered_ip" ]  || [ $force_interval_seconds -lt $time_since_update ]
+       then
+               verbose_echo "update necessary, performing update ..."
+
+               #do replacement
+               final_url=$update_url
+               for option_var in $ALL_OPTION_VARIABLES
+               do
+                       if [ "$option_var" != "update_url" ]
+                       then
+                               replace_name=$(echo "\[$option_var\]" | tr 'a-z' 'A-Z')
+                               replace_value=$(eval echo "\$$option_var")
+                               replace_value=$(echo $replace_value | sed -f /usr/lib/ddns/url_escape.sed)
+                               final_url=$(echo $final_url | sed s^"$replace_name"^"$replace_value"^g )
+                       fi
+               done
+               final_url=$(echo $final_url | sed s^"\[HTTPAUTH\]"^"${username//^/\\^}${password:+:${password//^/\\^}}"^g )
+               final_url=$(echo $final_url | sed s/"\[IP\]"/"$current_ip"/g )
+
+
+               verbose_echo "updating with url=\"$final_url\""
+
+               #here we actually connect, and perform the update
+               update_output=$( $retrieve_prog "$final_url" )
+               if [ $? -gt 0 ]
+               then
+                       syslog_echo "update failed, retrying in $retry_interval_seconds seconds"
+                       verbose_echo "update failed"
+                       sleep $retry_interval_seconds
+                       continue
+               fi
+               syslog_echo "Update successful"
+               verbose_echo "Update Output:"
+               verbose_echo "$update_output"
+               verbose_echo ""
+
+               #save the time of the update
+               current_time=$(monotonic_time)
+               last_update=$current_time
+               time_since_update='0'
+               registered_ip=$current_ip
+
+               human_time=$(date)
+               verbose_echo "update complete, time is: $human_time"
+
+               echo "$last_update" > "/var/run/dynamic_dns/$service_id.update"
+       else
+               human_time=$(date)
+               human_time_since_update=$(( $time_since_update / ( 60 * 60 ) ))
+               verbose_echo "update unnecessary"
+               verbose_echo "time since last update = $human_time_since_update hours"
+               verbose_echo "the time is now $human_time"
+       fi
+
+       #sleep for 10 minutes, then re-check ip && time since last update
+       sleep $check_interval_seconds
+done
+
+#should never get here since we're a daemon, but I'll throw it in anyway
+return 0
+
+
+
+
diff --git a/net/ddns-scripts/files/usr/lib/ddns/services b/net/ddns-scripts/files/usr/lib/ddns/services
new file mode 100644 (file)
index 0000000..744de02
--- /dev/null
@@ -0,0 +1,65 @@
+# This file contains the update urls for various dynamic dns services.
+# Column one contains the service name, column two contains the update url.
+# within the update url there are 4 variables you can use: [USERNAME], 
+# [PASSWORD], [DOMAIN] and [IP].  These are substituted for the username, 
+# password, and domain name specified in the /etc/config/ddns file when an 
+# update is performed.  The IP is substituted for the current ip address of the
+# router.  These variables are case sensitive, while urls generally are not, so 
+# if you need to enter the same text in the url (which seems very unlikely) put 
+# that text in lowercase, while the variables should remain in uppercase
+
+"dyndns.org"           "http://[USERNAME]:[PASSWORD]@members.dyndns.org/nic/update?hostname=[DOMAIN]&myip=[IP]"
+"changeip.com"         "http://[USERNAME]:[PASSWORD]@nic.changeip.com/nic/update?u=[USERNAME]&p=[PASSWORD]&cmd=update&hostname=[DOMAIN]&ip=[IP]"
+"zoneedit.com"         "http://[USERNAME]:[PASSWORD]@dynamic.zoneedit.com/auth/dynamic.html?host=[DOMAIN]&dnsto=[IP]"
+"free.editdns.net"     "http://dyndns-free.editdns.net/api/dynLinux.php?p=[PASSWORD]&r=[DOMAIN]"
+
+#noip is an alias of no-ip, so allow both names for the same service
+"no-ip.com"            "http://[USERNAME]:[PASSWORD]@dynupdate.no-ip.com/nic/update?hostname=[DOMAIN]&myip=[IP]"
+"noip.com"             "http://[USERNAME]:[PASSWORD]@dynupdate.no-ip.com/nic/update?hostname=[DOMAIN]&myip=[IP]"
+
+#freedns.afraid.org is weird, you just need an update code, for which we use the password variable
+"freedns.afraid.org"   "http://freedns.afraid.org/dynamic/update.php?[PASSWORD]&address=[IP]"
+
+#### ADD YOURS HERE! ######################################################################################
+#                                                                                                         #
+# There are TONS of dynamic dns services out there. There's a huge list of them at:                       #
+# http://www.dmoz.org/Computers/Software/Internet/Servers/Address_Management/Dynamic_DNS_Services/        #
+# If anyone has time they could update this file to be compatible with a bunch of them                    #
+#                                                                                                         #
+###########################################################################################################
+
+# DNS Max and resellers' update urls
+"dnsmax.com"   "http://update.dnsmax.com/update/?username=[USERNAME]&password=[PASSWORD]&resellerid=1&clientname=openwrt&clientversion=8.09&protocolversion=2.0&updatehostname=[DOMAIN]&ip=[IP]"
+"thatip.com"   "http://update.dnsmax.com/update/?username=[USERNAME]&password=[PASSWORD]&resellerid=2&clientname=openwrt&clientversion=8.09&protocolversion=2.0&updatehostname=[DOMAIN]&ip=[IP]"
+
+# Hurricane Electric Dynamic DNS
+"he.net"               "http://[DOMAIN]:[PASSWORD]@dyn.dns.he.net/nic/update?hostname=[DOMAIN]&myip=[IP]" 
+
+# DNSdynamic.org
+"dnsdynamic.org"       "http://[USERNAME]:[PASSWORD]@www.dnsdynamic.org/api/?hostname=[DOMAIN]&myip=[IP]"
+
+# dnsExit.com free dynamic DNS update url
+"dnsexit.com"          "http://www.dnsexit.com/RemoteUpdate.sv?login=[USERNAME]&password=[PASSWORD]&host=[DOMAIN]&myip=[IP]"
+
+# OVH
+"ovh.com" "http://[USERNAME]:[PASSWORD]@www.ovh.com/nic/update?system=dyndns&hostname=[DOMAIN]&myip=[IP]"
+
+# dns-o-matic is a free service by opendns.com for updating multiple hosts and
+# dynamic dns services in one api call. To update all your configured services
+# at once, use "all.dnsomatic.com as the hostname.
+"dnsomatic.com" "http://[USERNAME]:[PASSWORD]@updates.dnsomatic.com/nic/update?hostname=[DOMAIN]&myip=[IP]"
+
+# 3322.org
+"3322.org"  "http://[USERNAME]:[PASSWORD]@members.3322.org/dyndns/update?system=dyndns&hostname=[DOMAIN]&myip=[IP]"
+
+# namecheap.com
+"namecheap.com" "http://dynamicdns.park-your-domain.com/update?host=[USERNAME]&domain=[DOMAIN]&password=[PASSWORD]&ip=[IP]"
+
+# easydns.com dynamic DNS
+"easydns.com"          "http://[USERNAME]:[PASSWORD]@api.cp.easydns.com/dyn/tomato.php?hostname=[DOMAIN]&myip=[IP]"
+
+# Winco DDNS
+"ddns.com.br"  "http://[DOMAIN]:[PASSWORD]@members.ddns.com.br/nic/update?hostname=[DOMAIN]&myip=[IP]"
+
+# Mythic Beasts (https://www.mythic-beasts.com) Dynamic DNS
+"mythic-beasts.com"    "http://dnsapi4.mythic-beasts.com/?domain=[USERNAME]&password=[PASSWORD]&command=REPLACE%20[DOMAIN]%2060%20A%20DYNAMIC_IP"
diff --git a/net/ddns-scripts/files/usr/lib/ddns/url_escape.sed b/net/ddns-scripts/files/usr/lib/ddns/url_escape.sed
new file mode 100644 (file)
index 0000000..eac4002
--- /dev/null
@@ -0,0 +1,25 @@
+# sed url escaping
+s:%:%25:g
+s: :%20:g
+s:<:%3C:g
+s:>:%3E:g
+s:#:%23:g
+s:{:%7B:g
+s:}:%7D:g
+s:|:%7C:g
+s:\\:%5C:g
+s:\^:%5E:g
+s:~:%7E:g
+s:\[:%5B:g
+s:\]:%5D:g
+s:`:%60:g
+s:;:%3B:g
+s:/:%2F:g
+s:?:%3F:g
+s^:^%3A^g
+s:@:%40:g
+s:=:%3D:g
+s:&:%26:g
+s:\$:%24:g
+s:\!:%21:g
+s:\*:%2A:g