2014年1月21日火曜日

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

今回ばrouter-utilsのソースを前回の続きから全体の半分ぐらいまで見ていきます。

以下のソースはrouter-utils.rbからの抜粋です

 33  class ARPPacket
 34    attr_accessor :type, :tha, :sha, :tpa, :spa
 35  
 36    def initialize type, tha, sha, tpa, spa
 37      @type = type
 38      @tha = tha
 39      @sha = sha
 40      @tpa = tpa
 41      @spa = spa
 42    end
 43  
 44    def pack
 45      eth_header = EthernetHeader.new( @tha, @sha, 0x0806 )
 46  
 47      # arp
 48      arp = [ 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, @type ]
 49      arp += @sha.to_a + @spa.to_a + @tha.to_a + @tpa.to_a
 50  
 51      while arp.length < 46 do
 52        arp += [ 0x00 ]
 53      end
 54  
 55      eth_header.pack + arp.pack( "C*" )
 56    end
 57  end
 58  
 59  class ARPRequest < ARPPacket
 60    def initialize sha, tpa, spa
 61      tha = [ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ]
 62      super( 1, tha, sha, tpa, spa )
 63    end
 64  end
 65  
 66  class ARPReply < ARPPacket
 67    def initialize tha, sha, tpa, spa
 68      super( 2, tha, sha, tpa, spa )
 69    end
 70  end
 71  


33~43行目
ARPパケットを作るクラスです。
34行目はアクセサの宣言をしています。

36行目のinitializeで引数を変数にセットしています。
@typeにはARPリクエスト、ARPリプライといったARPパケットのタイプがセットされます。
@thaには宛先のmacアドレスが入ります。
@shaには送信元のmacアドレスが入ります。
@tpaには宛先のIPアドレスが入ります。
@spaには送信元のIPアドレスが入ります。

44~56行目
packメソッドではARPパケットのフォーマットに合わせてデータを並べていきます。
まずはeth_header変数にEthernetHeaderオブジェクトをセットしてイーサネットヘッダーを用意します。

arp変数には、ARPパケットフォーマットにしたがって、制御情報やプロトコル、ARPパケットのタイプを配列にセットします。
次いでarp変数に送信元macアドレス、送信元IPアドレス、宛先macアドレス、宛先IPアドレスをセットします。

51行目のループは、イーサネットフレームのデータ部分の長さは最低でも46バイトなので、arp変数の長さが46バイトになるまで0x00を追加していきます。
最後にeth_header変数をpackメソッドでバイナリにしたデータと、arp変数をpack変数でバイナリにしたデータをくっつけます。

59~64行目
ARPリクエストのパケットを作るクラスです。
APRPacketクラスを継承しています。

initializeメソッドで、tha変数にmacアドレスをセットしています。
ARPリクエストなので、macアドレスには「FF:FF:FF:FF:FF:FF」が入ります。

superでスーパークラスであるARPPacketクラスのinitializeメソッドを呼び出します。
一つ目の引数はARPパケットのタイプなので、ARPリクエストは1を指定します。

66~70行目
ARPリプライのパケットを作るクラスです。
ARPPacketクラスを継承しています。

superでスーパークラスであるARPPacketクラスのinitializeメソッドを呼び出します。
一つ目の引数はARPパケットのタイプなので、ARPリプライは2を指定します。


今回はここまでです。

0 件のコメント:

コメントを投稿