Linux下自定义TCP OPTIONS

Linux下自定义TCP OPTIONS

tags: 有趣小实验 Linux源码

  • Linux下自定义TCP OPTIONS
    • 序言
    • 正文
      • 动机
      • 实现效果
      • 存在问题
      • 实现介绍与使用方法
    • 引用


序言

本文通过修改、编译Linux内核实现自定义的TCP Options,在简要的叙述原理之后,附上内核补丁。基于内核版本3.19

正文

动机

TCP协议规定在TCP头部的末尾处有可变长的一段“options”用于对tcp协议的拓展,具体options的使用和解释请参照RFC1323和相关博客。由于实验需要想通过抓包分析包所在的流的tcp连接状态,思来想去决定通过修改内核将tcp协议中的拥塞窗口cwnd写到tcp options里面去。如果能做到的话,通过抓包工具分析tcp options即可知道当前tcp连接的状态,进而执行进一步的工作(流量控制、数据分析等)

实现效果

现在这篇文章介绍的补丁能够实现的效果为,通过sysctl决定是否开启此补丁

如上图所示,net.ipv4.tcp_sw为控制字段,为 0 表示没有开启、为 1 表示开启。开启之后的效果如下图示

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头部的时候关闭选择确认,^_^。如果有需要的话读者可以自行完善这个补丁。

实现介绍与使用方法

补丁放在了github上面

由于内核的性质,不大可能完全介绍一下该补丁的原理,只好大体上说一下。

  1. 所有和int sysctl_tcp_sw;相关的修改的目的就是希望能够通过sysctl来对自定义tcp选项是否开启进行控制。
  2. 新的选项的一些宏定义在/include/net/tcp.h中。
  3. tcp_established_options函数用来决定连接建立之后的数据包的tcp选项应该包含哪些,这个函数只是用来确定包含哪些tcp选项,实际的往tcp头部中写入数据不是在这里进行的。
  4. tcp_options_write实际的写入数据的函数,注意在写入数据的时候并没有进行tcp头部溢出的判断(为了简单起见)所以才会出现前文提到的问题。

至于使用方法,就和普通的补丁的使用方法是一样的,这个请自行搜索资料,就不在此赘述了,需要注意的就是内核版本为3.19


引用

  1. vcc实现
  2. linuxforums相关帖子
  3. 如何编译内核

你可能感兴趣的:(有趣小实验,Linux内核)