$Date: 2025/07/24 19:30:44 $
Lua スクリプト機能で使用できる API の一覧です。
[SYSLOG 例] 2009/09/21 12:20:07: lua: mail.lua:26: 'rt.mail': 'text' field value of argument #1 is invalid.API の引数誤りがあってもスクリプトの実行を中断させたくない場合は、Lua 標準関数の pcall( ) や xpcall( ) を使用してください。
使用できる API は Lua スクリプト機能バージョンによって異なります。Lua スクリプト機能バージョンと対応するファームウェアについては Lua スクリプト機能バージョンの変更履歴を参照してください。
ルーターのコマンドの実行、メールの送信など、基本的な操作を行うライブラリです。Lua スクリプト機能に対応した全てのファームウェアで使用可能です。
ルーターのブザーや LED 等のハードウェア制御用のライブラリです。
以下は _RT_LUA_VERSION が "1.02" 以上のファームウェアで使用可能です。
以下は _RT_LUA_VERSION が "1.04" 以上のファームウェアで使用可能です。
HTTP クライアントの機能を提供するHTTPライブラリです。_RT_LUA_VERSION が "1.02" 以上のファームウェアで使用可能です。
ソケットを使用して通信を行うためのライブラリです。_RT_LUA_VERSION が "1.06" 以上のファームウェアで使用可能です。
rt.command(COMMAND [, LOG])
| COMMAND | ... コマンド文字列 (パラメータも含む) |
| LOG | ... コマンド実行のログを出力するか否か (省略時は "on" ) |
|
LOG に "off" を指定すると、実行した COMMAND と実行の成否 (true/false) が、SYSLOG に出力されなくなる。LOG を省略、または "on" を指定した場合、従来と同様に実行した COMMAND と実行の成否 (true/false) を、DEBUG タイプで SYSLOG に出力する。
LOG は _RT_LUA_VERSION が "1.07" 以上のファームウェアで指定可能。
1 つ目の戻り値が true の場合、2 つ目の戻り値には、COMMAND を実行した結果、出力された文字列が格納される。1 つ目の戻り値が false の場合でも、エラーメッセージの出力があればその文字列が 2 つ目の戻り値に格納される。COMMAND を実行した結果、何も文字列が出力されなかった場合は、2 つ目の戻り値は nil になる。出力文字列の文字コードは console character コマンドの設定に従う。
例えば、rtn, str = rt.command("show status lan2")
を実行したとき、2 つの戻り値にはそれぞれ次のような情報が格納される。str は見やすくするために表記上は "\n" の部分で改行しているが、実際はすべての行が一つの文字列として str に格納されている。
rtn : true
str : "LAN2\r\n"
"説明:\r\n"
"IPアドレス: 192.168.2.1/24\r\n"
"イーサネットアドレス: 00:a0:de:00:00:00\r\n"
"動作モード設定: Auto Negotiation (Link Down)\r\n"
"最大パケット長(MTU): 1500 オクテット\r\n"
(中略)
" IPv6: 0 パケット\r\n"
また、
rtn, str = rt.command("show status tunnel 9999")
のようにコマンドの入力エラーがある場合、戻り値は次のようになる。
rtn : false str : "エラー: パラメータが範囲を越えています\r\n"
rtn, str = rt.command("ping -c 10 172.168.1.100")
if (rtn) and (str) then
loss = string.match(str, "(%d+)%.%d+%%") -- パケットロス率(NNN.N%)の整数部を抽出
if (loss ~= nil) then
loss = tonumber(loss) -- 文字列から数値へ変換
if (loss >= 30) then
rt.command("ip route default gateway pp 2")
rt.command("save")
text = string.format("パケットロス率が%d%%になったため、" ..
"デフォルト経路を変更しました",
loss)
rt.syslog("info", text)
end
end
end
当関数から ping / ping6 コマンドを COUNT オプション ( 回数指定 ) なしで実行する場合は、1 回だけ PING が送信される。
下記のルーターコマンドは当関数から実行できない。
COMMAND に指定できるコマンドは1つのみで、複数のコマンドを指定することはできない。
rt.mail(TABLE)
| TABLE | ... メール設定テーブル |
| メール設定テーブルの内容 |
| フィールド名 | 設定値 | 省略可・不可 | 初期値 |
|---|---|---|---|
| smtp_address | SMTPサーバーアドレスまたはホスト名を示す文字列 ( 最大64文字 ) | 省略不可 | - |
| smtp_port | SMTPサーバーのポート番号 (0 .. 65535) | 省略可 | smtps=false のとき 25、smtps=true のとき 465 |
| smtp_auth_name | SMTP 認証用ユーザー名を示す文字列 ( 最大64文字 ) | 省略可 | なし |
| smtp_auth_password | SMTP 認証用パスワードを示す文字列 ( 最大64文字 ) | 省略可 | なし |
| smtp_auth_protocol | SMTP-AUTH 認証プロトコルを示す文字列
|
省略可 | 順番に認証交渉を行う |
| pop_before_smtp | POP before SMTP 動作を行う場合に true を指定 smtps と同時に指定することはできない |
省略可 | false |
| pop_address | POPサーバーアドレスまたはホスト名を示す文字列 ( 最大64文字 ) | pop_before_smtp=true のとき、省略不可 |
なし |
| pop_port | POPサーバーのポート番号 (0 .. 65535) | 省略可 | 110 |
| pop_protocol | 受信プロトコルを示す文字列
|
pop_before_smtp=true のとき、省略不可 |
なし |
| pop_auth_name | POP 認証用ユーザー名を示す文字列 ( 最大64文字 ) | pop_before_smtp=true のとき、省略不可 |
なし |
| pop_auth_password | POP 認証用パスワードを示す文字列 ( 最大64文字 ) | pop_before_smtp=true のとき、省略不可 |
なし |
| timeout | 送受信処理のタイムアウト秒数(1 .. 600) | 省略可 | 60 |
| from | 送信元メールアドレスを示す文字列 | 省略不可 | - |
| to | 宛先メールアドレスを示す文字列 複数指定する場合はカンマ( , )で区切り、空白を入れてはいけない |
省略不可 | - |
| subject | 件名を示す文字列 ( 最大64文字 ) | 省略可 | 無題 |
| date | メールヘッダに表示する時刻を示す文字列 RFC822に示されるフォーマットで時刻を指定する |
省略可 | 送信時のルーターの時刻 |
| mime_version | メールヘッダに表示するMIME-Versionを示す文字列 | 省略可 | "1.0" |
| content_type | メールヘッダに表示するContent-Typeを示す文字列 type/subjectには"text/plain"、パラメータには "charset=us-ascii"および"charset=iso-2022-jp"が指定可能 |
省略可 | "text/plain; charset=iso-2022-jp" |
| text | 本文を示す文字列 ( RTX3500/RTX5000:最大8000KB, RTX3510/RTX1300/RTX1220/RTX1210:最大3MB, RTX1200:最大1250KB, RTX840/RTX830/RTX810/NVR700W/NVR510/NVR500/FWX120:最大640KB, SRT100:最大500KB ) 改行文字とタブ文字以外の制御文字を含ませることはできない |
省略可 | 本文なし |
| preface_of_text | 本文の先頭にルーターの情報を挿入しない場合 false を指定 _RT_LUA_VERSION が "1.05" 以上のファームウェアで指定可能 |
省略可 | true |
| smtps | SMTPS を用いてメールを送信する場合 true を指定 pop_before_smtp と同時に指定することはできない _RT_LUA_VERSION が "1.08" 以上のファームウェアで指定可能。 |
省略可 | false |
省略可と書かれているフィールドは、そのフィールド自体が TABLE に存在しなくても良い。省略不可のフィールドが TABLE にない場合は、API の引数誤りと見なされ、スクリプトの実行が中断される。
SMTP サーバーで認証が必要な場合は、smtp_auth_name / smtp_auth_password を設定する。
pop_before_smtp フィールドに true を設定する場合、POP サーバー関連の設定も併せて行う必要がある。
POP before SMTP と、SMTPS は併用できない。
(pop_before_smtp フィールドと、smtps フィールドは、同時に true を指定できない。)
smtp_port フィールドを省略した場合、 smtps フィールドの設定によって、SMTP サーバーのポート番号として使用する値が変わる。
smtps フィールドの設定と、SMTP サーバーのポート番号の対応は以下のとおり。
| smtps フィールド | 使用するポート番号 |
|---|---|
| false ( 省略 ) | 25 |
| true | 465 |
command = "show techinfo"
mail_table = {
smtp_address = "smtp.xxxx.co.jp",
from = "rt-admin@xxxx.co.jp",
to = "rt-admin@xxxx.co.jp",
subject = command
}
rtn, str = rt.command(command)
if (rtn) and (str) then
mail_table.text = string.format("\"%s\"の実行結果\r\n\r\n%s", command, str)
rt.mail(mail_table)
end
rt.sleep(SECONDS)
| SECONDS | ... スリープする秒数 ( 1 .. 864000 ) |
rt.syslog(TYPE, TEXT)
| TYPE | ... 書き込む SYSLOG のタイプ文字列 |
|
| TEXT | ... ログ文字列 ( 半角で最大231文字、全角で最大115文字 ) |
TYPE に "log_only" を指定すると、syslog host コマンドで SYSLOG の送信先のホストが設定されている場合でも、そのホストへの通知は行われず、ログ出力のみが行われる。
TEXT には改行文字 "\r\n" を含ませることができるが、TEXT の末尾に改行文字を入れる必要はない。なお、TEXT には改行文字以外の制御文字を含ませることはできない。
1 つ目の戻り値が true の場合、2 つ目の戻り値は nil になる。1 つ目の戻り値が false の場合、2 つ目の戻り値にエラー内容を示す文字列が格納される。
TYPE に NOTICE / DEBUG タイプを指定した場合は、対応する syslog notice/debug コマンドの設定が off になっていると SYSLOG の書き込みは行われず、書き込み結果は false が返る。TYPE に INFO タイプを指定した場合は、対応する syslog info コマンドの設定に関わらず常に SYSLOG の書き込みが行われるが、SYSLOG ホストへの通知は syslog info コマンドの設定が on になっている場合にのみ行われる。
command = "show environment"
rtn, str = rt.command(command)
if (rtn) and (str) then
cpu = string.match(str, "CPU:%s+(%d+)%%")
text = string.format("現在のCPU使用率は %s%% です", cpu)
rt.syslog("info", text)
end
rt.syslogwatch(PATTERN [, N [, SECONDS]])
| PATTERN | ... 検索文字列 |
| N | ... 検出回数 ( 1 .. 1000、省略時は 1 ) |
| SECONDS | ... 監視秒数 ( 1 .. 864000、省略時は無期限 ) |
SYSLOG の出力が行われない間、呼び出し元の Lua タスクはスリープ状態になる。
2 つ目の戻り値で返される配列には、検索文字列を含むタイムスタンプ付きの SYSLOG 行がヒットした順番に先頭要素から格納される。ヒット回数が N 回に満たずに SECONDS が満了した場合、ヒットした分の SYSLOG 行だけ 2 つ目の戻り値に格納される。何もヒットしなかった場合はヒット回数が 0 となり、2 つ目の戻り値は nil となる。
1 行の SYSLOG に複数の PATTERN が存在する場合でも、PATTERN の個数に関係なくヒット回数は 1 となる。したがって、1 つ目の戻り値のヒット回数と 2 つ目の戻り値の配列要素数は必ず一致する。つまり、PATTERN を含む SYSLOG 行の個数を表すものがヒット回数である。
例えば、rtn, str = rt.syslogwatch("100", 2)
を実行した後に、
"2009/08/22 13:11:02: [IKE] SEND ICMP Echo Request to 192.168.100.100" "2009/08/22 13:11:03: [IKE] RECV ICMP Echo Reply from 192.168.100.101"という SYSLOG が出力されたとき、戻り値は次のようになる。
rtn : 2 str[1] : "2009/08/22 13:11:02: [IKE] SEND ICMP Echo Request to 192.168.100.100" str[2] : "2009/08/22 13:11:03: [IKE] RECV ICMP Echo Reply from 192.168.100.101" str[3] : nil
mail_table = {
smtp_address = "smtp.xxxx.co.jp",
from = "rt-admin@xxxx.co.jp",
to = "rt-admin@xxxx.co.jp",
subject = "トンネルダウン"
}
rtn, str = rt.syslogwatch("IP Tunnel%[%d+%] Down")
mail_table.text = "トンネルダウンを検出しました\r\n" .. str[1]
rt.mail(mail_table)
rt.hw.open(RESOURCE [, TYPE] )
| RESOURCE | ... 制御するハードウェアを表す文字列 |
|
| TYPE | ... USB キーボードタイプを示す文字列(省略時は "jp" ) |
|
TYPE は USB キーボード "keyboard1" を制御する場合にのみ指定可能で、他のハードウェアのオープン時に指定した場合、当関数はエラー終了する。
当関数でオープンしたハードウェアは、呼び出し元の Lua タスクが占有するため、hwd:close でクローズするまでは他の Lua タスクから制御することができない。なお、温度計 "thermometer1" および CPU "cpu1" 以外のハードウェアに関しては、Lua タスクが占有しているときは他のルーターの機能からも制御することができなくなるため、ハードウェア本来の動作はしなくなる。
ハードウェアのオープンに成功した場合、1 つ目の戻り値としてディスクリプタが返り、2 つ目の戻り値は nil になる。ハードウェアのオープンに失敗した場合、1 つ目の戻り値は nil になり、2 つ目の戻り値にエラー内容を示す文字列が格納される。
ptn_unreach = "%[KEEPALIVE%]%s+1%: unreachable"
ptn_reach = "%[KEEPALIVE%]%s+1%: reachable"
while true do
rtn, str = rt.syslogwatch(ptn_unreach)
bz, err = rt.hw.open("buzzer1")
assert(bz, err)
bz:tone("B2")
rtn, str = rt.syslogwatch(ptn_reach)
bz:off()
bz:close()
end
hwd:close()
ブザーのディスクリプタをクローズする際、ブザーが鳴っていれば停止する。また LED のディスクリプタをクローズする際、LED が点灯または点滅状態であれば消灯する。スクリプト終了時にクローズされていないディスクリプタがある場合には、本関数が自動的に呼び出されてクローズされる。
led, str = rt.hw.open("status-led1")
if (led) then
led:on()
rt.sleep(60)
led:off()
led:close()
end
hwd:tone(TUNE)
| TUNE | ... 音程を表す文字列 |
TUNE は音程を表す文字列であり、"C1" のように、C、D、E、F、G、A、B のうちのアルファベットと 1 桁の数字との組合せで指定する。"C1" の "C" は音階を表し、C から順に ド、レ、ミ、ファ、ソ、ラ、シ に対応する。また、"1" は音の高さを表し、数値が 1 つ大きくなるとブザー音は 1 オクターブ高くなる。
出力できる音程は機種によって異なり、以下の表に示す音程に限られる。表に無い音程を指定した場合には入力エラーとなる。
| 機種 | 出力できる音程 |
|---|---|
| NVR500、NVR510、NVR700W、FWX120、RTX810、RTX830、RTX840、RTX1200、RTX1210、RTX1220、RTX1300、RTX3500、RTX3510、RTX5000 | B2、E3、B3、B4 |
| SRT100 | B2、B3 |
ブザーを停止させるには、hwd:off 関数を用いる。ブザーを鳴らし始めてから停止するまでの時間を制御するには、rt.sleep 関数と hwd:off 関数とを組み合わせて用いる。
ブザーが鳴っている状態で再度当関数を呼ぶなど、当関数からの指示が重複するような場合は、常に最後に呼んだときの設定でリセットされる。またディスクリプタをクローズしたり、スクリプトが終了したりすると、鳴っていたブザーは停止する。
なお alarm entire コマンドが off に設定されている場合、当関数を呼んでもブザー音は出力されない。また、ブザーが鳴っている最中に alarm entire コマンドを off に設定するとブザーは停止する。
| なし |
bz, err = rt.hw.open("buzzer1")
if (bz) then
for i = 1, 5 do
bz:tone("B3")
rt.sleep(1)
bz:tone("B2")
rt.sleep(1)
end
bz:off()
bz:close()
end
hwd:on()
| なし |
LED を消灯するには、hwd:off 関数を用いる。rt.sleep 関数と hwd:off 関数とを組み合わせて用いると、LED の点灯から消灯までの時間を制御することができる。
LED が点灯している状態で再度当関数を呼ぶなど、当関数からの指示が重複するような場合は、常に最後に呼んだときの設定でリセットされる。またディスクリプタをクローズしたり、スクリプトが終了したりすると、点灯していた LED は消灯した後、本来の動作に戻る。
| なし |
command = "show log"
mail_table = {
smtp_address = "mail.xxxx.com",
from = "net_admin@xxxx.com",
to = "net_admin@xxxx.com",
subject = command
}
led, err = rt.hw.open("status-led1")
if (led) then
led:on()
end
rtn, str = rt.command(command)
if (rtn) and (str) then
mail_table.text = string.format("\"%s\"の実行結果\r\n\r\n%s", command, str)
rt.mail(mail_table)
end
if (led) then
led:off()
led:close()
end
hwd:blink(INTERVAL_ON, INTERVAL_OFF)
| INTERVAL_ON | ... 点灯する時間( 100 .. 3000 ミリ秒) |
| INTERVAL_OFF | ... 消灯する時間( 100 .. 3000 ミリ秒) |
INTERVAL_ON / INTERVAL_OFF は、LED の点滅における点灯/消灯の時間(ミリ秒)であり、それぞれ 100 ミリ秒単位で 100 から 3000 の範囲で指定する。100 で割り切れない値が指定された場合 10 の位以下は切り捨てられる。
LED を点滅を停止するには、hwd:off 関数を用いる。rt.sleep 関数と hwd:off 関数とを組み合わせて用いると、LED の点滅時間を制御することができる。
LED が点滅している状態で再度当関数を呼ぶなど、当関数からの指示が重複するような場合は、常に最後に呼んだときの設定でリセットされる。またディスクリプタをクローズしたり、スクリプトが終了したりすると、点滅していた LED は消灯した後、本来の動作に戻る。
| なし |
ptn = "%[HEARTBEAT%]%s+Not received for a given period"
rtn, str1 = rt.syslogwatch(ptn)
led, str2 = rt.hw.open("alarm-led1")
if (led) then
led:blink(500, 500)
rt.sleep(60)
led:off()
led:close()
end
hwd:off()
hwd:read(N)
| N | ... USB キーボードから取得する文字数 |
引数 N は hwd が USB キーボードのディスクリプタの場合のみ指定することができ、hwd が温度計や CPU のディスクリプタの場合に指定すると、スクリプトがエラー終了する。
| テーブルの内容 |
| フィールド名 | データ型 | CPU 負荷率の測定間隔 |
|---|---|---|
| load_5s | 数値型 | 5 秒間 |
| load_1m | 数値型 | 1 分間 |
| load_5m | 数値型 | 5 分間 |
threshold = 50
sleep_sec = 60
temp = 0
while (true) do
th, err = rt.hw.open("thermometer1")
if (th) then
temp = th:read()
th:close()
end
if (temp > threshold) then
led, str = rt.hw.open("status-led1")
if (led) then
led:blink(500, 500)
end
else
if (led) then
led:off()
led:close()
end
end
rt.sleep(sleep_sec)
end
kbd, err = rt.hw.open("keyboard1", "jp")
if kbd then
data = kbd:read(5)
print(data)
kbd:close()
else
print(err)
end
hwd:getc([NOWAIT])
| NOWAIT | ... 論理型(省略可能) |
USB キーボードのディスクリプタ hwd に対するメソッドであり、キーボードからの出力を1文字読み取る。
NOWAIT に false を指定した場合は、ノーウェイトでキー入力を読み取ることができる。
| USB キーボードから出力される文字 (文字列型) |
kbd, str = rt.hw.open("keyboard1")
if kbd then
str = ""
n = 0
data = kbd:getc()
while data ~= '\n' do
if data then
str = str .. data
n = n + 1
data = kbd:getc()
end
end
kbd:close()
print(str .. " (" .. tostring(n) .. "文字)")
else
print(str)
end
hwd:getchar()
| なし |
NOWAIT を指定することができない点以外は hwd:getc 関数と同様に使用することができる。
| USB キーボードから出力される文字 (文字列型) |
hwd:gets()
| なし |
| USB キーボードから出力される文字 (文字列型) |
kbd, str = rt.hw.open("keyboard1")
if kbd then
data = kbd:gets()
if data then
print(data)
end
kbd:close()
else
print(str)
end
rt.httprequest(TABLE)
| TABLE | ... HTTP リクエスト設定テーブル |
| HTTP リクエスト設定テーブルの内容 |
| フィールド名 | 設定値 | 省略可・不可 | 初期値 | |||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| url |
リクエストの送信先 URL を示す文字列 "http(s)://サーバーの IP アドレスあるいはホスト名/パス名" という形式で入力する。 サーバーのポート番号が 80 (http)、または 443 (https) 以外の場合は、"http(s)://サーバーの IP アドレスあるいはホスト名:ポート番号/パス名" という形式で、URL の中に指定する。 指定可能な最大文字数は以下の通り。
|
省略不可 | - | |||||||||||||||||||||
| method | リクエストに使用する HTTP メソッドを示す文字列
|
省略不可 | - | |||||||||||||||||||||
| proxy | リクエストに使用する proxy サーバーを示す文字列 ( 最大128文字 ) | 省略可 | なし | |||||||||||||||||||||
| proxy_port |
リクエストに使用する proxy サーバーのポート番号 (1 .. 65535) proxy フィールドに proxy サーバーを指定し、かつ本フィールドを省略した場合には、本フィールドに 80 が指定されたものとして動作する。 |
省略可 | なし | |||||||||||||||||||||
| auth_type | 認証方式を示す文字列
|
省略可 | none | |||||||||||||||||||||
| auth_name | 認証用ユーザー名を示す文字列 ( 最大64文字 ) | auth_type="basic" のとき、省略不可 |
なし | |||||||||||||||||||||
| auth_pass | 認証用パスワードを示す文字列 ( 最大64文字 ) | auth_type="basic" のとき、省略不可 |
なし | |||||||||||||||||||||
| auth_token | 認証用トークンを示す文字列 ( 最大256文字 ) _RT_LUA_VERSION が "1.08" 以上のファームウェアで指定可能 |
auth_type="bearer" のとき、省略不可 |
なし | |||||||||||||||||||||
| timeout | リクエスト処理のタイムアウト秒数 (1 .. 180) | 省略可 | 30 | |||||||||||||||||||||
| save_file |
レスポンスデータをファイル保存する場合の保存先のパスを示す 文字列 ( 最大64文字 ) configN ( N = 0 .. 4 )を指定すれば設定ファイルへの書き込みができる ( NVR500 は N = 0 のみ) method に "HEAD" を指定した場合は無視される |
省略可 | なし | |||||||||||||||||||||
| post_text |
POST メソッドで送信するデータ本体を表す文字列 ( RTX3500/RTX5000:最大8000KB, RTX3510/RTX1300/RTX1220/RTX1210:最大3MB, RTX1200:最大1250KB, RTX840/RTX830/RTX810/NVR700W/NVR510/NVR500/FWX120:最大640KB, SRT100:最大500KB ) method に "GET" もしくは "HEAD" を指定した場合は無視される post_file と同時に指定することはできない |
method="POST" のとき、省略不可 |
なし | |||||||||||||||||||||
| post_file |
POST メソッドで送信するファイル名のパスを示す 文字列 ( 最大64文字 ) method に "GET" もしくは "HEAD" を指定した場合は無視される post_text と同時に指定することはできない |
method="POST" のとき、省略不可 |
なし | |||||||||||||||||||||
| content_type |
POST メソッドで送信するデータの形式を示す文字列 ( 最大128文字 ) method に "GET" もしくは "HEAD" を指定した場合は無視される |
method="POST" のとき、省略不可 |
なし |
省略可と書かれているフィールドは、そのフィールド自体が TABLE に存在しなくても良い。省略不可のフィールドが TABLE にない場合は、API の引数誤りと見なされ、スクリプトの実行が中断される。
HTTP リクエスト送信先のサーバーで認証が必要な場合は、認証方式に応じて以下の設定をする。
受信したデータは、save_file に保存先のパスを指定することにより、RTFS 領域や外部メモリにファイルとして保存することができる。保存することのできるファイルの容量は、RTFS や外部メモリの仕様に従う。また save_file に configN ( N = 0 .. 4, NVR500 は N = 0 のみ ) を指定した場合、設定ファイルへの書き込みが行われる。save_file に相対パスを指定した場合、環境変数 PWD を基点としたパスと解釈される。PWD は set コマンドで変更可能であり、初期値は "/" である。なお RTFS 領域や外部メモリに configN というファイル名でファイルを保存したい場合には、save_file に相対パスではなく絶対パスで指定する必要がある。
POST メソッドでデータを送信するには HTTPサーバー側で受信できる形式に合わせて content_type を指定する。指定できる文字列の例としては "application/x-www-form-urlencoded" 等がある。post_text に指定する文字列や post_file の内容も content_type に従った形式のデータである必要がある。(使用例 3、4 を参照)なお、ルーター内部では日本語漢字コードとして Shift-JIS が用いられているため、content_type に指定した文字列は Shift-JIS の文字列となるが、漢字コードを UTF-8 等に変換する必要がある場合には、漢字コード変換ライブラリを用いて変換するとよい。
_RT_LUA_VERSION が "1.08" 以上のファームウェアの場合、url に "https://" から始まる URL を指定すると、SSL による通信を行う。
| HTTP リクエストの実行結果及びレスポンスデータ(テーブル型) |
| 戻り値テーブルの内容 |
| フィールド名 | データ型 | データの内容 |
|---|---|---|
| rtn1 | 論理型 | HTTP リクエストの送信結果
|
| rtn2 | 論理型 | ファイル入出力の結果
|
| err | 文字列型 | エラーメッセージ |
| code | 数値型 | HTTP ステータスコード |
| header | 文字列型 | レスポンスデータのヘッダ |
| body | 文字列型 | レスポンスデータ本体 |
rtn1 は HTTP リクエストの送信結果を表し、サーバーからのレスポンスデータの受信に成功すると true が、失敗すると false が格納される。rtn2 はファイル入出力の結果を表し、save_file/post_file で指定したファイルの入出力に成功すると true が、失敗すると false が格納される。ファイルの入出力が行われない場合には、戻り値テーブルに rtn2 は存在しない。err には HTTP リクエストの送信やファイル入出力でエラーが発生した場合にエラーメッセージが格納される。エラーが発生しなかった場合には、戻り値テーブルに err は存在しない。
サーバーからのレスポンスデータの受信に成功した場合、code には HTTP ステータスコードが、header にはレスポンスデータのヘッダが、body にはレスポンスデータの本体が格納される。body に格納できるデータ容量には上限があり、RTX3500/RTX5000 では最大 2MB、RTX3510/RTX1300/RTX1220/RTX1210/RTX1200/RTX810/RTX830/NVR500/NVR510/NVR700W/FWX120 では最大 1MB、SRT100 では最大 250KB となる。受信したデータ容量が body に格納できる上限を超えた場合には、body は nil となる。画像データ等、大容量のデータを受信する場合には、save_file に外部メモリ上のファイルを指定して保存するとよい。また method に HEAD を指定した場合や、レスポンスデータが空の場合には戻り値テーブルに body は存在しない。
req_table = {
url = "http://www.exmaple.com/doc/manual.doc",
method = "GET",
save_file = "usb1:/docs/manual.doc"
}
rsp_table = rt.httprequest(req_table)
を実行した結果として、以下の 6 通りを考える。
このとき戻り値テーブル rsp_table には次のような情報が格納される。"-" は、テーブルにフィールドが存在しないことを示す。
| 条件 | rtn1 | rtn2 | err | code | header | body |
| 1 | true | true | - | 200 | (受信したヘッダ) | (受信したデータ本体) |
| 2 | true | false | "File write error(usb1:/docs/manual.doc)" | 200 | (受信したヘッダ) | (受信したデータ本体) |
| 3 | false | true | "Received data size is exceeded the upper limit" | 200 | (受信したヘッダ) | - |
| 4 | false | false | "File write error(usb1:/docs/manual.doc)" | 200 | (受信したヘッダ) | - |
| 5 | false | - | "Request timeout" | - | - | - |
| 6 | true | true | - | 404 | (受信したヘッダ) | (受信したデータ本体) |
条件 5 では、ファイルの入出力が行われる前にタイムアウトとなったため、ファイル入出力の結果である rtn2 には値が存在しない。条件 6 のようにサーバー上に指定したファイルが見つからなかったものの、HTTP リクエスト、受信データのファイルへの書き込みが成功し、rtn1/rtn2 共に true が格納される場合もあるため、注意が必要となる。
req_t = {
url = "http://www.exmaple.com/doc/manual.html",
method = "GET",
save_file = "usb1:/dir2/manual.html"
}
rsp_t = rt.httprequest(req_t)
assert(rsp_t.rtn2, rsp_t.err)
req_t = {
url = "http://www.exmaple2.net/setting/config.txt",
method = "GET",
auth_type = "basic",
auth_name = "user1",
auth_pass = "password1",
save_file = "config1"
}
rsp_t = rt.httprequest(req_t)
if (rsp_t.rtn1) and (rsp_t.rtn2) then
rt.syslog("info", "[LUA] Download and write config success.")
end
pattern = "IP Tunnel%[%d+%] Down"
req_t = {
url = "http://xxx.co.jp/bbs/bbs.cgi",
method = "POST",
auth_type = "basic",
auth_name = "user2",
auth_pass = "password2",
content_type = "application/x-www-form-urlencoded"
}
while (true) do
rtn, array = rt.syslogwatch(pattern, 1, 600)
if (rtn > 0) then
req_t.post_text = string.format("status=Tunnel Down: %s\n", string.match(array[1], pattern)))
rt.httprequest(req_t)
end
end
----------------------------------------------------
-- アップロードするデータを作成するための関数
----------------------------------------------------
-- ファイル名を作成する関数
function make_filename(name)
local t = os.date("*t")
return string.format("%s_%d%02d%02d%02d%02d%02d.txt",
name, t.year, t.month, t.day, t.hour, t.min, t.sec)
end
-- 境界文字列を作成する関数
function make_boundary()
math.randomseed(os.time())
return string.format("__________%d", math.random(999999))
end
-- アップロードするデータを作成する関数
function make_data(f, d, b)
local disp = string.format("Content-Disposition: form-data; name=\"config\"; filename=\"%s\"\r\n", f)
local type = string.format("Content-type: text/plain\r\n\r\n")
return string.format("--%s\r\n%s%s%s\r\n--%s--\r\n\r\n", b, disp, type, d, b)
end
----------------------------------------------------
-- 設定ファイルをアップロードするスクリプト
----------------------------------------------------
-- HTTPリクエストテーブルを作成
req_t = {
url = "http://www.xxx.net/upload_cfg.cgi",
method = "POST"
}
bound = make_boundary()
req_t.content_type = "multipart/form-data; boundary=" .. bound
-- アップロードするファイル名を作成
fname = make_filename("config")
-- show configコマンドを実行して、設定を取得
rtn, str = rt.command("show config")
if (rtn) and (str) then
-- アップロードするデータを作成
req_t.post_text = make_data(fname, str, bound)
-- 作成したデータのアップロードを実行
rsp_t = rt.httprequest(req_t)
if (rsp_t.rtn1) then
print("Upload success : ", fname)
else
print("Upload failed.")
end
else
print("Upload failed.")
end
ソケット通信ライブラリは、LuaSocketのC言語で記述されたライブラリ関数を移植したものです。LuaSocketのバージョンは 2.0.2 です。
LuaSocketはC言語で書かれたライブラリ関数と、Lua言語で書かれたライブラリ関数に分かれています。C言語で書かれたライブラリ関数が、ソケットシステムコールを呼び出すような低レベルの関数を用意しているのに対して、Lua言語で書かれたライブラリ関数は、HTTPやFTP、SMTP等のアプリケーションを利用するための関数を用意しています。
ルーターにはLuaSocketのC言語で書かれたライブラリ関数をAPIとして移植しているため、Lua言語のライブラリ関数についてもLuaSocketのホームページで公開されているスクリプトをそのまま使用することができません。以下にあるヤマハルーター用LuaSocketモジュールファイルを使用してください。
また、Lua言語で書かれたライブラリ関数についてはLuaSocketのリファレンスをご覧ください。
ヤマハルーター用LuaSocketモジュールファイル
本ライブラリでは、ソケットオブジェクトを生成し、オブジェクト単位での通信を行います。オブジェクトはプロトコル毎に性質が異なり、特定の関数によって状態を遷移させます。
| マスターオブジェクト: | rt.socket.tcp()にて生成されるオブジェクト。 |
| サーバーオブジェクト: | TCPコネクションを待ち受け可能な状態となったオブジェクト。 マスターオブジェクトがtcp:listen()をコールしコネクションの待ち受け状態に なるとサーバーオブジェクトに遷移する。 |
| クライアントオブジェクト: | リモートホストとのコネクションが確立し、データの送受信が可能な状態と なったオブジェクト。 マスターオブジェクトがconnectをコールしてクライアントオブジェクトに 遷移するか、サーバーオブジェクトでacceptを実行し、接続が確立した際に クライアントオブジェクトを返す。 |
| connectedオブジェクト: | 特定のホストとのみ通信を行うオブジェクト。unconnectedオブジェクトが setpeernameで接続相手を指定するとconnectedオブジェクトに遷移する。この オブジェクトでは、送受信にはsend/receiveを使用しなければならない。 |
| unconnectedオブジェクト: | 不特定のホストと通信が可能なオブジェクト |
| プロトコル | 機能名 | ポート番号 |
|---|---|---|
| TCP | www設定 | 80 (*) |
| TELNETサーバー | 23 (*) | |
| SSHサーバー | 22 (*) | |
| BGP | 179 | |
| PPTP | 1723 | |
| SIP | 5060 | |
| ONFS | 49501, 49502 (*) | |
| TCP (Socket) |
49152〜65535 (vRXシリーズ (Amazon EC2版 Rev.19.00.01を除く)) 1024〜5000 (その他の機種) |
|
| UDP | UDP ECHO | 7 |
| 生存通知 | 9 | |
| DNS | 53、始点ポート:10000〜10999 (*) | |
| DHCPサーバー | 67 | |
| DHCPクライアント | 68 | |
| TFTPサーバー | 69 | |
| SNMP | 161 | |
| IKE | 500 | |
| SYSLOG | 514 (*) | |
| RIP | 520 | |
| RIPng | 521 | |
| DHCP6クライアント | 546 | |
| DHCP6エージェント | 547 | |
| RADIUS | 1645 | |
| L2TP | 1701 | |
| UPnP | 1900 | |
| ネットボランチDNS | 2002 (*) | |
| MGCP | 2427〜2433 | |
| NATトラバーサル | 4500 | |
| データコネクト拠点間接続 | 4502 | |
| RTP | 5004〜5059 (*) | |
| SIP | 5060 | |
| 生存通知2 | 8512 | |
| QoS連携(負荷通知、帯域検出) | 59140 (*) | |
| UDP (Socket) |
49152〜65535 (vRXシリーズ (Amazon EC2版 Rev.19.00.01を除く)) 21024〜25000 (その他の機種) |
rt.socket.tcp()
オブジェクトの生成に成功した場合、1つ目の戻り値としてユーザデータ型のマスターオブジェクトが返り、2つ目はnilとなる。
エラーの場合には、1つ目の戻り値はnilとなり、2つ目の戻り値にエラーメッセージを格納する。
tcp = rt.socket.tcp()
tcp:setoption("reuseaddr", true)
res, err = tcp:bind("192.168.100.1", 11111)
if not res and err then
print(err)
os.exit(1)
end
res, err = tcp:listen()
if not res and err then
print(err)
os.exit(1)
end
while 1 do
control = assert(tcp:accept())
raddr, rport = control:getpeername()
print("remote host address:" .. raddr .. " port:" .. rport)
-- 受信待ちタイムアウトを30秒に設定
control:settimeout(30)
while 1 do
msg, err, partial = control:receive()
if (msg) then
local data
-- 受信データを処理する(例として、ここではコンソールに出力している)
print(msg)
-- レスポンスを送信
sent, err = control:send(data)
if (err) then
print("send error(" .. err .. ")")
control:close()
break
end
else
if (err ~= "closed") then
print(os.date() .. "receive error(" .. err .. ")")
if (partial) then
print("receive partial data(" .. partial .. ")")
end
end
control:close()
break;
end
end
end
tcp = rt.socket.tcp()
res, err = tcp:connect("192.168.100.1", 11111)
if not res then
print("connect error(" .. err .. ")")
os.exit(1)
end
print("Connected remote host:" ..host.. " port:" .. port)
lhost, lport = tcp:getsockname()
tcp:settimeout(5)
tcp:setoption("tcp-nodelay", true)
-- データを送信する
sent, err = tcp:send("test\n")
if (err) then
print("send error(" .. err .. ")")
tcp:close()
os.exit(1)
end
-- サーバーからのレスポンスを受信
data, err, partial = tcp:receive()
if (err) then
print("receive error("..err..")")
if (partial) then
print("receive partial data("..partial..")")
end
end
-- 受信データを処理する
...
tcp:close()
rt.socket.udp()
オブジェクトの生成に成功した場合、1つ目の戻り値としてユーザデータ型のUDPオブジェクトが返り、2つ目はnilとなる。
エラーの場合には、1つ目の戻り値はnilとなり、2つ目の戻り値にエラーメッセージを格納する。
host = "192.168.100.1"
port = 22222
udp = rt.socket.udp()
res, err = udp:setsockname(host, port)
if (err) then
print("setsockname error(" .. err .. ")")
udp:close()
os.exit(1)
end
lhost, lport = udp:getsockname()
print("Bind to host:" ..lhost.. " and port:" ..lport)
while 1 do
dgram, ip, port = udp:receivefrom()
if (dgram ~= nil) then
-- 受信データを処理する
-- (例として、ここではコンソールに出力し、受信した文字列をそのまま相手に返している)
print("Received '" .. dgram .. "' from " .. ip .. ":" .. port)
udp:sendto(dgram, ip, port)
else
print(ip)
udp:close()
os.exit(0)
end
end
udp = rt.socket.udp()
udp:setpeername("192.168.100.1", 22222)
rhost, rport = udp:getpeername()
print("remote host:" .. rhost .. " port:" .. rport)
-- データを送信
res, err = udp:send("test")
if (err) then
print("send error(" .. err .. ")")
udp:close()
os.exit(1)
end
udp:settimeout(10) -- 受信タイムアウトを10秒に設定
-- 相手からのレスポンスを受信
dgram, err = udp:receive()
if (not dgram) and err then
print("receive error("..err..")")
udp:close()
os.exit(1)
end
-- 受信データを処理する(例として、ここではコンソールに出力している)
print(dgram)
udp:close()
rt.socket.select(RECVT, SENDT[, TIMEOUT])
| RECVT | ... 読み込み可能状態を待つオブジェクト(ユーザーデータ型)の配列(読み込み待ちをしない場合には、nilまたは空のテーブルを指定) |
| SENDT | ... 書き出し可能状態を待つソケット(ユーザーデータ型)の配列(書き出し待ちをしない場合には、nilまたは空のテーブルを指定) |
| TIMEOUT | ... 状態変化を待つ秒数 (1 - 2147483647、負数および省略時は無期限) |
オブジェクトの配列として返されるテーブルは、整数とオブジェクト自身がキーとなっている。
エラーメッセージには、タイムアウトの場合には"timeout"が格納され、それ以外の場合にはnilとなる。
function create(addr, port)
s = rt.socket.tcp()
s:setoption("reuseaddr", true)
res, err = s:bind(addr, port)
if not res and err then
print(err)
os.exit(1)
end
res, err = s:listen()
if not res and err then
print(err)
os.exit(1)
end
return s
end
server1 = create("192.168.100.1", 11111)
server2 = create("192.168.100.1", 11112)
while 1 do
rcv, snd, err = rt.socket.select({server1, server2}, nil)
if rcv[server1] then
server = server1
elseif rcv[server2] then
server = server2
else
print("select error:"..err)
os.exit(1)
end
control = assert(server:accept())
raddr, rport = control:getpeername()
print("remote host address:" .. raddr .. " port:" .. rport)
-- 統計情報をクリア
res = control:setstats(0, 0)
-- 受信待ちタイムアウトを30秒に設定
control:settimeout(30)
while 1 do
msg, err, partial = control:receive()
if (msg) then
-- 受信データを処理する(例として、ここではコンソールに出力している)
print(msg)
-- レスポンスを送信
sent, err = control:send("response\n")
if (err) then
print("send error(" .. err .. ")")
control:shutdown()
break
end
else
if (err ~= "closed") then
print(os.date() .. "receive error(" .. err .. ")")
if (partial) then
print("receive partial data(" .. partial .. ")")
end
end
control:shutdown()
break;
end
end
rcv, snd, alive = control:getstats()
-- 統計情報を表示
print("receive: " .. rcv .. "bytes, send: " .. snd .. "bytes, alive time: " .. alive .. "sec")
end
rt.socket.dns.toip(HOSTNAME)
| HOSTNAME | ... IPv4アドレス、またはホスト名 |
成功した場合、1つ目の戻り値にはIPv4アドレスを返し、2つ目の戻り値にリゾルバからの全ての情報を格納する。リゾルバからの情報は次のテーブルで返される。
| キー文字列 | 設定値 | 型 |
|---|---|---|
| name | ホストの正式名称。 | 文字列型 |
| alias | ホストの別名。 (*)ヤマハルーターではホストの別名は取得できませんので、空のテーブルを返します。 |
文字列型の配列 |
| ip | IPv4アドレス。 (*)配列を返しますが、IPv4アドレスは1つだけです。 |
文字列型の配列 |
エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージが格納される。
host = "example.com" -- ホスト名を指定 ip, tbl = rt.socket.dns.toip(host) if ip then print(ip) -- 成功した場合、IPアドレスが返される end
rt.socket.dns.tohostname(ADDRESS)
| ADDRESS | ... IPv4アドレス、またはホスト名 |
成功した場合、1つ目の戻り値にはホスト名を返し、2つ目の戻り値にリゾルバからの全ての情報を格納する。リゾルバからの情報は次のテーブルで返される。
| キー文字列 | 設定値 | 型 |
|---|---|---|
| name | ホストの正式名称。 | 文字列型 |
| alias | ホストの別名。 (*)ヤマハルーターではホストの別名は取得できませんので、空のテーブルを返します。 |
文字列型の配列 |
| ip | IPv4アドレス。 (*)配列を返しますが、IPv4アドレスは1つだけです。 |
文字列型の配列 |
エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージが格納される。
ip = "10.0.0.1" -- IPアドレスを指定 host, tbl = rt.socket.dns.tohostname(ip) if host then print(host) -- 成功した場合、ホスト名が返される end
rt.socket.dns.gethostname()
ネットボランチDNS や、ip hostコマンドで設定されたルーター自身のホスト名を返す。
成功した場合、1つ目の戻り値にはホスト名を返し、2つ目の戻り値は nil となる。
エラーの場合は、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージが格納される。
host, err = rt.socket.dns.gethostname(host) if host then print(host) -- 成功した場合、ルーター自身のホスト名が返される end
rt.socket.sleep(SECONDS)
| SECONDS | ... スリープする秒数 ( 1 .. 2147483647 ) |
-- 10分置きにUDPパケットを送信する
udp = rt.socket.udp()
udp:setpeername("192.168.100.1", 22222)
while true do
-- データを送信
res, err = udp:send("notification")
if (err) then
print("send error(" .. err .. ")")
udp:close()
os.exit(1)
end
rt.socket.sleep(600)
end
udp:close()
rt.socket.gettime()
t1 = rt.socket.gettime()
-- 何かしらの処理をする。
...
t2 = rt.socket.gettime() - t1
print("execute time:" .. t2)
rt.socket.newtry(FINALIZER)
| FINALIZER | ... 例外エラーを投げる前に呼ばれる関数 |
FINALIZERは、例外エラーを投げる前に保護モードで呼ばれる関数である。
c = rt.socket.tcp()
sample = rt.socket.protect(function()
-- エラー発生時にclose()を呼ぶ関数の生成
local try = rt.socket.newtry(function() c:close() end)
-- エラー発生時には必ずソケットが閉じられる
try(c:connect("192.168.100.1", 8888))
try(c:send("test\r\n"))
local answer = try(c:receive())
-- 受信データを処理する
...
return c:close()
end)
ret, err = sample()
if not ret and err then
print(err)
end
rt.socket.protect(FUNC)
| FUNC | ... 例外エラーを投げる関数 |
FUNCには、newtryやassert、errorを呼んで例外エラーを投げる関数を指定する。
rt.socket.skip(NUM[, RET1, RET2, ..RETN])
| NUM | ... 破棄する引数の数(1 .. 2147483647) |
| RET1, RET2 ..RETN | ... 引数 |
RET1, RET2.. と列挙した引数のうち、最初からNUM個の引数を破棄し、残りのRET[NUM+1]からRETNまでの引数を返す。この関数を使用すると、不要な関数の戻り値を格納するためにダミー変数を用意する必要がなくなる。
NUM+1番目以降の引数がある場合、NUM+1番目以降の引数を返す。NUMが引数と同じか、引数の数より大きい場合、またはNUMが負数の場合には、戻り値はない。
-- パターンに合致した位置を表す数値を破棄し、キャプチャされた文字列だけを返す。
r = rt.socket.skip(2, string.find("ABCDE", "B(.)D"))
print(r)
-- コンソールにはキャプチャされた以下の文字が表示される。
-- C
rt.socket._VERSION
tcp:accept()
この関数は、サーバーオブジェクトで使用することができる。
コネクションが完了した場合には1つ目の戻り値にユーザデータ型のクライアントオブジェクトを返し、2つ目の戻り値は nil になる。
エラーの場合には、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージを格納する。
tcp:bind(ADDRESS, PORT)
| ADDRESS | ... IPv4アドレス、またはホスト名 |
| PORT | ... ポート番号(0 .. 65535) |
ADDRESSに "*" を指定した場合、INADDR_ANYを使用して全てのインタフェースに割り当てる。
PORTに0を指定した場合、システムがポート番号を自動的に割り当てる。割り当てるポート番号の範囲は、注意事項のポート番号表に「TCP (Socket)」として記載している。
DHCPサーバーからIPアドレスが割り当てられるなど動的にIPアドレスが決定される場合には、addressに"*" を指定する。
この関数は、マスターオブジェクトで使用することができる。
成功した場合には、1つ目の戻り値に 1 を返し、2つ目の戻り値は nil になる。
エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージを格納する。
tcp:listen(BACKLOG)
| BACKLOG | ... 保留中の接続キューの最大長(0 .. 128) (省略時は 32) |
この関数は、マスターオブジェクトで使用することができ、成功した場合にはサーバーオブジェクトへ遷移する。
成功した場合には、1つ目の戻り値に 1 を返し、2つ目の戻り値は nil になる。
エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージを格納する。
tcp:close()
オブジェクトで使用するソケットを閉じ、オブジェクトに割り当てられていたアドレス、ポート番号は他のアプリケーションで使用可能になる。
この関数は、マスターオブジェクト、サーバーオブジェクト、クライアントオブジェクトで使用することができる。
tcp:connect(ADDRESS, PORT)
| ADDRESS | ... IPv4アドレス、またはホスト名 |
| PORT | ... ポート番号(1 .. 65535) |
接続に成功した場合、関数を呼び出したマスターオブジェクトはクライアントオブジェクトに遷移する。
この関数は、マスターオブジェクトで使用することができる。
成功した場合には、1つ目の戻り値に 1 を返し、2つ目の戻り値は nil になる。
エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージを格納する。
tcp:getpeername()
この関数は、クライアントオブジェクトで使用することができる。
成功した場合には、1つ目の戻り値にIPアドレスを返し、2つ目の戻り値にポート番号を返す。
エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージを格納する。
tcp:getsockname()
この関数は、マスターオブジェクト、サーバーオブジェクト、クライアントオブジェクトで使用することができる。
成功した場合には、1つ目の戻り値にIPアドレスを返し、2つ目の戻り値にポート番号を返す。
エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージを格納する。
tcp:getstats()
この関数は、マスターオブジェクト、サーバーオブジェクト、クライアントオブジェクトで使用することができる。
tcp:receive([PATTERN[, PREFIX]])
| PATTERN | ... データを受信するパターンを指定する(省略時は '*l')
|
| PREFIX | ... 受信データの前に付加する文字列 |
データはPATTERNで指定した受信パターンによって読み込まれる。また、PREFIXを指定した場合には、受信したデータの前にPREFIXが付加される。
この関数は、クライアントオブジェクトで使用することができる。
成功した場合には、1つ目の戻り値に受信したデータを返し、2つ目および3つ目の戻り値は nil になる。
エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージを格納する。3つ目の戻り値には、エラーとなるまでに受信したデータを返す。指定したパターンによる受信が完了する前にコネクションが閉じられた場合には、エラーメッセージとして "closed" を返す。
tcp:send(DATA[, TOP[, TAIL]])
| DATA | ... 送信するデータ(文字列型) |
| TOP | ... 送信するDATAの最初の位置(省略時は 1) |
| TAIL | ... 送信するDATAの最後の位置(省略時はDATAの末尾) |
TOPおよびTAILを指定した場合、DATAのTOPの位置からTAILの位置までの間にあるデータを送信する。
TOPやTAILに負数を指定した場合、DATAの末尾から指定した数を引いた位置となり、位置がDATA内に収まらない場合には、省略時の値が適用される。
TOPよりもTAILの位置が前に来る場合には送信は行われない。
この関数は、クライアントオブジェクトで使用することができる。
成功した場合には、1つ目の戻り値には送信したDATAの最後の位置を返し、2つ目および3つ目の戻り値は nil になる。
エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージを格納し、3つ目の戻り値にはエラーが発生するまでに送信したデータの最後の位置を返す。
tcp:setoption(OPTION, VALUE)
| OPTION | VALUE | 説明 |
| reuseaddr | true | ローカルアドレスの再利用を許可する |
| false | ローカルアドレスの再利用を許可しない | |
| tcp-nodelay | true | Nagleアルゴリズムを有効にする |
| false | Nagleアルゴリズムを無効にする |
オプションは低レベルなアプリケーションや、時間に厳密なアプリケーションで必要とされる。
この関数は、サーバーオブジェクト、クライアントオブジェクトで使用することができる。
tcp:setstats([RECEIVED[, SENT[, AGE]]])
| RECEIVED | ... 受信バイト数(省略時は、現在の受信バイト数) |
| SENT | ... 送信バイト数(省略時は、現在の送信バイト数) |
| AGE | ... 生存時間(秒)(省略時は、現在の生存時間) |
この関数は、RECEIVEDおよびSENTに0を指定して一定期間の送受信量を計測する等に利用することができる。
この関数は、マスターオブジェクト、サーバーオブジェクト、クライアントオブジェクトで使用することができる。
tcp:settimeout(VALUE[, MODE])
| VALUE | ... タイムアウト時間
|
| MODE | ... タイムアウトのモード
|
初期状態のオブジェクトではすべての入出力操作がブロッキングモードで行われる。したがって、send、receive、acceptの各関数の実行では命令が完了するまでの間、無期限にブロックされることになる。
タイムアウト時間を設定し指定した時間が経過した場合、ブロックしていた関数は処理を中止してエラーを返す。
この関数は、マスターオブジェクト、サーバーオブジェクト、クライアントオブジェクトで使用することができる。
成功した場合には、1つ目の戻り値に 1 を返し、2つ目の戻り値は nil になる。エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージを格納する。
tcp:shutdown([MODE])
| MODE | ... 遮断する方向(文字列型)
|
この関数は、クライアントオブジェクトで使用することができる。
udp:close()
オブジェクトで使用するソケットを閉じ、オブジェクトに割り当てられていたアドレス、ポート番号は他のアプリケーションで使用可能になる。
この関数は、connectedオブジェクト、unconnectedオブジェクトで使用することができる。
udp:getpeername()
この関数は、connectedオブジェクトで使用することができる。
成功した場合には、1つ目の戻り値にIPアドレスを返し、2つ目の戻り値にポート番号を返す。
エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージを格納する。
udp:getsockname()
UDPでは、setsockname または sendto のどちらかを最初にコールするまで、どのアドレスも bind されない。その場合には、ワイルドカードアドレスと一時的なポートが bind される。
この関数は、connectedオブジェクト、unconnectedオブジェクトで使用することができる。
成功した場合には、1つ目の戻り値にIPアドレスを返し、2つ目の戻り値にポート番号を返す。
エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージを格納する。
udp:receive([SIZE])
| SIZE | ... 受信するデータグラムの最大サイズ(1 .. 2048、省略時は 2048バイト) |
SIZEに指定したデータサイズと、デフォルトの最大サイズ(2048バイト)のうち、小さい方の値を使用する。
この関数は、connectedオブジェクト、unconnectedオブジェクトで使用することができる。
connectedオブジェクトは接続した相手からのデータだけ受信し、unconnectedオブジェクトは不特定のホストからのデータを受信する。
成功した場合には、1つ目の戻り値に受信したデータを返し、2つ目の戻り値は nil になる。
エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージを格納する。
udp:receivefrom([SIZE])
| SIZE | ... 受信するデータグラムの最大サイズ(1 .. 2048、省略時は 2048バイト) |
SIZEに指定したデータサイズと、デフォルトの最大サイズ(2048バイト)のうち、小さい方の値を使用する。
udp:receive()が受信したデータだけを返すのに対して、udp:receivefrom()は受信したデータの他に、相手先の情報(IPアドレス、ポート番号)も返す。
この関数は、unconnectedオブジェクトで使用することができる。
成功した場合には、1つ目の戻り値に受信したデータを返し、2つ目の戻り値はデータを送信したホストのIPアドレス、3つ目はポート番号が返される。
エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージを格納する。
udp:send(DATAGRAM)
| DATAGRAM | ... 送信するデータ(文字列型) |
UDPでの送信ではブロックしない。
この関数は、connectedオブジェクトで使用することができる。
成功した場合には、1つ目の戻り値には送信したバイト数を返し、2つ目の戻り値は nil になる。
エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージを格納する。
udp:sendto(DATAGRAM, IP, PORT)
| DATAGRAM | ... 送信するデータ(文字列型) |
| IP | ... 宛先IPv4アドレス |
| PORT | ... 宛先ポート番号(1 .. 65535) |
IPにはIPアドレスを指定する。
UDPでの送信ではブロックしない。
この関数は、unconnectedオブジェクトで使用することができる。
成功した場合には、1つ目の戻り値には送信したバイト数を返し、2つ目の戻り値は nil になる。
エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージを格納する。
udp:setpeername(ADDRESS, PORT)
| ADDRESS | ... IPアドレスまたはホスト名、'*' |
| PORT | ... ポート番号(1 .. 65535) |
この関数は、connectedオブジェクト、unconnectedオブジェクトで使用することができる。
unconnectedオブジェクトで指定した相手との対応付けが行われると、connectedオブジェクトへ遷移する。connectedオブジェクトでは、送受信を行う際に send、receive 関数を使用しなければならない。
connectedオブジェクトにおいて、通信相手との対応付けを解除する場合、ADDRESSに '*' を指定し、PORTは省略する。通信相手との対応付けが解消されると、unconnectedオブジェクトへと遷移する。
成功した場合は、1つ目の戻り値に 1 を返し、2つ目の戻り値は nil になる。
エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージを格納する。
udp:setsockname(ADDRESS, PORT)
| ADDRESS | ... IPアドレスまたはホスト名、'*' |
| PORT | ... ポート番号(0 .. 65535) |
ADDRESSに '*' を指定した場合、INADDR_ANYを使用して全てのローカルインタフェースに対して関連付けを行う。
PORTに0を指定した場合、システムがポート番号を自動的に割り当てる。割り当てるポート番号の範囲は、注意事項のポート番号表に「UDP (Socket)」として記載している。
この関数は、unconnectedオブジェクトでデータを送信する前に1度だけ使用することができる。また、この関数を省略した場合、UDPでデータを送信するときに、システムが全てのローカルインタフェースに関連付け、一時的なポートの割り当てを行う。
成功した場合は、1つ目の戻り値に 1 を返し、2つ目の戻り値は nil になる。
エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージを格納する。
udp:settimeout(VALUE)
| VALUE | ... タイムアウト時間
|
初期状態のオブジェクトではすべての入出力操作がブロッキングモードで行われる。したがって、receive、receivefromの両関数の実行では命令が完了するまでの間、無期限にブロックされることになる。
UDPでは、sendおよびsendtoはブロックされないため、送信時には本関数による影響はない。
タイムアウト時間を設定し指定した時間が経過した場合、ブロックしていた関数は処理を中止してエラーを返す。
この関数は、connectedオブジェクト、unconnectedオブジェクトで使用することができる。
成功した場合には、1つ目の戻り値に 1 を返し、2つ目の戻り値は nil になる。エラーの場合、1つ目の戻り値は nil となり、2つ目の戻り値にエラーメッセージを格納する。
rt.mime.b64(DATA1[, DATA2])
| DATA1、DATA2 | ... エンコードする文字列またはバイナリデータ(文字列型) |
DATA2を指定した場合、DATA1とDATA2を連結してBase64エンコードを行う。パディングは行わず、エンコードできなかった残りのバイトデータ(文字列型)は2番目の戻り値に格納される。
DATA2を省略した場合、DATA1をBase64エンコードする。このとき、必要に応じてパディングを付与する。
DATA2を省略した場合、1つ目の戻り値にはDATA1をエンコードしたデータが格納される。このとき、DATA1全体がエンコードされるよう必要に応じてパディングを付与する。2つ目の戻り値は nil となる。
DATA2を指定した場合、1つ目の戻り値にはDATA1とDATA2を連結した文字列をエンコードしたデータが格納される。エンコードできない残りの文字列は、2つ目の戻り値に格納される。パディングは付与されない。
estr = rt.mime.b64("test")
print(estr)
-- estr = dGVzdA==
rt.mime.dot(NUM[, DATA])
| NUM | ... 直前のデータの最後にある改行の数 |
| DATA | ... 転送するメッセージ(文字列型) |
SMTPでは、<CRLF.CRLF>を送信してメッセージの完了を相手に通知している。送信メッセージの途中にこのパターンが含まれる場合、データの途中までしか送信されなくなってしまう。
送信メッセージ中に CRLF に続けて ピリオド(.)が来る場合、直後にもう1つピリオド(.) を追加し、メッセージ全体が送信されるようにする。
送信メッセージが複数のブロックに分割されている場合、NUMには直前のブロックの最後にある文字列のパターンに応じて、次のように数値を指定する。
| num | 説明 |
| 1 | 直前のブロックの最後の1バイトが CR の場合 |
| 2 | 直前のブロックの最後の2バイトが CRLF の場合 |
| 0 | 上記のどちらにも当てはまらない場合 |
SMTPのメッセージボディはCRLFから始まるように定義されている。そのため正しいメッセージに変換するためには、本関数を最初にコールする際に NUM に 2 を指定する必要がある。
1つ目の戻り値にはDATAを変換したメッセージを格納し、2つ目の戻り値にはDATAの末尾にある改行コードの数を返す。2つ目の戻り値である改行コードの数は、末尾がCRの場合は 1、末尾がCRLFの場合は 2となる。末尾がLFの場合でも直前がCRではない場合、2つ目の戻り値は 0 となる。
DATAがnilまたは省略された場合には、1つ目の戻り値でnilを返し、2つ目の戻り値は 2 となる。
-- Luaスクリプトでは、CR="\r", LF="\n" と記述します。 dotstr, num = rt.mime.dot(2, ".\r\nSend message.\r\n.\r\n.test\r\n") print(dotstr) --[[ 変換後の文字列。CRLFの次に"."が続く場合、"."が追加されている。 .. Send message. .. ..test ]]
rt.mime.eol(CODE[, DATA[, MARKER]])
| CODE | ... 変換する文字列が複数のブロックに分割されている場合、直前のブロックデータの最後の文字のアスキーコード(数値型) |
| DATA | ... 変換する文字列 |
| MARKER | ... 改行コード(省略時は CRLF) |
DATAに含まれる改行コードを、MARKERで指定した改行コードに置き換える。
変換する文字列が複数のブロックに分割されている場合、CODEには直前のブロックデータを本関数で変換した際の2つ目の戻りを指定する。先頭の文字列または複数のブロックに分割されていない場合は 0 を指定する。
DATAがnilまたは省略された場合には、1つ目の戻り値でnilを返し、2つ目の戻り値は 0 となる。
-- Luaスクリプトでは、CR="\r", LF="\n" と記述します。 str, num = rt.mime.eol(0, "test\rexample\rtest\r", "\r\n") print(str) -- 改行コードを可視化して表示する print(string.gsub(str, "\r\n", "\\r\\n")) --[[ 変換結果(コンソールに出力された文字列) test example test test\r\nexample\r\ntest\r\n 3 ]]
rt.mime.qp(DATA1[, DATA2[, MARKER]])
| DATA1、DATA2 | ... エンコードする文字列またはバイナリデータ(文字列型) |
| MARKER | ... 改行コード(省略時は CRLF) |
DATA2を指定した場合、DATA1とDATA2を連結してQuoted-Printableエンコードを行う。パディングは行わず、エンコードできなかった残りのバイトデータは2番目の戻り値に格納される。
DATA2を省略した場合、DATA1をQuoted-Printableエンコードする。このとき、必要に応じてパディングを付与する。
DATA1およびDATA2の中に改行コード(CRLF)があった場合、MARKERで指定した改行コードに置き換える。
DATA2を省略した場合、1つ目の戻り値にはDATA1をエンコードした文字列が格納される。このとき、DATA1全体がエンコードされるよう必要に応じてパディングを付与する。2つ目の戻り値は nil となる。
DATA2を指定した場合、1つ目の戻り値にはDATA1とDATA2を連結したデータをエンコードした文字列が格納される。エンコードできない残りのデータは、2つ目の戻り値に格納される。パディングは付与されない。この後に続くデータブロックがある場合、2つ目の戻り値を第一引数のDATA1に指定し、続くデータブロックをDATA2に指定して本関数を呼び出す。
estr, rem = rt.mime.qp("テスト")
print(estr)
-- estr = =83e=83X=83g
rt.mime.qpwrp(NUM[, DATA[, LENGTH]])
| LEFT_LEN | ... 直前のブロックの最終行の余りの長さ(数値型) |
| DATA | ... Quoted-Printableエンコードされた文字列 |
| LENGTH | ... 1行の長さ(省略時は 76) |
"=XX"のようなQuoted-Printableエンコードされた文字列の途中でLENGTHで指定した長さに達した場合、Quoted-Printableエンコードされた文字の前で改行します。また、文字列に改行コード(CRLF)が含まれる場合には、1行がLENGTH未満であっても、改行コードの位置で改行されます。
文字列が複数のブロックに分割されている場合、LEFT_LENには直前のブロックを本関数で処理した際に出た最終行の余りの長さを指定する。余りの長さは直前のブロックを本関数にて処理した際の2つ目の戻り値として返される。
処理する文字列が先頭のデータまたは複数のブロックに分割されていない場合、NUMには 0 を指定する。
1つ目の戻り値にはDATAを指定した長さで改行した文字列が格納され、2つ目の戻り値には、LENGTHから最終行の長さを引いた値が格納される。DATAに続くチャンクがある場合、2つ目の戻り値を第一引数のNUMとして指定する。
--[[
--Quoted-Printableエンコードされた文字列の配列
-- 「あいうえおかきくけこ」
-- 「さしすせそたちつてと」
tbl = {
"=82=A0=82=A2=82=A4=82=A6=82=A8=82=A9=82=AB=82=AD=82=AF=82=B1",
"=82=B3=82=B5=82=B7=82=B9=82=BB=82=BD=82=BF=82=C2=82=C4=82=C6"
}
estr = {}
len = 0
for i, v in ipairs(tbl) do
estr[i], len = rt.mime.qpwrp(len, v, 16)
end
print(estr[1] .. estr[2])
--[[ 変換結果(コンソールに出力された文字列)
=
=82=A0=82=A2=82=
=A4=82=A6=82=A8=
=82=A9=82=AB=82=
=AD=82=AF=82=B1=
=82=B3=82=B5=82=
=B7=82=B9=82=BB=
=82=BD=82=BF=82=
=C2=82=C4=82=C6
]]
rt.mime.unb64(DATA1[, DATA2])
| DATA1、DATA2 | ... Base64エンコードされたデータ(文字列型) |
DATA2を指定した場合、DATA1とDATA2を連結してデコードを行う。デコードできなかった残りの文字列は2番目の戻り値に格納される。
DATA2を省略した場合、DATA1だけをデコードする。
DATA2を省略した場合、1つ目の戻り値にはDATA1をデコードしたデータが格納される。このとき、2つ目の戻り値は nil となる。
DATA2を指定した場合、1つ目の戻り値にはDATA1とDATA2を連結した文字列をデコードしたデータが格納される。デコードできない残りの文字列は、2つ目の戻り値に格納される。
-- base64エンコードされた文字列をデコードする estr = "gqKC64LNgsmC2YLWgsY=" str = rt.mime.unb64(estr) print(str) --[[ デコードした結果。(コンソールに出力された文字列) いろはにほへと ]]
rt.mime.unqp(DATA1[, DATA2])
| DATA1、DATA2 | ... Quoted-Printableエンコードされたデータ(文字列型) |
DATA2を指定した場合、DATA1とDATA2を連結してQuoted-Printableでデコードを行う。デコードできなかった残りの文字列は2番目の戻り値に格納される。
DATA2を省略した場合、DATA1をQuoted-Printableデコードする。
DATA2を省略した場合、1つ目の戻り値にはDATA1をデコードしたデータが格納される。2つ目の戻り値は nil となる。
DATA2を指定した場合、1つ目の戻り値にはDATA1とDATA2を連結したデータをデコードしたデータが格納される。エンコードできない残りの文字列は、2つ目の戻り値に格納される。
--[[ -- Quoted-Printableエンコードされた文字列をデコードする data = "=83e=83X=83g" str = rt.mime.unqp(data) print(str) --[[ コンソールへの出力結果 テスト ]]
rt.mime.wrp(NUM[, DATA[, LENGTH]])
| LEFT_LEN | ... 直前のブロックの最終行の余りの長さ(数値型) |
| DATA | ... 文字列 |
| LENGTH | ... 1行の長さ(省略時は 76) |
LENGTHで指定した長さで文字列を改行する。また、DATAで指定した文字列に改行コード(CRLF)が含まれる場合には、1行がLENGTH未満の長さであっても、改行コードの位置で改行される。
文字列が複数のブロックに分割されている場合、LEFT_LENには直前のブロックを本関数で処理した際に出た最終行の余りの長さを指定する。余りの長さは直前のブロックを本関数にて処理した際の2つ目の戻り値として返される。
処理する文字列が先頭のデータまたは複数のブロックに分割されていない場合、NUMには 0 を指定する。
1つ目の戻り値にはDATAを指定した長さで改行したデータが格納され、2つ目の戻り値には、LENGTHから最終行の長さを引いた値が格納される。DATAに続くブロックがある場合、2つ目の戻り値を第一引数のLEFT_LENとして指定する。
-- 文字列の配列
tbl = {
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"0123456789"
}
estr = {}
len = 0
for i, v in ipairs(tbl) do
estr[i], len = rt.mime.wrp(len, v, 10)
end
print(estr[1] .. estr[2] .. estr[3])
--[[ 改行された結果。(コンソールに出力された文字列)
abcdefghij
klmnopqrst
uvwxyzABCD
EFGHIJKLMN
OPQRSTUVWX
YZ01234567
89
]]
API の実行で出力される SYSLOG メッセージを以下に示します。実際に出力されるメッセージには "[LUA]" というプレフィックスが付加されます。
| レベル | 出力メッセージ | 意味 |
|---|---|---|
| DEBUG | Task(N) executed rt.command("COMMAND"): true | Lua タスク番号 N の Lua タスクでルーターのコマンド "COMMAND" の実行に成功した。 |
| Task(N) executed rt.command("COMMAND"): false | Lua タスク番号 N の Lua タスクでルーターのコマンド "COMMAND" の実行に失敗した。 | |
| Task(N) executed rt.mail: true | Lua タスク番号 N の Lua タスクでメールの送信に成功した。 | |
| Task(N) executed rt.mail: false | Lua タスク番号 N の Lua タスクでメールの送信に失敗した。 | |
| Task(N) started rt.syslogwatch | Lua タスク番号 N の Lua タスクで SYSLOG の監視を開始した。 | |
| Task(N) detected time out in rt.syslogwatch | Lua タスク番号 N の Lua タスクで実行していた SYSLOG の監視でタイムアウトが発生した。 | |
| Task(N) completed rt.syslogwatch | Lua タスク番号 N の Lua タスクで実行していた SYSLOG の監視が完了した。 | |
| Task(N) opened RESOURCE | Lua タスク番号 N の Lua タスクでハードウェア、RESOURCE をオープンした。 | |
| Task(N) failed to open RESOURCE | Lua タスク番号 N の Lua タスクでハードウェア、RESOURCE のオープンに失敗した。 | |
| Task(N) closed RESOURCE | Lua タスク番号 N の Lua タスクでハードウェア、RESOURCE をクローズした。 | |
| Task(N) started rt.httprequest | Lua タスク番号 N の Lua タスクで HTTP リクエストの送信を開始した。 | |
| Task(N) detected time out in rt.httprequest | Lua タスク番号 N の Lua タスクで実行していた HTTP リクエストの送信処理、またはレスポンスデータの受信処理においてタイムアウトが発生した。 | |
| Task(N) completed rt.httprequest | Lua タスク番号 N の Lua タスクで実行していた HTTP リクエストの送信及びレスポンスデータの受信が完了した。 | |
| Task(N) TCP(UDP) Initialize failed | Lua タスク番号 N の Lua タスクで TCP または UDP の初期化に失敗した。 |
上記の他に、API の引数誤りやスクリプトの構文エラーによりスクリプトの実行が不可能な場合には、INFO タイプのエラーメッセージが SYSLOG に出力されます。詳細は注意事項を参照してください。