ソースの内容は前に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 件のコメント:
コメントを投稿