首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在TUN设备上实现TCP重传而不是ACK

在TUN设备上实现TCP重传而不是ACK
EN

Stack Overflow用户
提问于 2022-08-14 14:49:03
回答 1查看 275关注 0票数 2

我试图在TUN设备上根据Linux中的RFC 793实现TCP堆栈。默认情况下,我的程序处于LISTEN状态,正在等待SYN数据包建立连接。我使用nc发送SYN:

代码语言:javascript
运行
复制
$ nc 192.168.20.99 20

我的程序使用SYN、ACK进行响应,但是nc没有在最后发送ACK。这就是流程:

代码语言:javascript
运行
复制
# tshark -i tun0 -z flow,tcp,network
1 0.000000000 192.168.20.1 → 192.168.20.99 TCP 60 39284 → 20 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 SACK_PERM=1 TSval=1691638570 TSecr=0 WS=128
2 0.000112185 192.168.20.99 → 192.168.20.1 TCP 40 20 → 39284 [SYN, ACK] Seq=0 Ack=1 Win=10 Len=0
3 1.001056784 192.168.20.1 → 192.168.20.99 TCP 60 [TCP Retransmission] [TCP Port numbers reused] 39284 → 20 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 SACK_PERM=1 TSval=1691639571 TSecr=0 WS=128

|Time     | 192.168.20.1                          |
|         |                   | 192.168.20.99     |                   
|0.000000000|         SYN       |                   |Seq = 0
|         |(39284)  ------------------>  (20)     |
|0.000112185|         SYN, ACK  |                   |Seq = 0 Ack = 1
|         |(39284)  <------------------  (20)     |
|1.001056784|         SYN       |                   |Seq = 0
|         |(39284)  ------------------>  (20)     |

有关我的TCP头的更多信息:

代码语言:javascript
运行
复制
Frame 2: 40 bytes on wire (320 bits), 40 bytes captured (320 bits) on interface tun0, id 0
Raw packet data
Internet Protocol Version 4, Src: 192.168.20.99, Dst: 192.168.20.1
Transmission Control Protocol, Src Port: 20, Dst Port: 39310, Seq: 0, Ack: 1, Len: 0
    Source Port: 20
    Destination Port: 39310
    [Stream index: 0]
    [Conversation completeness: Incomplete, CLIENT_ESTABLISHED (3)]
    [TCP Segment Len: 0]
    Sequence Number: 0    (relative sequence number)
    Sequence Number (raw): 0
    [Next Sequence Number: 1    (relative sequence number)]
    Acknowledgment Number: 1    (relative ack number)
    Acknowledgment number (raw): 645383655
    0101 .... = Header Length: 20 bytes (5)
    Flags: 0x012 (SYN, ACK)
    Window: 10
    [Calculated window size: 10]
    Checksum: 0x99b0 [unverified]
    [Checksum Status: Unverified]
    Urgent Pointer: 0

注意到:我知道is预测攻击,但这只是一个测试,序列号的0与本例中的任何其他数字一样是随机的。

UPDATE:这是tcpdump的输出,它说我计算的校验和错误:

代码语言:javascript
运行
复制
# tcpdump -i tun0 -vv -n
...
 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40, bad cksum 16f3 (->911b)!)
    192.168.20.99.20 > 192.168.20.1.39308: Flags [S.], cksum 0x9bb0 (incorrect -> 0x1822), seq 0, ack 274285560, win 10, length 0
...

这是我的校验和计算器(来自RFC 1071):

代码语言:javascript
运行
复制
uint16_t checksum(void *addr, int count)
{
    uint32_t sum = 0;
    uint16_t *ptr = addr;

    while (count > 1) {
        sum += *ptr++;
        count -= 2;
    }

    if (count > 0)
        sum += *(uint8_t *)ptr;

    while (sum >> 16)
        sum = (sum & 0xffff) + (sum >> 16);

    return ~sum;
}

我把伪头和TCP段的组合传递给TCP校验和。(按大端顺序排列):

代码语言:javascript
运行
复制
uint16_t tcp_checksum(struct tcp_header *tcph, uint8_t *pseudo_header)
{
    size_t len = PSEUDO_HEADER_SIZE + (tcph->data_offset * 4);
    uint8_t combination[len];
    memcpy(combination, pseudo_header, PSEUDO_HEADER_SIZE);
    dump_tcp_header(tcph, combination, PSEUDO_HEADER_SIZE);
    return checksum(combination, len / 2);
}

我在这里做错什么了?

EN

Stack Overflow用户

回答已采纳

发布于 2022-08-18 15:18:36

通过cksum.ctcpdump源代码中计算校验和解决了问题,这是RFC 1071的逐行实现。我还必须为IFF_NO_PI设备设置tun。在这种情况下,使用tap设备而不是tun设备可能是处理EtherType的更好选择。

票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73352575

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档