mirror of
https://github.com/novatiq/packages.git
synced 2026-04-29 23:18:42 +01:00
[for-15.05] ddns-scripts: backport of 2.7.6-10
Backport of current version 2.7.6-10 - more services - more functionality - be prepared for next versions compiled ipk-packages available at https://github.com/chris5560/OpenWrt-Backports/tree/master/for-CC15.05.01/ddns-scripts_2.7.6-10 Signed-off-by: Christian Schoenebeck <christian.schoenebeck@gmail.com>
This commit is contained in:
@@ -1,20 +1,12 @@
|
||||
#!/bin/sh
|
||||
# /usr/lib/ddns/dynamic_dns_functions.sh
|
||||
#
|
||||
# Original written by Eric Paul Bishop, January 2008
|
||||
#.Distributed under the terms of the GNU General Public License (GPL) version 2.0
|
||||
# Original written by Eric Paul Bishop, January 2008
|
||||
# (Loosely) based on the script on the one posted by exobyte in the forums here:
|
||||
# http://forum.openwrt.org/viewtopic.php?id=14040
|
||||
#
|
||||
# extended and partial rewritten in August 2014 by
|
||||
#.Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
|
||||
# to support:
|
||||
# - IPv6 DDNS services
|
||||
# - setting DNS Server to retrieve current IP including TCP transport
|
||||
# - Proxy Server to send out updates or retrieving WEB based IP detection
|
||||
# - force_interval=0 to run once (useful for cron jobs etc.)
|
||||
# - the usage of BIND's host instead of BusyBox's nslookup if installed (DNS via TCP)
|
||||
# - extended Verbose Mode and log file support for better error detection
|
||||
# extended and partial rewritten
|
||||
#.2014-2017 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
|
||||
#
|
||||
# function timeout
|
||||
# copied from http://www.ict.griffith.edu.au/anthony/software/timeout.sh
|
||||
@@ -29,15 +21,17 @@
|
||||
. /lib/functions/network.sh
|
||||
|
||||
# GLOBAL VARIABLES #
|
||||
VERSION="2.7.6"
|
||||
SECTION_ID="" # hold config's section name
|
||||
VERBOSE_MODE=1 # default mode is log to console, but easily changed with parameter
|
||||
VERBOSE=0 # default mode is log to console, but easily changed with parameter
|
||||
MYPROG=$(basename $0) # my program call name
|
||||
|
||||
LOGFILE="" # logfile - all files are set in dynamic_dns_updater.sh
|
||||
PIDFILE="" # pid file
|
||||
UPDFILE="" # store UPTIME of last update
|
||||
DATFILE="" # save stdout data of WGet and other external programs called
|
||||
ERRFILE="" # save stderr output of WGet and other external programs called
|
||||
TLDFILE=/usr/lib/ddns/tld_names.dat.gz # TLD file used by split_FQDN
|
||||
TLDFILE=/usr/share/public_suffix_list.dat.gz # TLD file used by split_FQDN
|
||||
|
||||
CHECK_SECONDS=0 # calculated seconds out of given
|
||||
FORCE_SECONDS=0 # interval and unit
|
||||
@@ -53,44 +47,70 @@ LOCAL_IP="" # holds the local IP read from the box
|
||||
|
||||
URL_USER="" # url encoded $username from config file
|
||||
URL_PASS="" # url encoded $password from config file
|
||||
URL_PENC="" # url encoded $param_enc from config file
|
||||
|
||||
UPD_ANSWER="" # Answer given by service on success
|
||||
|
||||
ERR_LAST=0 # used to save $? return code of program and function calls
|
||||
ERR_UPDATE=0 # error counter on different local and registered ip
|
||||
|
||||
PID_SLEEP=0 # ProcessID of current background "sleep"
|
||||
|
||||
# allow NON-public IP's
|
||||
ALLOW_LOCAL_IP=$(uci -q get ddns.global.allow_local_ip) || ALLOW_LOCAL_IP=0
|
||||
|
||||
# directory to store run information to.
|
||||
RUNDIR=$(uci -q get ddns.global.run_dir) || RUNDIR="/var/run/ddns"
|
||||
[ -d $RUNDIR ] || mkdir -p -m755 $RUNDIR
|
||||
|
||||
# directory to store log files
|
||||
LOGDIR=$(uci -q get ddns.global.log_dir) || LOGDIR="/var/log/ddns"
|
||||
[ -d $LOGDIR ] || mkdir -p -m755 $LOGDIR
|
||||
|
||||
# number of lines to before rotate logfile
|
||||
LOGLINES=$(uci -q get ddns.global.log_lines) || LOGLINES=250
|
||||
LOGLINES=$((LOGLINES + 1)) # correct sed handling
|
||||
|
||||
# format to show date information in log and luci-app-ddns default ISO 8601 format
|
||||
DATE_FORMAT=$(uci -q get ddns.global.date_format) || DATE_FORMAT="%F %R"
|
||||
DATE_PROG="date +'$DATE_FORMAT'"
|
||||
|
||||
# regular expression to detect IPv4 / IPv6
|
||||
# IPv4 0-9 1-3x "." 0-9 1-3x "." 0-9 1-3x "." 0-9 1-3x
|
||||
IPV4_REGEX="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
|
||||
# IPv6 ( ( 0-9a-f 1-4char ":") min 1x) ( ( 0-9a-f 1-4char )optional) ( (":" 0-9a-f 1-4char ) min 1x)
|
||||
IPV6_REGEX="\(\([0-9A-Fa-f]\{1,4\}:\)\{1,\}\)\(\([0-9A-Fa-f]\{1,4\}\)\{0,1\}\)\(\(:[0-9A-Fa-f]\{1,4\}\)\{1,\}\)"
|
||||
|
||||
# detect if called by dynamic_dns_lucihelper.sh script, disable retrys (empty variable == false)
|
||||
[ "$(basename $0)" = "dynamic_dns_lucihelper.sh" ] && LUCI_HELPER="TRUE" || LUCI_HELPER=""
|
||||
# detect if called by ddns-lucihelper.sh script, disable retrys (empty variable == false)
|
||||
LUCI_HELPER=$(printf %s "$MYPROG" | grep -i "luci")
|
||||
|
||||
# Name Server Lookup Programs
|
||||
BIND_HOST=$(which host)
|
||||
KNOT_HOST=$(which khost)
|
||||
DRILL=$(which drill)
|
||||
HOSTIP=$(which hostip)
|
||||
NSLOOKUP=$(which nslookup)
|
||||
NSLOOKUP_MUSL=$($(which nslookup) localhost 2>&1 | grep -F "(null)") # not empty busybox compiled with musl
|
||||
|
||||
# Transfer Programs
|
||||
WGET=$(which wget)
|
||||
WGET_SSL=$(which wget-ssl)
|
||||
|
||||
CURL=$(which curl)
|
||||
# CURL_SSL not empty then SSL support available
|
||||
CURL_SSL=$($(which curl) -V 2>/dev/null | grep "Protocols:" | grep -F "https")
|
||||
# CURL_PROXY not empty then Proxy support available
|
||||
CURL_PROXY=$(find /lib /usr/lib -name libcurl.so* -exec grep -i "all_proxy" {} 2>/dev/null \;)
|
||||
|
||||
UCLIENT_FETCH=$(which uclient-fetch)
|
||||
# UCLIENT_FETCH_SSL not empty then SSL support available
|
||||
UCLIENT_FETCH_SSL=$(find /lib /usr/lib -name libustream-ssl.so* 2>/dev/null)
|
||||
|
||||
# Global configuration settings
|
||||
# allow NON-public IP's
|
||||
upd_privateip=$(uci -q get ddns.global.upd_privateip) || upd_privateip=0
|
||||
|
||||
# directory to store run information to.
|
||||
ddns_rundir=$(uci -q get ddns.global.ddns_rundir) || ddns_rundir="/var/run/ddns"
|
||||
[ -d $ddns_rundir ] || mkdir -p -m755 $ddns_rundir
|
||||
|
||||
# directory to store log files
|
||||
ddns_logdir=$(uci -q get ddns.global.ddns_logdir) || ddns_logdir="/var/log/ddns"
|
||||
[ -d $ddns_logdir ] || mkdir -p -m755 $ddns_logdir
|
||||
|
||||
# number of lines to before rotate logfile
|
||||
ddns_loglines=$(uci -q get ddns.global.ddns_loglines) || ddns_loglines=250
|
||||
ddns_loglines=$((ddns_loglines + 1)) # correct sed handling
|
||||
|
||||
# format to show date information in log and luci-app-ddns default ISO 8601 format
|
||||
ddns_dateformat=$(uci -q get ddns.global.ddns_dateformat) || ddns_dateformat="%F %R"
|
||||
DATE_PROG="date +'$ddns_dateformat'"
|
||||
|
||||
# USE_CURL if GNU Wget and cURL installed normally Wget is used by do_transfer()
|
||||
# to change this use global option use_curl '1'
|
||||
USE_CURL=$(uci -q get ddns.global.use_curl) || USE_CURL=0 # read config
|
||||
[ -x /usr/bin/curl ] || USE_CURL=0 # check for cURL
|
||||
[ -n "$CURL" ] || USE_CURL=0 # check for cURL
|
||||
|
||||
# loads all options for a given package and section
|
||||
# also, sets all_option_variables to a list of the variable names
|
||||
@@ -148,7 +168,7 @@ load_all_service_sections() {
|
||||
# starts updater script for all given sections or only for the one given
|
||||
# $1 = interface (Optional: when given only scripts are started
|
||||
# configured for that interface)
|
||||
# used by /etc/hotplug.d/iface/25-ddns on IFUP
|
||||
# used by /etc/hotplug.d/iface/95-ddns on IFUP
|
||||
# and by /etc/init.d/ddns start
|
||||
start_daemon_for_all_ddns_sections()
|
||||
{
|
||||
@@ -161,7 +181,11 @@ start_daemon_for_all_ddns_sections()
|
||||
for __SECTIONID in $__SECTIONS; do
|
||||
config_get __IFACE "$__SECTIONID" interface "wan"
|
||||
[ -z "$__EVENTIF" -o "$__IFACE" = "$__EVENTIF" ] || continue
|
||||
/usr/lib/ddns/dynamic_dns_updater.sh $__SECTIONID 0 >/dev/null 2>&1 &
|
||||
if [ $VERBOSE -eq 0 ]; then # start in background
|
||||
/usr/lib/ddns/dynamic_dns_updater.sh -v 0 -S "$__SECTIONID" -- start &
|
||||
else
|
||||
/usr/lib/ddns/dynamic_dns_updater.sh -v "$VERBOSE" -S "$__SECTIONID" -- start
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -169,7 +193,7 @@ start_daemon_for_all_ddns_sections()
|
||||
# $1 = section
|
||||
stop_section_processes() {
|
||||
local __PID=0
|
||||
local __PIDFILE="$RUNDIR/$1.pid"
|
||||
local __PIDFILE="$ddns_rundir/$1.pid"
|
||||
[ $# -ne 1 ] && write_log 12 "Error calling 'stop_section_processes()' - wrong number of parameters"
|
||||
|
||||
[ -e "$__PIDFILE" ] && {
|
||||
@@ -181,7 +205,7 @@ stop_section_processes() {
|
||||
|
||||
# stop updater script for all defines sections or only for one given
|
||||
# $1 = interface (optional)
|
||||
# used by /etc/hotplug.d/iface/25-ddns on 'ifdown'
|
||||
# used by /etc/hotplug.d/iface/95-ddns on 'ifdown'
|
||||
# and by /etc/init.d/ddns stop
|
||||
# needed because we also need to kill "sleep" child processes
|
||||
stop_daemon_for_all_ddns_sections() {
|
||||
@@ -234,14 +258,14 @@ write_log() {
|
||||
esac
|
||||
|
||||
# verbose echo
|
||||
[ $VERBOSE_MODE -gt 0 -o $__EXIT -gt 0 ] && echo -e "$__MSG"
|
||||
[ $VERBOSE -gt 0 -o $__EXIT -gt 0 ] && echo -e "$__MSG"
|
||||
# write to logfile
|
||||
if [ ${use_logfile:-1} -eq 1 -o $VERBOSE_MODE -gt 1 ]; then
|
||||
if [ ${use_logfile:-1} -eq 1 -o $VERBOSE -gt 1 ]; then
|
||||
echo -e "$__MSG" >> $LOGFILE
|
||||
# VERBOSE_MODE > 1 then NO loop so NO truncate log to $LOGLINES lines
|
||||
[ $VERBOSE_MODE -gt 1 ] || sed -i -e :a -e '$q;N;'$LOGLINES',$D;ba' $LOGFILE
|
||||
# VERBOSE > 1 then NO loop so NO truncate log to $ddns_loglines lines
|
||||
[ $VERBOSE -gt 1 ] || sed -i -e :a -e '$q;N;'$ddns_loglines',$D;ba' $LOGFILE
|
||||
fi
|
||||
[ $LUCI_HELPER ] && return # nothing else todo when running LuCI helper script
|
||||
[ -n "$LUCI_HELPER" ] && return # nothing else todo when running LuCI helper script
|
||||
[ $__LEVEL -eq 7 ] && return # no syslog for debug messages
|
||||
__CMD=$(echo -e "$__CMD" | tr -d '\n' | tr '\t' ' ') # remove \n \t chars
|
||||
[ $__EXIT -eq 1 ] && {
|
||||
@@ -250,6 +274,7 @@ write_log() {
|
||||
}
|
||||
[ $use_syslog -eq 0 ] && return
|
||||
[ $((use_syslog + __LEVEL)) -le 7 ] && $__CMD
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -295,44 +320,42 @@ urlencode() {
|
||||
}
|
||||
|
||||
# extract url or script for given DDNS Provider from
|
||||
# file /usr/lib/ddns/services for IPv4 or from
|
||||
# file /usr/lib/ddns/services_ipv6 for IPv6
|
||||
# file /etc/ddns/services for IPv4 or from
|
||||
# file /etc/ddns/services_ipv6 for IPv6
|
||||
# $1 Name of Variable to store url to
|
||||
# $2 Name of Variable to store script to
|
||||
# $3 Name of Variable to store service answer to
|
||||
get_service_data() {
|
||||
local __LINE __FILE __NAME __URL __SERVICES __DATA
|
||||
local __SCRIPT=""
|
||||
local __OLD_IFS=$IFS
|
||||
local __NEWLINE_IFS='
|
||||
' # __NEWLINE_IFS
|
||||
[ $# -ne 2 ] && write_log 12 "Error calling 'get_service_data()' - wrong number of parameters"
|
||||
[ $# -ne 3 ] && write_log 12 "Error calling 'get_service_data()' - wrong number of parameters"
|
||||
|
||||
__FILE="/usr/lib/ddns/services" # IPv4
|
||||
[ $use_ipv6 -ne 0 ] && __FILE="/usr/lib/ddns/services_ipv6" # IPv6
|
||||
__FILE="/etc/ddns/services" # IPv4
|
||||
[ $use_ipv6 -ne 0 ] && __FILE="/etc/ddns/services_ipv6" # IPv6
|
||||
|
||||
# remove any lines not containing data, and then make sure fields are enclosed in double quotes
|
||||
__SERVICES=$(cat $__FILE | grep "^[\t ]*[^#]" | \
|
||||
awk ' gsub("\x27", "\"") { if ($1~/^[^\"]*$/) $1="\""$1"\"" }; { if ( $NF~/^[^\"]*$/) $NF="\""$NF"\"" }; { print $0 }')
|
||||
# workaround with variables; pipe create subshell with no give back of variable content
|
||||
mkfifo pipe_$$
|
||||
# only grep without # or whitespace at linestart | remove "
|
||||
# grep -v -E "(^#|^[[:space:]]*$)" $__FILE | sed -e s/\"//g > pipe_$$ &
|
||||
sed '/^#/d; /^[ \t]*$/d; s/\"//g' $__FILE > pipe_$$ &
|
||||
|
||||
IFS=$__NEWLINE_IFS
|
||||
for __LINE in $__SERVICES; do
|
||||
# grep out proper parts of data and use echo to remove quotes
|
||||
__NAME=$(echo $__LINE | grep -o "^[\t ]*\"[^\"]*\"" | xargs -r -n1 echo)
|
||||
__DATA=$(echo $__LINE | grep -o "\"[^\"]*\"[\t ]*$" | xargs -r -n1 echo)
|
||||
while read __SERVICE __DATA __ANSWER; do
|
||||
if [ "$__SERVICE" = "$service_name" ]; then
|
||||
# check if URL or SCRIPT is given
|
||||
__URL=$(echo "$__DATA" | grep "^http")
|
||||
[ -z "$__URL" ] && __SCRIPT="/usr/lib/ddns/$__DATA"
|
||||
|
||||
if [ "$__NAME" = "$service_name" ]; then
|
||||
break # found so leave for loop
|
||||
eval "$1=\"$__URL\""
|
||||
eval "$2=\"$__SCRIPT\""
|
||||
eval "$3=\"$__ANSWER\""
|
||||
rm pipe_$$
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
IFS=$__OLD_IFS
|
||||
done < pipe_$$
|
||||
rm pipe_$$
|
||||
|
||||
# check if URL or SCRIPT is given
|
||||
__URL=$(echo "$__DATA" | grep "^http")
|
||||
[ -z "$__URL" ] && __SCRIPT="/usr/lib/ddns/$__DATA"
|
||||
|
||||
eval "$1=\"$__URL\""
|
||||
eval "$2=\"$__SCRIPT\""
|
||||
return 0
|
||||
eval "$1=\"\"" # no service match clear variables
|
||||
eval "$2=\"\""
|
||||
eval "$3=\"\""
|
||||
return 1
|
||||
}
|
||||
|
||||
# Calculate seconds from interval and unit
|
||||
@@ -451,6 +474,8 @@ timeout() {
|
||||
verify_host_port() {
|
||||
local __HOST=$1
|
||||
local __PORT=$2
|
||||
local __NC=$(which nc)
|
||||
local __NCEXT=$($(which nc) --help 2>&1 | grep "\-w" 2>/dev/null) # busybox nc compiled with extensions
|
||||
local __IP __IPV4 __IPV6 __RUNPROG __PROG __ERR
|
||||
# return codes
|
||||
# 1 system specific error
|
||||
@@ -465,12 +490,23 @@ verify_host_port() {
|
||||
__IPV6=$(echo $__HOST | grep -m 1 -o "$IPV6_REGEX")
|
||||
# if FQDN given get IP address
|
||||
[ -z "$__IPV4" -a -z "$__IPV6" ] && {
|
||||
if [ -x /usr/bin/host ]; then # use BIND host if installed
|
||||
if [ -n "$BIND_HOST" ]; then # use BIND host if installed
|
||||
__PROG="BIND host"
|
||||
__RUNPROG="/usr/bin/host -t ANY $__HOST >$DATFILE 2>$ERRFILE"
|
||||
__RUNPROG="$BIND_HOST $__HOST >$DATFILE 2>$ERRFILE"
|
||||
elif [ -n "$KNOT_HOST" ]; then # use Knot host if installed
|
||||
__PROG="Knot host"
|
||||
__RUNPROG="$KNOT_HOST $__HOST >$DATFILE 2>$ERRFILE"
|
||||
elif [ -n "$DRILL" ]; then # use drill if installed
|
||||
__PROG="drill"
|
||||
__RUNPROG="$DRILL -V0 $__HOST A >$DATFILE 2>$ERRFILE" # IPv4
|
||||
__RUNPROG="$__RUNPROG; $DRILL -V0 $__HOST AAAA >>$DATFILE 2>>$ERRFILE" # IPv6
|
||||
elif [ -n "$HOSTIP" ]; then # use hostip if installed
|
||||
__PROG="hostip"
|
||||
__RUNPROG="$HOSTIP $__HOST >$DATFILE 2>$ERRFILE" # IPv4
|
||||
__RUNPROG="$__RUNPROG; $HOSTIP -6 $__HOST >>$DATFILE 2>>$ERRFILE" # IPv6
|
||||
else # use BusyBox nslookup
|
||||
__PROG="BusyBox nslookup"
|
||||
__RUNPROG="/usr/bin/nslookup $__HOST >$DATFILE 2>$ERRFILE"
|
||||
__RUNPROG="$NSLOOKUP $__HOST >$DATFILE 2>$ERRFILE"
|
||||
fi
|
||||
write_log 7 "#> $__RUNPROG"
|
||||
eval $__RUNPROG
|
||||
@@ -482,9 +518,15 @@ verify_host_port() {
|
||||
return 2
|
||||
}
|
||||
# extract IP address
|
||||
if [ -x /usr/bin/host ]; then # use BIND host if installed
|
||||
if [ -n "$BIND_HOST" -o -n "$KNOT_HOST" ]; then # use BIND host or Knot host if installed
|
||||
__IPV4=$(cat $DATFILE | awk -F "address " '/has address/ {print $2; exit}' )
|
||||
__IPV6=$(cat $DATFILE | awk -F "address " '/has IPv6/ {print $2; exit}' )
|
||||
elif [ -n "$DRILL" ]; then # use drill if installed
|
||||
__IPV4=$(cat $DATFILE | awk '/^'"$lookup_host"'/ {print $5}' | grep -m 1 -o "$IPV4_REGEX")
|
||||
__IPV6=$(cat $DATFILE | awk '/^'"$lookup_host"'/ {print $5}' | grep -m 1 -o "$IPV6_REGEX")
|
||||
elif [ -n "$HOSTIP" ]; then # use hostip if installed
|
||||
__IPV4=$(cat $DATFILE | grep -m 1 -o "$IPV4_REGEX")
|
||||
__IPV6=$(cat $DATFILE | grep -m 1 -o "$IPV6_REGEX")
|
||||
else # use BusyBox nslookup
|
||||
__IPV4=$(cat $DATFILE | sed -ne "/^Name:/,\$ { s/^Address[0-9 ]\{0,\}: \($IPV4_REGEX\).*$/\\1/p }")
|
||||
__IPV6=$(cat $DATFILE | sed -ne "/^Name:/,\$ { s/^Address[0-9 ]\{0,\}: \($IPV6_REGEX\).*$/\\1/p }")
|
||||
@@ -497,17 +539,17 @@ verify_host_port() {
|
||||
[ $use_ipv6 -eq 0 -a -z "$__IPV4" ] && __ERR=4
|
||||
[ $use_ipv6 -eq 1 -a -z "$__IPV6" ] && __ERR=6
|
||||
[ $__ERR -gt 0 ] && {
|
||||
[ $LUCI_HELPER ] && return 4
|
||||
[ -n "$LUCI_HELPER" ] && return 4
|
||||
write_log 14 "Verify host Error '4' - Forced IP Version IPv$__ERR don't match"
|
||||
}
|
||||
fi
|
||||
|
||||
# verify nc command
|
||||
# busybox nc compiled without -l option "NO OPT l!" -> critical error
|
||||
/usr/bin/nc --help 2>&1 | grep -i "NO OPT l!" >/dev/null 2>&1 && \
|
||||
$__NC --help 2>&1 | grep -i "NO OPT l!" >/dev/null 2>&1 && \
|
||||
write_log 12 "Busybox nc (netcat) compiled without '-l' option, error 'NO OPT l!'"
|
||||
# busybox nc compiled with extensions
|
||||
/usr/bin/nc --help 2>&1 | grep "\-w" >/dev/null 2>&1 && __NCEXT="TRUE"
|
||||
$__NC --help 2>&1 | grep "\-w" >/dev/null 2>&1 && __NCEXT="TRUE"
|
||||
|
||||
# connectivity test
|
||||
# run busybox nc to HOST PORT
|
||||
@@ -518,7 +560,7 @@ verify_host_port() {
|
||||
[ $force_ipversion -ne 0 -a $use_ipv6 -ne 0 -o -z "$__IPV4" ] && __IP=$__IPV6 || __IP=$__IPV4
|
||||
|
||||
if [ -n "$__NCEXT" ]; then # BusyBox nc compiled with extensions (timeout support)
|
||||
__RUNPROG="/usr/bin/nc -w 1 $__IP $__PORT </dev/null >$DATFILE 2>$ERRFILE"
|
||||
__RUNPROG="$__NC -w 1 $__IP $__PORT </dev/null >$DATFILE 2>$ERRFILE"
|
||||
write_log 7 "#> $__RUNPROG"
|
||||
eval $__RUNPROG
|
||||
__ERR=$?
|
||||
@@ -527,7 +569,7 @@ verify_host_port() {
|
||||
write_log 7 "$(cat $ERRFILE)"
|
||||
return 3
|
||||
else # nc compiled without extensions (no timeout support)
|
||||
__RUNPROG="timeout 2 -- /usr/bin/nc $__IP $__PORT </dev/null >$DATFILE 2>$ERRFILE"
|
||||
__RUNPROG="timeout 2 -- $__NC $__IP $__PORT </dev/null >$DATFILE 2>$ERRFILE"
|
||||
write_log 7 "#> $__RUNPROG"
|
||||
eval $__RUNPROG
|
||||
__ERR=$?
|
||||
@@ -550,10 +592,10 @@ verify_dns() {
|
||||
# DNS uses port 53
|
||||
verify_host_port "$1" "53"
|
||||
__ERR=$?
|
||||
if [ $LUCI_HELPER ]; then # no retry if called by LuCI helper script
|
||||
if [ -n "$LUCI_HELPER" ]; then # no retry if called by LuCI helper script
|
||||
return $__ERR
|
||||
elif [ $__ERR -ne 0 -a $VERBOSE_MODE -gt 1 ]; then # VERBOSE_MODE > 1 then NO retry
|
||||
write_log 4 "Verify DNS server '$1' failed - Verbose Mode: $VERBOSE_MODE - NO retry on error"
|
||||
elif [ $__ERR -ne 0 -a $VERBOSE -gt 1 ]; then # VERBOSE > 1 then NO retry
|
||||
write_log 4 "Verify DNS server '$1' failed - Verbose Mode: $VERBOSE - NO retry on error"
|
||||
return $__ERR
|
||||
elif [ $__ERR -ne 0 ]; then
|
||||
__CNT=$(( $__CNT + 1 )) # increment error counter
|
||||
@@ -603,17 +645,17 @@ verify_proxy() {
|
||||
fi
|
||||
# No Port detected - EXITING
|
||||
[ -z "$__PORT" ] && {
|
||||
[ $LUCI_HELPER ] && return 5
|
||||
[ -n "$LUCI_HELPER" ] && return 5
|
||||
write_log 14 "Invalid Proxy server Error '5' - proxy port missing"
|
||||
}
|
||||
|
||||
while [ $__ERR -gt 0 ]; do
|
||||
verify_host_port "$__HOST" "$__PORT"
|
||||
__ERR=$?
|
||||
if [ $LUCI_HELPER ]; then # no retry if called by LuCI helper script
|
||||
if [ -n "$LUCI_HELPER" ]; then # no retry if called by LuCI helper script
|
||||
return $__ERR
|
||||
elif [ $__ERR -gt 0 -a $VERBOSE_MODE -gt 1 ]; then # VERBOSE_MODE > 1 then NO retry
|
||||
write_log 4 "Verify Proxy server '$1' failed - Verbose Mode: $VERBOSE_MODE - NO retry on error"
|
||||
elif [ $__ERR -gt 0 -a $VERBOSE -gt 1 ]; then # VERBOSE > 1 then NO retry
|
||||
write_log 4 "Verify Proxy server '$1' failed - Verbose Mode: $VERBOSE - NO retry on error"
|
||||
return $__ERR
|
||||
elif [ $__ERR -gt 0 ]; then
|
||||
__CNT=$(( $__CNT + 1 )) # increment error counter
|
||||
@@ -641,9 +683,8 @@ do_transfer() {
|
||||
[ $# -ne 1 ] && write_log 12 "Error in 'do_transfer()' - wrong number of parameters"
|
||||
|
||||
# lets prefer GNU Wget because it does all for us - IPv4/IPv6/HTTPS/PROXY/force IP version
|
||||
grep -i "\+ssl" /usr/bin/wget >/dev/null 2>&1 # check for Wget with SSL support
|
||||
if [ $? -eq 0 -a $USE_CURL -eq 0 ]; then # except global option use_curl is set to "1"
|
||||
__PROG="/usr/bin/wget -nv -t 1 -O $DATFILE -o $ERRFILE" # non_verbose no_retry outfile errfile
|
||||
if [ -n "$WGET_SSL" -a $USE_CURL -eq 0 ]; then # except global option use_curl is set to "1"
|
||||
__PROG="$WGET_SSL -nv -t 1 -O $DATFILE -o $ERRFILE" # non_verbose no_retry outfile errfile
|
||||
# force network/ip to use for communication
|
||||
if [ -n "$bind_network" ]; then
|
||||
local __BINDIP
|
||||
@@ -666,7 +707,7 @@ do_transfer() {
|
||||
__PROG="$__PROG --ca-certificate=${cacert}"
|
||||
elif [ -d "$cacert" ]; then
|
||||
__PROG="$__PROG --ca-directory=${cacert}"
|
||||
else # exit here because it makes no sense to start loop
|
||||
elif [ -n "$cacert" ]; then # it's not a file and not a directory but given
|
||||
write_log 14 "No valid certificate(s) found at '$cacert' for HTTPS communication"
|
||||
fi
|
||||
fi
|
||||
@@ -677,9 +718,12 @@ do_transfer() {
|
||||
__PROG="GNU Wget" # reuse for error logging
|
||||
|
||||
# 2nd choice is cURL IPv4/IPv6/HTTPS
|
||||
# libcurl might be compiled without Proxy Support (default in trunk)
|
||||
elif [ -x /usr/bin/curl ]; then
|
||||
__PROG="/usr/bin/curl -RsS -o $DATFILE --stderr $ERRFILE"
|
||||
# libcurl might be compiled without Proxy or HTTPS Support
|
||||
elif [ -n "$CURL" ]; then
|
||||
__PROG="$CURL -RsS -o $DATFILE --stderr $ERRFILE"
|
||||
# check HTTPS support
|
||||
[ -z "$CURL_SSL" -a $use_https -eq 1 ] && \
|
||||
write_log 13 "cURL: libcurl compiled without https support"
|
||||
# force network/interface-device to use for communication
|
||||
if [ -n "$bind_network" ]; then
|
||||
local __DEVICE
|
||||
@@ -700,7 +744,7 @@ do_transfer() {
|
||||
__PROG="$__PROG --cacert $cacert"
|
||||
elif [ -d "$cacert" ]; then
|
||||
__PROG="$__PROG --capath $cacert"
|
||||
else # exit here because it makes no sense to start loop
|
||||
elif [ -n "$cacert" ]; then # it's not a file and not a directory but given
|
||||
write_log 14 "No valid certificate(s) found at '$cacert' for HTTPS communication"
|
||||
fi
|
||||
fi
|
||||
@@ -708,19 +752,45 @@ do_transfer() {
|
||||
# or check if libcurl compiled with proxy support
|
||||
if [ -z "$proxy" ]; then
|
||||
__PROG="$__PROG --noproxy '*'"
|
||||
else
|
||||
elif [ -z "$CURL_PROXY" ]; then
|
||||
# if libcurl has no proxy support and proxy should be used then force ERROR
|
||||
# libcurl currently no proxy support by default
|
||||
grep -i "all_proxy" /usr/lib/libcurl.so* >/dev/null 2>&1 || \
|
||||
write_log 13 "cURL: libcurl compiled without Proxy support"
|
||||
write_log 13 "cURL: libcurl compiled without Proxy support"
|
||||
fi
|
||||
|
||||
__RUNPROG="$__PROG '$__URL'" # build final command
|
||||
__PROG="cURL" # reuse for error logging
|
||||
|
||||
# busybox Wget (did not support neither IPv6 nor HTTPS)
|
||||
elif [ -x /usr/bin/wget ]; then
|
||||
__PROG="/usr/bin/wget -q -O $DATFILE"
|
||||
# uclient-fetch possibly with ssl support if /lib/libustream-ssl.so installed
|
||||
elif [ -n "$UCLIENT_FETCH" ]; then
|
||||
__PROG="$UCLIENT_FETCH -q -O $DATFILE"
|
||||
# force network/ip not supported
|
||||
[ -n "$__BINDIP" ] && \
|
||||
write_log 14 "uclient-fetch: FORCE binding to specific address not supported"
|
||||
# force ip version to use
|
||||
if [ $force_ipversion -eq 1 ]; then
|
||||
[ $use_ipv6 -eq 0 ] && __PROG="$__PROG -4" || __PROG="$__PROG -6" # force IPv4/IPv6
|
||||
fi
|
||||
# https possibly not supported
|
||||
[ $use_https -eq 1 -a -z "$UCLIENT_FETCH_SSL" ] && \
|
||||
write_log 14 "uclient-fetch: no HTTPS support! Additional install one of ustream-ssl packages"
|
||||
# proxy support
|
||||
[ -z "$proxy" ] && __PROG="$__PROG -Y off" || __PROG="$__PROG -Y on"
|
||||
# https & certificates
|
||||
if [ $use_https -eq 1 ]; then
|
||||
if [ "$cacert" = "IGNORE" ]; then
|
||||
__PROG="$__PROG --no-check-certificate"
|
||||
elif [ -f "$cacert" ]; then
|
||||
__PROG="$__PROG --ca-certificate=$cacert"
|
||||
elif [ -n "$cacert" ]; then # it's not a file; nothing else supported
|
||||
write_log 14 "No valid certificate file '$cacert' for HTTPS communication"
|
||||
fi
|
||||
fi
|
||||
__RUNPROG="$__PROG '$__URL' 2>$ERRFILE" # build final command
|
||||
__PROG="uclient-fetch" # reuse for error logging
|
||||
|
||||
# Busybox Wget or any other wget in search $PATH (did not support neither IPv6 nor HTTPS)
|
||||
elif [ -n "$WGET" ]; then
|
||||
__PROG="$WGET -q -O $DATFILE"
|
||||
# force network/ip not supported
|
||||
[ -n "$__BINDIP" ] && \
|
||||
write_log 14 "BusyBox Wget: FORCE binding to specific address not supported"
|
||||
@@ -737,7 +807,7 @@ do_transfer() {
|
||||
__PROG="Busybox Wget" # reuse for error logging
|
||||
|
||||
else
|
||||
write_log 13 "Neither 'Wget' nor 'cURL' installed or executable"
|
||||
write_log 13 "Neither 'Wget' nor 'cURL' nor 'uclient-fetch' installed or executable"
|
||||
fi
|
||||
|
||||
while : ; do
|
||||
@@ -745,14 +815,14 @@ do_transfer() {
|
||||
eval $__RUNPROG # DO transfer
|
||||
__ERR=$? # save error code
|
||||
[ $__ERR -eq 0 ] && return 0 # no error leave
|
||||
[ $LUCI_HELPER ] && return 1 # no retry if called by LuCI helper script
|
||||
[ -n "$LUCI_HELPER" ] && return 1 # no retry if called by LuCI helper script
|
||||
|
||||
write_log 3 "$__PROG Error: '$__ERR'"
|
||||
write_log 7 "$(cat $ERRFILE)" # report error
|
||||
|
||||
[ $VERBOSE_MODE -gt 1 ] && {
|
||||
# VERBOSE_MODE > 1 then NO retry
|
||||
write_log 4 "Transfer failed - Verbose Mode: $VERBOSE_MODE - NO retry on error"
|
||||
[ $VERBOSE -gt 1 ] && {
|
||||
# VERBOSE > 1 then NO retry
|
||||
write_log 4 "Transfer failed - Verbose Mode: $VERBOSE - NO retry on error"
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -777,14 +847,18 @@ send_update() {
|
||||
|
||||
[ $# -ne 1 ] && write_log 12 "Error calling 'send_update()' - wrong number of parameters"
|
||||
|
||||
if [ $ALLOW_LOCAL_IP -eq 0 ]; then
|
||||
if [ $upd_privateip -eq 0 ]; then
|
||||
# verify given IP / no private IPv4's / no IPv6 addr starting with fxxx of with ":"
|
||||
[ $use_ipv6 -eq 0 ] && __IP=$(echo $1 | grep -v -E "(^0|^10\.|^100\.6[4-9]\.|^100\.[7-9][0-9]\.|^100\.1[0-1][0-9]\.|^100\.12[0-7]\.|^127|^169\.254|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-1]\.|^192\.168)")
|
||||
[ $use_ipv6 -eq 1 ] && __IP=$(echo $1 | grep "^[0-9a-eA-E]")
|
||||
[ -z "$__IP" ] && write_log 14 "Private or invalid or no IP '$1' given! Please check your configuration"
|
||||
else
|
||||
__IP="$1"
|
||||
__IP=$(echo $1 | grep -m 1 -o "$IPV4_REGEX") # valid IPv4 or
|
||||
[ -z "$__IP" ] && __IP=$(echo $1 | grep -m 1 -o "$IPV6_REGEX") # IPv6
|
||||
fi
|
||||
[ -z "$__IP" ] && {
|
||||
write_log 3 "No or private or invalid IP '$1' given! Please check your configuration"
|
||||
return 127
|
||||
}
|
||||
|
||||
if [ -n "$update_script" ]; then
|
||||
write_log 7 "parsing script '$update_script'"
|
||||
@@ -793,19 +867,19 @@ send_update() {
|
||||
local __URL __ERR
|
||||
|
||||
# do replaces in URL
|
||||
__URL=$(echo $update_url | sed -e "s#\[USERNAME\]#$URL_USER#g" -e "s#\[PASSWORD\]#$URL_PASS#g" \
|
||||
-e "s#\[DOMAIN\]#$domain#g" -e "s#\[IP\]#$__IP#g")
|
||||
__URL=$(echo $update_url | sed -e "s#\[USERNAME\]#$URL_USER#g" -e "s#\[PASSWORD\]#$URL_PASS#g" \
|
||||
-e "s#\[PARAMENC\]#$URL_PENC#g" -e "s#\[PARAMOPT\]#$param_opt#g" \
|
||||
-e "s#\[DOMAIN\]#$domain#g" -e "s#\[IP\]#$__IP#g")
|
||||
[ $use_https -ne 0 ] && __URL=$(echo $__URL | sed -e 's#^http:#https:#')
|
||||
|
||||
do_transfer "$__URL" || return 1
|
||||
|
||||
write_log 7 "DDNS Provider answered:\n$(cat $DATFILE)"
|
||||
|
||||
return 0
|
||||
# TODO analyze providers answer
|
||||
# "good" or "nochg" = dyndns.com compatible API
|
||||
# grep -i -E "good|nochg" $DATFILE >/dev/null 2>&1
|
||||
# return $? # "0" if found
|
||||
[ -z "$UPD_ANSWER" ] && return 0 # not set then ignore
|
||||
|
||||
grep -i -E "$UPD_ANSWER" $DATFILE >/dev/null 2>&1
|
||||
return $? # "0" if found
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -818,91 +892,123 @@ get_local_ip () {
|
||||
write_log 7 "Detect local IP on '$ip_source'"
|
||||
|
||||
while : ; do
|
||||
case $ip_source in
|
||||
network)
|
||||
# set correct program
|
||||
[ $use_ipv6 -eq 0 ] && __RUNPROG="network_get_ipaddr" \
|
||||
|| __RUNPROG="network_get_ipaddr6"
|
||||
eval "$__RUNPROG __DATA $ip_network" || \
|
||||
write_log 13 "Can not detect local IP using $__RUNPROG '$ip_network' - Error: '$?'"
|
||||
[ -n "$__DATA" ] && write_log 7 "Local IP '$__DATA' detected on network '$ip_network'"
|
||||
;;
|
||||
interface)
|
||||
if [ -n "$ip_network" ]; then
|
||||
# set correct program
|
||||
[ $use_ipv6 -eq 0 ] && __RUNPROG="network_get_ipaddr" \
|
||||
|| __RUNPROG="network_get_ipaddr6"
|
||||
eval "$__RUNPROG __DATA $ip_network" || \
|
||||
write_log 13 "Can not detect local IP using $__RUNPROG '$ip_network' - Error: '$?'"
|
||||
[ -n "$__DATA" ] && write_log 7 "Local IP '$__DATA' detected on network '$ip_network'"
|
||||
elif [ -n "$ip_interface" ]; then
|
||||
local __DATA4=""; local __DATA6=""
|
||||
if [ -n "$(which ip)" ]; then # ip program installed
|
||||
write_log 7 "#> ip -o addr show dev $ip_interface scope global >$DATFILE 2>$ERRFILE"
|
||||
ip -o addr show dev $ip_interface scope global >$DATFILE 2>$ERRFILE
|
||||
__ERR=$?
|
||||
if [ $__ERR -eq 0 ]; then
|
||||
# DATFILE (sample)
|
||||
# 5: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP qlen 1000\ link/ether 08:00:27:d0:10:32 brd ff:ff:ff:ff:ff:ff
|
||||
# 5: eth1 inet 172.27.10.128/24 brd 172.27.10.255 scope global eth1\ valid_lft forever preferred_lft forever
|
||||
# 5: eth1 inet 172.55.55.155/24 brd 172.27.10.255 scope global eth1\ valid_lft 12345sec preferred_lft 12345sec
|
||||
# 5: eth1 inet6 2002:b0c7:f326::806b:c629:b8b9:433/128 scope global dynamic \ valid_lft 8026sec preferred_lft 8026sec
|
||||
# 5: eth1 inet6 fd43:5368:6f6d:6500:806b:c629:b8b9:433/128 scope global dynamic \ valid_lft 8026sec preferred_lft 8026sec
|
||||
# 5: eth1 inet6 fd43:5368:6f6d:6500:a00:27ff:fed0:1032/64 scope global dynamic \ valid_lft 14352sec preferred_lft 14352sec
|
||||
# 5: eth1 inet6 2002:b0c7:f326::a00:27ff:fed0:1032/64 scope global dynamic \ valid_lft 14352sec preferred_lft 14352sec
|
||||
|
||||
# remove remove remove replace remove remove
|
||||
# BROADCAST inet6 fxxx sec forever=>-1 between / and pref.. linestart to inet
|
||||
sed -i "/BROADCAST/d; /inet6 f/d; s/sec//g; s/forever/-1/g; s/\/.*preferred_lft//g; s/^.*$ip_interface *//g" $DATFILE
|
||||
|
||||
local __TIME4=0; local __TIME6=0
|
||||
local __TYP __ADR __TIME
|
||||
while read __TYP __ADR __TIME; do
|
||||
__TIME=${__TIME:-0} # supress shell errors on last (empty) line of DATFILE
|
||||
# IPversion no "-1" record stored - now "-1" record or new time > oldtime
|
||||
[ "$__TYP" = "inet6" -a $__TIME6 -ge 0 -a \( $__TIME -lt 0 -o $__TIME -gt $__TIME6 \) ] && {
|
||||
__DATA6="$__ADR"
|
||||
__TIME6="$__TIME"
|
||||
}
|
||||
[ "$__TYP" = "inet" -a $__TIME4 -ge 0 -a \( $__TIME -lt 0 -o $__TIME -gt $__TIME4 \) ] && {
|
||||
__DATA4="$__ADR"
|
||||
__TIME4="$__TIME"
|
||||
}
|
||||
done < $DATFILE
|
||||
else
|
||||
write_log 3 "ip Error: '$__ERR'"
|
||||
write_log 7 "$(cat $ERRFILE)" # report error
|
||||
fi
|
||||
else # use deprecated ifconfig
|
||||
write_log 7 "#> ifconfig $ip_interface >$DATFILE 2>$ERRFILE"
|
||||
ifconfig $ip_interface >$DATFILE 2>$ERRFILE
|
||||
__ERR=$?
|
||||
if [ $__ERR -eq 0 ]; then
|
||||
if [ $use_ipv6 -eq 0 ]; then
|
||||
__DATA=$(awk '
|
||||
/inet addr:/ { # Filter IPv4
|
||||
# inet addr:192.168.1.1 Bcast:192.168.1.255 Mask:255.255.255.0
|
||||
$1=""; # remove inet
|
||||
$3=""; # remove Bcast: ...
|
||||
$4=""; # remove Mask: ...
|
||||
FS=":"; # separator ":"
|
||||
$0=$0; # reread to activate separator
|
||||
$1=""; # remove addr
|
||||
FS=" "; # set back separator to default " "
|
||||
$0=$0; # reread to activate separator (remove whitespaces)
|
||||
print $1; # print IPv4 addr
|
||||
}' $DATFILE
|
||||
)
|
||||
else
|
||||
__DATA=$(awk '
|
||||
/inet6/ && /: [0-9a-eA-E]/ && !/\/128/ { # Filter IPv6 exclude fxxx and /128 prefix
|
||||
# inet6 addr: 2001:db8::xxxx:xxxx/32 Scope:Global
|
||||
FS="/"; # separator "/"
|
||||
$0=$0; # reread to activate separator
|
||||
$2=""; # remove everything behind "/"
|
||||
FS=" "; # set back separator to default " "
|
||||
$0=$0; # reread to activate separator
|
||||
print $3; # print IPv6 addr
|
||||
}' $DATFILE
|
||||
)
|
||||
fi
|
||||
[ -n "$__DATA" ] && write_log 7 "Local IP '$__DATA' detected on interface '$ip_interface'"
|
||||
__DATA4=$(awk '
|
||||
/inet addr:/ { # Filter IPv4
|
||||
# inet addr:192.168.1.1 Bcast:192.168.1.255 Mask:255.255.255.0
|
||||
$1=""; # remove inet
|
||||
$3=""; # remove Bcast: ...
|
||||
$4=""; # remove Mask: ...
|
||||
FS=":"; # separator ":"
|
||||
$0=$0; # reread to activate separator
|
||||
$1=""; # remove addr
|
||||
FS=" "; # set back separator to default " "
|
||||
$0=$0; # reread to activate separator (remove whitespaces)
|
||||
print $1; # print IPv4 addr
|
||||
}' $DATFILE
|
||||
)
|
||||
__DATA6=$(awk '
|
||||
/inet6/ && /: [0-9a-eA-E]/ { # Filter IPv6 exclude fxxx
|
||||
# inet6 addr: 2001:db8::xxxx:xxxx/32 Scope:Global
|
||||
FS="/"; # separator "/"
|
||||
$0=$0; # reread to activate separator
|
||||
$2=""; # remove everything behind "/"
|
||||
FS=" "; # set back separator to default " "
|
||||
$0=$0; # reread to activate separator
|
||||
print $3; # print IPv6 addr
|
||||
}' $DATFILE
|
||||
)
|
||||
else
|
||||
write_log 3 "ifconfig Error: '$__ERR'"
|
||||
write_log 7 "$(cat $ERRFILE)" # report error
|
||||
fi
|
||||
;;
|
||||
script)
|
||||
write_log 7 "#> $ip_script >$DATFILE 2>$ERRFILE"
|
||||
eval $ip_script >$DATFILE 2>$ERRFILE
|
||||
__ERR=$?
|
||||
if [ $__ERR -eq 0 ]; then
|
||||
__DATA=$(cat $DATFILE)
|
||||
[ -n "$__DATA" ] && write_log 7 "Local IP '$__DATA' detected via script '$ip_script'"
|
||||
else
|
||||
write_log 3 "$ip_script Error: '$__ERR'"
|
||||
write_log 7 "$(cat $ERRFILE)" # report error
|
||||
fi
|
||||
;;
|
||||
web)
|
||||
do_transfer "$ip_url"
|
||||
# use correct regular expression
|
||||
[ $use_ipv6 -eq 0 ] \
|
||||
&& __DATA=$(grep -m 1 -o "$IPV4_REGEX" $DATFILE) \
|
||||
|| __DATA=$(grep -m 1 -o "$IPV6_REGEX" $DATFILE)
|
||||
[ -n "$__DATA" ] && write_log 7 "Local IP '$__DATA' detected on web at '$ip_url'"
|
||||
;;
|
||||
*)
|
||||
write_log 12 "Error in 'get_local_ip()' - unhandled ip_source '$ip_source'"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
[ $use_ipv6 -eq 0 ] && __DATA="$__DATA4" || __DATA="$__DATA6"
|
||||
[ -n "$__DATA" ] && write_log 7 "Local IP '$__DATA' detected on interface '$ip_interface'"
|
||||
elif [ -n "$ip_script" ]; then
|
||||
write_log 7 "#> $ip_script >$DATFILE 2>$ERRFILE"
|
||||
eval $ip_script >$DATFILE 2>$ERRFILE
|
||||
__ERR=$?
|
||||
if [ $__ERR -eq 0 ]; then
|
||||
__DATA=$(cat $DATFILE)
|
||||
[ -n "$__DATA" ] && write_log 7 "Local IP '$__DATA' detected via script '$ip_script'"
|
||||
else
|
||||
write_log 3 "$ip_script Error: '$__ERR'"
|
||||
write_log 7 "$(cat $ERRFILE)" # report error
|
||||
fi
|
||||
elif [ -n "$ip_url" ]; then
|
||||
do_transfer "$ip_url"
|
||||
# use correct regular expression
|
||||
[ $use_ipv6 -eq 0 ] \
|
||||
&& __DATA=$(grep -m 1 -o "$IPV4_REGEX" $DATFILE) \
|
||||
|| __DATA=$(grep -m 1 -o "$IPV6_REGEX" $DATFILE)
|
||||
[ -n "$__DATA" ] && write_log 7 "Local IP '$__DATA' detected on web at '$ip_url'"
|
||||
else
|
||||
write_log 12 "Error in 'get_local_ip()' - unhandled ip_source '$ip_source'"
|
||||
fi
|
||||
# valid data found return here
|
||||
[ -n "$__DATA" ] && {
|
||||
eval "$1=\"$__DATA\""
|
||||
return 0
|
||||
}
|
||||
|
||||
[ $LUCI_HELPER ] && return 1 # no retry if called by LuCI helper script
|
||||
[ -n "$LUCI_HELPER" ] && return 1 # no retry if called by LuCI helper script
|
||||
|
||||
write_log 7 "Data detected:\n$(cat $DATFILE)"
|
||||
write_log 7 "Data detected:"
|
||||
write_log 7 "$(cat $DATFILE)"
|
||||
|
||||
[ $VERBOSE_MODE -gt 1 ] && {
|
||||
# VERBOSE_MODE > 1 then NO retry
|
||||
write_log 4 "Get local IP via '$ip_source' failed - Verbose Mode: $VERBOSE_MODE - NO retry on error"
|
||||
[ $VERBOSE -gt 1 ] && {
|
||||
# VERBOSE > 1 then NO retry
|
||||
write_log 4 "Get local IP via '$ip_source' failed - Verbose Mode: $VERBOSE - NO retry on error"
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -925,31 +1031,83 @@ get_registered_ip() {
|
||||
# $2 (optional) if set, do not retry on error
|
||||
local __CNT=0 # error counter
|
||||
local __ERR=255
|
||||
local __REGEX __PROG __RUNPROG __DATA
|
||||
local __REGEX __PROG __RUNPROG __DATA __IP
|
||||
# return codes
|
||||
# 1 no IP detected
|
||||
|
||||
[ $# -lt 1 -o $# -gt 2 ] && write_log 12 "Error calling 'get_registered_ip()' - wrong number of parameters"
|
||||
[ $is_glue -eq 1 -a -z "$BIND_HOST" ] && write_log 14 "Lookup of glue records is only supported using BIND host"
|
||||
write_log 7 "Detect registered/public IP"
|
||||
|
||||
# set correct regular expression
|
||||
[ $use_ipv6 -eq 0 ] && __REGEX="$IPV4_REGEX" || __REGEX="$IPV6_REGEX"
|
||||
|
||||
if [ -x /usr/bin/host ]; then
|
||||
__PROG="/usr/bin/host"
|
||||
if [ -n "$BIND_HOST" ]; then
|
||||
__PROG="$BIND_HOST"
|
||||
[ $use_ipv6 -eq 0 ] && __PROG="$__PROG -t A" || __PROG="$__PROG -t AAAA"
|
||||
if [ $force_ipversion -eq 1 ]; then # force IP version
|
||||
[ $use_ipv6 -eq 0 ] && __PROG="$__PROG -4" || __PROG="$__PROG -6"
|
||||
fi
|
||||
[ $force_dnstcp -eq 1 ] && __PROG="$__PROG -T" # force TCP
|
||||
[ $is_glue -eq 1 ] && __PROG="$__PROG -v" # use verbose output to get additional section
|
||||
|
||||
__RUNPROG="$__PROG $lookup_host $dns_server >$DATFILE 2>$ERRFILE"
|
||||
__PROG="BIND host"
|
||||
elif [ -n "$KNOT_HOST" ]; then
|
||||
__PROG="$KNOT_HOST"
|
||||
[ $use_ipv6 -eq 0 ] && __PROG="$__PROG -t A" || __PROG="$__PROG -t AAAA"
|
||||
if [ $force_ipversion -eq 1 ]; then # force IP version
|
||||
[ $use_ipv6 -eq 0 ] && __PROG="$__PROG -4" || __PROG="$__PROG -6"
|
||||
fi
|
||||
[ $force_dnstcp -eq 1 ] && __PROG="$__PROG -T" # force TCP
|
||||
|
||||
__RUNPROG="$__PROG $domain $dns_server >$DATFILE 2>$ERRFILE"
|
||||
__PROG="BIND host"
|
||||
elif [ -x /usr/bin/nslookup ]; then # last use BusyBox nslookup
|
||||
[ $force_ipversion -ne 0 -o $force_dnstcp -ne 0 ] && \
|
||||
write_log 14 "Busybox nslookup - no support to 'force IP Version' or 'DNS over TCP'"
|
||||
__RUNPROG="$__PROG $lookup_host $dns_server >$DATFILE 2>$ERRFILE"
|
||||
__PROG="Knot host"
|
||||
elif [ -n "$DRILL" ]; then
|
||||
__PROG="$DRILL -V0" # drill options name @server type
|
||||
if [ $force_ipversion -eq 1 ]; then # force IP version
|
||||
[ $use_ipv6 -eq 0 ] && __PROG="$__PROG -4" || __PROG="$__PROG -6"
|
||||
fi
|
||||
[ $force_dnstcp -eq 1 ] && __PROG="$__PROG -t" || __PROG="$__PROG -u" # force TCP
|
||||
__PROG="$__PROG $lookup_host"
|
||||
[ -n "$dns_server" ] && __PROG="$__PROG @$dns_server"
|
||||
[ $use_ipv6 -eq 0 ] && __PROG="$__PROG A" || __PROG="$__PROG AAAA"
|
||||
|
||||
__RUNPROG="/usr/bin/nslookup $domain $dns_server >$DATFILE 2>$ERRFILE"
|
||||
__RUNPROG="$__PROG >$DATFILE 2>$ERRFILE"
|
||||
__PROG="drill"
|
||||
elif [ -n "$HOSTIP" ]; then # hostip package installed
|
||||
__PROG="$HOSTIP"
|
||||
[ $force_dnstcp -ne 0 ] && \
|
||||
write_log 14 "hostip - no support for 'DNS over TCP'"
|
||||
|
||||
# is IP given as dns_server ?
|
||||
__IP=$(echo $dns_server | grep -m 1 -o "$IPV4_REGEX")
|
||||
[ -z "$__IP" ] && __IP=$(echo $dns_server | grep -m 1 -o "$IPV6_REGEX")
|
||||
|
||||
# we got NO ip for dns_server, so build command
|
||||
[ -z "$__IP" -a -n "$dns_server" ] && {
|
||||
__IP="\`$HOSTIP"
|
||||
[ $use_ipv6 -eq 1 -a $force_ipversion -eq 1 ] && __IP="$__IP -6"
|
||||
__IP="$__IP $dns_server | grep -m 1 -o"
|
||||
[ $use_ipv6 -eq 1 -a $force_ipversion -eq 1 ] \
|
||||
&& __IP="$__IP '$IPV6_REGEX'" \
|
||||
|| __IP="$__IP '$IPV4_REGEX'"
|
||||
__IP="$__IP \`"
|
||||
}
|
||||
|
||||
[ $use_ipv6 -eq 1 ] && __PROG="$__PROG -6"
|
||||
[ -n "$dns_server" ] && __PROG="$__PROG -r $__IP"
|
||||
__RUNPROG="$__PROG $lookup_host >$DATFILE 2>$ERRFILE"
|
||||
__PROG="hostip"
|
||||
elif [ -n "$NSLOOKUP" ]; then # last use BusyBox nslookup
|
||||
[ $force_dnstcp -ne 0 ] && \
|
||||
write_log 14 "Busybox nslookup - no support for 'DNS over TCP'"
|
||||
[ -n "$NSLOOKUP_MUSL" -a -n "$dns_server" ] && \
|
||||
write_log 14 "Busybox compiled with musl - nslookup don't support the use of DNS Server"
|
||||
[ $force_ipversion -ne 0 ] && \
|
||||
write_log 5 "Busybox nslookup - no support to 'force IP Version' (ignored)"
|
||||
|
||||
__RUNPROG="$NSLOOKUP $lookup_host $dns_server >$DATFILE 2>$ERRFILE"
|
||||
__PROG="BusyBox nslookup"
|
||||
else # there must be an error
|
||||
write_log 12 "Error in 'get_registered_ip()' - no supported Name Server lookup software accessible"
|
||||
@@ -963,10 +1121,18 @@ get_registered_ip() {
|
||||
write_log 3 "$__PROG error: '$__ERR'"
|
||||
write_log 7 "$(cat $ERRFILE)"
|
||||
else
|
||||
if [ "$__PROG" = "BIND host" ]; then
|
||||
__DATA=$(cat $DATFILE | awk -F "address " '/has/ {print $2; exit}' )
|
||||
else
|
||||
__DATA=$(cat $DATFILE | sed -ne "/^Name:/,\$ { s/^Address[0-9 ]\{0,\}: \($__REGEX\).*$/\\1/p }" )
|
||||
if [ -n "$BIND_HOST" -o -n "$KNOT_HOST" ]; then
|
||||
if [ $is_glue -eq 1 ]; then
|
||||
__DATA=$(cat $DATFILE | grep "^$lookup_host" | grep -om1 "$__REGEX" )
|
||||
else
|
||||
__DATA=$(cat $DATFILE | awk -F "address " '/has/ {print $2; exit}' )
|
||||
fi
|
||||
elif [ -n "$DRILL" ]; then
|
||||
__DATA=$(cat $DATFILE | awk '/^'"$lookup_host"'/ {print $5; exit}' )
|
||||
elif [ -n "$HOSTIP" ]; then
|
||||
__DATA=$(cat $DATFILE | grep -om1 "$__REGEX")
|
||||
elif [ -n "$NSLOOKUP" ]; then
|
||||
__DATA=$(cat $DATFILE | sed -e '1,/Name:/d' | grep -om1 "$__REGEX" )
|
||||
fi
|
||||
[ -n "$__DATA" ] && {
|
||||
write_log 7 "Registered IP '$__DATA' detected"
|
||||
@@ -977,20 +1143,20 @@ get_registered_ip() {
|
||||
__ERR=127
|
||||
fi
|
||||
|
||||
[ $LUCI_HELPER ] && return $__ERR # no retry if called by LuCI helper script
|
||||
[ -n "$LUCI_HELPER" ] && return $__ERR # no retry if called by LuCI helper script
|
||||
[ -n "$2" ] && return $__ERR # $2 is given -> no retry
|
||||
[ $VERBOSE_MODE -gt 1 ] && {
|
||||
# VERBOSE_MODE > 1 then NO retry
|
||||
write_log 4 "Get registered/public IP for '$domain' failed - Verbose Mode: $VERBOSE_MODE - NO retry on error"
|
||||
[ $VERBOSE -gt 1 ] && {
|
||||
# VERBOSE > 1 then NO retry
|
||||
write_log 4 "Get registered/public IP for '$lookup_host' failed - Verbose Mode: $VERBOSE - NO retry on error"
|
||||
return $__ERR
|
||||
}
|
||||
|
||||
__CNT=$(( $__CNT + 1 )) # increment error counter
|
||||
# if error count > retry_count leave here
|
||||
[ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \
|
||||
write_log 14 "Get registered/public IP for '$domain' failed after $retry_count retries"
|
||||
write_log 14 "Get registered/public IP for '$lookup_host' failed after $retry_count retries"
|
||||
|
||||
write_log 4 "Get registered/public IP for '$domain' failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds"
|
||||
write_log 4 "Get registered/public IP for '$lookup_host' failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds"
|
||||
sleep $RETRY_SECONDS &
|
||||
PID_SLEEP=$!
|
||||
wait $PID_SLEEP # enable trap-handler
|
||||
@@ -1026,7 +1192,7 @@ trap_handler() {
|
||||
fi ;;
|
||||
1) write_log 6 "PID '$$' received 'SIGHUP' at $(eval $DATE_PROG)"
|
||||
# reload config via starting the script again
|
||||
eval "/usr/lib/ddns/dynamic_dns_updater.sh $SECTION_ID $VERBOSE_MODE &"
|
||||
/usr/lib/ddns/dynamic_dns_updater.sh -v "0" -S "$__SECTIONID" -- start || true
|
||||
exit 0 ;; # and leave this one
|
||||
2) write_log 5 "PID '$$' terminated by 'SIGINT' at $(eval $DATE_PROG)\n";;
|
||||
3) write_log 5 "PID '$$' terminated by 'SIGQUIT' at $(eval $DATE_PROG)\n";;
|
||||
@@ -1105,7 +1271,7 @@ split_FQDN() {
|
||||
|
||||
# the leftover parameters are the HOST/SUBDOMAIN
|
||||
while [ -n "$1" ]; do
|
||||
_HOST="$1 $HOST" # remember we need to invert
|
||||
_HOST="$1 $_HOST" # remember we need to invert
|
||||
shift
|
||||
done
|
||||
_HOST=$(echo $_HOST | tr " " ".") # insert DOT
|
||||
@@ -1122,3 +1288,68 @@ split_FQDN() {
|
||||
eval "$4=''" # clear HOST/SUBDOMAIN
|
||||
return 1
|
||||
}
|
||||
|
||||
expand_ipv6() {
|
||||
# Original written for bash by
|
||||
#.Author: Florian Streibelt <florian@f-streibelt.de>
|
||||
# Date: 08.04.2012
|
||||
# License: Public Domain, but please be fair and
|
||||
# attribute the original author(s) and provide
|
||||
# a link to the original source for corrections:
|
||||
#. https://github.com/mutax/IPv6-Address-checks
|
||||
|
||||
# $1 IPv6 to expand
|
||||
# $2 name of variable to store expanded IPv6
|
||||
[ $# -ne 2 ] && write_log 12 "Error calling 'expand_ipv6()' - wrong number of parameters"
|
||||
|
||||
INPUT="$(echo "$1" | tr 'A-F' 'a-f')"
|
||||
[ "$INPUT" = "::" ] && INPUT="::0" # special case ::
|
||||
|
||||
O=""
|
||||
|
||||
while [ "$O" != "$INPUT" ]; do
|
||||
O="$INPUT"
|
||||
|
||||
# fill all words with zeroes
|
||||
INPUT=$( echo "$INPUT" | sed -e 's|:\([0-9a-f]\{3\}\):|:0\1:|g' \
|
||||
-e 's|:\([0-9a-f]\{3\}\)$|:0\1|g' \
|
||||
-e 's|^\([0-9a-f]\{3\}\):|0\1:|g' \
|
||||
-e 's|:\([0-9a-f]\{2\}\):|:00\1:|g' \
|
||||
-e 's|:\([0-9a-f]\{2\}\)$|:00\1|g' \
|
||||
-e 's|^\([0-9a-f]\{2\}\):|00\1:|g' \
|
||||
-e 's|:\([0-9a-f]\):|:000\1:|g' \
|
||||
-e 's|:\([0-9a-f]\)$|:000\1|g' \
|
||||
-e 's|^\([0-9a-f]\):|000\1:|g' )
|
||||
|
||||
done
|
||||
|
||||
# now expand the ::
|
||||
ZEROES=""
|
||||
|
||||
echo "$INPUT" | grep -qs "::"
|
||||
if [ "$?" -eq 0 ]; then
|
||||
GRPS="$( echo "$INPUT" | sed 's|[0-9a-f]||g' | wc -m )"
|
||||
GRPS=$(( GRPS-1 )) # remove carriage return
|
||||
MISSING=$(( 8-GRPS ))
|
||||
while [ $MISSING -gt 0 ]; do
|
||||
ZEROES="$ZEROES:0000"
|
||||
MISSING=$(( MISSING-1 ))
|
||||
done
|
||||
|
||||
# be careful where to place the :
|
||||
INPUT=$( echo "$INPUT" | sed -e 's|\(.\)::\(.\)|\1'$ZEROES':\2|g' \
|
||||
-e 's|\(.\)::$|\1'$ZEROES':0000|g' \
|
||||
-e 's|^::\(.\)|'$ZEROES':0000:\1|g;s|^:||g' )
|
||||
fi
|
||||
|
||||
# an expanded address has 39 chars + CR
|
||||
if [ $(echo $INPUT | wc -m) != 40 ]; then
|
||||
write_log 4 "Error in 'expand_ipv6()' - invalid IPv6 found: '$1' expanded: '$INPUT'"
|
||||
eval "$2='invalid'"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# echo the fully expanded version of the address
|
||||
eval "$2=$INPUT"
|
||||
return 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user