gpt4 book ai didi

c++ - UDP校验和错误c++

转载 作者:行者123 更新时间:2023-11-30 02:11:02 26 4
gpt4 key购买 nike

我正在使用以下函数(在某处找到)计算 UDP 校验和:

   uint16_t udp_checksum(const void *buff, size_t len, in_addr_t src_addr, in_addr_t dest_addr)
{
const uint16_t *buf=(const uint16_t *)buff;
uint16_t *ip_src=(uint16_t *)&src_addr,
*ip_dst=(uint16_t *)&dest_addr;
uint32_t sum;
size_t length=len;


// Calculate the sum
sum = 0;
while (len > 1)
{
sum += *buf++;
if (sum & 0x80000000)
sum = (sum & 0xFFFF) + (sum >> 16);
len -= 2;
}

if ( len & 1 )
// Add the padding if the packet length is odd
sum += *((uint8_t *)buf);

// Add the pseudo-header
sum += *(ip_src++);
sum += *ip_src;

sum += *(ip_dst++);
sum += *ip_dst;

sum += htons(IPROTO_UDP);
sum += htons(length);

// Add the carries
while (sum >> 16)
sum = (sum & 0xFFFF) + (sum >> 16);

// Return the one's complement of sum
return ( (uint16_t)(~sum) );
}



int form_checksums(char * buff)
{
// Get IP and UDP headers
IP_Header* ipHdr = (IP_Header*)(buff);
struct UDP_Header* udpHdr = (struct UDP_Header*) (buff + 4*ipHdr->ihl);

//---- Form and fill IP checksum now--------------------------------------
ipHdr->check = 0;
ipHdr->check = in_cksum((unsigned short *)ipHdr, sizeof(*ipHdr));


//---- calculate and fill udp checksum now ---
udpHdr->checksum = 0;

udpHdr->checksum = udp_checksum(buff + 4*ipHdr->ihl, udpHdr->length, ipHdr->saddr, ipHdr->daddr);

return 0;
}

Wireshark 显示计算出错误的 UDP 校验和。我没有看到函数有任何问题。可能出了什么问题?

最佳答案

UDP 校验和计算需要 UDP 伪 header

以下是我的库中的一些代码示例,可能会有所帮助:

// SmartBuffer is a stream-like buffer class
uint16_t SmartBuffer::checksum(const void* buf, size_t buflen)
{
assert(buf);

uint32_t r = 0;
size_t len = buflen;

const uint16_t* d = reinterpret_cast<const uint16_t*>(buf);

while (len > 1)
{
r += *d++;
len -= sizeof(uint16_t);
}

if (len)
{
r += *reinterpret_cast<const uint8_t*>(d);
}

while (r >> 16)
{
r = (r & 0xffff) + (r >> 16);
}

return static_cast<uint16_t>(~r);
}

UDPFrame校验和计算:

uint16_t UDPFrame::computeChecksum(const ipv4_header& ih) const
{
udp_pseudo_header uph;

memset(&uph, 0x00, sizeof(uph));

uph.source = ih.source;
uph.destination = ih.destination;
uph.mbz = 0x00;
uph.type = ih.protocol;
uph.length = getData()->length;

systools::SmartBuffer tmp(sizeof(uph) + d_data.size());

tmp.appendValue(uph);
tmp.append(d_data); // d_data is the UDP frame payload

return tmp.checksum();
}

无论如何,请记住,wireshark 通常会警告您由于 UDP checksum offload 可能会计算出错误的校验和值。 .

也许您的校验和函数确实是错误的,但一种可靠的确定方法是尝试接收您的 UDP 帧。

关于c++ - UDP校验和错误c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4012750/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com