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