TCP:seq/ack号码是如何生成的?

20

我正在开发一个程序,用于嗅探发送到和从特定地址接收到的TCP数据包。我的目标是对某些已接收到的数据包进行自定义回复。我已经完成了解析工作,已经能生成有效的以太网、IP和大部分TCP数据包。

唯一无法确定的是seq / ack号码是如何确定的。

虽然这与问题可能无关,但该程序使用WinPCap编写的C ++。 我请求任何可以帮助我的提示、文章或其他资源。


与标准相关的最佳信息来源通常是原始的RFC(请求评论),在这种情况下,是RFC 2018。一般来说,维基百科也是一个不错的查找地点。如果以上都无法满足需求,那么在这里你几乎可以得到结果。 - Adam Liss
8个回答

29

当建立TCP连接时,每一方都会生成一个随机数作为其初始序列号。这是一个强随机数:如果互联网上的任何人可以猜测序列号,他们就可以轻松地伪造数据包注入到TCP流中,因此会存在安全问题。

此后,对于每个传输的字节,序列号将增加1。ACK字段是从另一方发送回来以确认接收的序列号。

RFC 793是TCP协议规范的原始文档,可以提供很大的帮助。


5
"ack"字段不是来自另一方的序列号,而是序列号加上已接收数据的长度(如下面Zainee Khan答案中所示)。 - Ben Schwehn

8
我有同样的工作要做。 首先,初始序列号将会随机生成(0-4294967297)。 然后接收者会计算接收到的数据长度并发送ACK,ACK中包含 seq# + length = x。此时序列号将变成x,发送方将发送数据。类似地,接收者会计算长度x + length = y,并以y作为ACK发送,如此循环...这就是序列号/确认号生成的方式...
如果您想实际演示,请在Wireshark中嗅探数据包,并跟踪TCP流,看看情况...

1
提高你的回答清晰度。 - JSuar
你还可以像这样从终端捕获数据包:sudo tcpdump -i eth0。 - z atef

6

3

1

RFC 793第3.3节涵盖了序列号。上次我在那个级别编写代码时,我想我们只是保留了一个持久化的递增计数器用于序列号。


1

这些值参考了数据包有效载荷的开始相对于连接初始序列号的预期偏移量。

参考

序列号(32位)- 具有双重作用。如果设置了SYN标志,则为初始序列号。实际第一个数据字节的序列号将是此序列号加1。如果未设置SYN标志,则为第一个数据字节的序列号。

确认号(32位)- 如果设置了ACK标志,则此字段的值是接收方期望的下一个字节。


1

从两端随机生成数字,然后增加发送的八位字节数。


0

连接建立后,序列号会递增。新连接的初始序列号理想情况下应该是随机选择的,但很多操作系统都有一些半随机算法。RFC文档是了解更多信息的最佳来源TCP RFC


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接