--[[

  ●対向ルーターの IPv6アドレスを取得し、設定を変更するスクリプト
  生存通知2 パケットの受信時に出力されるログから対向ルーターの 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 を使用してく
  ださい。

]]

--------------------------##  設定値  ##--------------------------------
-- 検出するパターン
ptn_hbt = "Received from "

-- トンネル番号
tunnel_num = 1

-- 出力する SYSLOG のレベル(info, debug, notice)
log_level = "(SYSLOGレベル)"				-- ★

----------------------##  設定値ここまで  ##----------------------------

------------------------------------------------------------
-- 設定されているIPv6アドレスを取得する関数               --
------------------------------------------------------------
function get_address_config(tunnel_num)
  local rtn, str, a, b, c, adr
  local ptn = "ipsec ike remote address " .. tostring(tunnel_num) .. " "

  rtn, str = rt.command("show config")
  if rtn and str then
    a, b = str:find(ptn)
    if a and b then
      c = str:find("%s", b+1)
      adr = str:sub(b+1, c-1)
    end
  end
  return adr
end

------------------------------------------------------------
-- hertbeat2ログからIPv6アドレスを取得する関数            --
------------------------------------------------------------
function get_remote_address(str)
  local s, e, adr
  local ptn = "Received from ([%x:]+) "

  s, e, adr = str:find(ptn)
  return adr

end

------------------------------------------------------------
-- 対向ルーターのIPv6アドレスが変更されていた場合、       --
-- IPsec のリモートアドレスの設定を変更する関数           --
------------------------------------------------------------
function change_config(tunnel_num, chg_adr)
  rt.command("tunnel select " .. tunnel_num)
  rt.command("ipsec ike remote address " .. tunnel_num .. " " .. chg_adr)
  rt.command("tunnel select none")
  rt.command("save")
  rt.syslog(log_level, "TUNNEL[" .. tunnel_num .. "]のリモートアドレスを変更しました。")
end

------------------------------------------------------------
-- メインルーチン                                         --
------------------------------------------------------------
local rtn, log, rmt_adr_cfg, rmt_adr_hbt 

-- エラーメッセージ
local err_msg1 = "からの情報の取得に失敗しました。(TUNNEL["
local err_msg2 = "])"

while true do
  rtn, log = rt.syslogwatch(ptn_hbt)

  if rtn > 0 then

    -- 対向ルーターの設定上のIPv6アドレスを取得
    rmt_adr_cfg = get_address_config(tunnel_num)

    if rmt_adr_cfg then

      -- ログから対向ルーターの現在のIPv6アドレスを取得
      rmt_adr_hbt = get_remote_address(log[1])

      -- IPv6アドレスが異なれば、設定を変更する
      if rmt_adr_hbt then

        if string.match(rmt_adr_cfg, rmt_adr_hbt) == nil then
            change_config(tunnel_num, rmt_adr_hbt)
        end

      else
        rt.syslog(log_level, "ログ" .. err_msg1 .. tostring(tunnel_num) .. err_msg2)
      end
    else
      rt.syslog(log_level, "設定ファイル" .. err_msg1 .. tostring(tunnel_num) .. err_msg2)
    end

  end

end