本文共 1335 字,大约阅读时间需要 4 分钟。
tags: 有趣小实验 Linux源码
本文通过修改、编译Linux内核实现自定义的TCP Options
,在简要的叙述原理之后,附上内核补丁。基于内核版本3.19
。
TCP协议
规定在TCP头部的末尾处有可变长的一段“options”
用于对tcp协议的拓展,具体options的使用和解释请参照和相关博客。由于实验需要想通过抓包分析包所在的流
的tcp连接状态,思来想去决定通过修改内核将tcp协议中的拥塞窗口cwnd
写到tcp options
里面去。如果能做到的话,通过抓包工具分析tcp options
即可知道当前tcp连接的状态,进而执行进一步的工作(流量控制、数据分析等)。
现在这篇文章介绍的补丁能够实现的效果为,通过sysctl
决定是否开启此补丁
如上图所示,net.ipv4.tcp_sw
为控制字段,为 0 表示没有开启、为
在wireshark
中解析查看抓到的包,可以看到选中的一行(红色背景)有一个Unknown (0x0a) (6 bytes)
。需要明确的是虽然对wireshark
来说这个tcp option
是一个“未知”,但是这个补丁增加的数据是完全符合tcp选项的规定的,要不然wireshark
也不能够正确的解析出来整个tcp数据包了,只不过wireshark
不能够理解其含义罢了。可以看到具体数据展示框中,自定义tcp选项的数据为0a 06 00 00 00 01
,其中0a
表示tcp 选项种类,是笔者自己随便选了一个数值;06
表示整个自定义tcp选项的长度,这个是规定要求的;最后的00 00 00 01
为真正需要的数据cwnd
的值。
由于tcp头部最长只能有60字节
,而头部中固定的部分大小为20字节
,也就是说所有的tcp选项的总长度不应该超过40字节
。在实际测试中发现如果开启了net.ipv4.tcp_sw
的同时也开启了选择确认
(Selective Acknowledgment,SACK),很容易就会tcp头部溢出,如下图示
但是由于时间原因,并没有去修复这个问题,而是决定在开启自定义tcp头部
的时候关闭选择确认
,^_^。如果有需要的话读者可以自行完善这个补丁。
由于内核的性质,不大可能完全介绍一下该补丁的原理,只好大体上说一下。
int sysctl_tcp_sw;
相关的修改的目的就是希望能够通过sysctl
来对自定义tcp选项是否开启进行控制。/include/net/tcp.h
中。tcp_established_options
函数用来决定连接建立之后的数据包的tcp选项应该包含哪些,这个函数只是用来确定包含哪些tcp选项,实际的往tcp头部中写入数据不是在这里进行的。tcp_options_write
实际的写入数据的函数,注意在写入数据的时候并没有进行tcp头部溢出的判断(为了简单起见)所以才会出现前文提到的问题。至于使用方法,就和普通的补丁的使用方法是一样的,这个请自行搜索资料,就不在此赘述了,需要注意的就是内核版本为3.19
。
转载地址:http://cpdws.baihongyu.com/