@jajabin

Как правильно посчитать контрольную сумму tcp пакета?

Пытаюсь реализовать алгоритм подсчета контрольной суммы при помощи данной ссылки
Вот пример слайса байтов и контрольные суммы для него.
[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)
}
  • Вопрос задан
  • 233 просмотра
Пригласить эксперта
Ответы на вопрос 1
@jajabin Автор вопроса
Оставлю этот тут вдруг кому будет нужно.
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)
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы