Files
netstack/tcpip/header/checksum.go

42 lines
1.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package header
import "netstack/tcpip"
// Checksum 校验和的计算
// UDP 检验和的计算方法是: 按每 16 位求和得出一个 32 位的数;
// 如果这个 32 位的数,高 16 位不为 0则高 16 位加低 16 位再得到一个 32 位的数;
// 重复第 2 步直到高 16 位为 0将低 16 位取反,得到校验和。
func Checksum(buf []byte, initial uint16) uint16 {
v := uint32(initial)
l := len(buf)
if l&1 != 0 {
l--
v += uint32(buf[l]) << 8
}
for i := 0; i < l; i += 2 {
v += (uint32(buf[i]) << 8) + uint32(buf[i+1])
}
return ChecksumCombine(uint16(v), uint16(v>>16))
}
// ChecksumCombine combines the two uint16 to form their checksum. This is done
// by adding them and the carry.
func ChecksumCombine(a, b uint16) uint16 {
v := uint32(a) + uint32(b)
return uint16(v + v>>16)
}
// PseudoHeaderChecksum calculates the pseudo-header checksum for the
// given destination protocol and network address, ignoring the length
// field. Pseudo-headers are needed by transport layers when calculating
// their own checksum.
// hash(protocol, hash(dst, hash(src, 0)))
func PseudoHeaderChecksum(protocol tcpip.TransportProtocolNumber, srcAddr tcpip.Address, dstAddr tcpip.Address) uint16 {
xsum := Checksum([]byte(srcAddr), 0)
xsum = Checksum([]byte(dstAddr), xsum)
return Checksum([]byte{0, uint8(protocol)}, xsum)
}