From b4211686d96911b070df954ea62b317300e55049 Mon Sep 17 00:00:00 2001 From: NYNEX Date: Sun, 21 Jul 2019 02:21:11 -0400 Subject: [PATCH] Add bind, libxml2 and ddns-scripts back to package feed. --- libs/libxml2/Makefile | 142 ++ net/bind/Config.in | 37 + net/bind/Makefile | 252 +++ net/bind/files/bind/db.0 | 12 + net/bind/files/bind/db.127 | 13 + net/bind/files/bind/db.255 | 12 + net/bind/files/bind/db.local | 13 + net/bind/files/bind/db.root | 90 ++ net/bind/files/bind/named.conf.example | 45 + net/bind/files/named.init | 35 + net/bind/patches/001-no-tests.patch | 26 + net/bind/patches/002-autoconf-ar-fix.patch | 31 + net/ddns-scripts/Makefile | 446 ++++++ net/ddns-scripts/files/ddns.config | 32 + net/ddns-scripts/files/ddns.defaults | 201 +++ net/ddns-scripts/files/ddns.hotplug | 11 + net/ddns-scripts/files/ddns.init | 27 + .../files/dynamic_dns_functions.sh | 1373 +++++++++++++++++ .../files/dynamic_dns_lucihelper.sh | 172 +++ net/ddns-scripts/files/dynamic_dns_updater.sh | 420 +++++ net/ddns-scripts/files/services | 180 +++ net/ddns-scripts/files/services_ipv6 | 103 ++ .../files/update_cloudflare_com_v4.sh | 193 +++ .../files/update_freedns_42_pl.sh | 17 + .../files/update_godaddy_com_v1.sh | 172 +++ net/ddns-scripts/files/update_no-ip_com.sh | 52 + net/ddns-scripts/files/update_nsupdate.sh | 48 + net/ddns-scripts/files/update_route53_v1.sh | 97 ++ net/ddns-scripts/samples/ddns.config_sample | 314 ++++ net/ddns-scripts/samples/getlocalip_sample.sh | 35 + net/ddns-scripts/samples/update_sample.sh | 41 + 31 files changed, 4642 insertions(+) create mode 100644 libs/libxml2/Makefile create mode 100644 net/bind/Config.in create mode 100644 net/bind/Makefile create mode 100644 net/bind/files/bind/db.0 create mode 100644 net/bind/files/bind/db.127 create mode 100644 net/bind/files/bind/db.255 create mode 100644 net/bind/files/bind/db.local create mode 100644 net/bind/files/bind/db.root create mode 100644 net/bind/files/bind/named.conf.example create mode 100644 net/bind/files/named.init create mode 100644 net/bind/patches/001-no-tests.patch create mode 100644 net/bind/patches/002-autoconf-ar-fix.patch create mode 100755 net/ddns-scripts/Makefile create mode 100644 net/ddns-scripts/files/ddns.config create mode 100755 net/ddns-scripts/files/ddns.defaults create mode 100755 net/ddns-scripts/files/ddns.hotplug create mode 100755 net/ddns-scripts/files/ddns.init create mode 100755 net/ddns-scripts/files/dynamic_dns_functions.sh create mode 100755 net/ddns-scripts/files/dynamic_dns_lucihelper.sh create mode 100755 net/ddns-scripts/files/dynamic_dns_updater.sh create mode 100644 net/ddns-scripts/files/services create mode 100644 net/ddns-scripts/files/services_ipv6 create mode 100755 net/ddns-scripts/files/update_cloudflare_com_v4.sh create mode 100755 net/ddns-scripts/files/update_freedns_42_pl.sh create mode 100755 net/ddns-scripts/files/update_godaddy_com_v1.sh create mode 100755 net/ddns-scripts/files/update_no-ip_com.sh create mode 100755 net/ddns-scripts/files/update_nsupdate.sh create mode 100644 net/ddns-scripts/files/update_route53_v1.sh create mode 100644 net/ddns-scripts/samples/ddns.config_sample create mode 100755 net/ddns-scripts/samples/getlocalip_sample.sh create mode 100644 net/ddns-scripts/samples/update_sample.sh diff --git a/libs/libxml2/Makefile b/libs/libxml2/Makefile new file mode 100644 index 0000000..445044e --- /dev/null +++ b/libs/libxml2/Makefile @@ -0,0 +1,142 @@ +# +# Copyright (C) 2006-2016 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=libxml2 +PKG_VERSION:=2.9.9 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://xmlsoft.org/sources/ +PKG_HASH:=94fb70890143e3c6549f265cee93ec064c80a84c42ad0f23e85ee1fd6540a871 + +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=COPYING +PKG_CPE_ID:=cpe:/a:xmlsoft:libxml2 + +PKG_MAINTAINER:=Michael Heimpold + +PKG_FIXUP:=autoreconf +PKG_INSTALL:=1 +PKG_BUILD_PARALLEL:=0 + +include $(INCLUDE_DIR)/host-build.mk +include $(INCLUDE_DIR)/package.mk + +define Package/libxml2 + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Gnome XML library + URL:=http://xmlsoft.org/ + DEPENDS:=+libpthread +zlib +endef + +define Package/libxml2/description + A library for manipulating XML and HTML resources. +endef + +TARGET_CFLAGS += $(FPIC) + +CONFIGURE_ARGS += \ + --enable-shared \ + --enable-static \ + --with-c14n \ + --without-catalog \ + --with-debug \ + --without-docbook \ + --with-html \ + --without-ftp \ + --without-http \ + --without-iconv \ + --without-iso8859x \ + --without-legacy \ + --with-output \ + --without-pattern \ + --without-push \ + --without-python \ + --with-reader \ + --without-readline \ + --without-regexps \ + --with-sax1 \ + --with-schemas \ + --with-threads \ + --with-tree \ + --with-valid \ + --with-writer \ + --with-xinclude \ + --with-xpath \ + --with-xptr \ + --with-zlib=$(STAGING_DIR)/usr \ + --without-lzma + +HOST_CONFIGURE_ARGS += \ + --enable-shared \ + --enable-static \ + --with-c14n \ + --without-catalog \ + --with-debug \ + --without-docbook \ + --with-html \ + --without-ftp \ + --without-http \ + --without-iconv \ + --without-iso8859x \ + --without-legacy \ + --with-output \ + --without-pattern \ + --without-push \ + --without-python \ + --with-reader \ + --without-readline \ + --without-regexps \ + --with-sax1 \ + --with-schemas \ + --with-threads \ + --with-tree \ + --with-valid \ + --with-writer \ + --with-xinclude \ + --with-xpath \ + --with-xptr \ + --with-zlib \ + --without-lzma + +define Build/InstallDev + $(INSTALL_DIR) $(2)/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/xml2-config $(2)/bin/ + $(SED) 's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' $(2)/bin/xml2-config + + $(INSTALL_DIR) $(1)/usr/include + $(CP) $(PKG_INSTALL_DIR)/usr/include/libxml2 $(1)/usr/include/ + + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libxml2.{la,a,so*} $(1)/usr/lib/ + + $(INSTALL_DIR) $(1)/usr/lib/cmake/libxml2 + $(CP) $(PKG_INSTALL_DIR)/usr/lib/cmake/libxml2/libxml2-config.cmake \ + $(1)/usr/lib/cmake/libxml2 + + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libxml-2.0.pc $(1)/usr/lib/pkgconfig/ + + $(INSTALL_DIR) $(2)/share/aclocal/ + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/aclocal/* $(2)/share/aclocal +endef + +define Package/libxml2/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libxml2.so* $(1)/usr/lib/ +endef + +define Host/Install + $(SED) 's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' $(HOST_BUILD_DIR)/xml2-config + $(call Host/Install/Default) +endef + +$(eval $(call HostBuild)) +$(eval $(call BuildPackage,libxml2)) diff --git a/net/bind/Config.in b/net/bind/Config.in new file mode 100644 index 0000000..ed37346 --- /dev/null +++ b/net/bind/Config.in @@ -0,0 +1,37 @@ +if PACKAGE_bind-server + +config BIND_ENABLE_FILTER_AAAA + bool + default y + prompt "Enable filtering of AAAA records returned to the client" + help + BIND 9 has an option to filter AAAA (IPv6 address) records + returned to the client based on the transport used for the + query, and other filtering conditions. This filtering does + not affect the recursive queries made by the server (if + any) as a result of the client request. + + Additional details are available at + https://kb.isc.org/article/AA-00576/0/Filter-AAAA-option-in-BIND-9-.html + +config BIND_LIBJSON + bool + default n + prompt "Include libjson support in bind-server" + help + BIND 9 supports reporting statistics about usage. libjson + is required to report server statistics in JSON format. + Building with libjson support will require the libjson-c + package to be installed as well. + +config BIND_LIBXML2 + bool + default n + prompt "Include libxml2 support in bind-server" + help + BIND 9 supports reporting statistics about usage. + libxml2 is required to report server statistics in XML + format. Building with libjson support will require the + libxml2 package to be installed as well. + +endif diff --git a/net/bind/Makefile b/net/bind/Makefile new file mode 100644 index 0000000..1005eae --- /dev/null +++ b/net/bind/Makefile @@ -0,0 +1,252 @@ +# +# Copyright (C) 2006-2012 OpenWrt.org +# 2014-2017 Noah Meyerhans +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=bind +PKG_VERSION:=9.11.2-P1 +PKG_RELEASE:=1 +USERID:=bind=57:bind=57 + +PKG_MAINTAINER:=Noah Meyerhans +PKG_LICENSE := BSD-3-Clause + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:= \ + http://www.mirrorservice.org/sites/ftp.isc.org/isc/bind9/$(PKG_VERSION) \ + http://ftp.isc.org/isc/bind9/$(PKG_VERSION) +PKG_HASH:=cec31548832fca3f85d95178d4019b7d702039e8595d4c93914feba337df1212 + +PKG_FIXUP:=autoreconf +PKG_REMOVE_FILES:=aclocal.m4 libtool.m4 + +PKG_INSTALL:=1 +PKG_USE_MIPS16:=0 + +PKG_CONFIG_DEPENDS := \ + CONFIG_BIND_ENABLE_FILTER_AAAA \ + CONFIG_BIND_LIBJSON \ + CONFIG_BIND_LIBXML2 + +ifdef CONFIG_BIND_LIBXML2 + PKG_BUILD_DEPENDS += libxml2 +endif +ifdef CONFIG_BIND_LIBJSON + PKG_BUILD_DEPENDS += libjson-c +endif + +include $(INCLUDE_DIR)/package.mk + +define Package/bind/Default + SECTION:=net + CATEGORY:=Network + DEPENDS:=+bind-libs +@OPENSSL_WITH_EC + TITLE:=bind + URL:=https://www.isc.org/software/bind + SUBMENU:=IP Addresses and Names +endef + +define Package/bind-libs + SECTION:=libs + CATEGORY:=Libraries + DEPENDS:=+libopenssl +zlib + TITLE:=bind shared libraries + URL:=https://www.isc.org/software/bind +ifdef CONFIG_BIND_LIBJSON + DEPENDS+= +libjson-c +endif +ifdef CONFIG_BIND_LIBXML2 + DEPENDS+= +libxml2 +endif +endef + +define Package/bind-server + $(call Package/bind/Default) + TITLE+= DNS server + DEPENDS+= +@OPENSSL_WITH_DEPRECATED +endef + +define Package/bind-server/config + source "$(SOURCE)/Config.in" +endef + +define Package/bind-client + $(call Package/bind/Default) + TITLE+= dynamic DNS client +endef + +define Package/bind-tools + $(call Package/bind/Default) + TITLE+= administration tools (all) +endef + +define Package/bind-rndc + $(call Package/bind/Default) + TITLE+= administration tools (rndc and rndc-confgen only) +endef + +define Package/bind-check + $(call Package/bind/Default) + TITLE+= administration tools (named-checkconf and named-checkzone only) +endef + +define Package/bind-dnssec + $(call Package/bind/Default) + TITLE+= administration tools (dnssec-keygen, dnssec-settime and dnssec-signzone only) +endef + +define Package/bind-host + $(call Package/bind/Default) + TITLE+= simple DNS client +endef + +define Package/bind-dig + $(call Package/bind/Default) + TITLE+= DNS excavation tool +endef + +export BUILD_CC="$(TARGET_CC)" + +CONFIGURE_ARGS += \ + --enable-shared \ + --enable-static \ + --with-randomdev="/dev/urandom" \ + --disable-threads \ + --disable-linux-caps \ + --with-openssl="$(STAGING_DIR)/usr" \ + --with-libtool \ + --without-lmdb \ + --enable-epoll=yes \ + --with-gost=no \ + --with-gssapi=no \ + --with-ecdsa=$(if $(CONFIG_OPENSSL_WITH_EC),yes,no) \ + --with-readline=no \ + --sysconfdir=/etc/bind + +ifdef CONFIG_BIND_ENABLE_FILTER_AAAA + CONFIGURE_ARGS += \ + --enable-filter-aaaa +endif + +ifdef CONFIG_BIND_LIBJSON + CONFIGURE_ARGS += \ + --with-libjson="$(STAGING_DIR)/usr" +else + CONFIGURE_ARGS += \ + --with-libjson=no +endif + +ifdef CONFIG_BIND_LIBXML2 + CONFIGURE_ARGS += \ + --with-libxml2="$(STAGING_DIR)/usr" +else + CONFIGURE_ARGS += \ + --with-libxml2=no +endif + +CONFIGURE_VARS += \ + BUILD_CC="$(TARGET_CC)" \ + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR)/lib/dns \ + BUILD_CC="$(HOSTCC)" \ + CC="$(HOSTCC)" \ + CFLAGS="-O2" \ + LIBS="" \ + gen + $(call Build/Compile/Default) +endef + +define Package/bind-libs/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib +endef + +define Package/bind-server/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/named $(1)/usr/sbin/ + $(INSTALL_DIR) $(1)/etc/bind + $(CP) \ + ./files/bind/db.0 \ + ./files/bind/db.127 \ + ./files/bind/db.255 \ + ./files/bind/db.local \ + ./files/bind/db.root \ + $(1)/etc/bind/ + $(CP) ./files/bind/named.conf.example $(1)/etc/bind/named.conf + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/named.init $(1)/etc/init.d/named + find $(1)/etc/bind/ -name ".svn" | xargs rm -rf +endef + +define Package/bind-server/conffiles +/etc/bind/db.0 +/etc/bind/db.127 +/etc/bind/db.255 +/etc/bind/db.local +/etc/bind/db.root +/etc/bind/named.conf +endef + +define Package/bind-client/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/nsupdate $(1)/usr/bin/ +endef + +define Package/bind-tools/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/dig $(1)/usr/bin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/host $(1)/usr/bin/ + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/dnssec-keygen $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/dnssec-settime $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/dnssec-signzone $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/named-checkconf $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/named-checkzone $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/rndc $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/rndc-confgen $(1)/usr/sbin/ +endef + +define Package/bind-rndc/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/rndc $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/rndc-confgen $(1)/usr/sbin/ +endef + +define Package/bind-check/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/named-checkconf $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/named-checkzone $(1)/usr/sbin/ +endef + +define Package/bind-dnssec/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/dnssec-keygen $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/dnssec-settime $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/dnssec-signzone $(1)/usr/sbin/ +endef + +define Package/bind-host/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/host $(1)/usr/bin/ +endef + +define Package/bind-dig/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/dig $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,bind-libs)) +$(eval $(call BuildPackage,bind-server)) +$(eval $(call BuildPackage,bind-client)) +$(eval $(call BuildPackage,bind-tools)) +$(eval $(call BuildPackage,bind-rndc)) +$(eval $(call BuildPackage,bind-check)) +$(eval $(call BuildPackage,bind-dnssec)) +$(eval $(call BuildPackage,bind-host)) +$(eval $(call BuildPackage,bind-dig)) diff --git a/net/bind/files/bind/db.0 b/net/bind/files/bind/db.0 new file mode 100644 index 0000000..e3aabdb --- /dev/null +++ b/net/bind/files/bind/db.0 @@ -0,0 +1,12 @@ +; +; BIND reverse data file for broadcast zone +; +$TTL 604800 +@ IN SOA localhost. root.localhost. ( + 1 ; Serial + 604800 ; Refresh + 86400 ; Retry + 2419200 ; Expire + 604800 ) ; Negative Cache TTL +; +@ IN NS localhost. diff --git a/net/bind/files/bind/db.127 b/net/bind/files/bind/db.127 new file mode 100644 index 0000000..cd05bef --- /dev/null +++ b/net/bind/files/bind/db.127 @@ -0,0 +1,13 @@ +; +; BIND reverse data file for local loopback interface +; +$TTL 604800 +@ IN SOA localhost. root.localhost. ( + 1 ; Serial + 604800 ; Refresh + 86400 ; Retry + 2419200 ; Expire + 604800 ) ; Negative Cache TTL +; +@ IN NS localhost. +1.0.0 IN PTR localhost. diff --git a/net/bind/files/bind/db.255 b/net/bind/files/bind/db.255 new file mode 100644 index 0000000..e3aabdb --- /dev/null +++ b/net/bind/files/bind/db.255 @@ -0,0 +1,12 @@ +; +; BIND reverse data file for broadcast zone +; +$TTL 604800 +@ IN SOA localhost. root.localhost. ( + 1 ; Serial + 604800 ; Refresh + 86400 ; Retry + 2419200 ; Expire + 604800 ) ; Negative Cache TTL +; +@ IN NS localhost. diff --git a/net/bind/files/bind/db.local b/net/bind/files/bind/db.local new file mode 100644 index 0000000..66b4892 --- /dev/null +++ b/net/bind/files/bind/db.local @@ -0,0 +1,13 @@ +; +; BIND data file for local loopback interface +; +$TTL 604800 +@ IN SOA localhost. root.localhost. ( + 1 ; Serial + 604800 ; Refresh + 86400 ; Retry + 2419200 ; Expire + 604800 ) ; Negative Cache TTL +; +@ IN NS localhost. +@ IN A 127.0.0.1 diff --git a/net/bind/files/bind/db.root b/net/bind/files/bind/db.root new file mode 100644 index 0000000..f0b79d2 --- /dev/null +++ b/net/bind/files/bind/db.root @@ -0,0 +1,90 @@ +; This file holds the information on root name servers needed to +; initialize cache of Internet domain name servers +; (e.g. reference this file in the "cache . " +; configuration file of BIND domain name servers). +; +; This file is made available by InterNIC +; under anonymous FTP as +; file /domain/named.cache +; on server FTP.INTERNIC.NET +; -OR- RS.INTERNIC.NET +; +; last update: February 17, 2016 +; related version of root zone: 2016021701 +; +; formerly NS.INTERNIC.NET +; +. 3600000 NS A.ROOT-SERVERS.NET. +A.ROOT-SERVERS.NET. 3600000 A 198.41.0.4 +A.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:ba3e::2:30 +; +; FORMERLY NS1.ISI.EDU +; +. 3600000 NS B.ROOT-SERVERS.NET. +B.ROOT-SERVERS.NET. 3600000 A 192.228.79.201 +B.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:84::b +; +; FORMERLY C.PSI.NET +; +. 3600000 NS C.ROOT-SERVERS.NET. +C.ROOT-SERVERS.NET. 3600000 A 192.33.4.12 +C.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2::c +; +; FORMERLY TERP.UMD.EDU +; +. 3600000 NS D.ROOT-SERVERS.NET. +D.ROOT-SERVERS.NET. 3600000 A 199.7.91.13 +D.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2d::d +; +; FORMERLY NS.NASA.GOV +; +. 3600000 NS E.ROOT-SERVERS.NET. +E.ROOT-SERVERS.NET. 3600000 A 192.203.230.10 +; +; FORMERLY NS.ISC.ORG +; +. 3600000 NS F.ROOT-SERVERS.NET. +F.ROOT-SERVERS.NET. 3600000 A 192.5.5.241 +F.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2f::f +; +; FORMERLY NS.NIC.DDN.MIL +; +. 3600000 NS G.ROOT-SERVERS.NET. +G.ROOT-SERVERS.NET. 3600000 A 192.112.36.4 +; +; FORMERLY AOS.ARL.ARMY.MIL +; +. 3600000 NS H.ROOT-SERVERS.NET. +H.ROOT-SERVERS.NET. 3600000 A 198.97.190.53 +H.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:1::53 +; +; FORMERLY NIC.NORDU.NET +; +. 3600000 NS I.ROOT-SERVERS.NET. +I.ROOT-SERVERS.NET. 3600000 A 192.36.148.17 +I.ROOT-SERVERS.NET. 3600000 AAAA 2001:7fe::53 +; +; OPERATED BY VERISIGN, INC. +; +. 3600000 NS J.ROOT-SERVERS.NET. +J.ROOT-SERVERS.NET. 3600000 A 192.58.128.30 +J.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:c27::2:30 +; +; OPERATED BY RIPE NCC +; +. 3600000 NS K.ROOT-SERVERS.NET. +K.ROOT-SERVERS.NET. 3600000 A 193.0.14.129 +K.ROOT-SERVERS.NET. 3600000 AAAA 2001:7fd::1 +; +; OPERATED BY ICANN +; +. 3600000 NS L.ROOT-SERVERS.NET. +L.ROOT-SERVERS.NET. 3600000 A 199.7.83.42 +L.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:3::42 +; +; OPERATED BY WIDE +; +. 3600000 NS M.ROOT-SERVERS.NET. +M.ROOT-SERVERS.NET. 3600000 A 202.12.27.33 +M.ROOT-SERVERS.NET. 3600000 AAAA 2001:dc3::35 +; End of file diff --git a/net/bind/files/bind/named.conf.example b/net/bind/files/bind/named.conf.example new file mode 100644 index 0000000..1624549 --- /dev/null +++ b/net/bind/files/bind/named.conf.example @@ -0,0 +1,45 @@ +// This is the primary configuration file for the BIND DNS server named. + +options { + directory "/tmp"; + + // If your ISP provided one or more IP addresses for stable + // nameservers, you probably want to use them as forwarders. + // Uncomment the following block, and insert the addresses replacing + // the all-0's placeholder. + + // forwarders { + // 0.0.0.0; + // }; + + auth-nxdomain no; # conform to RFC1035 +}; + +// prime the server with knowledge of the root servers +zone "." { + type hint; + file "/etc/bind/db.root"; +}; + +// be authoritative for the localhost forward and reverse zones, and for +// broadcast zones as per RFC 1912 + +zone "localhost" { + type master; + file "/etc/bind/db.local"; +}; + +zone "127.in-addr.arpa" { + type master; + file "/etc/bind/db.127"; +}; + +zone "0.in-addr.arpa" { + type master; + file "/etc/bind/db.0"; +}; + +zone "255.in-addr.arpa" { + type master; + file "/etc/bind/db.255"; +}; diff --git a/net/bind/files/named.init b/net/bind/files/named.init new file mode 100644 index 0000000..b7876d9 --- /dev/null +++ b/net/bind/files/named.init @@ -0,0 +1,35 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2014 Noah Meyerhans +# Licensed under the terms of the GNU General Public License version 2 +# or (at your discretion) any later later version + +USE_PROCD=1 + +START=50 + +config_file=/etc/bind/named.conf +pid_file=/var/run/named/named.pid + +logdir=/var/log/named/ +cachedir=/var/cache/bind +libdir=/var/lib/bind + +fix_perms() { + for dir in $libdir $logdir $cachedir; do + test -e "$dir" || { + mkdir -p "$dir" + chgrp bind "$dir" + chmod g+w "$dir" + } + done +} + +start_service() { + user_exists bind 57 || user_add bind 57 + group_exists bind 57 || group_add bind 57 + fix_perms + procd_open_instance + procd_set_param command /usr/sbin/named -u bind -f -c $config_file + procd_set_param respawn + procd_close_instance +} diff --git a/net/bind/patches/001-no-tests.patch b/net/bind/patches/001-no-tests.patch new file mode 100644 index 0000000..2d0c152 --- /dev/null +++ b/net/bind/patches/001-no-tests.patch @@ -0,0 +1,26 @@ +Index: bind-9.10.4-P3/bin/Makefile.in +=================================================================== +--- bind-9.10.4-P3.orig/bin/Makefile.in ++++ bind-9.10.4-P3/bin/Makefile.in +@@ -10,7 +10,7 @@ srcdir = @srcdir@ + VPATH = @srcdir@ + top_srcdir = @top_srcdir@ + +-SUBDIRS = named rndc dig delv dnssec tools tests nsupdate \ ++SUBDIRS = named rndc dig delv dnssec tools nsupdate \ + check confgen @NZD_TOOLS@ @PYTHON_TOOLS@ @PKCS11_TOOLS@ + TARGETS = + +Index: bind-9.10.4-P3/lib/Makefile.in +=================================================================== +--- bind-9.10.4-P3.orig/lib/Makefile.in ++++ bind-9.10.4-P3/lib/Makefile.in +@@ -14,7 +14,7 @@ top_srcdir = @top_srcdir@ + # Attempt to disable parallel processing. + .NOTPARALLEL: + .NO_PARALLEL: +-SUBDIRS = isc isccc dns isccfg bind9 lwres irs tests samples ++SUBDIRS = isc isccc dns isccfg bind9 lwres irs samples + TARGETS = + + @BIND9_MAKE_RULES@ diff --git a/net/bind/patches/002-autoconf-ar-fix.patch b/net/bind/patches/002-autoconf-ar-fix.patch new file mode 100644 index 0000000..878554f --- /dev/null +++ b/net/bind/patches/002-autoconf-ar-fix.patch @@ -0,0 +1,31 @@ +Index: bind-9.10.4-P3/configure.in +=================================================================== +--- bind-9.10.4-P3.orig/configure.in ++++ bind-9.10.4-P3/configure.in +@@ -157,26 +157,11 @@ esac + # + AC_CONFIG_FILES([make/rules make/includes]) + +-AC_PATH_PROG(AR, ar) +-ARFLAGS="cruv" +-AC_SUBST(AR) +-AC_SUBST(ARFLAGS) +- + # The POSIX ln(1) program. Non-POSIX systems may substitute + # "copy" or something. + LN=ln + AC_SUBST(LN) + +-case "$AR" in +- "") +- AC_MSG_ERROR([ +-ar program not found. Please fix your PATH to include the directory in +-which ar resides, or set AR in the environment with the full path to ar. +-]) +- +- ;; +-esac +- + # + # Etags. + # diff --git a/net/ddns-scripts/Makefile b/net/ddns-scripts/Makefile new file mode 100755 index 0000000..89e7e96 --- /dev/null +++ b/net/ddns-scripts/Makefile @@ -0,0 +1,446 @@ +# +# Copyright (C) 2008-2018 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=ddns-scripts +# Version == major.minor.patch +# increase on new functionality (minor) or patches (patch) +PKG_VERSION:=2.7.8 +# Release == build +# increase on changes of services files or tld_names.dat +PKG_RELEASE:=1 + +PKG_LICENSE:=GPL-2.0 +PKG_MAINTAINER:= + +include $(INCLUDE_DIR)/package.mk + +# no default dependencies +PKG_DEFAULT_DEPENDS= + +define Package/ddns-scripts/Default + SECTION:=net + CATEGORY:=Network + SUBMENU:=IP Addresses and Names + PKGARCH:=all +endef + +###### ************************************************************************* +define Package/ddns-scripts + $(call Package/ddns-scripts/Default) + TITLE:=Dynamic DNS Client scripts (with IPv6 support) +endef +# shown in LuCI package description +define Package/ddns-scripts/description + Dynamic DNS Client scripts (with IPv6 support) - Info: http://wiki.openwrt.org/doc/howto/ddns.client +endef +# shown in menuconfig +define Package/ddns-scripts/config + help + A highly configurable set of scripts for doing dynamic dns updates. + - IPv6 support + - DNS server support + - Glue Record support (require BIND host or KNOT host) + - DNS requests via TCP + - Proxy server support + - log file support + - support to run once + Version: $(PKG_VERSION)-$(PKG_RELEASE) + Info : http://wiki.openwrt.org/doc/howto/ddns.client +endef + +###### ************************************************************************* +define Package/ddns-scripts_cloudflare.com-v4 + $(call Package/ddns-scripts/Default) + TITLE:=CloudFlare.com API v4 (requires cURL) + DEPENDS:=ddns-scripts +curl +endef +define Package/ddns-scripts_cloudflare.com-v4/description + Dynamic DNS Client scripts extension for CloudFlare.com API-v4 (require/install cURL) +endef + +###### ************************************************************************* +define Package/ddns-scripts_freedns_42_pl + $(call Package/ddns-scripts/Default) + TITLE:=DDNS extension for FreeDNS.42.pl (requires cURL) + DEPENDS:=ddns-scripts +curl +endef +define Package/ddns-scripts_freedns_42_pl/description + Dynamic DNS Client scripts extension for freedns.42.pl +endef + +###### ************************************************************************* +define Package/ddns-scripts_godaddy.com-v1 + $(call Package/ddns-scripts/Default) + TITLE:=GoDaddy.com (require cURL) + DEPENDS:=ddns-scripts +curl +endef +define Package/ddns-scripts_godaddy.com-v1/description + Dynamic DNS Client scripts extension for GoDaddy.com (require/install cURL) +endef + +###### ************************************************************************* +define Package/ddns-scripts_no-ip_com + $(call Package/ddns-scripts/Default) + TITLE:=DDNS extension for No-IP.com + DEPENDS:=ddns-scripts +endef +define Package/ddns-scripts_no-ip_com/description + Dynamic DNS Client scripts extension for No-IP.com +endef + +###### ************************************************************************* +define Package/ddns-scripts_nsupdate + $(call Package/ddns-scripts/Default) + TITLE:=DDNS extension using Bind nsupdate + DEPENDS:=ddns-scripts +bind-client +endef +define Package/ddns-scripts_nsupdate/description + Dynamic DNS Client scripts extension for direct updates using Bind nsupdate +endef +define Package/ddns-scripts_nsupdate/config + help + The script directly updates a PowerDNS (or maybe bind server) via nsupdate + from bind-client package. It requires + "option dns_server" to be set to the server to be used by nsupdate. + "option username" should be set to the key name and + "option password" to the base64 encoded shared secret. + +endef + +###### ************************************************************************* +define Package/ddns-scripts_route53-v1 + $(call Package/ddns-scripts/Default) + TITLE:=Amazon AWS Route 53 API v1 + DEPENDS:=ddns-scripts +curl +openssl-util +endef +define Package/ddns-scripts_route53-v1/description + Dynamic DNS Client scripts extension for Amazon AWS Route53. Note: You + must also install ca-certificate or ca-bundle. + It requires: + "option username" to be a valid AWS access key id + "option password" to be the matching AWS secret key id + "option domain" to contain the hosted zone ID +endef + +###### ************************************************************************* +define Build/Configure +endef +define Build/Compile + $(CP) ./files $(PKG_BUILD_DIR) + # ensure that VERSION inside dynamic_dns_functions.sh reflect PKG_VERSION of Makefile + $(SED) '/^VERSION=*/s/.*/VERSION="$(PKG_VERSION)-$(PKG_RELEASE)"/' $(PKG_BUILD_DIR)/files/dynamic_dns_functions.sh + # remove comments, white spaces and empty lines + for FILE in `find $(PKG_BUILD_DIR)/files -type f`; do \ + $(SED) 's/^[[:space:]]*//' \ + -e '/^#[[:space:]]\|^#$$$$/d' \ + -e 's/[[:space:]]#[[:space:]].*$$$$//' \ + -e 's/[[:space:]]*$$$$//' \ + -e '/^\/\/[[:space:]]/d' \ + -e '/^[[:space:]]*$$$$/d' $$$$FILE; \ + done +endef + +define Package/ddns-scripts/conffiles +/etc/config/ddns +endef + +###### ************************************************************************* +define Package/ddns-scripts/preinst + #!/bin/sh + # if NOT run buildroot then stop service + [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 + exit 0 # suppress errors +endef +define Package/ddns-scripts/install + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.defaults $(1)/etc/uci-defaults/ddns + $(INSTALL_DIR) $(1)/etc/hotplug.d/iface + $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.hotplug $(1)/etc/hotplug.d/iface/95-ddns + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.init $(1)/etc/init.d/ddns + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) $(PKG_BUILD_DIR)/files/ddns.config $(1)/etc/config/ddns + + $(INSTALL_DIR) $(1)/etc/ddns + $(INSTALL_DATA) $(PKG_BUILD_DIR)/files/services* $(1)/etc/ddns + + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/dynamic_dns_*.sh $(1)/usr/lib/ddns +endef +define Package/ddns-scripts/postinst + #!/bin/sh + # if NOT run buildroot and PKG_UPGRADE then (re)start service if enabled + [ -z "$${IPKG_INSTROOT}" -a "$${PKG_UPGRADE}" = "1" ] && { + [ -x /etc/uci-defaults/ddns ] && \ + /etc/uci-defaults/ddns && \ + rm -f /etc/uci-defaults/ddns >/dev/null 2>&1 + /etc/init.d/ddns enabled && \ + /etc/init.d/ddns start >/dev/null 2>&1 + } + exit 0 # suppress errors +endef +define Package/ddns-scripts/prerm + #!/bin/sh + # if run within buildroot exit + [ -n "$${IPKG_INSTROOT}" ] && exit 0 + # stop running scripts + /etc/init.d/ddns stop + /etc/init.d/ddns disable + # clear LuCI indexcache + rm -f /tmp/luci-indexcache >/dev/null 2>&1 + exit 0 # suppress errors +endef + +###### ************************************************************************* +define Package/ddns-scripts_cloudflare.com-v4/preinst + #!/bin/sh + # if NOT run buildroot then stop service + [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 + exit 0 # suppress errors +endef +define Package/ddns-scripts_cloudflare.com-v4/install + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.defaults $(1)/etc/uci-defaults/ddns_cloudflare.com-v4 + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/update_cloudflare_com_v4.sh $(1)/usr/lib/ddns +endef +define Package/ddns-scripts_cloudflare.com-v4/postinst + #!/bin/sh + # remove old services file entries + /bin/sed -i '/cloudflare\.com-v4/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1 + /bin/sed -i '/cloudflare\.com-v4/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1 + # and create new + printf "%s\\t%s\\n" '"cloudflare.com-v4"' '"update_cloudflare_com_v4.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services + printf "%s\\t%s\\n" '"cloudflare.com-v4"' '"update_cloudflare_com_v4.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services_ipv6 + # on real system restart service if enabled + [ -z "$${IPKG_INSTROOT}" ] && { + [ -x /etc/uci-defaults/ddns_cloudflare.com-v4 ] && \ + /etc/uci-defaults/ddns_cloudflare.com-v4 && \ + rm -f /etc/uci-defaults/ddns_cloudflare.com-v4 >/dev/null 2>&1 + /etc/init.d/ddns enabled && \ + /etc/init.d/ddns start >/dev/null 2>&1 + } + exit 0 # suppress errors +endef +define Package/ddns-scripts_cloudflare.com-v4/prerm + #!/bin/sh + # if NOT run buildroot then stop service + [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 + # remove services file entries + /bin/sed -i '/cloudflare\.com-v4/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1 + /bin/sed -i '/cloudflare\.com-v4/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1 + exit 0 # suppress errors +endef + +###### ************************************************************************* +define Package/ddns-scripts_freedns_42_pl/preinst + #!/bin/sh + # if NOT run buildroot then stop service + [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 + exit 0 # suppress errors +endef +define Package/ddns-scripts_freedns_42_pl/install + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.defaults $(1)/etc/uci-defaults/ddns_freedns_42_pl + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/update_freedns_42_pl.sh $(1)/usr/lib/ddns +endef +define Package/ddns-scripts_freedns_42_pl/postinst + #!/bin/sh + # remove old services file entries + /bin/sed -i '/freedns\.42\.pl/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1 + # and create new + printf "%s\\t%s\\n" '"freedns.42.pl"' '"update_freedns_42_pl.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services + # on real system restart service if enabled + [ -z "$${IPKG_INSTROOT}" ] && { + [ -x /etc/uci-defaults/ddns_freedns_42_pl ] && \ + /etc/uci-defaults/ddns_freedns_42_pl && \ + rm -f /etc/uci-defaults/ddns_freedns_42_pl >/dev/null 2>&1 + /etc/init.d/ddns enabled && \ + /etc/init.d/ddns start >/dev/null 2>&1 + } + exit 0 # suppress errors +endef +define Package/ddns-scripts_freedns_42_pl/prerm + #!/bin/sh + # if NOT run buildroot then stop service + [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 + # remove services file entries + /bin/sed -i '/freedns\.42\.pl/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1 + exit 0 # suppress errors +endef + +###### ************************************************************************* +define Package/ddns-scripts_godaddy.com-v1/preinst + #!/bin/sh + # if NOT run buildroot then stop service + [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 + exit 0 # suppress errors +endef +define Package/ddns-scripts_godaddy.com-v1/install + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.defaults $(1)/etc/uci-defaults/ddns_godaddy.com-v1 + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/update_godaddy_com_v1.sh $(1)/usr/lib/ddns +endef +define Package/ddns-scripts_godaddy.com-v1/postinst + #!/bin/sh + # remove old services file entries + /bin/sed -i '/godaddy\.com-v1/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1 + /bin/sed -i '/godaddy\.com-v1/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1 + # and create new + printf "%s\\t%s\\n" '"godaddy.com-v1"' '"update_godaddy_com_v1.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services + printf "%s\\t%s\\n" '"godaddy.com-v1"' '"update_godaddy_com_v1.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services_ipv6 + # on real system restart service if enabled + [ -z "$${IPKG_INSTROOT}" ] && { + [ -x /etc/uci-defaults/ddns_godaddy.com-v1 ] && \ + /etc/uci-defaults/ddns_godaddy.com-v1 && \ + rm -f /etc/uci-defaults/ddns_godaddy.com-v1 >/dev/null 2>&1 + /etc/init.d/ddns enabled \ + && /etc/init.d/ddns start >/dev/null 2>&1 + } + exit 0 # suppress errors +endef +define Package/ddns-scripts_godaddy.com-v1/prerm + #!/bin/sh + # if NOT run buildroot then stop service + [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 + # remove services file entries + /bin/sed -i '/godaddy\.com-v1/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1 + /bin/sed -i '/godaddy\.com-v1/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1 + exit 0 # suppress errors +endef + +###### ************************************************************************* +define Package/ddns-scripts_no-ip_com/preinst + #!/bin/sh + # if NOT run buildroot then stop service + [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 + exit 0 # suppress errors +endef +define Package/ddns-scripts_no-ip_com/install + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.defaults $(1)/etc/uci-defaults/ddns_no-ip_com + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/update_no-ip_com.sh $(1)/usr/lib/ddns +endef +define Package/ddns-scripts_no-ip_com/postinst + #!/bin/sh + # remove old services file entries + /bin/sed -i '/no-ip\.com/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1 + # and create new + printf "%s\\t%s\\n" '"no-ip.com"' '"update_no-ip_com.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services + # on real system restart service if enabled + [ -z "$${IPKG_INSTROOT}" ] && { + [ -x /etc/uci-defaults/ddns_no-ip_com ] && \ + /etc/uci-defaults/ddns_no-ip_com && \ + rm -f /etc/uci-defaults/ddns_no-ip_com >/dev/null 2>&1 + /etc/init.d/ddns enabled && \ + /etc/init.d/ddns start >/dev/null 2>&1 + } + exit 0 # suppress errors +endef +define Package/ddns-scripts_no-ip_com/prerm + #!/bin/sh + # if NOT run buildroot then stop service + [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 + # remove services file entries + /bin/sed -i '/no-ip\.com/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1 + exit 0 # suppress errors +endef + +###### ************************************************************************* +define Package/ddns-scripts_nsupdate/preinst + #!/bin/sh + # if NOT run buildroot then stop service + [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 + exit 0 # suppress errors +endef +define Package/ddns-scripts_nsupdate/install + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.defaults $(1)/etc/uci-defaults/ddns_nsupdate + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/update_nsupdate.sh $(1)/usr/lib/ddns +endef +define Package/ddns-scripts_nsupdate/postinst + #!/bin/sh + # remove old services file entries + /bin/sed -i '/bind-nsupdate/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1 + /bin/sed -i '/bind-nsupdate/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1 + # and create new + printf "%s\\t%s\\n" '"bind-nsupdate"' '"update_nsupdate.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services + printf "%s\\t%s\\n" '"bind-nsupdate"' '"update_nsupdate.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services_ipv6 + # on real system restart service if enabled + [ -z "$${IPKG_INSTROOT}" ] && { + [ -x /etc/uci-defaults/ddns_nsupdate ] && \ + /etc/uci-defaults/ddns_nsupdate && \ + rm -f /etc/uci-defaults/ddns_nsupdate >/dev/null 2>&1 + /etc/init.d/ddns enabled && \ + /etc/init.d/ddns start >/dev/null 2>&1 + } + exit 0 # suppress errors +endef +define Package/ddns-scripts_nsupdate/prerm + #!/bin/sh + # if NOT run buildroot then stop service + [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 + # remove services file entries + /bin/sed -i '/bind-nsupdate/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1 + /bin/sed -i '/bind-nsupdate/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1 + exit 0 # suppress errors +endef + +###### ************************************************************************* +define Package/ddns-scripts_route53-v1/preinst + #!/bin/sh + # if NOT run buildroot then stop service + [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 + exit 0 # suppress errors +endef +define Package/ddns-scripts_route53-v1/install + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns.defaults $(1)/etc/uci-defaults/ddns_route53-v1 + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/update_route53_v1.sh $(1)/usr/lib/ddns +endef +define Package/ddns-scripts_route53-v1/postinst + #!/bin/sh + # remove old services file entries + /bin/sed -i '/route53-v1/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1 + /bin/sed -i '/route53-v1/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1 + # and create new + printf "%s\\t%s\\n" '"route53-v1"' '"update_route53_v1.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services + printf "%s\\t%s\\n" '"route53-v1"' '"update_route53_v1.sh"' >> $${IPKG_INSTROOT}/etc/ddns/services_ipv6 + # on real system restart service if enabled + [ -z "$${IPKG_INSTROOT}" ] && { + [ -x /etc/uci-defaults/ddns_route53-v1 ] && \ + /etc/uci-defaults/ddns_route53-v1 && \ + rm -f /etc/uci-defaults/route53.com-v1 >/dev/null 2>&1 + /etc/init.d/ddns enabled \ + && /etc/init.d/ddns start >/dev/null 2>&1 + } + exit 0 # suppress errors +endef +define Package/ddns-scripts_route53-v1/prerm + #!/bin/sh + # if NOT run buildroot then stop service + [ -z "$${IPKG_INSTROOT}" ] && /etc/init.d/ddns stop >/dev/null 2>&1 + # remove services file entries + /bin/sed -i 'route53-v1/d' $${IPKG_INSTROOT}/etc/ddns/services >/dev/null 2>&1 + /bin/sed -i 'route53-v1/d' $${IPKG_INSTROOT}/etc/ddns/services_ipv6 >/dev/null 2>&1 + exit 0 # suppress errors +endef + +###### ************************************************************************* +$(eval $(call BuildPackage,ddns-scripts)) +$(eval $(call BuildPackage,ddns-scripts_cloudflare.com-v4)) +$(eval $(call BuildPackage,ddns-scripts_freedns_42_pl)) +$(eval $(call BuildPackage,ddns-scripts_godaddy.com-v1)) +$(eval $(call BuildPackage,ddns-scripts_no-ip_com)) +$(eval $(call BuildPackage,ddns-scripts_nsupdate)) +$(eval $(call BuildPackage,ddns-scripts_route53-v1)) diff --git a/net/ddns-scripts/files/ddns.config b/net/ddns-scripts/files/ddns.config new file mode 100644 index 0000000..6d6b810 --- /dev/null +++ b/net/ddns-scripts/files/ddns.config @@ -0,0 +1,32 @@ +# +# Please read http://wiki.openwrt.org/doc/uci/ddns +# +config ddns "global" + option ddns_dateformat "%F %R" +# option ddns_rundir "/var/run/ddns" +# option ddns_logdir "/var/log/ddns" + option ddns_loglines "250" + option upd_privateip "0" + + +config service "myddns_ipv4" + option service_name "dyndns.org" + option lookup_host "yourhost.example.com" + option domain "yourhost.example.com" + option username "your_username" + option password "your_password" + option interface "wan" + option ip_source "network" + option ip_network "wan" + +config service "myddns_ipv6" + option update_url "http://[USERNAME]:[PASSWORD]@your.provider.net/nic/update?hostname=[DOMAIN]&myip=[IP]" + option lookup_host "yourhost.example.com" + option domain "yourhost.example.com" + option username "your_username" + option password "your_password" + option use_ipv6 "1" + option interface "wan6" + option ip_source "network" + option ip_network "wan6" + diff --git a/net/ddns-scripts/files/ddns.defaults b/net/ddns-scripts/files/ddns.defaults new file mode 100755 index 0000000..7e551d0 --- /dev/null +++ b/net/ddns-scripts/files/ddns.defaults @@ -0,0 +1,201 @@ +#!/bin/sh + +g_pslfile=/usr/share/public_suffix_list.dat.gz +[ -f "$g_pslfile" ] || g_pslfile="$(dirname $0)/public_suffix_list.dat.gz" + +g_pslerr=0 +g_cfgfile="ddns" + +# modify timer settings from interval and unit to dhms format +timer2dhms() { +# $1 Number and +# $2 Unit of time interval + local t=0 + case $2 in + days) t=$(( $1 * 86400 ));; + hours) t=$(( $1 * 3600 ));; + minutes) t=$(( $1 * 60 ));; + *) t=$1;; + esac + + local d=$(( $t / 86400 )) + local h=$(( $t % 86400 / 3600 )) + local m=$(( $t % 3600 / 60 )) + local s=$(( $t % 60 )) + if [ $d -gt 0 ]; then printf "%dd %02dh %02dm %02ds" "$d" "$h" "$m" "$s" + elif [ $h -gt 0 ]; then printf "%dh %02dm %02ds" "$h" "$m" "$s" + elif [ $m -gt 0 ]; then printf "%dm %02ds" "$m" "$s" + else printf "%ds" "$s"; fi + + unset d h m s t + return 0 +} + +# using function to not confuse function calls with existing ones inside /lib/functions.sh +update_config() { + uc_uci="$(which uci) -q" # ignore errors + uc_cfg="" + uc_name="" + uc_var="" + uc_val="" + package() { return 0; } + config () { + uc_cfg="$1" + uc_name="$2" + + # Type = ddns Name = global + if [ "$uc_cfg" = "$g_cfgfile" -a "$uc_name" = "global" ]; then + option() { + uc_var="$1"; shift + uc_val="$*" + case "$uc_var" in + allow_local_ip) $uc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_privateip";; + date_format) $uc_uci rename $g_cfgfile.$uc_name.$uc_var="ddns_dateformat";; + log_lines) $uc_uci rename $g_cfgfile.$uc_name.$uc_var="ddns_loglines";; + log_dir) $uc_uci rename $g_cfgfile.$uc_name.$uc_var="ddns_logdir";; + run_dir) $uc_uci rename $g_cfgfile.$uc_name.$uc_var="ddns_rundir";; + # leave all other options currently unchanged + *) ;; + esac + } + + # Type = service Name = ??? + elif [ "$uc_cfg" = "service" ]; then + option() { + uc_var="$1"; shift + uc_val="$*" + case "$uc_var" in + # fix some option service_name values + # and some settings for specific providers + service_name|upd_provider) + case "$uc_val" in + freedns\.afraid\.org|afraid\.org) + $uc_uci set $g_cfgfile.$uc_name.$uc_var="afraid.org-keyauth";; + Bind-nsupdate) + $uc_uci set $g_cfgfile.$uc_name.$uc_var="bind-nsupdate";; + dyndns\.org|dyndns\.com) + $uc_uci set $g_cfgfile.$uc_name.$uc_var="dyn.com";; + free\.editdns\.net) + $uc_uci set $g_cfgfile.$uc_name.$uc_var="editdns.net";; + FreeDNS\.42\.pl) + $uc_uci set $g_cfgfile.$uc_name.$uc_var="freedns.42.pl";; + domains\.google\.com) + $uc_uci set $g_cfgfile.$uc_name.$uc_var="google.com";; + loopia\.com) + $uc_uci set $g_cfgfile.$uc_name.$uc_var="loopia.se";; + NoIP\.com|No-IP\.com) + $uc_uci set $g_cfgfile.$uc_name.$uc_var="no-ip.com";; + spdns\.de) + $uc_uci set $g_cfgfile.$uc_name.$uc_var="spdyn.de";; + strato\.de) + $uc_uci set $g_cfgfile.$uc_name.$uc_var="strato.com";; + *) + # all others leave unchanged + ;; + esac + # rename option service_name to option upd_provider +# $uc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_provider" + ;; + domain|upd_object) + # verify if lookup_host is set + $uc_uci get $g_cfgfile.$uc_name.lookup_host >/dev/null 2>&1 || \ + $uc_uci set $g_cfgfile.$uc_name.lookup_host="$uc_val" + if [ -f "$g_pslfile" ]; then + # if service_name/upd_provider cloudflare_v1 then change domain/upd_object to new syntax + # there is no sort order inside uci data so we need multiple checks + uco_provider=$($uc_uci get $g_cfgfile.$uc_name.upd_provider 2>/dev/null) || \ + uco_provider=$($uc_uci get $g_cfgfile.$uc_name.service_name 2>/dev/null) + unset uco_provider + fi + # rename option domain to option upd_object +# $uc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_object" + ;; +# dns_server) +# # if bind-nsupdate takeover old "dns_server" value as new "upd_nsupd_server" value +# uco_provider=$($uc_uci get $g_cfgfile.$uc_name.upd_provider 2>/dev/null) || \ +# uco_provider=$($uc_uci get $g_cfgfile.$uc_name.service_name 2>/dev/null) +# [ "$uco_provider" = "Bind-nsupdate" -o \ +# "$uco_provider" = "bind-nsupdate" ] && \ +# $uc_uci set $g_cfgfile.$uc_name.upd_nsupd_server="$uc_val" +# # rename option dns_server to new option global_dnssvr +# $udc_uci rename $g_cfgfile.$uc_name.$uc_var="global_dnssvr" +# ;; +# bind_network) +# $udc_uci set $g_cfgfile.$uc_name.upd_url_bindnet="$uc_val" +# $udc_uci rename $g_cfgfile.$uc_name.$uc_var="lip_url_bindnet" +# ;; +# proxy) +# # proxy value must include protocoll +# $udc_uci set $g_cfgfile.$uc_name.$uc_var="http://$uc_val" +# $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_url_proxy" +# ;; +# use_ipv6) +# $udc_uci set $g_cfgfile.$uc_name.$uc_var="$(( 4 + ( 2 * $uc_val ) ))" +# $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_ipversion" +# TODO update_url) +# TODO update_script) + # other renames +# TODO lookup_host) -> rip_host +# enabled) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_enabled";; +# force_dnstcp) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="rip_host_dnstcp";; +# is_glue) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="rip_host_isglue";; +# ip_interface) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="lip_iface";; +# ip_network) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="lip_net";; +# use_https) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_url_secure";; +# cacert) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_url_cacert";; +# username) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_username";; +# password) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_password";; +# param_opt) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_paramopt";; +# param_enc) $udc_uci rename $g_cfgfile.$uc_name.$uc_var="upd_paramenc";; + + # leave all other options currently unchanged + *) ;; + esac + return 0 + } + return 0 + + # ignore unknown + else + return 0 + fi + } + + # read config file + uc_data=$($uc_uci -S -n export "$g_cfgfile") + uc_ret="$?" + # Error then create config file + [ $uc_ret -ne 0 ] && { + touch /etc/config/$uc_cfgfile + chmod 644 /etc/config/$uc_cfgfile + } + # No error and uc_data then execute (eval) + # this will call functions defined above + [ $uc_ret -eq 0 -a -n "$uc_data" ] && eval "$uc_data" + + # add config ddns "global" (ignore error if exists) + $uc_uci set ddns.global="$g_cfgfile" + + # write changes to config file + $uc_uci commit "$g_cfgfile" + + unset uc_uci uc_cfg uc_name uc_var uc_val uc_ret uc_data + return 0 +} + +# clear LuCI indexcache +rm -f /tmp/luci-indexcache >/dev/null 2>&1 + +# do config update +update_config + +#cleanup +[ $g_pslerr -ne 0 ] && { + unset g_pslfile g_pslerr g_cfgfile + return 1 +} + +[ -f "$g_pslfile" ] && rm -f "$g_pslfile" +unset g_pslfile g_pslerr g_cfgfile +return 0 + diff --git a/net/ddns-scripts/files/ddns.hotplug b/net/ddns-scripts/files/ddns.hotplug new file mode 100755 index 0000000..9ef172d --- /dev/null +++ b/net/ddns-scripts/files/ddns.hotplug @@ -0,0 +1,11 @@ +#!/bin/sh + +# there are other ACTIONs like ifupdate we don't need +case "$ACTION" in + ifup) # OpenWrt is giving a network not phys. Interface + /etc/init.d/ddns enabled && /usr/lib/ddns/dynamic_dns_updater.sh -n "$INTERFACE" -- start + ;; + ifdown) + /usr/lib/ddns/dynamic_dns_updater.sh -n "$INTERFACE" -- stop + ;; +esac diff --git a/net/ddns-scripts/files/ddns.init b/net/ddns-scripts/files/ddns.init new file mode 100755 index 0000000..b2156a6 --- /dev/null +++ b/net/ddns-scripts/files/ddns.init @@ -0,0 +1,27 @@ +#!/bin/sh /etc/rc.common +START=95 +STOP=10 + +boot() { + return 0 +} + +reload() { + /usr/lib/ddns/dynamic_dns_updater.sh -- reload + return 0 +} + +restart() { + /usr/lib/ddns/dynamic_dns_updater.sh -- stop + sleep 1 # give time to shutdown + /usr/lib/ddns/dynamic_dns_updater.sh -- start +} + +start() { + /usr/lib/ddns/dynamic_dns_updater.sh -- start +} + +stop() { + /usr/lib/ddns/dynamic_dns_updater.sh -- stop + return 0 +} diff --git a/net/ddns-scripts/files/dynamic_dns_functions.sh b/net/ddns-scripts/files/dynamic_dns_functions.sh new file mode 100755 index 0000000..7128807 --- /dev/null +++ b/net/ddns-scripts/files/dynamic_dns_functions.sh @@ -0,0 +1,1373 @@ +#!/bin/sh +# /usr/lib/ddns/dynamic_dns_functions.sh +# +#.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 +#.2014-2018 Christian Schoenebeck +# +# function timeout +# copied from http://www.ict.griffith.edu.au/anthony/software/timeout.sh +# @author Anthony Thyssen 6 April 2011 +# +# variables in small chars are read from /etc/config/ddns +# variables in big chars are defined inside these scripts as global vars +# variables in big chars beginning with "__" are local defined inside functions only +# set -vx #script debugger + +. /lib/functions.sh +. /lib/functions/network.sh + +# GLOBAL VARIABLES # +VERSION="2.7.8-1" +SECTION_ID="" # hold config's section name +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 +IPFILE="" # store registered IP for read by LuCI status +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 +RETRY_SECONDS=0 # in configuration + +LAST_TIME=0 # holds the uptime of last successful update +CURR_TIME=0 # holds the current uptime +NEXT_TIME=0 # calculated time for next FORCED update +EPOCH_TIME=0 # seconds since 1.1.1970 00:00:00 + +REGISTERED_IP="" # holds the IP read from DNS +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" + +# 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 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) + +# Transfer Programs +WGET=$(which wget) +WGET_SSL=$(which wget-ssl) + +CURL=$(which curl) + +# CURL_PROXY not empty then Proxy support available +CURL_PROXY=$(find /lib /usr/lib -name libcurl.so* -exec strings {} 2>/dev/null \; | grep -im1 "all_proxy") + +UCLIENT_FETCH=$(which uclient-fetch) + +# 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 +[ -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 +# $1 = ddns, $2 = SECTION_ID +load_all_config_options() +{ + local __PKGNAME="$1" + local __SECTIONID="$2" + local __VAR + local __ALL_OPTION_VARIABLES="" + + # this callback loads all the variables in the __SECTIONID section when we do + # config_load. We need to redefine the option_cb for different sections + # so that the active one isn't still active after we're done with it. For reference + # the $1 variable is the name of the option and $2 is the name of the section + config_cb() + { + if [ ."$2" = ."$__SECTIONID" ]; then + option_cb() + { + __ALL_OPTION_VARIABLES="$__ALL_OPTION_VARIABLES $1" + } + else + option_cb() { return 0; } + fi + } + + config_load "$__PKGNAME" + + # Given SECTION_ID not found so no data, so return 1 + [ -z "$__ALL_OPTION_VARIABLES" ] && return 1 + + for __VAR in $__ALL_OPTION_VARIABLES + do + config_get "$__VAR" "$__SECTIONID" "$__VAR" + done + return 0 +} + +# read's all service sections from ddns config +# $1 = Name of variable to store +load_all_service_sections() { + local __DATA="" + config_cb() + { + # only look for section type "service", ignore everything else + [ "$1" = "service" ] && __DATA="$__DATA $2" + } + config_load "ddns" + + eval "$1=\"$__DATA\"" + return +} + +# 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/95-ddns on IFUP +# and by /etc/init.d/ddns start +start_daemon_for_all_ddns_sections() +{ + local __EVENTIF="$1" + local __SECTIONS="" + local __SECTIONID="" + local __IFACE="" + + load_all_service_sections __SECTIONS + for __SECTIONID in $__SECTIONS; do + config_get __IFACE "$__SECTIONID" interface "wan" + [ -z "$__EVENTIF" -o "$__IFACE" = "$__EVENTIF" ] || continue + 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 +} + +# stop sections process incl. childs (sleeps) +# $1 = section +stop_section_processes() { + local __PID=0 + local __PIDFILE="$ddns_rundir/$1.pid" + [ $# -ne 1 ] && write_log 12 "Error calling 'stop_section_processes()' - wrong number of parameters" + + [ -e "$__PIDFILE" ] && { + __PID=$(cat $__PIDFILE) + ps | grep "^[\t ]*$__PID" >/dev/null 2>&1 && kill $__PID || __PID=0 # terminate it + } + [ $__PID -eq 0 ] # report if process was running +} + +# stop updater script for all defines sections or only for one given +# $1 = interface (optional) +# 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() { + local __EVENTIF="$1" + local __SECTIONS="" + local __SECTIONID="" + local __IFACE="" + + load_all_service_sections __SECTIONS + for __SECTIONID in $__SECTIONS; do + config_get __IFACE "$__SECTIONID" interface "wan" + [ -z "$__EVENTIF" -o "$__IFACE" = "$__EVENTIF" ] || continue + stop_section_processes "$__SECTIONID" + done +} + +# reports to console, logfile, syslog +# $1 loglevel 7 == Debug to 0 == EMERG +# value +10 will exit the scripts +# $2..n text to report +write_log() { + local __LEVEL __EXIT __CMD __MSG __MSE + local __TIME=$(date +%H%M%S) + [ $1 -ge 10 ] && { + __LEVEL=$(($1-10)) + __EXIT=1 + } || { + __LEVEL=$1 + __EXIT=0 + } + shift # remove loglevel + [ $__EXIT -eq 0 ] && __MSG="$*" || __MSG="$* - TERMINATE" + case $__LEVEL in # create log message and command depending on loglevel + 0) __CMD="logger -p user.emerg -t ddns-scripts[$$] $SECTION_ID: $__MSG" + __MSG=" $__TIME EMERG : $__MSG" ;; + 1) __CMD="logger -p user.alert -t ddns-scripts[$$] $SECTION_ID: $__MSG" + __MSG=" $__TIME ALERT : $__MSG" ;; + 2) __CMD="logger -p user.crit -t ddns-scripts[$$] $SECTION_ID: $__MSG" + __MSG=" $__TIME CRIT : $__MSG" ;; + 3) __CMD="logger -p user.err -t ddns-scripts[$$] $SECTION_ID: $__MSG" + __MSG=" $__TIME ERROR : $__MSG" ;; + 4) __CMD="logger -p user.warn -t ddns-scripts[$$] $SECTION_ID: $__MSG" + __MSG=" $__TIME WARN : $__MSG" ;; + 5) __CMD="logger -p user.notice -t ddns-scripts[$$] $SECTION_ID: $__MSG" + __MSG=" $__TIME note : $__MSG" ;; + 6) __CMD="logger -p user.info -t ddns-scripts[$$] $SECTION_ID: $__MSG" + __MSG=" $__TIME info : $__MSG" ;; + 7) __MSG=" $__TIME : $__MSG";; + *) return;; + esac + + # verbose echo + [ $VERBOSE -gt 0 -o $__EXIT -gt 0 ] && echo -e "$__MSG" + # write to logfile + if [ ${use_logfile:-1} -eq 1 -o $VERBOSE -gt 1 ]; then + if [ -n "$password" ]; then + # url encode __MSG, password already done + urlencode __MSE "$__MSG" + # replace encoded password inside encoded message + # and url decode (newline was encoded as %00) + __MSG=$( echo -e "$__MSE" \ + | sed -e "s/$URL_PASS/***PW***/g" \ + | sed -e "s/+/ /g; s/%00/\n/g; s/%/\\\\x/g" | xargs -0 printf "%b" ) + fi + printf "%s\n" "$__MSG" >> $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 + [ -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 ] && { + $__CMD # force syslog before exit + exit 1 + } + [ $use_syslog -eq 0 ] && return + [ $((use_syslog + __LEVEL)) -le 7 ] && $__CMD + + return +} + +# replace all special chars to their %hex value +# used for USERNAME and PASSWORD in update_url +# unchanged: "-"(minus) "_"(underscore) "."(dot) "~"(tilde) +# to verify: "'"(single quote) '"'(double quote) # because shell delimiter +# "$"(Dollar) # because used as variable output +# tested with the following string stored via Luci Application as password / username +# A B!"#AA$1BB%&'()*+,-./:;<=>?@[\]^_`{|}~ without problems at Dollar or quotes +urlencode() { + # $1 Name of Variable to store encoded string to + # $2 string to encode + local __STR __LEN __CHAR __OUT + local __ENC="" + local __POS=1 + + [ $# -ne 2 ] && write_log 12 "Error calling 'urlencode()' - wrong number of parameters" + + __STR="$2" # read string to encode + __LEN=${#__STR} # get string length + + while [ $__POS -le $__LEN ]; do + # read one chat of the string + __CHAR=$(expr substr "$__STR" $__POS 1) + + case "$__CHAR" in + [-_.~a-zA-Z0-9] ) + # standard char + __OUT="${__CHAR}" + ;; + * ) + # special char get %hex code + __OUT=$(printf '%%%02x' "'$__CHAR" ) + ;; + esac + __ENC="${__ENC}${__OUT}" # append to encoded string + __POS=$(( $__POS + 1 )) # increment position + done + + eval "$1=\"$__ENC\"" # transfer back to variable + return 0 +} + +# extract url or script for given DDNS Provider from +# 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() { + [ $# -ne 3 ] && write_log 12 "Error calling 'get_service_data()' - wrong number of parameters" + + __FILE="/etc/ddns/services" # IPv4 + [ $use_ipv6 -ne 0 ] && __FILE="/etc/ddns/services_ipv6" # IPv6 + + # 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_$$ & + + 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" + + eval "$1=\"$__URL\"" + eval "$2=\"$__SCRIPT\"" + eval "$3=\"$__ANSWER\"" + rm pipe_$$ + return 0 + fi + done < pipe_$$ + rm pipe_$$ + + eval "$1=\"\"" # no service match clear variables + eval "$2=\"\"" + eval "$3=\"\"" + return 1 +} + +# Calculate seconds from interval and unit +# $1 Name of Variable to store result in +# $2 Number and +# $3 Unit of time interval +get_seconds() { + [ $# -ne 3 ] && write_log 12 "Error calling 'get_seconds()' - wrong number of parameters" + case "$3" in + "days" ) eval "$1=$(( $2 * 86400 ))";; + "hours" ) eval "$1=$(( $2 * 3600 ))";; + "minutes" ) eval "$1=$(( $2 * 60 ))";; + * ) eval "$1=$2";; + esac + return 0 +} + +timeout() { + #.copied from http://www.ict.griffith.edu.au/anthony/software/timeout.sh + # only did the following changes + # - commented out "#!/bin/bash" and usage section + # - replace exit by return for usage as function + # - some reformatting + # + # timeout [-SIG] time [--] command args... + # + # Run the given command until completion, but kill it if it runs too long. + # Specifically designed to exit immediately (no sleep interval) and clean up + # nicely without messages or leaving any extra processes when finished. + # + # Example use + # timeout 5 countdown + # + # Based on notes in my "Shell Script Hints", section "Command Timeout" + # http://www.ict.griffith.edu.au/~anthony/info/shell/script.hints + # + # This script uses a lot of tricks to terminate both the background command, + # the timeout script, and even the sleep process. It also includes trap + # commands to prevent sub-shells reporting expected "Termination Errors". + # + # It took years of occasional trials, errors and testing to get a pure bash + # timeout command working as well as this does. + # + #.Anthony Thyssen 6 April 2011 + # +# PROGNAME=$(type $0 | awk '{print $3}') # search for executable on path +# PROGDIR=$(dirname $PROGNAME) # extract directory of program +# PROGNAME=$(basename $PROGNAME) # base name of program + + # output the script comments as docs +# Usage() { +# echo >&2 "$PROGNAME:" "$@" +# sed >&2 -n '/^###/q; /^#/!q; s/^#//; s/^ //; 3s/^/Usage: /; 2,$ p' "$PROGDIR/$PROGNAME" +# exit 10; +# } + + SIG=-TERM + + while [ $# -gt 0 ]; do + case "$1" in + --) + # forced end of user options + shift; + break ;; +# -\?|--help|--doc*) +# Usage ;; + [0-9]*) + TIMEOUT="$1" ;; + -*) + SIG="$1" ;; + *) + # unforced end of user options + break ;; + esac + shift # next option + done + + # run main command in backgrounds and get its pid + "$@" & + command_pid=$! + + # timeout sub-process abort countdown after ABORT seconds! also backgrounded + sleep_pid=0 + ( + # cleanup sleep process + trap 'kill -TERM $sleep_pid; return 1' 1 2 3 15 + # sleep timeout period in background + sleep $TIMEOUT & + sleep_pid=$! + wait $sleep_pid + # Abort the command + kill $SIG $command_pid >/dev/null 2>&1 + return 1 + ) & + timeout_pid=$! + + # Wait for main command to finished or be timed out + wait $command_pid + status=$? + + # Clean up timeout sub-shell - if it is still running! + kill $timeout_pid 2>/dev/null + wait $timeout_pid 2>/dev/null + + # Uncomment to check if a LONG sleep still running (no sleep should be) + # sleep 1 + # echo "-----------" + # /bin/ps j # uncomment to show if abort "sleep" is still sleeping + + return $status +} + +# verify given host and port is connectable +# $1 Host/IP to verify +# $2 Port to verify +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 + # 2 nslookup/host error + # 3 nc (netcat) error + # 4 unmatched IP version + + [ $# -ne 2 ] && write_log 12 "Error calling 'verify_host_port()' - wrong number of parameters" + + # check if ip or FQDN was given + __IPV4=$(echo $__HOST | grep -m 1 -o "$IPV4_REGEX$") # do not detect ip in 0.0.0.0.example.com + __IPV6=$(echo $__HOST | grep -m 1 -o "$IPV6_REGEX") + # if FQDN given get IP address + [ -z "$__IPV4" -a -z "$__IPV6" ] && { + if [ -n "$BIND_HOST" ]; then # use BIND host if installed + __PROG="BIND host" + __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="$NSLOOKUP $__HOST >$DATFILE 2>$ERRFILE" + fi + write_log 7 "#> $__RUNPROG" + eval $__RUNPROG + __ERR=$? + # command error + [ $__ERR -gt 0 ] && { + write_log 3 "DNS Resolver Error - $__PROG Error '$__ERR'" + write_log 7 "$(cat $ERRFILE)" + return 2 + } + # extract IP address + 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 }") + fi + } + + # check IP version if forced + if [ $force_ipversion -ne 0 ]; then + __ERR=0 + [ $use_ipv6 -eq 0 -a -z "$__IPV4" ] && __ERR=4 + [ $use_ipv6 -eq 1 -a -z "$__IPV6" ] && __ERR=6 + [ $__ERR -gt 0 ] && { + [ -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 + $__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 + $__NC --help 2>&1 | grep "\-w" >/dev/null 2>&1 && __NCEXT="TRUE" + + # connectivity test + # run busybox nc to HOST PORT + # busybox might be compiled with "FEATURE_PREFER_IPV4_ADDRESS=n" + # then nc will try to connect via IPv6 if there is any IPv6 available on any host interface + # not worrying, if there is an IPv6 wan address + # so if not "force_ipversion" to use_ipv6 then connect test via ipv4, if available + [ $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="$__NC -w 1 $__IP $__PORT $DATFILE 2>$ERRFILE" + write_log 7 "#> $__RUNPROG" + eval $__RUNPROG + __ERR=$? + [ $__ERR -eq 0 ] && return 0 + write_log 3 "Connect error - BusyBox nc (netcat) Error '$__ERR'" + write_log 7 "$(cat $ERRFILE)" + return 3 + else # nc compiled without extensions (no timeout support) + __RUNPROG="timeout 2 -- $__NC $__IP $__PORT $DATFILE 2>$ERRFILE" + write_log 7 "#> $__RUNPROG" + eval $__RUNPROG + __ERR=$? + [ $__ERR -eq 0 ] && return 0 + write_log 3 "Connect error - BusyBox nc (netcat) timeout Error '$__ERR'" + return 3 + fi +} + +# verify given DNS server if connectable +# $1 DNS server to verify +verify_dns() { + local __ERR=255 # last error buffer + local __CNT=0 # error counter + + [ $# -ne 1 ] && write_log 12 "Error calling 'verify_dns()' - wrong number of parameters" + write_log 7 "Verify DNS server '$1'" + + while [ $__ERR -ne 0 ]; do + # DNS uses port 53 + verify_host_port "$1" "53" + __ERR=$? + if [ -n "$LUCI_HELPER" ]; then # no retry if called by LuCI helper script + return $__ERR + 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 + # if error count > retry_count leave here + [ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \ + write_log 14 "Verify DNS server '$1' failed after $retry_count retries" + + write_log 4 "Verify DNS server '$1' failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds" + sleep $RETRY_SECONDS & + PID_SLEEP=$! + wait $PID_SLEEP # enable trap-handler + PID_SLEEP=0 + fi + done + return 0 +} + +# analyze and verify given proxy string +# $1 Proxy-String to verify +verify_proxy() { + # complete entry user:password@host:port + # inside user and password NO '@' of ":" allowed + # host and port only host:port + # host only host ERROR unsupported + # IPv4 address instead of host 123.234.234.123 + # IPv6 address instead of host [xxxx:....:xxxx] in square bracket + local __TMP __HOST __PORT + local __ERR=255 # last error buffer + local __CNT=0 # error counter + + [ $# -ne 1 ] && write_log 12 "Error calling 'verify_proxy()' - wrong number of parameters" + write_log 7 "Verify Proxy server 'http://$1'" + + # try to split user:password "@" host:port + __TMP=$(echo $1 | awk -F "@" '{print $2}') + # no "@" found - only host:port is given + [ -z "$__TMP" ] && __TMP="$1" + # now lets check for IPv6 address + __HOST=$(echo $__TMP | grep -m 1 -o "$IPV6_REGEX") + # IPv6 host address found read port + if [ -n "$__HOST" ]; then + # IPv6 split at "]:" + __PORT=$(echo $__TMP | awk -F "]:" '{print $2}') + else + __HOST=$(echo $__TMP | awk -F ":" '{print $1}') + __PORT=$(echo $__TMP | awk -F ":" '{print $2}') + fi + # No Port detected - EXITING + [ -z "$__PORT" ] && { + [ -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 [ -n "$LUCI_HELPER" ]; then # no retry if called by LuCI helper script + return $__ERR + 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 + # if error count > retry_count leave here + [ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \ + write_log 14 "Verify Proxy server '$1' failed after $retry_count retries" + + write_log 4 "Verify Proxy server '$1' failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds" + sleep $RETRY_SECONDS & + PID_SLEEP=$! + wait $PID_SLEEP # enable trap-handler + PID_SLEEP=0 + fi + done + return 0 +} + +do_transfer() { + # $1 # URL to use + local __URL="$1" + local __ERR=0 + local __CNT=0 # error counter + local __PROG __RUNPROG + + [ $# -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 + 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 + # set correct program to detect IP + [ $use_ipv6 -eq 0 ] && __RUNPROG="network_get_ipaddr" || __RUNPROG="network_get_ipaddr6" + eval "$__RUNPROG __BINDIP $bind_network" || \ + write_log 13 "Can not detect local IP using '$__RUNPROG $bind_network' - Error: '$?'" + write_log 7 "Force communication via IP '$__BINDIP'" + __PROG="$__PROG --bind-address=$__BINDIP" + fi + # 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 + # set certificate parameters + if [ $use_https -eq 1 ]; then + if [ "$cacert" = "IGNORE" ]; then # idea from Ticket #15327 to ignore server cert + __PROG="$__PROG --no-check-certificate" + elif [ -f "$cacert" ]; then + __PROG="$__PROG --ca-certificate=${cacert}" + elif [ -d "$cacert" ]; then + __PROG="$__PROG --ca-directory=${cacert}" + 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 + # disable proxy if no set (there might be .wgetrc or .curlrc or wrong environment set) + [ -z "$proxy" ] && __PROG="$__PROG --no-proxy" + + __RUNPROG="$__PROG '$__URL'" # build final command + __PROG="GNU Wget" # reuse for error logging + + # 2nd choice is cURL IPv4/IPv6/HTTPS + # libcurl might be compiled without Proxy or HTTPS Support + elif [ -n "$CURL" ]; then + # CURL_SSL not empty then SSL support available + CURL_SSL=$($(which curl) -V 2>/dev/null | grep "Protocols:" | grep -F "https") + __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 + network_get_physdev __DEVICE $bind_network || \ + write_log 13 "Can not detect local device using 'network_get_physdev $bind_network' - Error: '$?'" + write_log 7 "Force communication via device '$__DEVICE'" + __PROG="$__PROG --interface $__DEVICE" + fi + # 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 + # set certificate parameters + if [ $use_https -eq 1 ]; then + if [ "$cacert" = "IGNORE" ]; then # idea from Ticket #15327 to ignore server cert + __PROG="$__PROG --insecure" # but not empty better to use "IGNORE" + elif [ -f "$cacert" ]; then + __PROG="$__PROG --cacert $cacert" + elif [ -d "$cacert" ]; then + __PROG="$__PROG --capath $cacert" + 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 + # disable proxy if no set (there might be .wgetrc or .curlrc or wrong environment set) + # or check if libcurl compiled with proxy support + if [ -z "$proxy" ]; then + __PROG="$__PROG --noproxy '*'" + elif [ -z "$CURL_PROXY" ]; then + # if libcurl has no proxy support and proxy should be used then force ERROR + write_log 13 "cURL: libcurl compiled without Proxy support" + fi + + __RUNPROG="$__PROG '$__URL'" # build final command + __PROG="cURL" # reuse for error logging + + # uclient-fetch possibly with ssl support if /lib/libustream-ssl.so installed + elif [ -n "$UCLIENT_FETCH" ]; then + # UCLIENT_FETCH_SSL not empty then SSL support available + UCLIENT_FETCH_SSL=$(find /lib /usr/lib -name libustream-ssl.so* 2>/dev/null) + __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" + # force ip version not supported + [ $force_ipversion -eq 1 ] && \ + write_log 14 "BusyBox Wget: Force connecting to IPv4 or IPv6 addresses not supported" + # https not supported + [ $use_https -eq 1 ] && \ + write_log 14 "BusyBox Wget: no HTTPS support" + # disable proxy if no set (there might be .wgetrc or .curlrc or wrong environment set) + [ -z "$proxy" ] && __PROG="$__PROG -Y off" + + __RUNPROG="$__PROG '$__URL' 2>$ERRFILE" # build final command + __PROG="Busybox Wget" # reuse for error logging + + else + write_log 13 "Neither 'Wget' nor 'cURL' nor 'uclient-fetch' installed or executable" + fi + + while : ; do + write_log 7 "#> $__RUNPROG" + eval $__RUNPROG # DO transfer + __ERR=$? # save error code + [ $__ERR -eq 0 ] && return 0 # no error leave + [ -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 -gt 1 ] && { + # VERBOSE > 1 then NO retry + write_log 4 "Transfer failed - Verbose Mode: $VERBOSE - NO retry on error" + return 1 + } + + __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 "Transfer failed after $retry_count retries" + + write_log 4 "Transfer failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds" + sleep $RETRY_SECONDS & + PID_SLEEP=$! + wait $PID_SLEEP # enable trap-handler + PID_SLEEP=0 + done + # we should never come here there must be a programming error + write_log 12 "Error in 'do_transfer()' - program coding error" +} + +send_update() { + # $1 # IP to set at DDNS service provider + local __IP + + [ $# -ne 1 ] && write_log 12 "Error calling 'send_update()' - wrong number of parameters" + + 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]") + else + __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'" + . $update_script + else + 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#\[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)" + + [ -z "$UPD_ANSWER" ] && return 0 # not set then ignore + + grep -i -E "$UPD_ANSWER" $DATFILE >/dev/null 2>&1 + return $? # "0" if found + fi +} + +get_local_ip () { + # $1 Name of Variable to store local IP (LOCAL_IP) + local __CNT=0 # error counter + local __RUNPROG __DATA __URL __ERR + + [ $# -ne 1 ] && write_log 12 "Error calling 'get_local_ip()' - wrong number of parameters" + write_log 7 "Detect local IP on '$ip_source'" + + while : ; do + if [ -n "$ip_network" ]; then + # set correct program + network_flush_cache # force re-read data from ubus + [ $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) + # 10: l2tp-inet: mtu 1456 qdisc fq_codel state UNKNOWN qlen 3\ link/ppp + # 10: l2tp-inet inet 95.30.176.51 peer 95.30.176.1/32 scope global l2tp-inet\ valid_lft forever preferred_lft forever + # 5: eth1: 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 replace + # link inet6 fxxx sec forever=>-1 / => ' ' to separate subnet from ip + sed "/link/d; /inet6 f/d; s/sec//g; s/forever/-1/g; s/\// /g" $DATFILE | \ + awk '{ print $3" "$4" "$NF }' > $ERRFILE # temp reuse ERRFILE + # we only need inet? IP prefered time + + 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 < $ERRFILE + 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 + __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 + 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 + } + + [ -n "$LUCI_HELPER" ] && return 1 # no retry if called by LuCI helper script + + write_log 7 "Data detected:" + write_log 7 "$(cat $DATFILE)" + + [ $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 + } + + __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 local IP via '$ip_source' failed after $retry_count retries" + write_log 4 "Get local IP via '$ip_source' failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds" + sleep $RETRY_SECONDS & + PID_SLEEP=$! + wait $PID_SLEEP # enable trap-handler + PID_SLEEP=0 + done + # we should never come here there must be a programming error + write_log 12 "Error in 'get_local_ip()' - program coding error" +} + +get_registered_ip() { + # $1 Name of Variable to store public IP (REGISTERED_IP) + # $2 (optional) if set, do not retry on error + local __CNT=0 # error counter + local __ERR=255 + 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 [ -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 $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="$__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 + NSLOOKUP_MUSL=$($(which nslookup) localhost 2>&1 | grep -F "(null)") # not empty busybox compiled with musl + [ $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" + fi + + while : ; do + write_log 7 "#> $__RUNPROG" + eval $__RUNPROG + __ERR=$? + if [ $__ERR -ne 0 ]; then + write_log 3 "$__PROG error: '$__ERR'" + write_log 7 "$(cat $ERRFILE)" + else + 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 -ne "/^Name:/,\$ { s/^Address[0-9 ]\{0,\}: \($__REGEX\).*$/\\1/p }" ) + fi + [ -n "$__DATA" ] && { + write_log 7 "Registered IP '$__DATA' detected" + [ -z "$IPFILE" ] || echo "$__DATA" > $IPFILE + eval "$1=\"$__DATA\"" # valid data found + return 0 # leave here + } + write_log 4 "NO valid IP found" + __ERR=127 + fi + [ -z "$IPFILE" ] || echo "" > $IPFILE + + [ -n "$LUCI_HELPER" ] && return $__ERR # no retry if called by LuCI helper script + [ -n "$2" ] && return $__ERR # $2 is given -> no retry + [ $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 '$lookup_host' failed after $retry_count retries" + + 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 + PID_SLEEP=0 + done + # we should never come here there must be a programming error + write_log 12 "Error in 'get_registered_ip()' - program coding error" +} + +get_uptime() { + # $1 Variable to store result in + [ $# -ne 1 ] && write_log 12 "Error calling 'verify_host_port()' - wrong number of parameters" + local __UPTIME=$(cat /proc/uptime) + eval "$1=\"${__UPTIME%%.*}\"" +} + +trap_handler() { + # $1 trap signal + # $2 optional (exit status) + local __PIDS __PID + local __ERR=${2:-0} + local __OLD_IFS=$IFS + local __NEWLINE_IFS=' +' # __NEWLINE_IFS + + [ $PID_SLEEP -ne 0 ] && kill -$1 $PID_SLEEP 2>/dev/null # kill pending sleep if exist + + case $1 in + 0) if [ $__ERR -eq 0 ]; then + write_log 5 "PID '$$' exit normal at $(eval $DATE_PROG)${N}" + else + write_log 4 "PID '$$' exit WITH ERROR '$__ERR' at $(eval $DATE_PROG)${N}" + fi ;; + 1) write_log 6 "PID '$$' received 'SIGHUP' at $(eval $DATE_PROG)" + # reload config via starting the script again + /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}";; + 15) write_log 5 "PID '$$' terminated by 'SIGTERM' at $(eval $DATE_PROG)${N}";; + *) write_log 13 "Unhandled signal '$1' in 'trap_handler()'";; + esac + + __PIDS=$(pgrep -P $$) # get my childs (pgrep prints with "newline") + IFS=$__NEWLINE_IFS + for __PID in $__PIDS; do + kill -$1 $__PID # terminate it + done + IFS=$__OLD_IFS + + # remove out and err file + [ -f $DATFILE ] && rm -f $DATFILE + [ -f $ERRFILE ] && rm -f $ERRFILE + + # exit with correct handling: + # remove trap handling settings and send kill to myself + trap - 0 1 2 3 15 + [ $1 -gt 0 ] && kill -$1 $$ +} + +split_FQDN() { + # $1 FQDN to split + # $2 name of variable to store TLD + # $3 name of variable to store (reg)Domain + # $4 name of variable to store Host/Subdomain + + [ $# -ne 4 ] && write_log 12 "Error calling 'split_FQDN()' - wrong number of parameters" + [ -z "$1" ] && write_log 12 "Error calling 'split_FQDN()' - missing FQDN to split" + [ -f $TLDFILE ] || write_log 12 "Error calling 'split_FQDN()' - missing file '$TLDFILE'" + + local _HOST _FDOM _CTLD _FTLD + local _SET="$@" # save given function parameters + + local _PAR=$(echo "$1" | tr [A-Z] [a-z] | tr "." " ") # to lower and replace DOT with SPACE + set -- $_PAR # set new as function parameters + _PAR="" # clear variable for later reuse + while [ -n "$1" ] ; do # as long we have parameters + _PAR="$1 $_PAR" # invert order of parameters + shift + done + set -- $_PAR # use new as function parameters + _PAR="" # clear variable + + while [ -n "$1" ] ; do # as long we have parameters + if [ -z "$_CTLD" ]; then # first loop + _CTLD="$1" # CURRENT TLD to look at + shift + else + _CTLD="$1.$_CTLD" # Next TLD to look at + shift + fi + # check if TLD exact match in tld_names.dat, save TLD + zcat $TLDFILE | grep -E "^$_CTLD$" >/dev/null 2>&1 && { + _FTLD="$_CTLD" # save found + _FDOM="$1" # save domain next step might be invalid + continue + } + # check if match any "*" in tld_names.dat, + zcat $TLDFILE | grep -E "^\*.$_CTLD$" >/dev/null 2>&1 && { + [ -z "$1" ] && break # no more data break + # check if next level TLD match excludes "!" in tld_names.dat + if zcat $TLDFILE | grep -E "^!$1.$_CTLD$" >/dev/null 2>&1 ; then + _FTLD="$_CTLD" # Yes + else + _FTLD="$1.$_CTLD" + shift + fi + _FDOM="$1"; shift + } + [ -n "$_FTLD" ] && break # we have something valid, break + done + + # the leftover parameters are the HOST/SUBDOMAIN + while [ -n "$1" ]; do + _HOST="$1 $_HOST" # remember we need to invert + shift + done + _HOST=$(echo $_HOST | tr " " ".") # insert DOT + + set -- $_SET # set back parameters from function call + [ -n "$_FTLD" ] && { + eval "$2=$_FTLD" # set TLD + eval "$3=$_FDOM" # set registrable domain + eval "$4=$_HOST" # set HOST/SUBDOMAIN + return 0 + } + eval "$2=''" # clear TLD + eval "$3=''" # clear registrable domain + eval "$4=''" # clear HOST/SUBDOMAIN + return 1 +} + +expand_ipv6() { + # Original written for bash by + #.Author: Florian Streibelt + # 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 +} diff --git a/net/ddns-scripts/files/dynamic_dns_lucihelper.sh b/net/ddns-scripts/files/dynamic_dns_lucihelper.sh new file mode 100755 index 0000000..ab3eb78 --- /dev/null +++ b/net/ddns-scripts/files/dynamic_dns_lucihelper.sh @@ -0,0 +1,172 @@ +#!/bin/sh +# /usr/lib/ddns/dynamic_dns_lucihelper.sh +# +#.Distributed under the terms of the GNU General Public License (GPL) version 2.0 +#.2014-2018 Christian Schoenebeck +# This script is used by luci-app-ddns +# +# variables in small chars are read from /etc/config/ddns as parameter given here +# variables in big chars are defined inside these scripts as gloval vars +# variables in big chars beginning with "__" are local defined inside functions only +# set -vx #script debugger + +. /usr/lib/ddns/dynamic_dns_functions.sh # global vars are also defined here + +usage() { + cat << EOF + +Usage: + $MYPROG [options] -- command + +Commands: + get_local_ip using given INTERFACE or NETWORK or SCRIPT or URL + get_registered_ip for given FQDN + verify_dns given DNS-SERVER + verify_proxy given PROXY + start start given SECTION + reload force running ddns processes to reload changed configuration + restart restart all ddns processes + +Parameters: + -6 => use_ipv6=1 (default 0) + -d DNS-SERVER => dns_server=SERVER[:PORT] + -f => force_ipversion=1 (default 0) + -g => is_glue=1 (default 0) + -i INTERFACE => ip_interface=INTERFACE; ip_source="interface" + -l FQDN => lookup_host=FQDN + -n NETWORK => ip_network=NETWORK; ip_source="network" + -p PROXY => proxy=[USER:PASS@]PROXY:PORT + -s SCRIPT => ip_script=SCRIPT; ip_source="script" + -t => force_dnstcp=1 (default 0) + -u URL => ip_url=URL; ip_source="web" + -S SECTION SECTION to start + + -h => show this help and exit + -L => use_logfile=1 (default 0) + -v LEVEL => VERBOSE=LEVEL (default 0) + -V => show version and exit + +EOF +} + +usage_err() { + printf %s\\n "$MYPROG: $@" >&2 + usage >&2 + exit 255 +} + +# preset some variables, wrong or not set in ddns-functions.sh +SECTION_ID="lucihelper" +LOGFILE="$ddns_logdir/$SECTION_ID.log" +DATFILE="$ddns_rundir/$SECTION_ID.$$.dat" # save stdout data of WGet and other extern programs called +ERRFILE="$ddns_rundir/$SECTION_ID.$$.err" # save stderr output of WGet and other extern programs called +DDNSPRG="/usr/lib/ddns/dynamic_dns_updater.sh" +VERBOSE=0 # no console logging +# global variables normally set by reading DDNS UCI configuration +use_syslog=0 # no syslog +use_logfile=0 # no logfile + +use_ipv6=0 # Use IPv6 - default IPv4 +force_ipversion=0 # Force IP Version - default 0 - No +force_dnstcp=0 # Force TCP on DNS - default 0 - No +is_glue=0 # Is glue record - default 0 - No +use_https=0 # not needed but must be set + +while getopts ":6d:fghi:l:n:p:s:S:tu:Lv:V" OPT; do + case "$OPT" in + 6) use_ipv6=1;; + d) dns_server="$OPTARG";; + f) force_ipversion=1;; + g) is_glue=1;; + i) ip_interface="$OPTARG"; ip_source="interface";; + l) lookup_host="$OPTARG";; + n) ip_network="$OPTARG"; ip_source="network";; + p) proxy="$OPTARG";; + s) ip_script="$OPTARG"; ip_source="script";; + t) force_dnstcp=1;; + u) ip_url="$OPTARG"; ip_source="web";; + h) usage; exit 255;; + L) use_logfile=1;; + v) VERBOSE=$OPTARG;; + S) SECTION=$OPTARG;; + V) printf %s\\n "ddns-scripts $VERSION"; exit 255;; + :) usage_err "option -$OPTARG missing argument";; + \?) usage_err "invalid option -$OPTARG";; + *) usage_err "unhandled option -$OPT $OPTARG";; + esac +done +shift $((OPTIND - 1 )) # OPTIND is 1 based + +[ $# -eq 0 ] && usage_err "missing command" + +__RET=0 +case "$1" in + get_registered_ip) + [ -z "$lookup_host" ] && usage_err "command 'get_registered_ip': 'lookup_host' not set" + write_log 7 "-----> get_registered_ip IP" + [ -z "$SECTION" ] || IPFILE="$ddns_rundir/$SECTION.ip" + IP="" + get_registered_ip IP + __RET=$? + [ $__RET -ne 0 ] && IP="" + printf "%s" "$IP" + ;; + verify_dns) + [ -z "$dns_server" ] && usage_err "command 'verify_dns': 'dns_server' not set" + write_log 7 "-----> verify_dns '$dns_server'" + verify_dns "$dns_server" + __RET=$? + ;; + verify_proxy) + [ -z "$proxy" ] && usage_err "command 'verify_proxy': 'proxy' not set" + write_log 7 "-----> verify_proxy '$proxy'" + verify_proxy "$proxy" + __RET=$? + ;; + get_local_ip) + [ -z "$ip_source" ] && usage_err "command 'get_local_ip': 'ip_source' not set" + [ -n "$proxy" -a "$ip_source" = "web" ] && { + # proxy defined, used for ip_source=web + export HTTP_PROXY="http://$proxy" + export HTTPS_PROXY="http://$proxy" + export http_proxy="http://$proxy" + export https_proxy="http://$proxy" + } + # don't need IP only the return code + IP="" + if [ "$ip_source" = "web" -o "$ip_source" = "script" ]; then + # we wait only 3 seconds for an + # answer from "web" or "script" + write_log 7 "-----> timeout 3 -- get_local_ip IP" + timeout 3 -- get_local_ip IP + else + write_log 7 "-----> get_local_ip IP" + get_local_ip IP + fi + __RET=$? + ;; + start) + [ -z "$SECTION" ] && usage_err "command 'start': 'SECTION' not set" + if [ $VERBOSE -eq 0 ]; then # start in background + $DDNSPRG -v 0 -S $SECTION -- start & + else + $DDNSPRG -v $VERBOSE -S $SECTION -- start + fi + ;; + reload) + $DDNSPRG -- reload + ;; + restart) + $DDNSPRG -- stop + sleep 1 + $DDNSPRG -- start + ;; + *) + __RET=255 + ;; +esac + +# remove out and err file +[ -f $DATFILE ] && rm -f $DATFILE +[ -f $ERRFILE ] && rm -f $ERRFILE +return $__RET diff --git a/net/ddns-scripts/files/dynamic_dns_updater.sh b/net/ddns-scripts/files/dynamic_dns_updater.sh new file mode 100755 index 0000000..b84e829 --- /dev/null +++ b/net/ddns-scripts/files/dynamic_dns_updater.sh @@ -0,0 +1,420 @@ +#!/bin/sh +# /usr/lib/ddns/dynamic_dns_updater.sh +# +#.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 +#.2014-2018 Christian Schoenebeck +# +# variables in small chars are read from /etc/config/ddns +# variables in big chars are defined inside these scripts as global vars +# variables in big chars beginning with "__" are local defined inside functions only +# set -vx #script debugger + +. $(dirname $0)/dynamic_dns_functions.sh # global vars are also defined here + +usage() { + cat << EOF + +Usage: + $MYPROG [options] -- command + +Commands: +start Start SECTION or NETWORK or all +stop Stop NETWORK or all + +Parameters: + -n NETWORK Start/Stop sections in background monitoring NETWORK, force VERBOSE=0 + -S SECTION SECTION to start + use either -N NETWORK or -S SECTION + + -h show this help and exit + -V show version and exit + -v LEVEL VERBOSE=LEVEL (default 1) + '0' NO output to console + '1' output to console + '2' output to console AND logfile + + run once WITHOUT retry on error + '3' output to console AND logfile + + run once WITHOUT retry on error + + NOT sending update to DDNS service + +EOF +} + +usage_err() { + printf %s\\n "$MYPROG: $@" >&2 + usage >&2 + exit 1 +} + +while getopts ":hv:n:S:V" OPT; do + case "$OPT" in + h) usage; exit 0;; + v) VERBOSE=$OPTARG;; + n) NETWORK=$OPTARG;; + S) SECTION_ID=$OPTARG;; + V) printf %s\\n "ddns-scripts $VERSION"; exit 0;; + :) usage_err "option -$OPTARG missing argument";; + \?) usage_err "invalid option -$OPTARG";; + *) usage_err "unhandled option -$OPT $OPTARG";; + esac +done +shift $((OPTIND - 1 )) # OPTIND is 1 based + +[ -n "$NETWORK" -a -n "$SECTION_ID" ] && usage_err "use either option '-N' or '-S' not both" +[ $# -eq 0 ] && usage_err "missing command" +[ $# -gt 1 ] && usage_err "to much commands" + +case "$1" in + start) + if [ -n "$NETWORK" ]; then + start_daemon_for_all_ddns_sections "$NETWORK" + exit 0 + fi + if [ -z "$SECTION_ID" ]; then + start_daemon_for_all_ddns_sections + exit 0 + fi + ;; + stop) + if [ -n "$INTERFACE" ]; then + stop_daemon_for_all_ddns_sections "$NETWORK" + exit 0 + else + stop_daemon_for_all_ddns_sections + exit 0 + fi + exit 1 + ;; + reload) + killall -1 dynamic_dns_updater.sh 2>/dev/null + exit $? + ;; + *) usage_err "unknown command - $1";; +esac + +# set file names +PIDFILE="$ddns_rundir/$SECTION_ID.pid" # Process ID file +UPDFILE="$ddns_rundir/$SECTION_ID.update" # last update successful send (system uptime) +DATFILE="$ddns_rundir/$SECTION_ID.dat" # save stdout data of WGet and other extern programs called +ERRFILE="$ddns_rundir/$SECTION_ID.err" # save stderr output of WGet and other extern programs called +IPFILE="$ddns_rundir/$SECTION_ID.ip" # +LOGFILE="$ddns_logdir/$SECTION_ID.log" # log file + +# VERBOSE > 1 delete logfile if exist to create an empty one +# only with this data of this run for easier diagnostic +# new one created by write_log function +[ $VERBOSE -gt 1 -a -f $LOGFILE ] && rm -f $LOGFILE + +# TRAP handler +trap "trap_handler 0 \$?" 0 # handle script exit with exit status +trap "trap_handler 1" 1 # SIGHUP Hangup / reload config +trap "trap_handler 2" 2 # SIGINT Terminal interrupt +trap "trap_handler 3" 3 # SIGQUIT Terminal quit +# trap "trap_handler 9" 9 # SIGKILL no chance to trap +trap "trap_handler 15" 15 # SIGTERM Termination + +################################################################################ +# Leave this comment here, to clearly document variable names that are expected/possible +# Use load_all_config_options to load config options, which is a much more flexible solution. +# +# config_load "ddns" +# config_get $SECTION_ID