我花了一些时间尝试计算UDP校验和,但是每次我在Wireshark中观察数据包时,它都会说校验和不正确。 代码如下:
uint16_t compute_udp_checksum(IP *ip, UDP *u,
void *data, int data_len)
{
uint32_t sum = 0;
uint16_t *arr = NULL;
void *buffer = NULL;
int size = 0;
PSEUDO_HDR *ps = NULL;
size = PS_SIZE + UDP_SIZE + data_len;
if (size % 2)
size += 1;
buffer = malloc(size);
if (!buffer)
{
perror("malloc");
return 0;
}
ps = create_pseudo_hdr(ip, u);
if (!ps)
{
free(buffer);
perror("malloc");
return 0;
}
memset(buffer, 0, size);
memcpy(buffer, ps, PS_SIZE);
memcpy(buffer + PS_SIZE, u, UDP_SIZE);
memcpy(buffer + PS_SIZE + UDP_SIZE, data, data_len);
arr = (uint16_t *) buffer;
int i = size;
while (i > 1)
{
sum += *arr++;
i -= 2;
}
sum = (sum & 0xFFFF) + (sum >> 16);
return ~sum;
}
正如我所说,当我将数据包发送到网络中时,Wireshark 报告(在接收端)校验和不正确。任何帮助将不胜感激。
谢谢。
最佳答案
由于我真的不知道你在用所有结构做什么,我会给你一个引用校验和实现,希望它能帮助你弄清楚你的事情:
#include <stdint.h>
#include <netinet/in.h>
struct udp {
uint16_t u_sport; /* source port */
uint16_t u_dport; /* dest port */
uint16_t u_len; /* length */
uint16_t u_chksum; /* checksum */
} __attribute__((packed));
uint16_t udp_checksum(const void *buffer, size_t length, in_addr_t src_addr, in_addr_t dest_addr)
{
const uint16_t *buf = buffer; /* treat input as bunch of uint16_t's */
uint16_t *src_ip = (void *) &src_addr;
uint16_t *dest_ip = (void *)&dest_addr;
uint32_t sum;
size_t len = length;
sum = 0;
/* fold the carry bits for the buffer */
while (length > 1) {
sum += *buf++;
if (sum & 0x80000000)
sum = (sum & 0xFFFF) + (sum >> 16); /* fold carries */
length -= 2;
}
if(length & 1)
sum += *((uint8_t *)buf); // add the padding if packet length is odd */
/* inject checksum of the pseudo-header */
sum += *(src_ip++);
sum += *(src_ip);
sum += *(dest_ip++);
sum += *(dest_ip);
sum += htons(IPPROTO_UDP); /* protocol info */
sum += htons(len); /* original length! */
/* fold any carry bits created by adding header sums */
while(sum >> 16)
sum = (sum & 0xFFFF) + (sum >> 16);
return (uint16_t)(~sum);
}
关于c - 计算 UDP 校验和时校验和错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49848010/