【问题标题】:Unable to verify TCP checksum无法验证 TCP 校验和
【发布时间】:2020-08-11 23:29:00
【问题描述】:

我一直在使用原始套接字在 C 中创建自定义 TCP 数据包。为了验证,我将它们发送到环回接口,当我使用 TCPDUMP 检查接收到的数据包时,校验和与 TCP 数据包不匹配。以下是 TCP 标头中的字段:

        tcp->th_sport = temp_port;      // The TCP structure. The source port, spoofed, we accept through the command line
        tcp->th_dport = atoi(argv[2]);  // The destination port, we accept through command line
        tcp->th_seq = htonl(random_id()%1000);
        tcp->th_ack = htonl(random_id()%1000);
        tcp->th_off = 5;
        tcp->th_flags = TH_SYN;
        tcp->th_win = 10000;
        tcp->th_sum = 0;
        tcp->th_urp = 0;
        
        //pseudo header for TCP checksum calculation
        p_hdr->source = t1->s_addr;
        p_hdr->dest = t2->s_addr;
        p_hdr->reserved = 0;
        p_hdr->protocol = IPPROTO_TCP;  //TCP
        p_hdr->tcp_size = sizeof(struct tcphdr);
        memcpy(buffer2 + sizeof(struct pseudo_tcp_header) , tcp , sizeof(struct tcphdr) );
        tcp->th_sum = htons(csum((unsigned short *) (buffer2 ), sizeof(struct tcphdr) + sizeof(struct pseudo_tcp_header)));

这是 random_id 函数:

int random_id()
{
    int lower = 1, upper = 65535,number;
    number = (rand() % (upper - lower + 1)) + lower;
    return number;
}

校验和由函数计算,

unsigned short csum(unsigned short *buf, int len)
{
    unsigned long sum;
    for(sum=0; len>0; len--)
        sum += *buf++;
    sum = (sum >> 16) + (sum &0xffff);
    sum += (sum >> 16);
    return (unsigned short)(~sum);
}

在 C 中是否有计算 tcpchecksum 的默认函数?

【问题讨论】:

  • 您没有在校验和字段中填写总和,而是将其设置为 0tcp->th_sum = 0;
  • tcp->th_sum = htons(csum((unsigned short *) (buffer + sizeof(struct ip)), sizeof(struct tcphdr)));,这个语句是用来填sum的
  • 这也不对。您必须通过 TCP 'pseudo-header' 计算它,其中包括 IP 标头的一部分。对此有一个 RFC。你读过吗?
  • 好的,让我们检查一下 TCP 伪标头,谢谢
  • "C语言中是否有这个过程的默认函数?"没有。

标签: c linux networking checksum raw-sockets


【解决方案1】:

我了解计算ip/tcp 校验和的默认函数没有。可以通过以下代码找到:

unsigned short csum(unsigned short *buf, int len)
{
    unsigned long sum;
    for(sum=0; len>0; len--)
        sum += *buf++;
    while (sum>>16)
        sum = (sum >> 16) + (sum &0xffff);
    return (unsigned short)(~sum);
}

在哪里输入,buf如果是带有伪头的数据。

仅当数据包仅遍历localhost 时才需要此计算。如果它将网卡传递到外部网络,请将sum 字段留空。网卡会自动计算header值。

【讨论】:

    猜你喜欢
    • 2013-01-02
    • 2014-03-09
    • 1970-01-01
    • 2022-07-29
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多