RST 未在 C 中通过套接字发送或接收

问题描述 投票:0回答:1

在我向关闭的端口发送几个 SYN 数据包后,我试图接收发送到我的程序的 RST 数据包,情况是我看到任何 RST 段正在发送或接收,正如我通过 Wireshark 确认的那样。 这是 SYN 段配置:

    char packet[BUF_SIZE];
    struct iphdr* ip_h = (struct iphdr*) packet;
    struct tcphdr* tcp_h = (struct tcphdr*) (packet + sizeof(struct iphdr));
    struct pseudo_header ps_h;

    ip_h->ihl = 5;
    ip_h->version = 4;
    ip_h->tos = 0;
    ip_h->tot_len = sizeof (struct iphdr) + sizeof (struct tcphdr);
    ip_h->id = htons(54321);
    ip_h->frag_off = 0;
    ip_h->ttl = 255;
    ip_h->protocol = IPPROTO_TCP;
    ip_h->check = 0;
    ip_h->saddr = inet_addr(cf->src_ip);
    ip_h->daddr = inet_addr(cf->server_ip);

    tcp_h->source = htons(12345);
    tcp_h->dest = htons(dest_port);
    tcp_h->seq = 0;
    tcp_h->ack_seq = 0;
    tcp_h->doff = 5;
    tcp_h->fin = 0;
    tcp_h->syn = 1;
    tcp_h->rst = 0;
    tcp_h->psh = 0;
    tcp_h->ack = 0;
    tcp_h->urg = 0;
    tcp_h->check = 0;
    tcp_h->window = htons (5840);
    tcp_h->urg_ptr = 0;

    memset(&ps_h, 0, sizeof(ps_h));
    ps_h.source_address = inet_addr("192.168.128.2");
    ps_h.dest_address = inet_addr(cf->server_ip);
    ps_h.placeholder = 0;
    ps_h.protocol = IPPROTO_TCP;
    ps_h.tcp_length = htons(sizeof(struct tcphdr));

    int pseudo_size = sizeof(struct pseudo_header) + sizeof(struct tcphdr);
    char *pseudo_packet = malloc(pseudo_size);
    memcpy(pseudo_packet, (char *) &ps_h, sizeof(struct pseudo_header));
    memcpy(pseudo_packet + sizeof(struct pseudo_header), tcp_h, sizeof(struct tcphdr));

    tcp_h->check = checksum(pseudo_packet, pseudo_size);
    ip_h->check = checksum(packet, ip_h->tot_len);

伪标题

struct pseudo_header {
    u_int32_t source_address;
    u_int32_t dest_address;
    u_int8_t placeholder;
    u_int8_t protocol;
    u_int16_t tcp_length;
};

校验和算法:

unsigned short checksum(const char *buf, unsigned size) {
    unsigned sum = 0, i;
    /* Accumulate checksum */
    for (i = 0; i < size - 1; i += 2) {
        unsigned short word16 = *(unsigned short *) &buf[i];
        sum += word16;
    }
    /* Handle odd-sized case */
    if (size & 1) {
        unsigned short word16 = (unsigned char) buf[i];
        sum += word16;
    }
    /* Fold to get the ones-complement result */
    while (sum >> 16) sum = (sum & 0xFFFF)+(sum >> 16);
    /* Invert to get the negative in ones-complement arithmetic */
    return ~sum;
}

SYN 段屏幕截图

另外,当我通过Wireshark检查SYN段时,这对我来说有点奇怪,因为ECN和CWR不应该被设置,包括保留,但我不认为我能够手动设置他们在节目中消失了。

目前,我只能想到两个问题,要么是我的 SYN 段设置不正确,但对我来说看起来不错。或者服务器根本不发送RST,为此,我尝试使用

nc -l -p 9999
(发送SYN的目标端口)在服务器端打开此端口,希望它发送SYN-ACK,但仍然没有响应。

c sockets tcp
1个回答
0
投票

我以某种方式解决了问题所在,即我的 ip 和 tcp 标头长度计算不正确,由这个 project 给出,除了长度之外还应该有一个 OPT_SIZE 。

© www.soinside.com 2019 - 2024. All rights reserved.