ソースの内容は前にlearning_switchのところで見たfdb.rbとよく似ています。
(arp-table.rb)
1 class ARPEntry 2 include Trema::DefaultLogger 3 4 attr_reader :port 5 attr_reader :hwaddr 6 attr_writer :age_max 7 8 def initialize port, hwaddr, age_max 9 @port = port 10 @hwaddr = hwaddr 11 @age_max = age_max 12 @last_updated = Time.now 13 info "New entry: MAC addr = #{ @hwaddr.to_s }, port = #{ @port }" 14 end 15 16 def update port, hwaddr 17 @port = port 18 @hwaddr = hwaddr 19 @last_updated = Time.now 20 info "Update entry: MAC addr = #{ @hwaddr.to_s }, port = #{ @port }" 21 end 22 23 def aged_out? 24 aged_out = Time.now - @last_updated > @age_max 25 info "Age out: An ARP entry (MAC address = #{ @hwaddr.to_s }, port number = #{ @port }) has been aged-out" if aged_out 26 aged_out 27 end 28 end 29 30 class ARPTable 31 DEFAULT_AGE_MAX = 300 32 33 def initialize 34 @db = {} 35 end 36 37 def update port, ipaddr, hwaddr 38 entry = @db[ ipaddr.to_i ] 39 if entry 40 entry.update( port, hwaddr ) 41 else 42 new_entry = ARPEntry.new( port, hwaddr, DEFAULT_AGE_MAX ) 43 @db[ ipaddr.to_i ] = new_entry 44 end 45 end 46 47 def lookup ipaddr 48 @db[ ipaddr.to_i ] 49 end 50 51 def age 52 @db.delete_if do | ipaddr, entry | 53 entry.aged_out? 54 end 55 end 56 end
このソースプログラムにはARPEntryクラスとARPTableクラスが書かれています。
ARPEntryクラスはARPTableクラスが使っているクラスなので、まずARPTableクラスから見ていきます。
31行目
DEFAULT_AGE_MAXは定数です。
ARPEntryクラスに渡され、arp情報の有効期限として指定されます。
33~35行目ARPEntryクラスに渡され、arp情報の有効期限として指定されます。
initializeはクラスのオブジェクトが作成される時に実行されるメソッドです。
処理の内容は@db変数に空のハッシュを定義しています。
後の処理で@db変数のハッシュ値にARPEntryオブジェクトが代入されます。
37~45行目処理の内容は@db変数に空のハッシュを定義しています。
後の処理で@db変数のハッシュ値にARPEntryオブジェクトが代入されます。
updateメソッドは@db変数にハッシュ要素を追加、もしくはハッシュ値を更新するメソッドです。
まず、引数のIPアドレスをハッシュキーにして@db変数からハッシュ値を取得し、entry変数にセットしています。
ハッシュ値が取得できた場合は、ARPEntryクラスのupdateメソッドを実行して変数の値を更新します。
ハッシュ値が取得できなかった場合は、引数の物理ポート番号、macアドレス、DEFAULT_AGE_MAX定数を元に新たにARPEntryオブジェクトを作り、IPアドレスをハッシュキーにして@db変数にハッシュ要素を追加しています。
47~49行目まず、引数のIPアドレスをハッシュキーにして@db変数からハッシュ値を取得し、entry変数にセットしています。
ハッシュ値が取得できた場合は、ARPEntryクラスのupdateメソッドを実行して変数の値を更新します。
ハッシュ値が取得できなかった場合は、引数の物理ポート番号、macアドレス、DEFAULT_AGE_MAX定数を元に新たにARPEntryオブジェクトを作り、IPアドレスをハッシュキーにして@db変数にハッシュ要素を追加しています。
lookupメソッドは引数のIPアドレスに紐づくハッシュ値であるARPEntryのオブジェクトを返すメソッドです。
51~55行目
ageメソッドは@db変数から一定時間が経過したハッシュ要素を削除します。
ここでの一定時間は、定数「DEFAULT_AGE_MAX」の値で300秒になります。
ハッシュ値の削除はdelete_ifメソッドで行っています。
delete_ifは指定した条件にマッチした場合、ハッシュから要素を削除するメソッドです。
ここでの条件はARPEntryクラスのage_out?メソッドの結果です。
ipaddr変数にはハッシュキー、entry変数にはハッシュ値が入り、@dbの全ての要素に対して条件にマッチするか評価をします。
続いてARPEntryクラスを見ていきます。ここでの一定時間は、定数「DEFAULT_AGE_MAX」の値で300秒になります。
ハッシュ値の削除はdelete_ifメソッドで行っています。
delete_ifは指定した条件にマッチした場合、ハッシュから要素を削除するメソッドです。
ここでの条件はARPEntryクラスのage_out?メソッドの結果です。
ipaddr変数にはハッシュキー、entry変数にはハッシュ値が入り、@dbの全ての要素に対して条件にマッチするか評価をします。
2行目
includeでモジュールを読み込みます。
DefaultLoggerモジュールが使えるようになります。
4~6行目DefaultLoggerモジュールが使えるようになります。
アクセサの宣言をしています。
これで、クラスの外からインスタンス変数にアクセスすることができます。
8~14行目これで、クラスの外からインスタンス変数にアクセスすることができます。
initializeはARPEntryオブジェクトが作成される時に実行されます。
ここではオブジェクトを作成するときに指定した引数をインスタンス変数に代入しています。
@last_update変数にはRuby組み込みメソッドのTimeメソッドを使い現在時刻を代入しています。 infoメソッドでmacアドレスと物理ポート番号をログに出力します。
16~21行目ここではオブジェクトを作成するときに指定した引数をインスタンス変数に代入しています。
@last_update変数にはRuby組み込みメソッドのTimeメソッドを使い現在時刻を代入しています。 infoメソッドでmacアドレスと物理ポート番号をログに出力します。
updateメソッドは、引数を元にインスタンス変数の値を更新します。
@port_no変数と@hwaddr変数の値は引数の物理ポート番号とmacアドレスの値に更新し、@last_update変数の値は現在時刻に書き換えます。
infoでmacアドレスと物理ポート番号をログに出力します。
23~27行目@port_no変数と@hwaddr変数の値は引数の物理ポート番号とmacアドレスの値に更新し、@last_update変数の値は現在時刻に書き換えます。
infoでmacアドレスと物理ポート番号をログに出力します。
aged_out?メソッドは、ARPEntryオブジェクトを作成、もしくはupdateメソッドを実行してから所定の時間が経過しているか否かを返します。
現在時刻から@last_update変数を引いた値が、FDBクラスの「DEFAULT_AGE_MAX」定数である300より大きい場合はaged_out変数にはtrueがセットされます。
25行目は、末尾に書かれたifの式がTrueの場合、左側の式が実行されます。
ここでは、age_out変数の値がTrueの場合は、infoメソッドでmacアドレスと物理ポート番号をログに出力します。
26行目は、24行目の式の結果(trueかfalse)をaged_out?メソッドの戻り値にしています。
今回は以上です。現在時刻から@last_update変数を引いた値が、FDBクラスの「DEFAULT_AGE_MAX」定数である300より大きい場合はaged_out変数にはtrueがセットされます。
25行目は、末尾に書かれたifの式がTrueの場合、左側の式が実行されます。
ここでは、age_out変数の値がTrueの場合は、infoメソッドでmacアドレスと物理ポート番号をログに出力します。
26行目は、24行目の式の結果(trueかfalse)をaged_out?メソッドの戻り値にしています。
0 件のコメント:
コメントを投稿