2014年1月21日火曜日

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

今回はrouter-utilsのソースを見ていきます。
前回見たrouter-utils.rbから抜粋しました

  1  require 'ipaddr'
  2  
  3  def get_checksum csum, val
  4    sum = ( ~csum & 0xffff ) + val
  5    while sum > 0xffff
  6      sum = ( sum & 0xffff ) + ( sum >> 16 )
  7    end
  8    ~sum & 0xffff
  9  end
 10  
 11  class IPAddr
 12    def to_a
 13      self.to_s.split( "." ).collect do | each |
 14        each.to_i
 15      end
 16    end
 17  end
 18  
 19  class EthernetHeader
 20    attr_accessor :macda, :macsa, :eth_type
 21  
 22    def initialize macda, macsa, eth_type
 23      @macda = macda
 24      @macsa = macsa
 25      @eth_type = eth_type
 26    end
 27  
 28    def pack
 29      ( @macda.to_a + @macsa.to_a + [ eth_type ] ).pack( "C12n" )
 30    end
 31  end
 32  

1行目
rubyの標準ライブラリのipaddrファイルを読み込み、IPAddrクラスを使えるようにします。

3~9行目
IPv4パケットのチェックサムを計算するメソッドです。
4行目は、引数のcsum変数の値を1の補数にし、0xffffをビット論理積で演算した結果に引数のvalの値を足してsum変数にセットしています。

5行目は、sum変数の値が0xffffを超えている間はループを繰り返します。
ループの中では、sum変数の値をビット論理積で16ビットにした値と、sum変数を右に16ビットシフトした値を足しています。
16ビット右シフトする事で、16ビットからあふれた値をチェックサムに足しています。

8行目でsum変数の値を1の補数にしています。

11~17行目
標準ライブラリのIPAddrクラスに定義を追加しています。
標準ライブラリのIPAddrクラスに定義を追加しています。
ここではto_aメソッドを追加しています。
このメソッドでは、IPAddrオブジェクトの値を文字列に変換し、ドットで分割して、10進数に変換した値を配列にして返します。

19~31行目
このメソッドではイーサネットヘッダーを構成します。
まずアクセサの宣言をして外部からアクセス出来るようにします。

initializeでは、オブジェクトを作る時に渡された引数を変数にセットします。
@macda変数には宛先のmacアドレスが入ります。
@macsa変数には送信元のmacアドレスが入ります。
@eth_typeにはパケットのプロトコルのタイプが入ります。例えばIPv4やARPなどです。

28行目以降で、packメソッドを定義しています。
@macda変数と@macsa変数をeth_type変数が含まれている配列に追加し、packメソッドでバイナリにしています。
Cは8bitの符号なし整数、nはネットワークバイトオーダーです。

短いですが、今日はここまでにします。

0 件のコメント:

コメントを投稿