如何计算 RFC 791 IP 标头校验和?
我正在为自学 Ruby 项目滚动自己的 IP 数据包,并且需要计算 IP 标头校验和(如 RFC 791 p.14 中所述)。当我在这里输入问题时出现的相关问题之一指向我 RFC 1071,所以我可能大部分都在那里,但只是为了添加到 Stack Overflow,任何人(可能是 Future Josh)都可以提供一些 Ruby 代码吗?为了计算校验和,假设以下 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
常量在文件顶部定义,但如果您正在查看 RFC791 p.11,它们应该是不言自明的。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
RFC 1071 提供了以下 C 语言示例实现:
}
我编写了以下 C 代码对其进行单元测试:
有点令人不安的是,我的代码没有像 RFC 实现那样在 checksum() 函数的最后一行中采用 sum 的按位 NOT,但是添加按位 NOT 会破坏我的单元测试。
运行代码会产生:
我将其移植到 Ruby,如下所示:
我像这样调用该方法:
以下是单元测试:
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: