I am rolling my own IP packets for a teach-yourself-Ruby project, and need to compute the IP header checksum (as described in RFC 791 p.14). One of the related questions that popped up when I typed my question here pointed me at RFC 1071, so I'm probably most of the way there, but just to add to Stack Overflow, can anyone (possibly Future Josh) provide some Ruby code for computing the checksum, assuming the following bit of Ruby:
def build_ip_packet(tos, ttl, protocol, dst_addr, data)
len = (IP_HEADER_LEN * 4) + data.size
ip_header = %w{ #{IP_VERSION} #{IP_HEADER_LEN} #{tos} #{len} #{IP_IDENTIFICATION} #{IP_FLAGS_BIT_0} #{IP_FLAGS_BIT_1} #{IP_FLAGS_BIT_2} #{IP_FRAG_OFFSET} #{ttl} #{protocol} #{hdr_checksum} #{src_addr} #{dst_addr} }
[...]
end
The constants are defined at the top of the file, but they should be self-explanatory if you're looking at RFC791 p.11.
RFC 1071 provides the following sample implementation in C:
}
I wrote the following C code to unit test it:
It is slightly disconcerting that my code does not take the bitwise NOT of sum in the last line of the checksum() function like the RFC implementation does, but adding the bitwise NOT broke my unit tests.
Running the code yields:
I ported this to Ruby as follows:
I call the method like this:
And here are the unit tests: