#!/usr/bin/env ruby WANT = 0x44d4 # checksum you want IS = 0x50d4 # checksum it is # your IP header DATA = [0x4500, 0x0028, 0x1e4f, 0x4000, 0x7b06, 0x0, 0xXXXX, 0xXXXX, 0xXXXX, 0xXXXX] ELEMENT = [ 'version+ihl+tos', 'packet length', 'id', 'fragmentation info', 'ttl+protocol', 'checksum', 'saddr upper', 'saddr lower', 'daddr upper', 'daddr lower', ] def csum data sum = data.inject(0){|r,m|r+m} sum1 = (sum & 0xffff0000) >> 16 sum2 = (sum & 0xffff) sum = (sum1+sum2)^0xffff sum end my_data = DATA.dup offset = nil 65535.times do |x| my_data[0] = x result = csum(my_data) offset = IS-result if result==WANT if result==IS unless my_data[0] == DATA[0] warn 'packet incorrectly entered' exit 42 end end end 10.times do |element| next if element == 5 # checksum is 0 puts '------ element: %d (%s) -------' % [element, ELEMENT[element]] x = DATA[element] puts 'we have %016b (%x)' % [x, x] puts 'we want %016b (%x)' % [x+offset, x+offset] end