#!/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