--[[ ●ルーターの IPv6アドレスを取得し、設定を変更するスクリプト   show ipv6 address の出力結果からルーターの IPv6アドレスを取得し、   IPv6アドレスに変更があった場合には、コマンドを再設定するスクリプトです。 <説明> ・このファイルを RTFS か外部メモリに保存してください。 ・本項目の config の設定では schedule at コマンドでルーター起動時に Lua スク リプトが実行されるように設定しています。 ・スクリプトを停止するときは terminate lua コマンドを実行してください。 ・再度、Lua スクリプトを実行する場合は lua コマンドで実行してください。 ・★マークの付いた設定値は変更が可能です。 <ノート>  ・設定を変更した時に出力する SYSLOG レベルを指定可能です。   SYSLOG のレベルを指定するには、log_level を設定してください。   debug レベル、notice レベルの SYSLOG を出力するためには、それぞれ以下の設定   が必要です。    debug レベル ・・・ syslog debug on    notice レベル・・・ syslog notice on  ・本スクリプトファイルを編集する場合、文字コードは必ず Shift-JIS を使用してく   ださい。 ]] --------------------------## 設定値 ##-------------------------------- -- 出力する SYSLOG のレベル(info, debug, notice) log_level = "(SYSLOGレベル)" -- ★ ----------------------## 設定値ここまで ##---------------------------- ---------------------------------------------------------------- -- show ipv6 address の結果から現在のIPv6アドレスを返す関数 -- ---------------------------------------------------------------- function get_ipv6_address(lan) local rtn, str, s1, s2, e, adr, time, i, a, max, max_n local p_time, v local ptn_g = "バル%s+" local t = {} local ret local err -- コマンド実行 -- rtn, str = rt.command("show ipv6 address " .. lan) -- 現在のIPv6アドレスと寿命時間の検出 -- i = 1 if rtn and str then s1 = str:find(ptn_g, 0) if s1 then while true do s2 = str:find("%x+", s1) e = str:find("%/", s2) adr = str:sub(s2, e-1) p_time = tonumber(str:match("lifetime: (%d+)%/", e)) t[i] = {a = adr, time = p_time} next = str:find(ptn_g, e) if next then s1 = next i = i + 1 else break end end -- 最大寿命のIPv6アドレスの検出 -- max = 0 max_n = 1 for i, v in ipairs(t) do if v.time > max then max_n = i max = v.time end end ret = t[max_n].a else err = "グローバルアドレスがありません。" end end return ret, err end --------------------------------------------------------------- -- show ipv6 addressの結果とprefixからIPv6アドレスを返す関数 -- --------------------------------------------------------------- function get_address(lan, prefix) local rtn, str, a, b, c, pfx, adr, err rtn, str = rt.command("show ipv6 address " .. lan) if rtn and str then a = str:find(prefix) b, c = str:find("%/%d+", a) pfx = prefix .. str:sub(b, c) adr = str:sub(a, b-1) else err = "コマンド実行に失敗" end return pfx, adr, err end ------------------------------------------------------------ -- 監視しているlogからprefixを検出する関数 -- ------------------------------------------------------------ function get_prefix(str) local s1, s, e, pfx local ptn_s = "IPv6 prefix%s+" local ptn_e = "%/%d+%s+%b()" s1, s = str:find(ptn_s) e = str:find(ptn_e) pfx = str:sub(s+1, e-2) return pfx end ------------------------------------------------------------ -- メインルーチン -- ------------------------------------------------------------ local adr1, adr2, prefix, pfx, err, rtn, str -- 検出するパターン local ptn = "Add IPv6 prefix%s+" -- 現在のIPv6アドレスを取得 adr1, err = get_ipv6_address("lan2") assert(adr1, err) rt.command("ipsec ike local address 1 " .. adr1) rt.command("heartbeat2 myname " .. adr1) while true do rtn, str = rt.syslogwatch(ptn) if rtn and str then prefix = get_prefix(str[1]) pfx, adr2, err = get_address("lan2", prefix) if adr2 then -- 今までのIPv6アドレスと現在のIPv6アドレスが異なる場合、設定の変更 if string.match(adr1, adr2) == nil then rt.command("tunnel select 1") rt.command("ipsec ike local address 1 " .. adr2) rt.command("tunnel select none") rt.command("heartbeat2 myname " .. adr2) rt.syslog(log_level, "アドレスを変更し、設定を変更しました。") adr1 = adr2 else print("アドレスに変更はありません。") end else rt.syslog(log_level, err) end end end