github.com/koomox/wireguard-go@v0.0.0-20230722134753-17a50b2f22a3/tun/checksum.go (about) 1 package tun 2 3 import "encoding/binary" 4 5 // TODO: Explore SIMD and/or other assembly optimizations. 6 func checksumNoFold(b []byte, initial uint64) uint64 { 7 ac := initial 8 i := 0 9 n := len(b) 10 for n >= 4 { 11 ac += uint64(binary.BigEndian.Uint32(b[i : i+4])) 12 n -= 4 13 i += 4 14 } 15 for n >= 2 { 16 ac += uint64(binary.BigEndian.Uint16(b[i : i+2])) 17 n -= 2 18 i += 2 19 } 20 if n == 1 { 21 ac += uint64(b[i]) << 8 22 } 23 return ac 24 } 25 26 func checksum(b []byte, initial uint64) uint16 { 27 ac := checksumNoFold(b, initial) 28 ac = (ac >> 16) + (ac & 0xffff) 29 ac = (ac >> 16) + (ac & 0xffff) 30 ac = (ac >> 16) + (ac & 0xffff) 31 ac = (ac >> 16) + (ac & 0xffff) 32 return uint16(ac) 33 } 34 35 func pseudoHeaderChecksumNoFold(protocol uint8, srcAddr, dstAddr []byte, totalLen uint16) uint64 { 36 sum := checksumNoFold(srcAddr, 0) 37 sum = checksumNoFold(dstAddr, sum) 38 sum = checksumNoFold([]byte{0, protocol}, sum) 39 tmp := make([]byte, 2) 40 binary.BigEndian.PutUint16(tmp, totalLen) 41 return checksumNoFold(tmp, sum) 42 }