Answer the question
In order to leave comments, you need to log in
How to correctly calculate the tcp checksum of a packet?
I'm trying to implement a checksum calculation algorithm using this link
. Here is an example of a byte slice and checksums for it.
[69 0 0 60 179 32 64 0 64 6 108 0 192 168 77 61 192 168 77 13 203 50 0 22 69 21 146 157 0 0 0 0 160 194 250 240 65 21 0 0 2 4 5 180 4 2 8 10 38 105 38 58 0 0 0 0 1 3 3 7]
src chkSumOriginaltcp = 0x4115 calc chkSumFaketcp = 0x72e8
[69 0 0 60 0 0 64 0 64 6 31 33 192 168 77 13 192 168 77 61 0 22 203 50 88 167 128 107 69 21 146 158 160 82 113 32 198 58 0 0 2 4 5 180 4 2 8 10 246 88 53 174 38 105 38 58 1 3 3 7]
src chkSumOriginaltcp = 0xc63a calc chkSumFaketcp = 0xa550
var buff = make([]byte,len(payload))
copy(buff,payload)
ip, _ := ipv4.ParseHeader(buff)
checkSum := chksum(ip,buff[ip.Len:])
tcp := payload[ip.Len:]
checkSumTcp := binary.BigEndian.Uint16(tcp[16:])
fmt.Printf("src chkSumOriginaltcp = %#x calc chkSumFaketcp = %#x\n",checkSumTcp,checkSum)
//https://gist.github.com/david-hoze/0c7021434796997a4ca42d7731a7073a
func chksum(iph *ipv4.Header,payload []byte)uint16{
// https://github.com/mikioh/-stdyng/blob/master/afpacket.go
var htons = func(i uint16) uint16 {return (i<<8)&0xff00 | i>>8}
tcpLen := iph.TotalLen - iph.Len
src := iph.Src
dst := iph.Dst
var csum uint32
for i := 0; i < 16; i += 2 {
csum += uint32(src[i]) << 8
csum += uint32(src[i+1])
csum += uint32(dst[i]) << 8
csum += uint32(dst[i+1])
}
csum += uint32(htons(6)) // TCP PROTO
csum += uint32(htons(uint16(tcpLen)))
var i int
for tcpLen > 1 {
csum += uint32(payload[i]) << 8
csum += uint32(payload[i+1])
tcpLen -= 2
i++
}
if tcpLen % 2 == 1 {
csum += uint32(payload[tcpLen - 1]) << 8
}
for csum > 0xffff{
csum = (csum >> 16) + (csum & 0xffff)
}
return ^uint16(csum)
}
Answer the question
In order to leave comments, you need to log in
I'll leave this here for anyone who needs it.
func chksum(data []byte, srcip, dstip []byte) uint16 {
data[16],data[17] = 0,0 //zero on original check sum
psheader := []byte{
srcip[0], srcip[1], srcip[2], srcip[3],
dstip[0], dstip[1], dstip[2], dstip[3],
0,
6, // TCP
0, byte(len(data)), // length (16 bits)
}
csum := make([]byte, 0, len(psheader)+len(data))
csum = append(csum, psheader...)
csum = append(csum, data...)
lenSumThis := len(csum)
var word uint16
var sum uint32
for i := 0; i+1 < lenSumThis; i += 2 {
word = uint16(csum[i])<<8 | uint16(csum[i+1])
sum += uint32(word)
}
if lenSumThis%2 != 0 {
sum += uint32(csum[len(csum)-1])
}
sum = (sum >> 16) + (sum & 0xffff)
sum = sum + (sum >> 16)
return uint16(^sum)
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question