RC_IP_CONNECT_FAILED

| コメント(0) | トラックバック(0)

ルーターにDD-WRTを入れました。WZR-HP-AG300Hに米Buffalo謹製のProfessional Firmwareです。ルーター自身でMyDNS.jpを更新させるただそれだけのために。

ちなみに無線LANは社外ファームでは法令に触れるので使ってはダメだとか。送信出力を10dBmにすると同等らしいですが、法律がそうなっているとかで。

さてMyDNS更新ですが、先人の知恵により、サービス名を手動設定にした上でURLに"/login.html?"と記述すれば通りました。

ところがRC_IP_CONNECT_FAILEDが発生してダメになる場合がありました。色々調べていくと、どうもWAN IPアドレスの確認に失敗した場合のエラーメッセージのようでした。

DDNSクライアントinadynはデフォルトでcheckip.dyndns.org使っていました。これはリモートホストのIPアドレスを表示するだけのサービスで、DDNS更新のために用意されている物のようです。DynDNS以外で使われるのは迷惑だろうになあ、と思わなくもありません。

一つのホスト名に複数のIPアドレスが割り当てられている(DNSラウンドロビンとか呼ぶらしい)のですが、inadynは立ち上がるとDNSを一度しか引かないため、落ちていても余所に回りません。こうして接続できない場合にRC_IP_CONNECT_FAILEDが記録されます。

inadynを更新すれば回避できるらしいですが、せっかく米Buffaloが動作確認してくれたバージョンからずらすのも嫌ですし、inadynだけ更新も怖いので、外から何とかすることにしました。

そもそもルーター自身がWAN IPアドレスを把握しているのに、わざわざ外のCGIに調べてもらうなんておかしいだルルォ!?

というわけで、設定画面のInfo.htmからPerlでWANのIPアドレスを取り出して表示するcgiを設置しました。Perlなんて自分で書くのは初めてですが、こんな感じ(後述)で良いのでしょうか。

後は、これをDDNS設定画面の追加オプションで
--ip_server_name サーバーのLAN IPアドレス cgiへの絶対パス
とすればWAN IPアドレスの確認に使ってくれます。詳細はDD-WRT公式のこちらを。

DD-WRTにPerlを入れてしまえば1台で完結できますが、今のところはこのWebサーバーに設置しています。ルーターで完結していませんが、WAN IP確認はローカルで行なわなければならないものでもないので、おまけです。

クラスCプライベートIPアドレスを判別して上記仕組みを動作させ、それ以外なら相手のリモートIPアドレスを表示します(つまりcheckip.dyndns.org等と同じ動作)。

#!/usr/bin/perl

use utf8;
use LWP::UserAgent;
use HTML::TreeBuilder;

print "Content-type: text/plain\n\n";

my $ip = $ENV{'REMOTE_ADDR'};

if ($ip =~ /^(192\.168)/) {
  my $ua = LWP::UserAgent->new;
  my $req = HTTP::Request->new(GET => 'http://ルーターのLAN IPアドレス/Info.htm');
  $req->authorization_basic('ユーザー', 'パスワード');

  my $res = $ua->request($req);
  if ($res->is_success) {
    $tree = HTML::TreeBuilder->new;
    $tree->parse($res->content);
    $tree->eof();

    my $ipaddr = $tree->look_down(_tag => "span", id => "wan_ipaddr")->as_text;
    print $ipaddr, "\n";
  } else {
    print "ERROR.\n";
    print $res->status_line, "\n";
  }
} else {
  print $ip, "\n";
}

トラックバック(0)

トラックバックURL: http://mychro.mydns.jp/cgi-bin/mt/mt-tb.cgi/392

コメントする

アーカイブ

ウェブページ

Powered by Movable Type 5.2.13

ホームページ