2014年1月16日木曜日

Tremaを試す ~simple-ruter その4~

今回はinterfaceを見ていきいます。
このソースはsimple_routerのインターフェイス情報を管理するプログラムです。

ソースは今まで見たものがわかれば理解できるレベルと思います。

(interface.rb)
 1  require "arp-table"
 2  require "routing-table"
 3  
 4  class Interface
 5    attr_reader :hwaddr
 6    attr_reader :ipaddr
 7    attr_reader :masklen
 8    attr_reader :port
 9  
10    def initialize options
11      @port = options[ :port ]
12      @hwaddr = Mac.new( options[ :hwaddr ] )
13      @ipaddr = IPAddr.new( options[ :ipaddr ] )
14      @masklen = options[ :masklen ]
15    end
16  
17    def has? mac
18      mac == hwaddr
19    end
20  end
21  
22  class Interfaces
23    def initialize interfaces = []
24      @list = []
25      interfaces.each do | each |
26        @list << Interface.new( each )
27      end
28    end
29  
30    def find_by_port port
31      @list.find do | each |
32        each.port == port
33      end
34    end
35  
36    def find_by_ipaddr ipaddr
37      @list.find do | each |
38        each.ipaddr == ipaddr
39      end
40    end
41  
42    def find_by_prefix ipaddr
43      @list.find do | each |
44        masklen = each.masklen
45        each.ipaddr.mask( masklen ) == ipaddr.mask( masklen )
46      end
47    end
48  
49    def find_by_port_and_ipaddr port, ipaddr
50      @list.find do | each |
51        each.port == port and each.ipaddr == ipaddr
52      end
53    end
54  
55    def ours? port, macda
56      return true if macda.broadcast?
57  
58      interface = find_by_port( port )
59      if not interface.nil? and interface.has?( macda )
60        return true
61      end
62    end
63  end

このソースにはInterfaceクラスとInterfacesクラスが書かれています。
まずはInterfaceクラスです。

1~2行目
Interfaceクラスに入る前に、先頭でarp-table.rbとrouting-table.rbを読み込んでいます。

5~8行目
アクセサの宣言をしています。
これで、クラスの外からインスタンス変数にアクセスすることができます。

10~15行目
initializeはInterfaceオブジェクトが作成される時に実行されます。
ここでは、オブジェクトを作成する時に指定した引数をインスタンス変数に代入しています。

Interfaceオブジェクトを作成する時はハッシュが引数に渡されるので、ハッシュキーを指定してハッシュ値を変数に格納しています。
@portにはルータの物理ポート番号が代入されます。
@hwaddrにはマックアドレスが代入されます。
@ipaddrにはIPアドレスが代入されます。
@masklenにはプレフィックス長が格納されます。

17~19行目
has?メソッドは引数とhwaddrが一致するかを評価し、一致したらtrueを返します。

次はInterfacesクラスです。

23~28行目
initializeはクラスのオブジェクトが作成される時に実行されるメソッドです。
オブジェクトを作成する時の引数は配列で、引数がない場合は空の配列になります。
@list変数を空の配列で初期化します。
引数の配列の要素を@list変数に追加します。

30~34行目
find_by_portメソッドは@list変数から引数で指定したポート番号を検索し、物理ポート番号が一致したInterfaceオブジェクトを返します。

36~40行目
find_by_ipaddrメソッドは@list変数から引数で指定したIPアドレスを検索し、IPアドレスが一致したInterfaceオブジェクトを返します。

42~47行目
find_by_prefixメソッドは@list変数から引数で指定したIPアドレスをマスクした値で検索し、一致したInterfaceオブジェクトを返します。
この時、@list変数の要素のIPアドレスもマスクして比較します。

49~53行目
find_by_port_and_ipaddrメソッドは@list変数から引数で指定した物理ポート番号とIPアドレスを検索し、両方が一致したInterfaceオブジェクトを返します。

55~62行目
ours?メソッドは引数のポート番号とmacアドレスがインターフェイス情報として存在するかを判定するメソッドです。
宛先のmacアドレスがブロードキャストだった場合はtrueを返します。

ブロードキャストでない場合は、find_by_portメソッドで引数のポート番号を元にInterfaceオブジェクトを取得します。
Interfaceオブジェクトが取得できて、かつ、そのmacアドレスが一致した場合はtrueを返します。

今回は以上になります。

0 件のコメント:

コメントを投稿