github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/tcpip/checksum/checksum.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package checksum provides the implementation of the encoding and decoding of 16 // network protocol headers. 17 package checksum 18 19 import ( 20 "encoding/binary" 21 ) 22 23 // Size is the size of a checksum. 24 // 25 // The checksum is held in a uint16 which is 2 bytes. 26 const Size = 2 27 28 // Put puts the checksum in the provided byte slice. 29 func Put(b []byte, xsum uint16) { 30 binary.BigEndian.PutUint16(b, xsum) 31 } 32 33 // Checksum calculates the checksum (as defined in RFC 1071) of the bytes in the 34 // given byte array. This function uses an optimized version of the checksum 35 // algorithm. 36 // 37 // The initial checksum must have been computed on an even number of bytes. 38 func Checksum(buf []byte, initial uint16) uint16 { 39 s, _ := calculateChecksum(buf, false, initial) 40 return s 41 } 42 43 // Checksumer calculates checksum defined in RFC 1071. 44 type Checksumer struct { 45 sum uint16 46 odd bool 47 } 48 49 // Add adds b to checksum. 50 func (c *Checksumer) Add(b []byte) { 51 if len(b) > 0 { 52 c.sum, c.odd = calculateChecksum(b, c.odd, c.sum) 53 } 54 } 55 56 // Checksum returns the latest checksum value. 57 func (c *Checksumer) Checksum() uint16 { 58 return c.sum 59 } 60 61 // Combine combines the two uint16 to form their checksum. This is done 62 // by adding them and the carry. 63 // 64 // Note that checksum a must have been computed on an even number of bytes. 65 func Combine(a, b uint16) uint16 { 66 v := uint32(a) + uint32(b) 67 return uint16(v + v>>16) 68 }