RubyでTCP/IPのチェックサムを計算する
»
Tremaでは低レイヤーにばかり関心が集まっているのか、TCPの細かな状態を取得・変化させる機能がまだ実装されていないようです。わたしが目指しているのは高レイヤーでのパケット書き換えなので、どうしてもTCP/IPのチェックサムを再計算する必要があります。
以前の記事「Windows計算機でTCPチェックサムを計算する方法」では手作業で算出する方法を解説しましたが、今回はその方法をRubyで実装しました。Rubyでその計算を行うモジュール/メソッドです。
16進数でデータを引数に渡して、結果も16進数で受け取ります。 TCPチェックサムの作成のためには擬似IPヘッダを作成する必要があり、そのためのメソッドが「mk_pseudo_ip_hdr」です。送信元&送信先IPとTCPヘッダ長を引数に取ります。「mk_checksum」メソッドでは、擬似IPヘッダとTCPヘッダとTCPデータを連結した16進数を引数に取ります。戻り値も16進数です。
「mk_checksum」メソッドはIPチェックサム作成にも使えます。IPヘッダだけを16進数で取得し、既存のIPチェックサムを0パディングし、当メソッドの引数に入れると16進数でチェックサムが得られます。 以下がソースコードです。コピペしてお使いください。
module PacketInfo def mk_pseudo_ip_hdr src_ip, dst_ip, tcp_hdr_data_length # Expect instance of IP class in src_ip and dst_ip # Expect Integer in tcp_hdr_data_length pseudo_ip_hdr = '' for i2 in [src_ip, dst_ip] for i in [0, 1, 2, 3] pseudo_ip_hdr << i2.to_a[i].to_s(16).rjust(2, '0') end end pseudo_ip_hdr << '0006' #info "tcp_hdr_data_length: " + tcp_hdr_data_length.to_s pseudo_ip_hdr << tcp_hdr_data_length.to_s(16).rjust(4, '0') #info "pseudo_ip_hdr: " + pseudo_ip_hdr end def mk_checksum data_hex # Expect pseudo ip header + tcp header + tcp data in data_hex, in case of TCP #info "mk_checksum data_hex: \n" + data_hex checksum = 0 for i in 0..(data_hex.length/4) do #/ data_hex_sliced = data_hex.slice(4*i, 4) data_hex_sliced = data_hex_sliced.ljust(4, '0') checksum = checksum + data_hex_sliced.hex #print data_hex_sliced + " + " end #info "" #info "checksum: 0x" + checksum.to_s(16) while checksum.to_s(16).length > 4 do #info "checksum has more than 5 digits. Will cut it off." checksum_left = checksum.to_s(16).slice(0, checksum.to_s(16).length - 4) #info "checksum_left: " + checksum_left checksum_right = checksum.to_s(16).slice((checksum.to_s(16).length - 4)..-1) #info "checksum_right: " + checksum_right checksum = checksum_left.hex + checksum_right.hex end checksum = checksum ^ 0xffff #info "checksum: 0x" + checksum.to_s(16) return checksum end end
コメント
コメントを投稿する
SpecialPR