Browse Source

ddns-scripts: Update to Version 2.0.1-1

Squashed commit of the following:

commit fc1d42f069
Author: Christian Schoenebeck <christian.schoenebeck@gmail.com>
Date:   Sun Sep 21 18:01:43 2014 +0200

    [ddns-scripts] Update to Version 2.0.1-1

commit 731f9b4df0
Author: Christian Schoenebeck <christian.schoenebeck@gmail.com>
Date:   Sun Sep 21 17:59:25 2014 +0200

    [ddns-scripts] Update to Version 2.0.1-1

    personal helper script to create hashes for CA-Certificates for Wget and cURL using https protocol without errors.

    Sorry GitHub web interface only supports single commits that will be summarized into one pull request.
    Signed-off-by: Christian Schoenebeck <christian.schoenebeck@gmail.com>

commit df8f6c9d5d
Author: Christian Schoenebeck <christian.schoenebeck@gmail.com>
Date:   Sun Sep 21 17:56:05 2014 +0200

    [ddns-scripts] Update to Version 2.0.1-1

    rewritten

    Sorry GitHub web interface only supports single commits that will be summarized into one pull request.
    Signed-off-by: Christian Schoenebeck <christian.schoenebeck@gmail.com>

commit 50cdf5acb9
Author: Christian Schoenebeck <christian.schoenebeck@gmail.com>
Date:   Sun Sep 21 17:54:40 2014 +0200

    [ddns-scripts] Update to Version 2.0.1-1

    rewritten

    Sorry GitHub web interface only supports single commits that will be summarized into one pull request.
    Signed-off-by: Christian Schoenebeck <christian.schoenebeck@gmail.com>

commit b1d650a345
Author: Christian Schoenebeck <christian.schoenebeck@gmail.com>
Date:   Sun Sep 21 17:52:52 2014 +0200

    [ddns-scripts] Update to Version 2.0.1-1

    not needed in this version

    Sorry GitHub web interface only supports single commits that will be summarized into one pull request.
    Signed-off-by: Christian Schoenebeck <christian.schoenebeck@gmail.com>

commit 9532114b03
Author: Christian Schoenebeck <christian.schoenebeck@gmail.com>
Date:   Sun Sep 21 17:51:39 2014 +0200

    [ddns-scripts] Update to Version 2.0.1-1

    same function as existing services file but used for IPv6

    Sorry GitHub web interface only supports single commits that will be summarized into one pull request.
    Signed-off-by: Christian Schoenebeck <christian.schoenebeck@gmail.com>

commit a636bc25c6
Author: Christian Schoenebeck <christian.schoenebeck@gmail.com>
Date:   Sun Sep 21 17:46:56 2014 +0200

    [ddns-scripts] Update to Version 2.0.1-1

    New file explaining availible parameters.

    Sorry GitHub web interface only supports single commits that will be summarized into one pull request.
    Signed-off-by: Christian Schoenebeck <christian.schoenebeck@gmail.com>

commit 52332354fc
Author: Christian Schoenebeck <christian.schoenebeck@gmail.com>
Date:   Sun Sep 21 17:44:45 2014 +0200

    [ddns-scripts] Update to Version 2.0.1-1

    Sorry GitHub web interface only supports single commits that will be summarized into one pull request.

    Signed-off-by: Christian Schoenebeck <christian.schoenebeck@gmail.com>
Steven Barth 10 years ago
parent
commit
07d3672d46

+ 61
- 13
net/ddns-scripts/Makefile View File

@@ -1,8 +1,8 @@
1 1
 include $(TOPDIR)/rules.mk
2 2
 
3 3
 PKG_NAME:=ddns-scripts
4
-PKG_VERSION:=1.0.0
5
-PKG_RELEASE:=23
4
+PKG_VERSION:=2.0.1
5
+PKG_RELEASE:=1
6 6
 PKG_LICENSE:=GPL-2.0
7 7
 
8 8
 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
@@ -10,17 +10,25 @@ PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
10 10
 include $(INCLUDE_DIR)/package.mk
11 11
 
12 12
 define Package/ddns-scripts
13
-	SECTION:=net
14
-	CATEGORY:=Network
15
-        SUBMENU:=IP Addresses and Names
16
-	TITLE:=Dynamic DNS Scripts
17
-	PKGARCH:=all
18
-	MAINTAINER:=Christian Schoenebeck <christian.schoenebeck@gmail.com>
13
+    SECTION:=net
14
+    CATEGORY:=Network
15
+    SUBMENU:=IP Addresses and Names
16
+    TITLE:=Dynamic DNS Scripts (with IPv6 support)
17
+    PKGARCH:=all
18
+    MAINTAINER:=Christian Schoenebeck <christian.schoenebeck@gmail.com>
19 19
 endef
20 20
 
21 21
 define Package/ddns-scripts/description
22
-	A highly configurable set of scripts for doing
23
-	dynamic dns updates
22
+	A highly configurable set of scripts for doing dynamic dns updates. 
23
+	NEW in this version:
24
+	- IPv6 support
25
+	- force communication to IPv4 or IPv6 only
26
+	- DNS server support
27
+	- using BIND host if installed
28
+	- DNS requests via TCP
29
+	- Proxy server support
30
+	- log file support
31
+	- support to run once
24 32
 endef
25 33
 
26 34
 define Build/Prepare
@@ -37,10 +45,50 @@ define Package/ddns-scripts/conffiles
37 45
 endef
38 46
 
39 47
 define Package/ddns-scripts/install
40
-	$(INSTALL_DIR) $(1)
41
-	$(CP) ./files/* $(1)/
48
+	$(INSTALL_DIR) $(1)/etc/config
49
+	$(INSTALL_CONF) ./files/etc/config/* $(1)/etc/config
50
+
51
+	$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
52
+	$(INSTALL_BIN) ./files/etc/hotplug.d/iface/* $(1)/etc/hotplug.d/iface
53
+
42 54
 	$(INSTALL_DIR) $(1)/etc/init.d
43
-	$(INSTALL_BIN) ./files/etc/init.d/ddns $(1)/etc/init.d/
55
+	$(INSTALL_BIN) ./files/etc/init.d/* $(1)/etc/init.d/
56
+
57
+	$(INSTALL_DIR) $(1)/usr/lib/ddns
58
+	$(INSTALL_DATA) ./files/usr/lib/ddns/service* $(1)/usr/lib/ddns
59
+	$(INSTALL_BIN)  ./files/usr/lib/ddns/*.sh $(1)/usr/lib/ddns
60
+endef
61
+
62
+define Package/ddns-scripts/postinst
63
+	#!/bin/sh
64
+	# if run within buildroot exit
65
+	[ -n "${IPKG_INSTROOT}" ] && exit 0
66
+
67
+	# add new section "ddns" "global" if not exists
68
+	uci -q get ddns.global > /dev/null || uci -q set ddns.global='ddns'
69
+	uci -q get ddns.global.date_format > /dev/null || uci -q set ddns.global.date_format='%F %R'
70
+	uci -q get ddns.global.log_lines > /dev/null || uci -q set ddns.global.log_lines='250'
71
+	uci -q commit ddns
72
+
73
+	# clear LuCI indexcache 
74
+	rm -f /tmp/luci-indexcache >/dev/null 2>&1
75
+
76
+	exit 0
77
+endef
78
+
79
+define Package/ddns-scripts/prerm
80
+	#!/bin/sh
81
+	# if run within buildroot exit
82
+	[ -n "${IPKG_INSTROOT}" ] && exit 0
83
+
84
+	# stop running scripts
85
+	/etc/init.d/ddns disable
86
+	/etc/init.d/ddns stop
87
+
88
+	# clear LuCI indexcache 
89
+	rm -f /tmp/luci-indexcache >/dev/null 2>&1
90
+
91
+	exit 0
44 92
 endef
45 93
 
46 94
 $(eval $(call BuildPackage,ddns-scripts))

+ 24
- 92
net/ddns-scripts/files/etc/config/ddns View File

@@ -1,97 +1,29 @@
1
-#################################################################
2
-# In order to enable dynamic dns you need at least one section,
3
-# and in that seciton the "enabled" option must be set to one
4
-# 
5
-# Each section represents an update to a different service
6 1
 #
7
-# You specify your domain name, your username and your password
8
-# with the optins "domain", "username" and "password" respectively
2
+# Please read ddns.sample
9 3
 #
10
-# Next you need to specify the name of the service you are 
11
-# connecting to "eg. dyndns.org".  The format of the update
12
-# urls for several different dynamic dns services is specified
13
-# in the /usr/lib/ddns/services file.  This list is hardly complete
14
-# as there are many, many different dynamic dns services.  If your
15
-# service is on the list you can merely specify it with the 
16
-# "service_name" option.  Otherwise you will need to determine
17
-# the format of the url to update with.  You can either add an
18
-# entry to the /usr/lib/ddns/services file or specify this with
19
-# the "update_url" option.
20
-#
21
-# We also need to specify the source of the ip address to associate with
22
-# your domain.  The "ip_source" option can be "network", "interface"
23
-# or "web", with "network" as the default.  
24
-#
25
-# If "ip_source" is "network" you specify a network section in your 
26
-# /etc/network config file (e.g. "wan", which is the default) with
27
-# the "ip_network" option.  If you specify "wan", you will update
28
-# with whatever the ip for your wan is.
29
-# 
30
-# If "ip_source" is "interface" you specify a hardware interface 
31
-# (e.g. "eth1") and whatever the current ip of this interface is
32
-# will be associated with the domain when an update is performed.
33
-#
34
-# If "ip_source" is "script" you specify a script to obtain ip address.
35
-# The "ip_script" option should contain path to your script.
36
-#
37
-# The last possibility is that "ip_source" is "web", which means
38
-# that in order to obtain our ip address we will connect to a 
39
-# website, and the first valid ip address listed on that page
40
-# will be assumed to be ours.  If you are behind another firewall
41
-# this is the best option since none of the local networks or 
42
-# interfaces will have the external ip.  The website to connect
43
-# to is specified by the "ip_url" option.  You may specify multiple
44
-# urls in the option, separated by whitespace.
45
-#
46
-# Finally we need to specify how often to check whether we need
47
-# to check whether the ip address has changed (and if so update
48
-# it) and how often we need to force an update ( many services
49
-# will expire your domain if you don't connect and do an update
50
-# every so often).  Use the "check_interval" to specify how
51
-# often to check whether an update is necessary, the "retry_interval"
52
-# to specify how often to retry in case the update has failed, and
53
-# the "force_interval" option to specify how often to force an
54
-# update.  Specify the units for these values with the "check_unit",
55
-# the "retry_init" and the "force_unit" options.  Units can be
56
-# "days", "hours", "minutes" or "seconds".  The default force_unit
57
-# is hours, the default retry_unit is seconds and the default
58
-# check_unit is seconds.  The default check_interval is 600 seconds,
59
-# or ten minutes.  The default retry_interval is 60 seconds, or one
60
-# minute. The default force_interval is 72 hours or 3 days.
61
-#
62
-#
63
-#########################################################
4
+config ddns "global"
5
+	option date_format "%F %R"
6
+#	option run_dir "/var/run/ddns"
7
+#	option log_dir "/var/log/ddns"
8
+	option log_lines "250"
64 9
 
65
-config service "myddns"
66
-	option enabled		"0"
67
-	option interface	"wan"
68
-	option use_syslog	"1"
69 10
 
11
+config service "myddns_ipv4"
70 12
 	option service_name	"dyndns.org"
71
-	option domain		"mypersonaldomain.dyndns.org"
72
-	option username		"myusername"
73
-	option password		"mypassword"	
74
-	option use_https	"0"
75
-
76
-	option force_interval	"72"
77
-	option force_unit	"hours"
78
-	option check_interval	"10"
79
-	option check_unit	"minutes"
80
-	option retry_interval	"60"
81
-	option retry_unit	"seconds"
82
-
83
-	#option ip_source	"network" 
84
-	#option ip_network	"wan"
85
-
86
-	#option ip_source	"interface"
87
-	#option ip_interface	"eth0.1"
88
-
89
-	#option ip_source	"script"
90
-	#option	ip_script	"path to your scrip"
91
-
92
-	option ip_source	"web"
93
-	option ip_url		"http://checkip.dyndns.com/"
94
-
95
-	#option update_url	"http://[USERNAME]:[PASSWORD]@members.dyndns.org/nic/update?hostname=[DOMAIN]&myip=[IP]"
96
-
97
-
13
+	option domain		"yourhost.dyndns.org"
14
+	option username		"your_username"
15
+	option password		"your_password"
16
+	option interface	"wan"
17
+	option ip_source	"network"
18
+	option ip_network	"wan"
19
+
20
+config service "myddns_ipv6"
21
+	option update_url	"http://[USERNAME]:[PASSWORD]@your.provider.net/nic/update?hostname=[DOMAIN]&myip=[IP]"
22
+	option domain		"yourhost.dyndns.org"
23
+	option username		"your_username"
24
+	option password		"your_password"
25
+	option use_ipv6		"1"
26
+	option interface	"wan6"
27
+	option ip_source	"network"
28
+	option ip_network	"wan6"
29
+	

+ 272
- 0
net/ddns-scripts/files/etc/config/ddns.sample View File

@@ -0,0 +1,272 @@
1
+#
2
+#
3
+# Here you find a description on every parameter supported
4
+# and used by ddns-scripts and corresponding LuCI application
5
+#
6
+# Inside your ddns configuration file (/etc/config/ddns)
7
+# you might not find some of below described options. 
8
+# This is because you don't need to define options
9
+# if using there defaults. The LuCI application will delete
10
+# options that configured to there default values.
11
+#
12
+# If you have a working ddns configuration from old ddns-scripts (Version 1.x)
13
+# everything will function the same with new scripts 
14
+# without any changes to the configuration.
15
+#
16
+# If you like to use this file for your configuration then
17
+# use a copy, because the used software to modify the 
18
+# configuration files will throw away all empty lines 
19
+# and those starting with # (comments).
20
+#
21
+
22
+#####################################################################
23
+# Global application settings
24
+#
25
+config ddns "global"
26
+
27
+	###########
28
+	# set date format to use for display date in logfiles
29
+	# and LuCI web application.
30
+	# For codes see man pages of date command.
31
+	# default: "%F %R" (ISO 8601 format)
32
+#	option date_format "%F %R"
33
+
34
+	###########
35
+	# set run directory to use for .pid and .update files
36
+	# there will be a separate file for every running service section
37
+	# default: "/var/run/ddns"
38
+#	option run_dir "/var/run/ddns"
39
+
40
+	###########
41
+	# set log directory to use for .log files
42
+	# there will be a separate file for every running service section
43
+	# default: "/var/log/ddns"
44
+#	option log_dir "/var/log/ddns"
45
+
46
+	###########
47
+	# set number of lines stored in .log file before auto truncated
48
+	# default: "250" lines
49
+#	option log_lines "250"
50
+
51
+
52
+#####################################################################
53
+# DDNS service settings
54
+#
55
+# for each service you want to serve you need a separate configuration
56
+# if you need IPv4 and IPv6 you need to setup 2 separate configurations
57
+# with different names. (i.e. "myddns_ipv4" and "myddns_ipv6")
58
+# do not use white-spaces or dashes "-" or "@" ":" "!" or 
59
+# other special characters inside name.
60
+config service "myddns"
61
+	
62
+	########### Basic settings ########################
63
+
64
+	###########
65
+	# enable/disable this service section
66
+	# default: "0"	disabled
67
+	option enabled "0"
68
+
69
+	###########
70
+	# detecting/sending IPv4 or IPv6 address to the DDNS provider
71
+	# set to "1" if you want to use IPv6
72
+	# default: "0"	use IPv4
73
+	option use_ipv6 "0"
74
+
75
+	###########
76
+	# defines the network as defined in /etc/config/network
77
+	# to be monitored for up/down events to start via hotplug 
78
+	default: "wan"	for IPv4
79
+	default: "wan6"	for IPv6
80
+	option interface "wan"
81
+
82
+	###########
83
+	# Next you need to specify the name of the service you are 
84
+	# connecting to "eg. dyndns.org".  The format of the update
85
+	# urls for several different dynamic dns services is specified
86
+	# in the "/usr/lib/ddns/services" file for IPv4 and in 
87
+	# "/usr/lib/ddns/service_ipv6" file. This list is hardly complete
88
+	# as there are many, many different dynamic dns services.
89
+	# If your service is on the list you can merely specify it with the 
90
+	# "service_name" option.  Otherwise you will need to determine
91
+	# the format of the url to update with.  You can either add an
92
+	# entry to the "/usr/lib/ddns/services" or "services_ipv6" file 
93
+	# or specify this with the "update_url" option.
94
+	# default: none
95
+	option service_name "dyndns.org"
96
+
97
+	# sample: 
98
+	# "http://[USERNAME]:[PASSWORD]@members.dyndns.org/nic/update?hostname=[DOMAIN]&myip=[IP]"
99
+#	option update_url   ""
100
+
101
+	###########
102
+	# You must specify your domain/host name, your username and your password
103
+	# as you get from you DDNS provider. Keep an eye on providers help pages.
104
+	#	
105
+	# Your DNS name / replace [DOMAIN] in update_url
106
+	# default: none
107
+	option domain ""
108
+
109
+	# Username of your DDNS service account / replace [USERNAME] in update_url
110
+	# default: none
111
+	option username ""
112
+
113
+	# Password of your DDNS service account / replace [PASSWORD] in update_url
114
+	# default: none
115
+	option password ""
116
+
117
+	###########
118
+	# use HTTPS for secure communication with you DDNS provider
119
+	# personally found some providers having problems when not sending 
120
+	# updates via HTTPS. Yyou must not specify "https://" in update_url. 
121
+	# It's modified by the scripts themselves
122
+	# Needs GNU Wget (with SSL support) or cURL to be installed.
123
+	# default: "0"	do not use HTTPS
124
+	option use_https "0"
125
+
126
+	# if using HTTPS (see above) the transfer program tries to verify 
127
+	# the providers server certificate. For verification there needs to be
128
+	# the counterpart on this machine. Specify the path or path/file where
129
+	# the transfer program can find them. (might need package CA-certificates)
130
+	# if you don't want to verify servers certificate (insecure) you should
131
+	# this parameter to "IGNORE" (in capital letters)
132
+	# default: "/etc/cacert"	path where CA-certificate package is installed
133
+	option cacert "/etc/cacert"
134
+
135
+	###########
136
+	# for logging and control if everything work fine you can get information inside
137
+	# system log . Critical Errors are always send to system log.
138
+	# You can define which information you like to log
139
+	# 1 == info, notice, warning, errors
140
+	# 2 == notice, warning, errors
141
+	# 3 == warning, errors
142
+	# 4 == errors
143
+	# default: "0" off
144
+	option use_syslog  "0"
145
+
146
+	###########
147
+	# for logging and control if everything work fine you can get information inside
148
+	# log file. You find the file per default in /var/log/ddns/[sectionname].log
149
+	# The path can be modified for all log files in ddns.global section (see above)
150
+	# default: "1" on
151
+	option use_logfile "1"
152
+
153
+	########### Advanced settings #####################
154
+
155
+	###########
156
+	# you need to specify how ddns-scripts should detect you current local ip.
157
+	# the ip_source could be set to "network", "web", "interface" or "script"
158
+	# the parameters below specifying the additional information needed for
159
+	# the corresponding ip_spource configuration
160
+	# default: "network"
161
+
162
+	# ip_source "network" additional uses option ip_network and detects the
163
+	# current local ip on network as defined in /etc/config/network
164
+	# default: "wan"  using IPv4
165
+	# default: "wan6" using IPv6
166
+	option ip_source  "network"
167
+	option ip_network "wan"
168
+
169
+	# ip_source "web" additional uses option ip_url and detects the current 
170
+	# local ip from special web sides that response with the ip address of
171
+	# calling host. If you are behind a firewall/NAT this is the best option
172
+	# since none of the local networks or interfaces will have the external ip.
173
+	# default: "http://checkip.dyndns.com"   using IPv4
174
+	# default: "http://checkipv6.dyndns.com" using IPv6
175
+#	option ip_source "web"
176
+#	option ip_url    "http://checkip.dyndns.com"
177
+
178
+	# ip_source "interface" additional uses option ip_interface
179
+	# ip_source "interface" uses one of the locally installed physical interfaces
180
+	# to detect independent from network they configured to.
181
+	# default: none
182
+#	option ip_source    "interface"
183
+#	option ip_interface "eth1"
184
+
185
+	# ip_source "script" additional uses option ip_script
186
+	# it's useful if you want to write your own script to detect the
187
+	# current local ip. put full path into ip_script option.
188
+	# The script must be executable.
189
+	# default: none
190
+#	option ip_source "script"
191
+#	option ip_script ""
192
+
193
+	###########
194
+	# force_ipversion option will set the "-4" respectively "-6" parameter 
195
+	# on command line of transfer and DNS lookup program. 
196
+	# So the whole communication uses the selected IP version between both ends.
197
+	# needs GNU Wget or cURL installed for transfer and
198
+	# BIND's host for DNS lookup.
199
+	# default: "0" disabled
200
+	option force_ipversion "0"
201
+
202
+	###########
203
+	# normally the current (in the internet) registered ip is detected using the
204
+	# local defined name lookup policies (i.e. /etc/resolve.conf etc.)
205
+	# Specify here a DNS server to use instead of the defaults.
206
+	# you can use hostname or ip address
207
+	# IPv6 address must be in squared brackets "[...]"
208
+	# i.e. "google-public-dns-a.google.com"
209
+	# default: none
210
+#	option dns_server "google-public-dns-a.google.com"
211
+
212
+	# By default every DNS call is made via UDP protocol
213
+	# Some internet provider offer modems that cache UDP DNS requests.
214
+	# They also redirect calls to external servers to local.
215
+	# To force the usage of TCP for DNS requests enable this option
216
+	# Needs BIND's host program be installed
217
+	# default: "0" disabled
218
+#	option force_dnstcp "0"
219
+
220
+	###########
221
+	# If a Proxy is need to access HTTP/HTTPS pages on the WEB
222
+	# it can be configured here also for sending updates to the
223
+	# DDNS provider. If you configured use_https='1' above, you
224
+	# need to setup your HTTPS proxy here, otherwise your 
225
+	# HTTP proxy. !!! You should not detect your current IP
226
+	# ip_source='web' (see above) because this request is also 
227
+	# send via the configured proxy !!!
228
+	# Syntax: [user:password@]proxy:port !port is required !
229
+	# default: none
230
+#	option proxy ''
231
+
232
+	########### Timer settings ########################
233
+
234
+	###########
235
+	# defines the time interval to check if local IP has changed
236
+	# After the first start and first update send, the system will
237
+	# wait this time before verify if update was successful send.
238
+	# !!! checks below 5 minutes make no sense because the Internet 
239
+	# needs about 5-10 minutes to sync an IP-change to all DNS servers !!!
240
+	# accepted unit entry’s: 'seconds' 'minutes' 'hours' 'days'
241
+	# minimum 5 minutes == 300 seconds
242
+	# default 10 minutes
243
+	option check_interval	'10'
244
+	option check_unit	'minutes'
245
+
246
+	###########
247
+	# force to send an update to service provider, if no change was detected.
248
+	# consult DDNS providers documentation if your DDNS entry might timeout.
249
+	# accepted unit entry’s: 'seconds' 'minutes' 'hours' 'days'
250
+	# minimum needs to be greater or equal check interval (see above)
251
+	# A special setting of '0' is allowed, which forces the script to run once.
252
+	# It sends an update, verify if update was accepted by DNS 
253
+	# (retry if not) and finish. Useful if you want to start by your own (i.e. cron) 
254
+	# default 3 days == 72 hours
255
+	option force_interval	'72'
256
+	option force_unit	'hours'
257
+
258
+	###########
259
+	# if error happen on detecting, sending or updating the
260
+	# script will retry the relevant action for retry_count times
261
+	# before stopping script execution.
262
+	# default: 5
263
+	option retry_count '5'
264
+
265
+	###########
266
+	# if error happen on detecting, sending or updating the
267
+	# script will retry the relevant action.
268
+	# here you define the time to wait before retry is started
269
+	# accepted unit entry’s: 'seconds' 'minutes' 'hours' 'days'
270
+	# default: 60 seconds
271
+	option retry_interval	'60'
272
+	option retry_unit	'seconds'

+ 34
- 0
net/ddns-scripts/files/usr/lib/ddns/create_cert_hashes.sh View File

@@ -0,0 +1,34 @@
1
+#!/bin/sh
2
+#
3
+#set -vx
4
+
5
+[ -d /etc/ssl/certs ] || {
6
+        echo "CA-Certificates not istalled - please install first"
7
+        exit 1
8
+}
9
+
10
+NUMCERT=$(find /etc/ssl/certs -name *.crt 2>/dev/null | wc -l)
11
+NUMLINK=$(find /etc/ssl/certs -type l 2>/dev/null | wc -l)
12
+
13
+[ $NUMLINK -gt 0 ] && {
14
+	echo "File-Links already exist. Exiting"
15
+	exit 0
16
+}
17
+
18
+[ -f /usr/bin/openssl ] && OPENSSL="EXIST"
19
+[ -z "$OPENSSL" ] && {
20
+	opkg update || exit 1
21
+	opkg install openssl-util 2>/dev/null
22
+}
23
+
24
+for CERTFILE in `ls -1 $(1)/etc/ssl/certs`; do \
25
+	HASH=`openssl x509 -hash -noout -in /etc/ssl/certs/$CERTFILE`
26
+	SUFFIX=0
27
+	while [ -h "/etc/ssl/certs/$HASH.$SUFFIX" ]; do
28
+		let "SUFFIX += 1"
29
+	done
30
+	ln -s "$CERTFILE" "/etc/ssl/certs/$HASH.$SUFFIX"
31
+	echo "link $HASH.$SUFFIX created for $CERTFILE"
32
+done
33
+
34
+[ -z "$OPENSSL" ] && opkg remove --force-remove --autoremove openssl-util 2>/dev/null

+ 665
- 94
net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_functions.sh View File

@@ -1,144 +1,715 @@
1
-# /usr/lib/dynamic_dns/dynamic_dns_functions.sh
1
+#!/bin/sh
2
+# /usr/lib/ddns/dynamic_dns_functions.sh
2 3
 #
3
-# Written by Eric Paul Bishop, Janary 2008
4
+# Original written by Eric Paul Bishop, January 2008
4 5
 # Distributed under the terms of the GNU General Public License (GPL) version 2.0
5
-#
6
-# This script is (loosely) based on the one posted by exobyte in the forums here:
6
+# (Loosely) based on the script on the one posted by exobyte in the forums here:
7 7
 # http://forum.openwrt.org/viewtopic.php?id=14040
8
-
9
-
8
+#
9
+# extended and partial rewritten by Christian Schoenebeck in August 2014 to support:
10
+# - IPv6 DDNS services
11
+# - setting DNS Server to retrieve current IP including TCP transport
12
+# - Proxy Server to send out updates or retrieving WEB based IP detection
13
+# - force_interval=0 to run once (usefull for cron jobs etc.)
14
+# - the usage of BIND's host instead of BusyBox's nslookup if installed (DNS via TCP)
15
+# - extended Verbose Mode and log file support for better error detection 
16
+#
17
+# function __timeout
18
+# copied from http://www.ict.griffith.edu.au/anthony/software/timeout.sh
19
+# @author Anthony Thyssen  6 April 2011
20
+#
21
+# variables in small chars are read from /etc/config/ddns
22
+# variables in big chars are defined inside these scripts as global vars
23
+# variables in big chars beginning with "__" are local defined inside functions only
24
+#set -vx  	#script debugger
10 25
 
11 26
 . /lib/functions.sh
12 27
 . /lib/functions/network.sh
13 28
 
29
+# GLOBAL VARIABLES #
30
+SECTION_ID=""		# hold config's section name
31
+VERBOSE_MODE=1		# default mode is log to console, but easily changed with parameter
32
+LUCI_HELPER=""		# set by dynamic_dns_lucihelper.sh, if filled supress all error logging
33
+
34
+PIDFILE=""		# pid file
35
+UPDFILE=""		# store UPTIME of last update
36
+
37
+# directory to store run information to. 
38
+RUNDIR=$(uci -q get ddns.global.run_dir) || RUNDIR="/var/run/ddns"
39
+# NEW # directory to store log files
40
+LOGDIR=$(uci -q get ddns.global.log_dir) || LOGDIR="/var/log/ddns"
41
+LOGFILE=""		# NEW # logfile can be enabled as new option
42
+# number of lines to before rotate logfile
43
+LOGLINES=$(uci -q get ddns.global.log_lines) || LOGLINES=250
44
+
45
+CHECK_SECONDS=0		# calculated seconds out of given
46
+FORCE_SECONDS=0		# interval and unit
47
+RETRY_SECONDS=0		# in configuration
48
+
49
+OLD_PID=0		# Holds the PID of already running process for the same config section
50
+
51
+LAST_TIME=0		# holds the uptime of last successful update
52
+CURR_TIME=0		# holds the current uptime
53
+NEXT_TIME=0		# calculated time for next FORCED update
54
+EPOCH_TIME=0		# seconds since 1.1.1970 00:00:00
55
+
56
+REGISTERED_IP=""	# holds the IP read from DNS
57
+LOCAL_IP=""		# holds the local IP read from the box
58
+
59
+ERR_LAST=0		# used to save $? return code of program and function calls
60
+ERR_LOCAL_IP=0		# error counter on getting local ip
61
+ERR_REG_IP=0		# error counter on getting DNS registered ip
62
+ERR_SEND=0		# error counter on sending update to DNS provider
63
+ERR_UPDATE=0		# error counter on different local and registered ip
64
+
65
+# format to show date information in log and luci-app-ddns default ISO 8601 format
66
+DATE_FORMAT=$(uci -q get ddns.global.date_format) || DATE_FORMAT="%F %R"
67
+DATE_PROG="date +'$DATE_FORMAT'"
68
+
69
+# regular expression to detect IPv4 / IPv6
70
+# IPv4       0-9   1-3x "." 0-9  1-3x "." 0-9  1-3x "." 0-9  1-3x
71
+IPV4_REGEX="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
72
+# IPv6       ( ( 0-9a-f  1-4char ":") min 1x) ( ( 0-9a-f  1-4char   )optional) ( (":" 0-9a-f 1-4char  ) min 1x)
73
+IPV6_REGEX="\(\([0-9A-Fa-f]\{1,4\}:\)\{1,\}\)\(\([0-9A-Fa-f]\{1,4\}\)\{0,1\}\)\(\(:[0-9A-Fa-f]\{1,4\}\)\{1,\}\)"
14 74
 
15
-#loads all options for a given package and section
16
-#also, sets all_option_variables to a list of the variable names
75
+# loads all options for a given package and section
76
+# also, sets all_option_variables to a list of the variable names
77
+# $1 = ddns, $2 = SECTION_ID
17 78
 load_all_config_options()
18 79
 {
19
-	pkg_name="$1"
20
-	section_id="$2"
21
-
22
-	ALL_OPTION_VARIABLES=""
23
-	# this callback loads all the variables
24
-	# in the section_id section when we do
25
-	# config_load. We need to redefine
26
-	# the option_cb for different sections
27
-	# so that the active one isn't still active
28
-	# after we're done with it.  For reference
29
-	# the $1 variable is the name of the option
30
-	# and $2 is the name of the section
80
+	local __PKGNAME="$1"
81
+	local __SECTIONID="$2"
82
+	local __VAR
83
+	local __ALL_OPTION_VARIABLES=""
84
+
85
+	# this callback loads all the variables in the __SECTIONID section when we do
86
+	# config_load. We need to redefine the option_cb for different sections
87
+	# so that the active one isn't still active after we're done with it.  For reference
88
+	# the $1 variable is the name of the option and $2 is the name of the section
31 89
 	config_cb()
32 90
 	{
33
-		if [ ."$2" = ."$section_id" ]; then
91
+		if [ ."$2" = ."$__SECTIONID" ]; then
34 92
 			option_cb()
35 93
 			{
36
-				ALL_OPTION_VARIABLES="$ALL_OPTION_VARIABLES $1"
94
+				__ALL_OPTION_VARIABLES="$__ALL_OPTION_VARIABLES $1"
37 95
 			}
38 96
 		else
39 97
 			option_cb() { return 0; }
40 98
 		fi
41 99
 	}
42 100
 
101
+	config_load "$__PKGNAME"
102
+	
103
+	# Given SECTION_ID not found so no data, so return 1
104
+	[ -z "$__ALL_OPTION_VARIABLES" ] && return 1
43 105
 
44
-	config_load "$pkg_name"
45
-	for var in $ALL_OPTION_VARIABLES
106
+	for __VAR in $__ALL_OPTION_VARIABLES
46 107
 	do
47
-		config_get "$var" "$section_id" "$var"
108
+		config_get "$__VAR" "$__SECTIONID" "$__VAR"
48 109
 	done
110
+	return 0
49 111
 }
50 112
 
51
-
52
-get_current_ip()
113
+# starts updater script for all given sections or only for the one given
114
+# $1 = interface (Optional: when given only scripts are started
115
+# configured for that interface)
116
+start_daemon_for_all_ddns_sections()
53 117
 {
118
+	local __EVENTIF="$1"
119
+	local __SECTIONS=""
120
+	local __SECTIONID=""
121
+	local __IFACE=""
122
+
123
+	config_cb() 
124
+	{
125
+		# only look for section type "service", ignore everything else
126
+		[ "$1" == "service" ] && __SECTIONS="$__SECTIONS $2"
127
+	}
128
+	config_load "ddns"
54 129
 
55
-	#if ip source is not defined, assume we want to get ip from wan 
56
-	if [ "$ip_source" != "interface" ] && [ "$ip_source" != "web" ] && [ "$ip_source" != "script" ]
57
-	then
58
-		ip_source="network"
130
+	for __SECTIONID in $__SECTIONS
131
+	do
132
+		config_get __IFACE "$__SECTIONID" interface "wan"
133
+		[ -z "$__EVENTIF" -o "$__IFACE" = "$__EVENTIF" ] || continue
134
+		/usr/lib/ddns/dynamic_dns_updater.sh $__SECTIONID 0 > /dev/null 2>&1 &
135
+	done
136
+}
137
+
138
+verbose_echo()
139
+{
140
+	[ -n "$LUCI_HELPER" ] && return	# nothing to report when used by LuCI helper script
141
+	[ $VERBOSE_MODE -gt 0 ] && echo -e " $*"
142
+	if [ ${use_logfile:-0} -eq 1 -o $VERBOSE_MODE -gt 1 ]; then
143
+		[ -d $LOGDIR ] || mkdir -p -m 755 $LOGDIR
144
+		echo -e " $*" >> $LOGFILE
145
+		# VERBOSE_MODE > 1 then NO loop so NO truncate log to $LOGLINES lines
146
+		[ $VERBOSE_MODE -gt 1 ] || sed -i -e :a -e '$q;N;'$LOGLINES',$D;ba' $LOGFILE
59 147
 	fi
148
+	return
149
+}
60 150
 
61
-	if [ "$ip_source" = "network" ]
62
-	then
63
-		if [ -z "$ip_network" ]
64
-		then
65
-			ip_network="wan"
151
+syslog_info(){
152
+	[ $use_syslog -eq 1 ] && logger -p user.info -t ddns-scripts[$$] "$SECTION_ID: $*"
153
+	return
154
+}
155
+syslog_notice(){
156
+	[ $use_syslog -ge 1 -a $use_syslog -le 2 ] && logger -p user.notice -t ddns-scripts[$$] "$SECTION_ID: $*"
157
+	return
158
+}
159
+syslog_warn(){
160
+	[ $use_syslog -ge 1 -a $use_syslog -le 3 ] && logger -p user.warn -t ddns-scripts[$$] "$SECTION_ID: $*"
161
+	return
162
+}
163
+syslog_err(){
164
+	[ $use_syslog -ge 1 ] && logger -p user.err -t ddns-scripts[$$] "$SECTION_ID: $*"
165
+	return
166
+}
167
+
168
+critical_error() {
169
+	[ -n "$LUCI_HELPER" ] && return	# nothing to report when used by LuCI helper script
170
+	verbose_echo "\n CRITICAL ERROR =: $* - EXITING\n"
171
+	[ $VERBOSE_MODE -eq 0 ] && echo -e "\n$SECTION_ID: CRITICAL ERROR - $* - EXITING\n"
172
+	logger -t ddns-scripts[$$] -p user.crit "$SECTION_ID: CRITICAL ERROR - $* - EXITING"
173
+	exit 1		# critical error -> leave here
174
+}
175
+
176
+# extract update_url for given DDNS Provider from
177
+# file /usr/lib/ddns/services for IPv4 or from
178
+# file /usr/lib/ddns/services_ipv6 for IPv6
179
+get_service_url() {
180
+	# $1	Name of Variable to store url to
181
+	local __LINE __FILE __NAME __URL __SERVICES
182
+	local __OLD_IFS=$IFS
183
+	local __NEWLINE_IFS='
184
+' #__NEWLINE_IFS
185
+
186
+	__FILE="/usr/lib/ddns/services"					# IPv4
187
+	[ $use_ipv6 -ne 0 ] && __FILE="/usr/lib/ddns/services_ipv6"	# IPv6
188
+
189
+	#remove any lines not containing data, and then make sure fields are enclosed in double quotes
190
+	__SERVICES=$(cat $__FILE | grep "^[\t ]*[^#]" | \
191
+		awk ' gsub("\x27", "\"") { if ($1~/^[^\"]*$/) $1="\""$1"\"" }; { if ( $NF~/^[^\"]*$/) $NF="\""$NF"\""  }; { print $0 }')
192
+
193
+	IFS=$__NEWLINE_IFS
194
+	for __LINE in $__SERVICES
195
+	do
196
+		#grep out proper parts of data and use echo to remove quotes
197
+		__NAME=$(echo $__LINE | grep -o "^[\t ]*\"[^\"]*\"" | xargs -r -n1 echo)
198
+		__URL=$(echo $__LINE | grep -o "\"[^\"]*\"[\t ]*$" | xargs -r -n1 echo)
199
+
200
+		if [ "$__NAME" = "$service_name" ]; then
201
+			break			# found so leave for loop
66 202
 		fi
203
+	done
204
+	IFS=$__OLD_IFS
205
+	
206
+	eval "$1='$__URL'"
207
+	return 0
208
+}
209
+
210
+get_seconds() {
211
+	# $1	Name of Variable to store result in
212
+	# $2	Number and
213
+	# $3	Unit of time interval
214
+	case "$3" in
215
+		"days" )	eval "$1=$(( $2 * 86400 ))";;
216
+		"hours" )	eval "$1=$(( $2 * 3600 ))";;
217
+		"minutes" )	eval "$1=$(( $2 * 60 ))";;
218
+		* )		eval "$1=$2";;
219
+	esac
220
+	return 0
221
+}
222
+
223
+__timeout() {
224
+	# copied from http://www.ict.griffith.edu.au/anthony/software/timeout.sh
225
+	# only did the folloing changes
226
+	#	- commented out "#!/bin/bash" and usage section
227
+	#	- replace exit by return for usage as function
228
+	#	- some reformating
229
+	#
230
+	# timeout [-SIG] time [--] command args...
231
+	#
232
+	# Run the given command until completion, but kill it if it runs too long.
233
+	# Specifically designed to exit immediatally (no sleep interval) and clean up
234
+	# nicely without messages or leaving any extra processes when finished.
235
+	#
236
+	# Example use
237
+	#    timeout 5 countdown
238
+	#
239
+	###
240
+	#
241
+	# Based on notes in my "Shell Script Hints", section "Command Timeout"
242
+	#   http://www.ict.griffith.edu.au/~anthony/info/shell/script.hints
243
+	#
244
+	# This script uses a lot of tricks to terminate both the background command,
245
+	# the timeout script, and even the sleep process.  It also includes trap
246
+	# commands to prevent sub-shells reporting expected "Termination Errors".
247
+	#
248
+	# It took years of occasional trials, errors and testing to get a pure bash
249
+	# timeout command working as well as this does.
250
+	#
251
+	###
252
+	#
253
+	# Anthony Thyssen     6 April 2011
254
+	#
255
+#	PROGNAME=$(type $0 | awk '{print $3}')	# search for executable on path
256
+#	PROGDIR=$(dirname $PROGNAME)		# extract directory of program
257
+#	PROGNAME=$(basename $PROGNAME)		# base name of program
258
+
259
+	# output the script comments as docs
260
+#	Usage() {
261
+#		echo >&2 "$PROGNAME:" "$@"
262
+#		sed >&2 -n '/^###/q; /^#/!q; s/^#//; s/^ //; 3s/^/Usage: /; 2,$ p' "$PROGDIR/$PROGNAME"
263
+#		exit 10;
264
+#	}
265
+
266
+	SIG=-TERM
267
+
268
+	while [  $# -gt 0 ]; do
269
+		case "$1" in
270
+			--)
271
+				# forced end of user options
272
+				shift;
273
+				break ;;
274
+#			-\?|--help|--doc*)
275
+#				Usage ;;
276
+			[0-9]*)
277
+				TIMEOUT="$1" ;;
278
+			-*)
279
+				SIG="$1" ;;
280
+			*)
281
+				# unforced  end of user options
282
+				break ;;
283
+		esac
284
+		shift	# next option
285
+	done
286
+
287
+	# run main command in backgrouds and get its pid
288
+	"$@" &
289
+	command_pid=$!
290
+
291
+	# timeout sub-process abort countdown after ABORT seconds! also backgrounded
292
+	sleep_pid=0
293
+	(
294
+		# cleanup sleep process
295
+		trap 'kill -TERM $sleep_pid; return 1' 1 2 3 15
296
+		# sleep timeout period in background
297
+		sleep $TIMEOUT &
298
+		sleep_pid=$!
299
+		wait $sleep_pid
300
+		# Abort the command
301
+		kill $SIG $command_pid >/dev/null 2>&1
302
+		return 1
303
+	) &
304
+	timeout_pid=$!
305
+
306
+	# Wait for main command to finished or be timed out
307
+	wait $command_pid
308
+	status=$?
309
+
310
+	# Clean up timeout sub-shell - if it is still running!
311
+	kill $timeout_pid 2>/dev/null
312
+	wait $timeout_pid 2>/dev/null
313
+
314
+	# Uncomment to check if a LONG sleep still running (no sleep should be)
315
+	# sleep 1
316
+	# echo "-----------"
317
+	# /bin/ps j  # uncomment to show if abort "sleep" is still sleeping
318
+
319
+	return $status
320
+}
321
+
322
+__verify_host_port() {
323
+	# $1	Host/IP to verify
324
+	# $2	Port to verify
325
+	local __HOST=$1
326
+	local __PORT=$2
327
+	local __TMP __IP __IPV4 __IPV6 __RUNPROG __ERRPROG __ERR
328
+	# return codes
329
+	# 1	system specific error
330
+	# 2	nslookup error
331
+	# 3	nc (netcat) error
332
+	# 4	unmatched IP version
333
+
334
+	__RUNPROG="nslookup $__HOST 2>/dev/null"
335
+	__ERRPROG="nslookup $__HOST 2>&1"
336
+	verbose_echo " resolver prog =: '$__RUNPROG'"
337
+	__TMP=$(eval $__RUNPROG)	# test if nslookup runs without errors
338
+	__ERR=$?
339
+	# command error
340
+	[ $__ERR -gt 0 ] && {
341
+		verbose_echo "\n!!!!!!!!! ERROR =: BusyBox nslookup Error '$__ERR'\n$(eval $__ERRPROG)\n"
342
+		syslog_err "DNS Resolver Error - BusyBox nslookup Error: '$__ERR'"
343
+		return 2
344
+	} || {
345
+		# we need to run twice because multi-line output needs to be directly piped to grep because
346
+		# pipe returns return code of last prog in pipe but we need errors from nslookup command
347
+		__IPV4=$(eval $__RUNPROG | sed '1,2d' | grep -o "Name:\|Address.*" | grep -m 1 -o "$IPV4_REGEX")
348
+		__IPV6=$(eval $__RUNPROG | sed '1,2d' | grep -o "Name:\|Address.*" | grep -m 1 -o "$IPV6_REGEX")
349
+	}
350
+
351
+	# check IP version if forced
352
+	if [ $force_ipversion -ne 0 ]; then
353
+		[ $use_ipv6 -eq 0 -a -z "$__IPV4" ] && return 4
354
+		[ $use_ipv6 -eq 1 -a -z "$__IPV6" ] && return 4
67 355
 	fi
68 356
 
69
-	current_ip='';
70
-	if [ "$ip_source" = "network" ]
71
-	then
72
-		network_get_ipaddr current_ip "$ip_network" || return
73
-	elif [ "$ip_source" = "interface" ]
74
-	then
75
-		current_ip=$(ifconfig $ip_interface | grep -o 'inet addr:[0-9.]*' | grep -o "$ip_regex")
76
-	elif [ "$ip_source" = "script" ]
77
-	then
78
-		# get ip from script
79
-		current_ip=$($ip_script)
80
-	else
81
-		# get ip from web
82
-		# we check each url in order in ip_url variable, and if no ips are found we use dyndns ip checker
83
-		# ip is set to FIRST expression in page that matches the ip_regex regular expression
84
-		for addr in $ip_url
85
-		do
86
-			if [ -z "$current_ip" ]
87
-			then
88
-				current_ip=$(echo $( wget -O - $addr 2>/dev/null) | grep -o "$ip_regex")
89
-			fi
90
-		done
357
+	# verify nc command
358
+	# busybox nc compiled without -l option "NO OPT l!" -> critical error
359
+	nc --help 2>&1 | grep -iq "NO OPT l!" && \
360
+		critical_error "Busybox nc: netcat compiled with errors"
361
+	# busybox nc compiled with extensions
362
+	nc --help 2>&1 | grep -q "\-w" && __NCEXT="TRUE"
91 363
 
92
-		#here we hard-code the dyndns checkip url in case no url was specified
93
-		if [ -z "$current_ip" ]
94
-		then
95
-			current_ip=$(echo $( wget -O - http://checkip.dyndns.org 2>/dev/null) | grep -o "$ip_regex")
96
-		fi
364
+	# connectivity test
365
+	# run busybox nc to HOST PORT
366
+	# busybox might be compiled with "FEATURE_PREFER_IPV4_ADDRESS=n"
367
+	# then nc will try to connect via IPv6 if there is an IPv6 availible for host
368
+	# not worring if there is an IPv6 wan address
369
+	# so if not "forced_ipversion" to use ipv6 then connect test via ipv4 if availible
370
+	[ $force_ipversion -ne 0 -a $use_ipv6 -ne 0 -o -z "$__IPV4" ] && {
371
+		# force IPv6
372
+		__IP=$__IPV6
373
+	} || __IP=$__IPV4
374
+
375
+	if [ -n "$__NCEXT" ]; then	# nc compiled with extensions (timeout support)
376
+		__RUNPROG="nc -w 1 $__IP $__PORT </dev/null >/dev/null 2>&1"
377
+		__ERRPROG="nc -vw 1 $__IP $__PORT </dev/null 2>&1"
378
+		verbose_echo "  connect prog =: '$__RUNPROG'"
379
+		eval $__RUNPROG
380
+		__ERR=$?
381
+		[ $__ERR -eq 0 ] && return 0
382
+		verbose_echo "\n!!!!!!!!! ERROR =: BusyBox nc Error '$__ERR'\n$(eval $__ERRPROG)\n"
383
+		syslog_err "host verify Error - BusyBox nc Error: '$__ERR'"
384
+		return 3
385
+	else		# nc compiled without extensions (no timeout support)
386
+		__RUNPROG="__timeout 2 -- nc $__IP $__PORT </dev/null >/dev/null 2>&1"
387
+		verbose_echo "  connect prog =: '$__RUNPROG'"
388
+		eval $__RUNPROG
389
+		__ERR=$?
390
+		[ $__ERR -eq 0 ] && return 0
391
+		verbose_echo "\n!!!!!!!!! ERROR =: BusyBox nc Error '$__ERR' (timeout)"
392
+		syslog_err "host verify Error - BusyBox nc Error: '$__ERR' (timeout)"
393
+		return 3
97 394
 	fi
395
+}
98 396
 
99
-	echo "$current_ip"
397
+verify_dns() {
398
+	# $1	DNS server to verify
399
+	# we need DNS server to verify otherwise exit with ERROR 1
400
+	[ -z "$1" ] && return 1
401
+
402
+	# DNS uses port 53
403
+	__verify_host_port "$1" "53"
100 404
 }
101 405
 
406
+verify_proxy() {
407
+	# $1	Proxy-String to verify
408
+	#		complete entry		user:password@host:port
409
+	#		host and port only	host:port
410
+	#		host only		host		unsupported
411
+	#		IPv4 address instead of host	123.234.234.123
412
+	#		IPv6 address instead of host	[xxxx:....:xxxx]	in square bracket
413
+	local __TMP __HOST __PORT
102 414
 
103
-verbose_echo()
104
-{
105
-	if [ "$verbose_mode" = 1 ]
106
-	then
107
-		echo $1
415
+	# we need Proxy-Sting to verify otherwise exit with ERROR 1
416
+	[ -z "$1" ] && return 1
417
+
418
+	# try to split user:password "@" host:port
419
+	__TMP=$(echo $1 | awk -F "@" '{print $2}')
420
+	# no "@" found - only host:port is given
421
+	[ -z "$__TMP" ] && __TMP="$1"
422
+	# now lets check for IPv6 address
423
+	__HOST=$(echo $__TMP | grep -m 1 -o "$IPV6_REGEX")
424
+	# IPv6 host address found read port
425
+	if [ -n "$__HOST" ]; then
426
+		# IPv6 split at "]:"
427
+		__PORT=$(echo $__TMP | awk -F "]:" '{print $2}')
428
+	else
429
+		__HOST=$(echo $__TMP | awk -F ":" '{print $1}')
430
+		__PORT=$(echo $__TMP | awk -F ":" '{print $2}')
108 431
 	fi
432
+	# No Port detected ERROR 5
433
+	[ -z "$__PORT" ] && return 5
434
+
435
+	__verify_host_port "$__HOST" "$__PORT"
109 436
 }
110 437
 
111
-syslog_echo()
112
-{
113
-	if [ "$use_syslog" = 1 ]
114
-	then
115
-		echo $1|logger -t ddns-scripts-$service_id
438
+__do_transfer() {
439
+	# $1	# Variable to store Answer of transfer
440
+	# $2	# URL to use
441
+	local __URL="$2"
442
+	local __ERR=0
443
+	local __PROG  __RUNPROG  __ERRPROG  __DATA
444
+
445
+	# lets prefer GNU Wget because it does all for us - IPv4/IPv6/HTTPS/PROXY/force IP version
446
+	if /usr/bin/wget --version 2>&1 | grep -q "\+ssl"; then
447
+		__PROG="/usr/bin/wget -t 2 -O -"	# standard output only 2 retrys on error
448
+		# force ip version to use
449
+		if [ $force_ipversion -eq 1 ]; then	
450
+			[ $use_ipv6 -eq 0 ] && __PROG="$__PROG -4" || __PROG="$__PROG -6"	# force IPv4/IPv6
451
+		fi
452
+		# set certificate parameters
453
+		if [ $use_https -eq 1 ]; then
454
+			if [ "$cacert" = "IGNORE" ]; then	# idea from Ticket #15327 to ignore server cert
455
+				__PROG="$__PROG --no-check-certificate"
456
+			elif [ -f "$cacert" ]; then
457
+				__PROG="$__PROG --ca-certificate=${cacert}"
458
+			elif [ -d "$cacert" ]; then
459
+				__PROG="$__PROG --ca-directory=${cacert}"
460
+			else	# exit here because it makes no sense to start loop
461
+				critical_error "Wget: No valid certificate(s) found for running HTTPS"
462
+			fi
463
+		fi
464
+		# disable proxy if no set (there might be .wgetrc or .curlrc or wrong environment set)
465
+		[ -z "$proxy" ] && __PROG="$__PROG --no-proxy"
466
+
467
+		__RUNPROG="$__PROG -q '$__URL' 2>/dev/null"	# do transfer with "-q" to suppress not needed output
468
+		__ERRPROG="$__PROG -d '$__URL' 2>&1"		# do transfer with "-d" for debug mode
469
+		verbose_echo " transfer prog =: $__RUNPROG"
470
+		__DATA=$(eval $__RUNPROG)
471
+		__ERR=$?
472
+		[ $__ERR -gt 0 ] && {
473
+			verbose_echo "\n!!!!!!!!! ERROR =: GNU Wget Error '$__ERR'\n$(eval $__ERRPROG)\n"
474
+			syslog_err "Communication Error - GNU Wget Error: '$__ERR'"
475
+			return 1
476
+		}
477
+
478
+	# 2nd choice is cURL IPv4/IPv6/HTTPS
479
+	# libcurl might be compiled without Proxy Support (default in trunk)
480
+	elif [ -x /usr/bin/curl ]; then
481
+		__PROG="/usr/bin/curl"
482
+		# force ip version to use
483
+		if [ $force_ipversion -eq 1 ]; then	
484
+			[ $use_ipv6 -eq 0 ] && __PROG="$__PROG -4" || __PROG="$__PROG -6"	# force IPv4/IPv6
485
+		fi
486
+		# set certificate parameters
487
+		if [ $use_https -eq 1 ]; then
488
+			if [ "$cacert" = "IGNORE" ]; then	# idea from Ticket #15327 to ignore server cert
489
+				__PROG="$__PROG --insecure"	# but not empty better to use "IGNORE"
490
+			elif [ -f "$cacert" ]; then
491
+				__PROG="$__PROG --cacert $cacert"
492
+			elif [ -d "$cacert" ]; then
493
+				__PROG="$__PROG --capath $cacert"
494
+			else	# exit here because it makes no sense to start loop
495
+				critical_error "cURL: No valid certificate(s) found for running HTTPS"
496
+			fi
497
+		fi
498
+		# disable proxy if no set (there might be .wgetrc or .curlrc or wrong environment set)
499
+		# or check if libcurl compiled with proxy support
500
+		if [ -z "$proxy" ]; then
501
+			__PROG="$__PROG --noproxy '*'"
502
+		else
503
+			# if libcurl has no proxy support and proxy should be used then force ERROR
504
+			# libcurl currently no proxy support by default
505
+			grep -iq all_proxy /usr/lib/libcurl.so* || \
506
+				critical_error "cURL: libcurl compiled without Proxy support"
507
+		fi
508
+
509
+		__RUNPROG="$__PROG -q '$__URL' 2>/dev/null"	# do transfer with "-s" to suppress not needed output
510
+		__ERRPROG="$__PROG -v '$__URL' 2>&1"		# do transfer with "-v" for verbose mode
511
+		verbose_echo " transfer prog =: $__RUNPROG"
512
+		__DATA=$(eval $__RUNPROG)
513
+		__ERR=$?
514
+		[ $__ERR -gt 0 ] && {
515
+			verbose_echo "\n!!!!!!!!! ERROR =: cURL Error '$__ERR'\n$(eval $__ERRPROG)\n"
516
+			syslog_err "Communication Error - cURL Error: '$__ERR'"
517
+			return 1
518
+		}
519
+
520
+	# busybox Wget (did not support neither IPv6 nor HTTPS)
521
+	elif [ -x /usr/bin/wget ]; then
522
+		__PROG="/usr/bin/wget -O -"
523
+		# force ip version not supported
524
+		[ $force_ipversion -eq 1 ] && \
525
+			critical_error "BusyBox Wget: can not force IP version to use"
526
+		# https not supported
527
+		[ $use_https -eq 1 ] && \
528
+			critical_error "BusyBox Wget: no HTTPS support"
529
+		# disable proxy if no set (there might be .wgetrc or .curlrc or wrong environment set)
530
+		[ -z "$proxy" ] && __PROG="$__PROG -Y off"
531
+		
532
+		__RUNPROG="$__PROG -q '$__URL' 2>/dev/null"	# do transfer with "-q" to suppress not needed output
533
+		__ERRPROG="$__PROG '$__URL' 2>&1"
534
+		verbose_echo " transfer prog =: $__RUNPROG"
535
+		__DATA=$(eval $__RUNPROG)
536
+		__ERR=$?
537
+		[ $__ERR -gt 0 ] && {
538
+			verbose_echo "\n!!!!!!!!! ERROR =: BusyBox Wget Error '$__ERR'\n$(eval $__ERRPROG)\n"
539
+			syslog_err "Communication Error - BusyBox Wget Error: '$__ERR'"
540
+			return 1
541
+		}
542
+
543
+	else
544
+		critical_error "Program not found - Neither 'Wget' nor 'cURL' installed or executable"
116 545
 	fi
546
+
547
+	eval "$1='$__DATA'"
548
+	return 0
117 549
 }
118 550
 
119
-start_daemon_for_all_ddns_sections()
120
-{
121
-	local event_interface="$1"
551
+send_update() {
552
+	# $1	# IP to set at DDNS service provider
553
+	local __IP __URL __ANSWER __ERR
122 554
 
123
-	SECTIONS=""
124
-	config_cb() 
125
-	{
126
-		SECTIONS="$SECTIONS $2"
555
+	# verify given IP
556
+	[ $use_ipv6 -eq 0 ] && __IP=$(echo $1 | grep -v -E "(^0|^10|^127|^172|^192)")	# no private IPv4's
557
+	[ $use_ipv6 -eq 1 ] && __IP=$(echo $1 | grep "^[0-9a-eA-E]")	# no IPv6 addr starting with fxxx of with ":"
558
+	[ -z "$__IP" ] && critical_error "Invalid or no IP '$1' given"
559
+
560
+	# do replaces in URL
561
+	__URL=$(echo $update_url | sed -e "s#\[USERNAME\]#$username#g" -e "s#\[PASSWORD\]#$password#g" \
562
+				       -e "s#\[DOMAIN\]#$domain#g" -e "s#\[IP\]#$__IP#g")
563
+	[ $use_https -ne 0 ] && __URL=$(echo $__URL | sed -e 's#^http:#https:#')
564
+
565
+	__do_transfer __ANSWER "$__URL"
566
+	__ERR=$?
567
+	[ $__ERR -gt 0 ] && {
568
+		verbose_echo "\n!!!!!!!!! ERROR =: Error sending update to DDNS Provider\n"
569
+		return 1
127 570
 	}
128
-	config_load "ddns"
129 571
 
130
-	for section in $SECTIONS
131
-	do
132
-		local iface
133
-		config_get iface "$section" interface "wan"
134
-		[ -z "$event_interface" -o "$iface" = "$event_interface" ] || continue
135
-		/usr/lib/ddns/dynamic_dns_updater.sh $section 0 > /dev/null 2>&1 &
136
-	done
572
+	verbose_echo "   update send =: DDNS Provider answered\n$__ANSWER"
573
+	
574
+	return 0
137 575
 }
138 576
 
139
-monotonic_time()
140
-{
141
-	local uptime
142
-	read uptime < /proc/uptime
143
-	echo "${uptime%%.*}"
577
+get_local_ip () {
578
+	# $1	Name of Variable to store local IP (LOCAL_IP)
579
+	local __RUNPROG __IP __URL __ANSWER
580
+
581
+	case $ip_source in
582
+		network )
583
+			# set correct program
584
+			[ $use_ipv6 -eq 0 ] && __RUNPROG="network_get_ipaddr" \
585
+					    || __RUNPROG="network_get_ipaddr6"
586
+			$__RUNPROG __IP "$ip_network"
587
+			verbose_echo "      local ip =: '$__IP' detected on network '$ip_network'"
588
+			;;
589
+		interface )
590
+			if [ $use_ipv6 -eq 0 ]; then
591
+				__IP=$(ifconfig $ip_interface | awk '
592
+					/Bcast.*Mask/ {	# Filter IPv4
593
+					#   inet addr:192.168.1.1  Bcast:192.168.1.255  Mask:255.255.255.0
594
+					$1="";		# remove inet
595
+					$3="";		# remove Bcast: ...
596
+					$4="";		# remove Mask: ...
597
+					FS=":";		# separator ":"
598
+					$0=$0;		# reread to activate separator
599
+					$1="";		# remove addr
600
+					FS=" ";		# set back separator to default " "
601
+					$0=$0;		# reread to activate separator (remove whitespaces)
602
+					print $1;	# print IPv4 addr
603
+					}'
604
+				)
605
+			else
606
+				__IP=$(ifconfig $ip_interface | awk '
607
+					/inet6/ && /: [0-9a-eA-E]/ && !/\/128/ {	# Filter IPv6 exclude fxxx and /128 prefix
608
+					#   inet6 addr: 2001:db8::xxxx:xxxx/32 Scope:Global
609
+					FS="/";		# separator "/"
610
+					$0=$0;		# reread to activate separator
611
+					$2="";		# remove everything behind "/"
612
+					FS=" ";		# set back separator to default " "
613
+					$0=$0;		# reread to activate separator
614
+					print $3;	# print IPv6 addr
615
+					}'
616
+				)
617
+			fi
618
+			verbose_echo "      local ip =: '$__IP' detected on interface '$ip_interface'"
619
+			;;
620
+		script )
621
+			# get ip from script
622
+			__IP=$($ip_script)
623
+			verbose_echo "      local ip =: '$__IP' detected via script '$ip_script'"
624
+			;;
625
+		* )
626
+			for __URL in $ip_url; do
627
+				__do_transfer __ANSWER "$__URL"
628
+				[ -n "$__IP" ] && break	# Answer detected, leave for loop
629
+			done
630
+			# use correct regular expression
631
+			[ $use_ipv6 -eq 0 ] \
632
+				&& __IP=$(echo "$__ANSWER" | grep -m 1 -o "$IPV4_REGEX") \
633
+				|| __IP=$(echo "$__ANSWER" | grep -m 1 -o "$IPV6_REGEX")
634
+			verbose_echo "      local ip =: '$__IP' detected via web at '$__URL'"
635
+			;;
636
+	esac
637
+
638
+	# if NO IP was found
639
+	[ -z "$__IP" ] && return 1
640
+
641
+	eval "$1='$__IP'"
642
+	return 0
643
+}
644
+
645
+get_registered_ip() {
646
+	# $1	Name of Variable to store public IP (REGISTERED_IP)
647
+	local __IP  __REGEX  __PROG  __RUNPROG  __ERRPROG  __ERR
648
+	# return codes
649
+	# 1	no IP detected
650
+
651
+	# set correct regular expression
652
+	[ $use_ipv6 -eq 0 ] && __REGEX="$IPV4_REGEX" || __REGEX="$IPV6_REGEX"
653
+
654
+	if [ -x /usr/bin/host ]; then		# otherwise try to use BIND host
655
+		__PROG="/usr/bin/host"
656
+		[ $use_ipv6 -eq 0 ] && __PROG="$__PROG -t A"  || __PROG="$__PROG -t AAAA"
657
+		if [ $force_ipversion -eq 1 ]; then			# force IP version
658
+			[ $use_ipv6 -eq 0 ] && __PROG="$__PROG -4"  || __PROG="$__PROG -6"
659
+		fi			
660
+		[ $force_dnstcp -eq 1 ] && __PROG="$__PROG -T"	# force TCP
661
+
662
+		__RUNPROG="$__PROG $domain $dns_server 2>/dev/null"
663
+		__ERRPROG="$__PROG -v $domain $dns_server 2>&1"
664
+		verbose_echo " resolver prog =: $__RUNPROG"
665
+		__IP=$(eval $__RUNPROG)
666
+		__ERR=$?
667
+		# command error
668
+		[ $__ERR -gt 0 ] && {
669
+			verbose_echo "\n!!!!!!!!! ERROR =: BIND host Error '$__ERR'\n$(eval $__ERRPROG)\n"
670
+			syslog_err "DNS Resolver Error - BIND host Error: '$__ERR'"
671
+			return 1
672
+		} || {
673
+			# we need to run twice because multi-line output needs to be directly piped to grep because
674
+			# pipe returns return code of last prog in pipe but we need errors from host command
675
+			__IP=$(eval $__RUNPROG | grep "^$domain" | grep -m 1 -o "$__REGEX")
676
+		}
677
+
678
+	elif [ -x /usr/bin/nslookup ]; then	# last use BusyBox nslookup
679
+		[ $force_ipversion -ne 0 -o $force_dnstcp -ne 0 ] && \
680
+			critical_error "nslookup - no support to 'force IP Version' or 'DNS over TCP'"
681
+
682
+		__RUNPROG="nslookup $domain $dns_server 2>/dev/null"
683
+		__ERRPROG="nslookup $domain $dns_server 2>&1"
684
+		verbose_echo " resolver prog =: $__RUNPROG"
685
+		__IP=$(eval $__RUNPROG)
686
+		__ERR=$?
687
+		# command error
688
+		[ $__ERR -gt 0 ] && {
689
+			verbose_echo "\n!!!!!!!!! ERROR =: BusyBox nslookup Error '$__ERR'\n$(eval $__ERRPROG)\n"
690
+			syslog_err "DNS Resolver Error - BusyBox nslookup Error: '$__ERR'"
691
+			return 1
692
+		} || {
693
+			# we need to run twice because multi-line output needs to be directly piped to grep because
694
+			# pipe returns return code of last prog in pipe but we need errors from nslookup command
695
+			__IP=$(eval $__RUNPROG | sed '1,2d' | grep -o "Name:\|Address.*" | grep -m 1 -o "$__REGEX")
696
+		}
697
+
698
+	else					# there must be an error
699
+		critical_error "No program found to request public registered IP"
700
+	fi
701
+
702
+	verbose_echo "   resolved ip =: '$__IP'"
703
+
704
+	# if NO IP was found
705
+	[ -z "$__IP" ] && return 1
706
+
707
+	eval "$1='$__IP'"
708
+	return 0
709
+}
710
+
711
+get_uptime() {
712
+	# $1	Variable to store result in
713
+	local __UPTIME=$(cat /proc/uptime)
714
+	eval "$1='${__UPTIME%%.*}'"
144 715
 }

+ 364
- 325
net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_updater.sh View File

@@ -1,360 +1,399 @@
1 1
 #!/bin/sh
2
-# /usr/lib/dynamic_dns/dynamic_dns_updater.sh
2
+# /usr/lib/ddns/dynamic_dns_updater.sh
3 3
 #
4
-# Written by Eric Paul Bishop, Janary 2008
4
+# Original written by Eric Paul Bishop, January 2008
5 5
 # Distributed under the terms of the GNU General Public License (GPL) version 2.0
6
-#
7
-# This script is (loosely) based on the one posted by exobyte in the forums here:
6
+# (Loosely) based on the script on the one posted by exobyte in the forums here:
8 7
 # http://forum.openwrt.org/viewtopic.php?id=14040
9 8
 #
10
-
11
-. /usr/lib/ddns/dynamic_dns_functions.sh
12
-
13
-
14
-service_id=$1
15
-if [ -z "$service_id" ]
16
-then
17
-	echo "ERRROR: You must specify a service id (the section name in the /etc/config/ddns file) to initialize dynamic DNS."
18
-	return 1
19
-fi
20
-
21
-#default mode is verbose_mode, but easily turned off with second parameter
22
-verbose_mode="1"
23
-if [ -n "$2" ]
24
-then
25
-	verbose_mode="$2"
26
-fi
27
-
28
-###############################################################
29
-# Leave this comment here, to clearly document variable names
30
-# that are expected/possible
9
+# extended and partial rewritten by Christian Schoenebeck in August 2014 to support:
10
+# - IPv6 DDNS services
11
+# - DNS Server to retrieve registered IP including TCP transport
12
+# - Proxy Server to send out updates
13
+# - force_interval=0 to run once
14
+# - the usage of BIND's host command instead of BusyBox's nslookup if installed
15
+# - extended Verbose Mode and log file support for better error detection 
31 16
 #
32
-# Now use load_all_config_options to load config
33
-# options, which is a much more flexible solution.
17
+# variables in small chars are read from /etc/config/ddns
18
+# variables in big chars are defined inside these scripts as global vars
19
+# variables in big chars beginning with "__" are local defined inside functions only
20
+#set -vx  	#script debugger
21
+
22
+[ $# -lt 1 -o -n "${2//[0-3]/}" -o ${#2} -gt 1 ] && {
23
+	echo -e "\n  USAGE:"
24
+	echo -e "  $0 [SECTION] [VERBOSE_MODE]\n"
25
+	echo    "  [SECTION]      - service section as defined in /etc/config/ddns"
26
+	echo    "  [VERBOSE_MODE] - '0' NO output to console"
27
+	echo    "                   '1' output to console"
28
+	echo    "                   '2' output to console AND logfile"
29
+	echo    "                       + run once WITHOUT retry on error"
30
+	echo    "                   '3' output to console AND logfile"
31
+	echo    "                       + run once WITHOUT retry on error"
32
+	echo -e "                       + NOT sending update to DDNS service\n"
33
+	exit 1
34
+}
35
+
36
+. /usr/lib/ddns/dynamic_dns_functions.sh	# global vars are also defined here
37
+
38
+SECTION_ID="$1"
39
+VERBOSE_MODE=${2:-1}	#default mode is log to console
40
+
41
+# set file names
42
+PIDFILE="$RUNDIR/$SECTION_ID.pid"	# Process ID file
43
+UPDFILE="$RUNDIR/$SECTION_ID.update"	# last update successful send (system uptime)
44
+LOGFILE="$LOGDIR/$SECTION_ID.log"	# log file
45
+
46
+# VERBOSE_MODE > 1 delete logfile if exist to create an empty one
47
+# only with this data of this run for easier diagnostic
48
+# new one created by verbose_echo function
49
+[ $VERBOSE_MODE -gt 1 -a -f $LOGFILE ] && rm -f $LOGFILE
50
+
51
+################################################################################
52
+# Leave this comment here, to clearly document variable names that are expected/possible
53
+# Use load_all_config_options to load config options, which is a much more flexible solution.
34 54
 #
55
+# config_load "ddns"
56
+# config_get <variable> $SECTION_ID <option]>
35 57
 #
36
-#config_load "ddns"
58
+# defined options (also used as variable):
59
+# 
60
+# enable	self-explanatory
61
+# interface 	network interface used by hotplug.d i.e. 'wan' or 'wan6'
37 62
 #
38
-#config_get enabled $service_id enabled
39
-#config_get service_name $service_id service_name
40
-#config_get update_url $service_id update_url
63
+# service_name	Which DDNS service do you use or "custom"
64
+# update_url	URL to use to update your "custom" DDNS service
41 65
 #
66
+# domain 	Your DNS name / replace [DOMAIN] in update_url
67
+# username 	Username of your DDNS service account / replace [USERNAME] in update_url
68
+# password 	Password of your DDNS service account / replace [PASSWORD] in update_url
42 69
 #
43
-#config_get username $service_id username
44
-#config_get password $service_id password
45
-#config_get domain $service_id domain
70
+# use_https	use HTTPS to update DDNS service
71
+# cacert	file or directory where HTTPS can find certificates to verify server; 'IGNORE' ignore check of server certificate
46 72
 #
73
+# use_syslog	log activity to syslog
47 74
 #
48
-#config_get use_https $service_id use_https
49
-#config_get use_syslog $service_id use_syslog
50
-#config_get cacert $service_id cacert
75
+# ip_source	source to detect current local IP ('network' or 'web' or 'script' or 'interface')
76
+# ip_network	local defined network to read IP from i.e. 'wan' or 'wan6'
77
+# ip_url	URL to read local address from i.e. http://checkip.dyndns.com/ or http://checkipv6.dyndns.com/
78
+# ip_script	full path and name of your script to detect local IP
79
+# ip_interface	physical interface to use for detecting 
51 80
 #
52
-#config_get ip_source $service_id ip_source
53
-#config_get ip_interface $service_id ip_interface
54
-#config_get ip_network $service_id ip_network
55
-#config_get ip_url $service_id ip_url
81
+# check_interval	check for changes every  !!! checks below 10 minutes make no sense because the Internet 
82
+# check_unit		'days' 'hours' 'minutes' !!! needs about 5-10 minutes to sync an IP-change for an DNS entry
56 83
 #
57
-#config_get force_interval $service_id force_interval
58
-#config_get force_unit $service_id force_unit
84
+# force_interval	force to send an update to your service if no change was detected
85
+# force_unit		'days' 'hours' 'minutes' !!! force_interval="0" runs this script once for use i.e. with cron
59 86
 #
60
-#config_get check_interval $service_id check_interval
61
-#config_get check_unit $service_id check_unit
62
-#########################################################
63
-load_all_config_options "ddns" "$service_id"
64
-
65
-
66
-#some defaults
67
-if [ -z "$check_interval" ]
68
-then
69
-	check_interval=600
70
-fi
71
-
72
-if [ -z "$retry_interval" ]
73
-then
74
-	retry_interval=60
75
-fi
76
-
77
-if [ -z "$check_unit" ]
78
-then
79
-	check_unit="seconds"
80
-fi
81
-
82
-if [ -z "$force_interval" ]
83
-then
84
-	force_interval=72
85
-fi
86
-
87
-if [ -z "$force_unit" ]
88
-then
89
-	force_unit="hours"
90
-fi
91
-
92
-if [ -z $use_syslog ]
93
-then
94
-	use_syslog=0
95
-fi
96
-
97
-if [ -z "$use_https" ]
98
-then
99
-	use_https=0
100
-fi
101
-
102
-
103
-#some constants
104
-
105
-retrieve_prog="/usr/bin/wget -O - ";
106
-if [ "x$use_https" = "x1" ]
107
-then
108
-	/usr/bin/wget --version 2>&1 |grep -q "\+ssl"
109
-	if [ $? -eq 0 ]
110
-	then
111
-		if [ -f "$cacert" ]
112
-		then
113
-			retrieve_prog="${retrieve_prog}--ca-certificate=${cacert} "
114
-		elif [ -d "$cacert" ]
115
-		then
116
-			retrieve_prog="${retrieve_prog}--ca-directory=${cacert} "
117
-		fi
118
-	else
119
-		retrieve_prog="/usr/bin/curl "
120
-		if [ -f "$cacert" ]
121
-		then
122
-			retrieve_prog="${retrieve_prog}--cacert $cacert "
123
-		elif [ -d "$cacert" ]
124
-		then
125
-			retrieve_prog="${retrieve_prog}--capath $cacert "
126
-		fi
127
-	fi
128
-fi
129
-
130
-
131
-service_file="/usr/lib/ddns/services"
132
-
133
-ip_regex="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
134
-
135
-NEWLINE_IFS='
136
-'
137
-
138
-#determine what update url we're using if the service_name is supplied
139
-if [ -n "$service_name" ]
140
-then
141
-	#remove any lines not containing data, and then make sure fields are enclosed in double quotes
142
-	quoted_services=$(cat $service_file |  grep "^[\t ]*[^#]" |  awk ' gsub("\x27", "\"") { if ($1~/^[^\"]*$/) $1="\""$1"\"" }; { if ( $NF~/^[^\"]*$/) $NF="\""$NF"\""  }; { print $0 }' )
143
-
144
-
145
-	#echo "quoted_services = $quoted_services"
146
-	OLD_IFS=$IFS
147
-	IFS=$NEWLINE_IFS
148
-	for service_line in $quoted_services
149
-	do
150
-		#grep out proper parts of data and use echo to remove quotes
151
-		next_name=$(echo $service_line | grep -o "^[\t ]*\"[^\"]*\"" | xargs -r -n1 echo)
152
-		next_url=$(echo $service_line | grep -o "\"[^\"]*\"[\t ]*$" | xargs -r -n1 echo)
153
-
154
-		if [ "$next_name" = "$service_name" ]
155
-		then
156
-			update_url=$next_url
157
-		fi
158
-	done
159
-	IFS=$OLD_IFS
160
-fi
161
-
162
-if [ "x$use_https" = x1 ]
163
-then
164
-	update_url=$(echo $update_url | sed -e 's/^http:/https:/')
165
-fi
166
-
167
-verbose_echo "update_url=$update_url"
168
-
169
-#if this service isn't enabled then quit
170
-if [ "$enabled" != "1" ] 
171
-then
172
-	return 0
173
-fi
174
-
175
-#compute update interval in seconds
176
-case "$force_unit" in
177
-	"days" )
178
-		force_interval_seconds=$(($force_interval*60*60*24))
179
-		;;
180
-	"hours" )
181
-		force_interval_seconds=$(($force_interval*60*60))
182
-		;;
183
-	"minutes" )
184
-		force_interval_seconds=$(($force_interval*60))
185
-		;;
186
-	"seconds" )
187
-		force_interval_seconds=$force_interval
188
-		;;
189
-	* )
190
-		#default is hours
191
-		force_interval_seconds=$(($force_interval*60*60))
192
-		;;
193
-esac
194
-
195
-
196
-#compute check interval in seconds
197
-case "$check_unit" in
198
-	"days" )
199
-		check_interval_seconds=$(($check_interval*60*60*24))
200
-		;;
201
-	"hours" )
202
-		check_interval_seconds=$(($check_interval*60*60))
203
-		;;
204
-	"minutes" )
205
-		check_interval_seconds=$(($check_interval*60))
206
-		;;
207
-	"seconds" )
208
-		check_interval_seconds=$check_interval
209
-		;;
210
-	* )
211
-		#default is seconds
212
-		check_interval_seconds=$check_interval
213
-		;;
214
-esac
215
-
216
-
217
-#compute retry interval in seconds
218
-case "$retry_unit" in
219
-	"days" )
220
-		retry_interval_seconds=$(($retry_interval*60*60*24))
221
-		;;
222
-	"hours" )
223
-		retry_interval_seconds=$(($retry_interval*60*60))
224
-		;;
225
-	"minutes" )
226
-		retry_interval_seconds=$(($retry_interval*60))
227
-		;;
228
-	"seconds" )
229
-		retry_interval_seconds=$retry_interval
230
-		;;
231
-	* )
232
-		#default is seconds
233
-		retry_interval_seconds=$retry_interval
234
-		;;
87
+# retry_interval	if error was detected retry in
88
+# retry_unit		'days' 'hours' 'minutes' 'seconds'
89
+# retry_count 		#NEW# number of retries before scripts stops
90
+#
91
+# use_ipv6		#NEW# detecting/sending IPv6 address
92
+# force_ipversion	#NEW# force usage of IPv4 or IPv6 for the whole detection and update communication
93
+# dns_server		#NEW# using a non default dns server to get Registered IP from Internet
94
+# force_dnstcp		#NEW# force communication with DNS server via TCP instead of default UDP
95
+# proxy			#NEW# using a proxy for communication !!! ALSO used to detect local IP via web => return proxy's IP !!!
96
+# use_logfile		#NEW# self-explanatory "/var/log/ddns/$SECTION_ID.log"
97
+#
98
+# some functionality needs 
99
+# - GNU Wget or cURL installed for sending updates to DDNS service
100
+# - BIND host installed to detect Registered IP
101
+#
102
+################################################################################
103
+
104
+# verify and load SECTION_ID is exists
105
+[ "$(uci_get ddns $SECTION_ID)" != "service" ] && {
106
+	[ $VERBOSE_MODE -le 1 ] && VERBOSE_MODE=2	# force console out and logfile output
107
+	[ -f $LOGFILE ] && rm -f $LOGFILE		# clear logfile before first entry
108
+	verbose_echo "\n ************** =: ************** ************** **************"
109
+	verbose_echo "       STARTED =: PID '$$' at $(eval $DATE_PROG)"
110
+	verbose_echo "    UCI CONFIG =:\n$(uci -q show ddns | grep '=service' | sort)"
111
+	critical_error "Service '$SECTION_ID' not defined"
112
+}
113
+load_all_config_options "ddns" "$SECTION_ID"
114
+
115
+verbose_echo "\n ************** =: ************** ************** **************"
116
+verbose_echo "       STARTED =: PID '$$' at $(eval $DATE_PROG)"
117
+syslog_info "Started"
118
+case $VERBOSE_MODE in
119
+	0) verbose_echo "  verbose mode =: '0' - run normal, NO console output";;
120
+	1) verbose_echo "  verbose mode =: '1' - run normal, console mode";;
121
+	2) verbose_echo "  verbose mode =: '2' - run once, NO retry on error";;
122
+	3) verbose_echo "  verbose mode =: '3' - run once, NO retry on error, NOT sending update";;
123
+	*) critical_error "ERROR detecting VERBOSE_MODE '$VERBOSE_MODE'"
235 124
 esac
125
+verbose_echo "    UCI CONFIG =:\n$(uci -q show ddns.$SECTION_ID | sort)"
126
+
127
+# set defaults if not defined
128
+[ -z "$enabled" ]	  && enabled=0
129
+[ -z "$retry_count" ]	  && retry_count=5
130
+[ -z "$use_syslog" ]      && use_syslog=0	# not use syslog
131
+[ -z "$use_https" ]       && use_https=0	# not use https
132
+[ -z "$use_logfile" ]     && use_logfile=1	# NEW - use logfile by default
133
+[ -z "$use_ipv6" ]	  && use_ipv6=0		# NEW - use IPv4 by default
134
+[ -z "$force_ipversion" ] && force_ipversion=0	# NEW - default let system decide
135
+[ -z "$force_dnstcp" ]	  && force_dnstcp=0	# NEW - default UDP
136
+[ -z "$ip_source" ]	  && ip_source="network"
137
+[ "$ip_source" = "network" -a -z "$ip_network" -a $use_ipv6 -eq 0 ] && ip_network="wan"  # IPv4: default wan
138
+[ "$ip_source" = "network" -a -z "$ip_network" -a $use_ipv6 -eq 1 ] && ip_network="wan6" # IPv6: default wan6
139
+[ "$ip_source" = "web" -a -z "$ip_url" -a $use_ipv6 -eq 0 ] && ip_url="http://checkip.dyndns.com"
140
+[ "$ip_source" = "web" -a -z "$ip_url" -a $use_ipv6 -eq 1 ] && ip_url="http://checkipv6.dyndns.com"
141
+[ "$ip_source" = "interface" -a -z "$ip_interface" ] && ip_interface="eth1"
142
+
143
+# check configuration and enabled state
144
+[ -z "$domain" -o -z "$username" -o -z "$password" ] && critical_error "Service Configuration not correctly configured"
145
+[ $enabled -eq 0 ] && critical_error "Service Configuration is disabled"
146
+
147
+# verify script if configured and executable
148
+if [ "$ip_source" = "script" ]; then
149
+	[ -z "$ip_script" ] && critical_error "No script defined to detect local IP"
150
+	[ -x "$ip_script" ] || critical_error "Script to detect local IP not found or not executable"
151
+fi
236 152
 
153
+# compute update interval in seconds
154
+get_seconds CHECK_SECONDS ${check_interval:-10} ${check_unit:-"minutes"} # default 10 min
155
+get_seconds FORCE_SECONDS ${force_interval:-72} ${force_unit:-"hours"}	 # default 3 days
156
+get_seconds RETRY_SECONDS ${retry_interval:-60} ${retry_unit:-"seconds"} # default 60 sec
157
+verbose_echo "check interval =: $CHECK_SECONDS seconds"
158
+verbose_echo "force interval =: $FORCE_SECONDS seconds"
159
+verbose_echo "retry interval =: $RETRY_SECONDS seconds"
160
+verbose_echo " retry counter =: $retry_count times"
237 161
 
238
-verbose_echo "force seconds = $force_interval_seconds"
239
-verbose_echo "check seconds = $check_interval_seconds"
162
+# determine what update url we're using if a service_name is supplied
163
+# otherwise update_url is set inside configuration (custom service)
164
+[ -n "$service_name" ] && get_service_url update_url
165
+[ -z "$update_url" ]   && critical_error "no update url found/defined"
240 166
 
241 167
 #kill old process if it exists & set new pid file
242
-if [ -d /var/run/dynamic_dns ]
243
-then
168
+if [ -d $RUNDIR ]; then
244 169
 	#if process is already running, stop it
245
-	if [ -e "/var/run/dynamic_dns/$service_id.pid" ]
246
-	then
247
-		old_pid=$(cat /var/run/dynamic_dns/$service_id.pid)
248
-		test_match=$(ps | grep "^[\t ]*$old_pid")
249
-		verbose_echo "old process id (if it exists) = \"$test_match\""
250
-		if [ -n  "$test_match" ]
251
-		then
252
-			kill $old_pid
253
-		fi
170
+	if [ -e "$PIDFILE" ]; then
171
+		OLD_PID=$(cat $PIDFILE)
172
+		ps | grep -q "^[\t ]*$OLD_PID" && {
173
+			verbose_echo "   old process =: PID '$OLD_PID'"
174
+			kill $OLD_PID
175
+		} || verbose_echo "old process id =: PID 'none'"
176
+	else
177
+		verbose_echo "old process id =: PID 'none'"
254 178
 	fi
255
-
256 179
 else
257 180
 	#make dir since it doesn't exist
258
-	mkdir /var/run/dynamic_dns
181
+	mkdir -p $RUNDIR
182
+	verbose_echo "old process id =: PID 'none'"
259 183
 fi
260
-echo $$ > /var/run/dynamic_dns/$service_id.pid
261
-
262
-
263
-
264
-
265
-#determine when the last update was
266
-current_time=$(monotonic_time)
267
-last_update=$(( $current_time - (2*$force_interval_seconds) ))
268
-if [ -e "/var/run/dynamic_dns/$service_id.update" ]
269
-then
270
-	last_update=$(cat /var/run/dynamic_dns/$service_id.update)
184
+echo $$ > $PIDFILE
185
+
186
+# determine when the last update was
187
+# the following lines should prevent multiple updates if hotplug fires multiple startups 
188
+# as described in Ticket #7820, but did not function if never an update take place
189
+# i.e. after a reboot (/var is linked to /tmp)
190
+# using uptime as reference because date might not be updated via NTP client 
191
+get_uptime CURR_TIME
192
+[ -e "$UPDFILE" ] && {
193
+	LAST_TIME=$(cat $UPDFILE)
194
+	# check also LAST > CURR because link of /var/run to /tmp might be removed
195
+	# i.e. boxes with larger filesystems
196
+	[ -z "$LAST_TIME" ] && LAST_TIME=0
197
+	[ $LAST_TIME -gt $CURR_TIME ] && LAST_TIME=0
198
+}
199
+if [ $LAST_TIME -eq 0 ]; then
200
+	verbose_echo "   last update =: never"
201
+else
202
+	EPOCH_TIME=$(( $(date +%s) - CURR_TIME + LAST_TIME ))
203
+	EPOCH_TIME="date -d @$EPOCH_TIME +'$DATE_FORMAT'"
204
+	verbose_echo "   last update =: $(eval $EPOCH_TIME)"
271 205
 fi
272
-time_since_update=$(($current_time - $last_update))
273
-
274
-
275
-human_time_since_update=$(( $time_since_update / ( 60 * 60 ) ))
276
-verbose_echo "time_since_update = $human_time_since_update hours"
277
-
278
-
279 206
 
280
-#do update and then loop endlessly, checking ip every check_interval and forcing an updating once every force_interval
281
-
282
-while [ true ]
283
-do
284
-	registered_ip=$(echo $(nslookup "$domain" 2>/dev/null) |  grep -o "Name:.*" | grep -o "$ip_regex")
285
-	current_ip=$(get_current_ip)
286
-
287
-
288
-	current_time=$(monotonic_time)
289
-	time_since_update=$(($current_time - $last_update))
290
-
291
-	syslog_echo "Running IP check ..."
292
-	verbose_echo "Running IP check..."
293
-	verbose_echo "current system ip = $current_ip"
294
-	verbose_echo "registered domain ip = $registered_ip"
295
-
296
-
297
-	if [ "$current_ip" != "$registered_ip" ]  || [ $force_interval_seconds -lt $time_since_update ]
298
-	then
299
-		verbose_echo "update necessary, performing update ..."
300
-
301
-		#do replacement
302
-		final_url=$update_url
303
-		for option_var in $ALL_OPTION_VARIABLES
304
-		do
305
-			if [ "$option_var" != "update_url" ]
306
-			then
307
-				replace_name=$(echo "\[$option_var\]" | tr 'a-z' 'A-Z')
308
-				replace_value=$(eval echo "\$$option_var")
309
-				replace_value=$(echo $replace_value | sed -f /usr/lib/ddns/url_escape.sed)
310
-				final_url=$(echo $final_url | sed s^"$replace_name"^"$replace_value"^g )
207
+# we need time here because hotplug.d is fired by netifd
208
+# but IP addresses are not set by DHCP/DHCPv6 etc.
209
+verbose_echo "       waiting =: 10 seconds for interfaces to fully come up"
210
+sleep 10
211
+
212
+# verify DNS server
213
+[ -n "$dns_server" ] && {
214
+	verbose_echo "******* VERIFY =: DNS server '$dns_server'"
215
+	verify_dns "$dns_server"
216
+	case $? in
217
+		0)	;;	# everything OK
218
+		2)	critical_error "Invalid DNS server Error: '2' - nslookup can not resolve host";;
219
+		3)	critical_error "Invalid DNS server Error: '3' - nc (netcat) can not connect";;
220
+		4)	critical_error "Invalid DNS server Error: '4' - Forced IP Version don't matched";;
221
+		*)	critical_error "Invalid DNS server Error: '1' - unspecific error";;
222
+	esac
223
+}
224
+
225
+# verify Proxy server and set environment
226
+[ -n "$proxy" ] && {
227
+	verbose_echo "******* VERIFY =: Proxy server 'http://$proxy'"
228
+	verify_proxy "$proxy"
229
+	case $? in
230
+		0)	# everything OK
231
+			export HTTP_PROXY="http://$proxy"
232
+			export HTTPS_PROXY="http://$proxy"
233
+			export http_proxy="http://$proxy"
234
+			export https_proxy="http://$proxy"
235
+			;;
236
+		2)	critical_error "Invalid Proxy server Error: '2' - nslookup can not resolve host";;
237
+		3)	critical_error "Invalid Proxy server Error: '3' - nc (netcat) can not connect";;
238
+		4)	critical_error "Invalid Proxy server Error: '4' - Forced IP Version don't matched";;
239
+		5)	critical_error "Invalid Proxy server Error: '5' - proxy port missing";;
240
+		*)	critical_error "Invalid Proxy server Error: '1' - unspecific error";;
241
+	esac
242
+}
243
+
244
+# let's check if there is already an IP registered at the web
245
+# but ignore errors if not
246
+verbose_echo "******* DETECT =: Registered IP"
247
+get_registered_ip REGISTERED_IP
248
+
249
+# loop endlessly, checking ip every check_interval and forcing an updating once every force_interval
250
+# NEW: ### Luci Ticket 538
251
+# a "force_interval" of "0" will run this script only once
252
+# the update is only done once when an interface goes up
253
+# or you run /etc/init.d/ddns start or you can use a cron job
254
+# it will force an update without check when lastupdate happen
255
+# but it will verify after "check_interval" if update is seen in the web 
256
+# and retries on error retry_count times
257
+# CHANGES: ### Ticket 16363
258
+# modified nslookup / sed / grep to detect registered ip
259
+# NEW: ### Ticket 7820
260
+# modified nslookup to support non standard dns_server (needs to be defined in /etc/config/ddns)
261
+# support for BIND host command.
262
+# Wait for interface to fully come up, before the first update is done
263
+verbose_echo "*** START LOOP =: $(eval $DATE_PROG)"
264
+# we run NOT once
265
+[ $FORCE_SECONDS -gt 0 -o $VERBOSE_MODE -le 1 ] && syslog_info "Starting main loop"
266
+
267
+while : ; do
268
+
269
+	# read local IP
270
+	verbose_echo "******* DETECT =: Local IP"
271
+	get_local_ip LOCAL_IP
272
+	ERR_LAST=$?	# save return value
273
+	# Error in function
274
+	[ $ERR_LAST -gt 0 ] && {
275
+		if [ $VERBOSE_MODE -le 1 ]; then	# VERBOSE_MODE <= 1 then retry
276
+			# we can't read local IP
277
+			ERR_LOCAL_IP=$(( $ERR_LOCAL_IP + 1 ))
278
+			[ $ERR_LOCAL_IP -gt $retry_count ] && critical_error "Can not detect local IP"
279
+			verbose_echo "\n!!!!!!!!! ERROR =: detecting local IP - retry $ERR_LOCAL_IP/$retry_count in $RETRY_SECONDS seconds\n"
280
+			syslog_err "Error detecting local IP - retry $ERR_LOCAL_IP/$retry_count in $RETRY_SECONDS seconds"
281
+			sleep $RETRY_SECONDS
282
+			continue	# jump back to the beginning of while loop
283
+		else
284
+			verbose_echo "\n!!!!!!!!! ERROR =: detecting local IP - NO retry\n"
285
+		fi
286
+	}
287
+	ERR_LOCAL_IP=0	# reset err counter
288
+
289
+	# prepare update
290
+	# never updated or forced immediate then NEXT_TIME = 0 
291
+	[ $FORCE_SECONDS -eq 0 -o $LAST_TIME -eq 0 ] \
292
+		&& NEXT_TIME=0 \
293
+		|| NEXT_TIME=$(( $LAST_TIME + $FORCE_SECONDS ))
294
+	# get current uptime
295
+	get_uptime CURR_TIME
296
+	
297
+	# send update when current time > next time or local ip different from registered ip (as loop on error)
298
+	ERR_SEND=0
299
+	while [ $CURR_TIME -ge $NEXT_TIME -o "$LOCAL_IP" != "$REGISTERED_IP" ]; do
300
+		if [ $VERBOSE_MODE -gt 2 ]; then
301
+			verbose_echo "  VERBOSE MODE =: NO UPDATE send to DDNS provider"
302
+		elif [ "$LOCAL_IP" != "$REGISTERED_IP" ]; then
303
+			verbose_echo "******* UPDATE =: LOCAL: '$LOCAL_IP' <=> REGISTERED: '$REGISTERED_IP'"
304
+		else
305
+			verbose_echo "******* FORCED =: LOCAL: '$LOCAL_IP' == REGISTERED: '$REGISTERED_IP'"
306
+		fi
307
+		# only send if VERBOSE_MODE < 3
308
+		ERR_LAST=0
309
+		[ $VERBOSE_MODE -lt 3 ] && {
310
+			send_update "$LOCAL_IP" 
311
+			ERR_LAST=$?	# save return value
312
+		}
313
+
314
+		# Error in function 
315
+		if [ $ERR_LAST -gt 0 ]; then
316
+			if [ $VERBOSE_MODE -le 1 ]; then	# VERBOSE_MODE <=1 then retry
317
+				# error sending local IP
318
+				ERR_SEND=$(( $ERR_SEND + 1 ))
319
+				[ $ERR_SEND -gt $retry_count ] && critical_error "can not send update to DDNS Provider"
320
+				verbose_echo "\n!!!!!!!!! ERROR =: sending update - retry $ERR_SEND/$retry_count in $RETRY_SECONDS seconds\n"
321
+				syslog_err "Error sending update - retry $ERR_SEND/$retry_count in $RETRY_SECONDS seconds"
322
+				sleep $RETRY_SECONDS
323
+				continue # re-loop
324
+			else
325
+				verbose_echo "\n!!!!!!!!! ERROR =: sending update to DDNS service - NO retry\n"
326
+				break
311 327
 			fi
312
-		done
313
-		final_url=$(echo $final_url | sed s^"\[HTTPAUTH\]"^"${username//^/\\^}${password:+:${password//^/\\^}}"^g )
314
-		final_url=$(echo $final_url | sed s/"\[IP\]"/"$current_ip"/g )
315
-
316
-
317
-		verbose_echo "updating with url=\"$final_url\""
318
-
319
-		#here we actually connect, and perform the update
320
-		update_output=$( $retrieve_prog "$final_url" )
321
-		if [ $? -gt 0 ]
322
-		then
323
-			syslog_echo "update failed, retrying in $retry_interval_seconds seconds"
324
-			verbose_echo "update failed"
325
-			sleep $retry_interval_seconds
326
-			continue
328
+		else
329
+			# we send data so save "last time"
330
+			get_uptime LAST_TIME
331
+			echo $LAST_TIME > $UPDFILE	# save LASTTIME to file
332
+			[ "$LOCAL_IP" != "$REGISTERED_IP" ] \
333
+				&& syslog_notice "Changed IP: '$LOCAL_IP' successfully send" \
334
+				|| syslog_notice "Forced Update: IP: '$LOCAL_IP' successfully send"
335
+			break # leave while
327 336
 		fi
328
-		syslog_echo "Update successful"
329
-		verbose_echo "Update Output:"
330
-		verbose_echo "$update_output"
331
-		verbose_echo ""
332
-
333
-		#save the time of the update
334
-		current_time=$(monotonic_time)
335
-		last_update=$current_time
336
-		time_since_update='0'
337
-		registered_ip=$current_ip
338
-
339
-		human_time=$(date)
340
-		verbose_echo "update complete, time is: $human_time"
337
+	done
341 338
 
342
-		echo "$last_update" > "/var/run/dynamic_dns/$service_id.update"
343
-	else
344
-		human_time=$(date)
345
-		human_time_since_update=$(( $time_since_update / ( 60 * 60 ) ))
346
-		verbose_echo "update unnecessary"
347
-		verbose_echo "time since last update = $human_time_since_update hours"
348
-		verbose_echo "the time is now $human_time"
349
-	fi
339
+	# now we wait for check interval before testing if update was recognized
340
+	# only sleep if VERBOSE_MODE <= 2 because nothing send so do not wait
341
+	[ $VERBOSE_MODE -le 2 ] && {
342
+		verbose_echo "****** WAITING =: $CHECK_SECONDS seconds (Check Interval) before continue"
343
+		sleep $CHECK_SECONDS
344
+	} || verbose_echo "  VERBOSE MODE =: NO WAITING for Check Interval\n"
345
+
346
+	# read at DDNS service registered IP (in loop on error)
347
+	REGISTERED_IP=""
348
+	ERR_REG_IP=0
349
+	while : ; do
350
+		verbose_echo "******* DETECT =: Registered IP"
351
+		get_registered_ip REGISTERED_IP
352
+		ERR_LAST=$?	# save return value
353
+
354
+		# No Error in function we leave while loop
355
+		[ $ERR_LAST -eq 0  ] && break
356
+
357
+		# we can't read Registered IP
358
+		if [ $VERBOSE_MODE -le 1 ]; then	# VERBOSE_MODE <=1 then retry
359
+			ERR_REG_IP=$(( $ERR_REG_IP + 1 ))
360
+			[ $ERR_REG_IP -gt $retry_count ] && critical_error "can not detect registered local IP"
361
+			verbose_echo "\n!!!!!!!!! ERROR =: detecting Registered IP - retry $ERR_REG_IP/$retry_count in $RETRY_SECONDS seconds\n"
362
+			syslog_err "Error detecting Registered IP - retry $ERR_REG_IP/$retry_count in $RETRY_SECONDS seconds"
363
+			sleep $RETRY_SECONDS
364
+		else
365
+			verbose_echo "\n!!!!!!!!! ERROR =: detecting Registered IP - NO retry\n"
366
+			break	# leave while loop
367
+		fi
368
+	done
350 369
 
351
-	#sleep for 10 minutes, then re-check ip && time since last update
352
-	sleep $check_interval_seconds
370
+	# IP's are still different
371
+	if [ "$LOCAL_IP" != "$REGISTERED_IP" ]; then
372
+		if [ $VERBOSE_MODE -le 1 ]; then	# VERBOSE_MODE <=1 then retry
373
+			ERR_UPDATE=$(( $ERR_UPDATE + 1 ))
374
+			[ $ERR_UPDATE -gt $retry_count ] && critical_error "Registered IP <> Local IP - LocalIP: '$LOCAL_IP' - RegisteredIP: '$REGISTERED_IP'"
375
+			verbose_echo "\n!!!!!!!!! ERROR =: Registered IP <> Local IP - starting retry $ERR_UPDATE/$retry_count\n"
376
+			syslog_warn "Warning: Registered IP <> Local IP - starting retry $ERR_UPDATE/$retry_count"
377
+			continue # loop to beginning
378
+		else
379
+			verbose_echo "\n!!!!!!!!! ERROR =: Registered IP <> Local IP - LocalIP: '$LOCAL_IP' - RegisteredIP: '$REGISTERED_IP' - NO retry\n"
380
+		fi
381
+	fi		
382
+
383
+	# we checked successful the last update
384
+	ERR_UPDATE=0			# reset error counter
385
+
386
+	# force_update=0 or VERBOSE_MODE > 1 - leave the main loop
387
+	[ $FORCE_SECONDS -eq 0 -o $VERBOSE_MODE -gt 1 ] && {
388
+		verbose_echo "****** LEAVING =: $(eval $DATE_PROG)"
389
+		syslog_info "Leaving"
390
+		break
391
+	}
392
+	verbose_echo "********* LOOP =: $(eval $DATE_PROG)"
393
+	syslog_info "Rerun IP check"
353 394
 done
354 395
 
355
-#should never get here since we're a daemon, but I'll throw it in anyway
356
-return 0
357
-
358
-
359
-
396
+verbose_echo "****** STOPPED =: PID '$$' at $(eval $DATE_PROG)\n"
397
+syslog_info "Done"
360 398
 
399
+exit 0

+ 29
- 0
net/ddns-scripts/files/usr/lib/ddns/services_ipv6 View File

@@ -0,0 +1,29 @@
1
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2
+# !!!!! IPv6 Version of original services file			!!!!!
3
+# !!!!! funtionally and syntax is the same			!!!!!
4
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
5
+# This file contains the update urls for various dynamic dns services.
6
+# Column one contains the service name, column two contains the update url.
7
+# within the update url there are 4 variables you can use: [USERNAME], 
8
+# [PASSWORD], [DOMAIN] and [IP].  These are substituted for the username, 
9
+# password, and domain name specified in the /etc/config/ddns file when an 
10
+# update is performed.  The IP is substituted for the current ip address of the
11
+# router.  These variables are case sensitive, while urls generally are not, so 
12
+# if you need to enter the same text in the url (which seems very unlikely) put 
13
+# that text in lowercase, while the variables should remain in uppercase
14
+
15
+# tested with
16
+
17
+# Securepoint Dynamic-DNS-Service
18
+"spdns.de"	"http://[USERNAME]:[PASSWORD]@update.spdns.de/nic/update?hostname=[DOMAIN]&myip=[IP]"
19
+
20
+# Hurricane Electric Dynamic DNS
21
+"he.net"	"http://[DOMAIN]:[PASSWORD]@dyn.dns.he.net/nic/update?hostname=[DOMAIN]&myip=[IP]" 
22
+
23
+#### ADD YOURS HERE! ######################################################################################
24
+#                                                                                                         #
25
+# There are TONS of dynamic dns services out there. There's a huge list of them at:                       #
26
+# http://www.dmoz.org/Computers/Software/Internet/Servers/Address_Management/Dynamic_DNS_Services/        #
27
+# If anyone has time they could update this file to be compatible with a bunch of them                    #
28
+#                                                                                                         #
29
+###########################################################################################################

+ 0
- 25
net/ddns-scripts/files/usr/lib/ddns/url_escape.sed View File

@@ -1,25 +0,0 @@
1
-# sed url escaping
2
-s:%:%25:g
3
-s: :%20:g
4
-s:<:%3C:g
5
-s:>:%3E:g
6
-s:#:%23:g
7
-s:{:%7B:g
8
-s:}:%7D:g
9
-s:|:%7C:g
10
-s:\\:%5C:g
11
-s:\^:%5E:g
12
-s:~:%7E:g
13
-s:\[:%5B:g
14
-s:\]:%5D:g
15
-s:`:%60:g
16
-s:;:%3B:g
17
-s:/:%2F:g
18
-s:?:%3F:g
19
-s^:^%3A^g
20
-s:@:%40:g
21
-s:=:%3D:g
22
-s:&:%26:g
23
-s:\$:%24:g
24
-s:\!:%21:g
25
-s:\*:%2A:g