Last active
August 19, 2021 13:50
-
-
Save taka-tactical/a487f08e3837d9e54c634a15ace27f51 to your computer and use it in GitHub Desktop.
[YAMAHAルーター DDNS更新用 Luaスクリプト] YAMAHAルーター向けのDDNS更新用 Luaスクリプト #yamaha #lua #ddns #nvr700w #nvr500
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --[[ | |
| DDNSのIPアップデート | |
| *** YAMAHAルーター専用 *** | |
| PPPoEで設定されたlocal側のIPアドレスを取得し、既存IPアドレスと異なれば取得したIPアドレスでDDNSを更新する。 | |
| IPアドレスが同じであれば更新はしない。interval_watch * interval_update(秒)で設定された期間更新されない | |
| 場合、強制的にIPアドレスを更新する。 | |
| ※下記サンプルはNO-IP用に記述されているが、UpHostを書き換えることでそのままDynDNSにも使用可能。 | |
| 他のDDNSサービスに使用する場合は、サービスに応じたUpType/UpHost/UpUrlパラメータを記述すること。 | |
| ]] | |
| ----------------------## 設定 ここから ##---------------- | |
| -- debug(tru | false で指定) | |
| debug = false | |
| -- DDNS service user account | |
| username = "Enter your username" | |
| password = "Enter your password" | |
| ddnshost = "Enter your ddns hostname" | |
| -- IP取得するPP番号 | |
| pp_num = 1 | |
| -- 実行指定時間(hh:mm) | |
| schedule = "01:00" | |
| -- 実行間隔秒数と強制アップデート実施カウンターのしきい値 | |
| -- | |
| -- IP取得リトライ回数と間隔(秒数) | |
| interval_retrypp = 3 | |
| interval_timespp = 10 | |
| -- syslogwatch time 86400/day, max 864000(10days) | |
| -- interval_watch * interval_update | |
| interval_watch = 86400 | |
| interval_update = 7 | |
| -- syslogwatch タイマー誤差の補正値(NVR500の実績でNVR700Wでは不要の模様) | |
| -- for NVR500 (-90秒) | |
| --correction_time = -90 | |
| -- for NVR700W (補正不要) | |
| correction_time = 0 | |
| -- DDNS update api address | |
| -- | |
| -- UpUrl の末尾にIPが自動付加されるのでパラメータ構成に注意 | |
| -- ポート指定が必要な場合は UpHost パラメータを "FQDN:8080" 形式で記述のこと。 | |
| UpType = (_RT_LUA_VERSION_NUM >= 108) and "https" or "http" | |
| UpHost = "dynupdate.no-ip.com" | |
| UpUrl = UpType .. "://" .. UpHost .. "/nic/update?hostname=" .. ddnshost .. "&myip=" | |
| ----------------------## 設定 ここまで ##---------------- | |
| ------------------------------------------------------------ | |
| -- syslog出力関数 -- | |
| ------------------------------------------------------------ | |
| function putSyslog(msg) | |
| rt.syslog("info", "[LUA] ddns-update.lua DDNS " .. msg) | |
| end | |
| ------------------------------------------------------------ | |
| -- 指定した時間までの秒数を返す関数 -- | |
| ------------------------------------------------------------ | |
| function getDiffTime(t_dest) | |
| local t_adjust, t_diff | |
| local tmp = {string.split(t_dest, /:/)} | |
| local now = os.time() | |
| local time = os.date("*t", now) | |
| time.hour = tmp[1] | |
| time.min = tmp[2] | |
| time.sec = 0 | |
| tmp = os.time(time) | |
| if os.difftime(tmp, now) <= 60 then | |
| time = os.date("*t", tmp + interval_watch) | |
| end | |
| t_diff = os.difftime(os.time(time), now) | |
| t_adjust = (t_diff * correction_time) / interval_watch | |
| return (t_diff + t_adjust) | |
| end | |
| ------------------------------------------------------------ | |
| -- 指定されたPPの local IP 取得関数 -- | |
| ------------------------------------------------------------ | |
| function getLocalIp(id) | |
| local rtn, str, ipadr | |
| local cmd = "show status pp " .. tostring(id) | |
| local ptn = "PP IP Address Local:%s+(%d+%.%d+%.%d+%.%d+)" | |
| rtn, str = rt.command(cmd) | |
| if (rtn) and (str) then | |
| ipadr = str:match(ptn) | |
| if (ipadr == nil) then | |
| rtn = false | |
| ipadr = "PPP not linked up" | |
| end | |
| else | |
| rtn = false | |
| ipadr = cmd .. "Can not obtain IPaddr (command exec failure: " .. cmd .. ")\r\n" | |
| end | |
| return rtn, ipadr | |
| end | |
| ------------------------------------------------------------ | |
| -- IPアドレスの変化検出関数 -- | |
| ------------------------------------------------------------ | |
| function isNew(ip) | |
| local blip | |
| blip = os.getenv("GLOBALIP") | |
| if (blip) then | |
| if (blip == ip) then | |
| return false | |
| else | |
| rt.command("set GLOBALIP=" .. ip) | |
| return true | |
| end | |
| else | |
| rt.command("set GLOBALIP=" .. ip) | |
| return true | |
| end | |
| end | |
| ------------------------------------------------------------ | |
| -- DDNS Update 関数 -- | |
| ------------------------------------------------------------ | |
| function UpdateDDNS(ip) | |
| local url = UpUrl .. ip | |
| local resp_table | |
| local req_table = { | |
| url = url, | |
| method = "GET", | |
| auth_type = "basic", | |
| auth_name = username, | |
| auth_pass = password | |
| } | |
| putSyslog("update url = " .. url) | |
| resp_table = rt.httprequest(req_table) | |
| if (resp_table.rtn1) then | |
| putSyslog("new IP = " .. ip) | |
| else | |
| putSyslog("update failed - " .. "\nrtn1-> " .. tostring(resp_table.rtn1) .. "\nrtn2-> " .. tostring(resp_table.rtn2) .. "\nerr-> " .. tostring(resp_table.err) .. "\ncode-> " .. tostring(resp_table.code) .. "\nheader-> " .. tostring(resp_table.header) .. "\nbody-> " .. tostring(resp_table.body)) | |
| end | |
| end | |
| ------------------------------------------------------------ | |
| -- main -- | |
| ------------------------------------------------------------ | |
| local rtn, str, lip, cnt, sec | |
| cnt = 0 | |
| putSyslog("updater starting (lua = " .. _RT_LUA_VERSION .. " , using " .. UpType .. ") ...") | |
| rtn, str = getLocalIp(pp_num) | |
| -- IP取得できない場合(リンクアップ待ち、等)は指定の回数・間隔でリトライ | |
| if (not rtn) then | |
| cnt = interval_retrypp | |
| repeat | |
| putSyslog("try to specify target ... retry " .. math.abs(cnt - interval_retrypp - 1)) | |
| rt.sleep(interval_timespp) | |
| rtn, str = getLocalIp(pp_num) | |
| cnt = cnt - 1 | |
| until (rtn or cnt < 1) | |
| end | |
| if (rtn) then | |
| putSyslog("target is (if = " .. string.format("PP[%02d]:", pp_num) .. str .. ")") | |
| lip = str | |
| if (isNew(lip)) then | |
| if (not debug) then UpdateDDNS(lip) else print("-- UpdateDDNS(lip)") end | |
| end | |
| else | |
| putSyslog("target specify failure. aborted: " .. str) | |
| os.exit(1) | |
| end | |
| cnt = 0 | |
| sec = getDiffTime(schedule) | |
| putSyslog("next ip-check is after " .. sec .. " seconds") | |
| while (true) do | |
| local rtn, str, lip, gip | |
| rtn, str = rt.syslogwatch(string.format("PP%%[%02d%%]", pp_num) .. " PPP/IPCP up%s+%(Local:%s+(%d+%.%d+%.%d+%.%d+)", 1, sec) | |
| if (rtn == 0) then | |
| gip = os.getenv("GLOBALIP") or "" | |
| cnt = cnt + 1 | |
| if (cnt == interval_update) then | |
| cnt = 0 | |
| putSyslog("force update, new ip = " .. gip) | |
| if (not debug) then | |
| UpdateDDNS(gip) | |
| else | |
| print("Skip counter = " .. tostring(interval_update) .. ", DDNS update ip = " .. gip) | |
| end | |
| end | |
| else | |
| lip = string.match(str[rtn], "Local:%s+(%d+%.%d+%.%d+%.%d+)") | |
| putSyslog("detected new ip and update (old/new ip): " .. gip .. "/" .. lip) | |
| if (isNew(lip)) then | |
| if (not debug) then | |
| UpdateDDNS(lip) | |
| else | |
| print("DDNS update called in while loop\n") | |
| end | |
| cnt = 0 | |
| end | |
| end | |
| sec = getDiffTime(schedule) | |
| putSyslog("next ip-check is after " .. sec .. " seconds") | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment