Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 计算UDP校验和时校验和错误_C_Udp_Checksum - Fatal编程技术网

C 计算UDP校验和时校验和错误

C 计算UDP校验和时校验和错误,c,udp,checksum,C,Udp,Checksum,我花了一些时间试图计算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_

我花了一些时间试图计算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);
}
#包括
#包括
结构udp{
uint16\u t u\u sport;/*源端口*/
uint16\u t u\u dport;/*目的港*/
uint16_t u_len;/*长度*/
uint16\u t u\u chksum;/*校验和*/
}_uuu属性_uuu((压缩));
uint16\u t udp\u校验和(常量无效*缓冲区、大小长度、输入地址、输入地址、输出地址)
{
const uint16_t*buf=buffer;/*将输入视为一堆uint16_t*/
uint16\u t*src\u ip=(void*)和src\u addr;
uint16目的地ip=(无效*)和目的地地址;
uint32_t sum;
尺寸长度=长度;
总和=0;
/*折叠缓冲区的进位*/
而(长度>1){
总和+=*buf++;
如果(总和&0x8000000)
总和=(总和&0xFFFF)+(总和>>16);/*倍进位*/
长度-=2;
}
如果(长度&1)
sum+=*((uint8_t*)buf);//如果数据包长度为奇数,则添加填充*/
/*注入伪头的校验和*/
sum+=*(src_ip++);
总和+=*(src_ip);
总和+=*(目的地ip++);
总和+=*(目的地ip);
sum+=htons(IPPROTO_UDP);/*协议信息*/
总和+=htons(len);/*原始长度*/
/*折叠通过添加标头和创建的任何进位*/
而(总和>>16)
总和=(总和&0xFFFF)+(总和>>16);
回报率(uint16_t)(~sum);
}

1)您的短裤不是以1为补充。您可能需要使用HTON。2) 您可能会丢失while循环中的最后一个字节和,而且您的和是假设在一次传递后它将最终为16位。不确定您是如何添加IP地址信息的(不知道您的UDP*看起来是什么样子),也没有将数据长度添加到总和中(必须是1s补码),所以是的。“Wireshark报告(在接收端)校验和不正确。”发布报告、代码结果和预期结果比简单描述错误更有用。它是否在big-endian和little-endian平台上正确处理最终字节?