tc通过u32匹配数据包头匹配arp mpls tcp udp等数据

tc通过u32匹配数据包头匹配arp mpls tcp udp等数据,第1张

tc通过u32匹配数据包头匹配arp mpls tcp udp等数据

tc就是traffic control,是linux上的一个常用限速工具,他的作用很多,除了限速还有镜像等其它功能,它的工作原理我这里就不多做介绍,我们这篇文章关注的是如果通过u32来匹配数据流量;比如我要通过tc来限速,那我肯定要有限速的对象吧,tc的filter就是用来匹配流量的,而filter中有个u32可以匹配ip包头的任何部分从而匹配对应的流量来限速;这就要求我们对包头的结构非常的了解。

 上图是一个我用wireshark抓的tcp包,我们从第二行看起,第二行这里是以太网头部,有源目Mac地址和以太网类型,后面就是IP头部了,再后面就tcp协议头部,我们可以通过匹配Mac地址或者ip地址或者协议端口等把这个包给过滤出来,下面是我们今天的第一个例子:

实例一:

匹配目的端口为22的数据包

#创建eth0接口入方向的队列
tc qdisc add dev eth0 ingress
#匹配端口号为22的数据包从定向到lo口,lo就是我们的环回口,等下我们通过tcpdump在lo口上抓包
tc filter add dev eth0 parent ffff: protocol all prio 5 u32 
 match  u16 0x0016 0xffff at 22 flowid 1:40 action mirred egress mirror dev lo 

#查看我们配置的filter有没有匹配到数据
tc -s filter show dev eth0 parent ffff:




下面的截图是查看filter匹配的输出结果,第一行红框表示match参数,第二行红框表示这个match匹配到的数据包个数和字节数。

 下面解释命令和回显的具体含义:

tc filter add dev eth0 parent ffff: protocol all prio 5 u32 
 match  u16 0x0016 0xffff at 22 flowid 1:40 action mirred egress mirror dev lo 

上面第一行特别需要注意的就是protocol后面跟的参数all,因为我曾经在这个参数踩坑研究了一天,这个all可以替换为ip或者arp,网上最常见的就是这个参数写IP,匹配正常的tcp udp包没有问题,但是对于arp或者mpls报文时就匹配不上,这时候就要写all了,再有第一行的u32就表示通过u32来匹配数据,然后我们看第二行;我们重点关注第二行flowid前面一部分参数,match表示匹配,后面跟具体的匹配东西,u16表示匹配16个比特的数据,对应2字节,也就是端口字段对应的占的字节数,然后后面跟的是2个16进制的数,前面是要匹配的值,后面对应的掩码用来做匹配用的,0x0016对应2个字节,对应的10进制数就是22,后面的0xffff表示16个1,1表示绝对匹配,0表示不匹配。at 22表示从22字节开始匹配(这里非常重要,很多资料上都说了这at后面的22是偏移量,但是这个偏移的开始位置是哪里呢,偏移是从以太网头末尾开始计算的,在这之后用正数表示偏移量,在这之前用负数表示偏移量,比如现在我们是匹配目的端口是22的数据,如果是一个正常的tcp报文,以太网后后面就是ip头,占20字节,ip头后面就是tcp头,开头2字节表示源端口,紧接着后面就是2字节表示目的端口,所以我这里写at 22表示从22字节处开始匹配,然后匹配2字节,值为22,正好就对上了)

然后我们看filter的输出match为:match 00000016/0000ffff at 20,我明明match写的是at22呀,为啥回显展示是at20呢,这是因为我们不管match时用的是u32 u16 u8来匹配数据,最终都会转化为u32来显示, 所以回显展示的是at 20,去掉前面的4个0(2字节占位)不就是at 22的0x0016吗!

下面是tcp抓lo接口的数据包,发现都是目的为22端口的数据:

实例二:

匹配mpls数据包并且目的IP是1.1.1.1的数据

#创建eth0接口入方向的队列
tc qdisc add dev eth0 ingress
#匹配mpls数据包源为1.1.1.1的数据包从定向到lo口,lo就是我们的环回口,等下我们通过tcpdump在lo口上抓#包
tc filter add dev eth0 parent ffff: protocol all prio 5 u32 
 match  u16 0x8847 0xffff at -2 
 match u32 0x01010101 0xffffffff at 20 
 flowid 1:40 action mirred egress mirror dev lo 

#查看我们配置的filter有没有匹配到数据
tc -s filter show dev eth0 parent ffff:



下面是回显,这里我们看上面命令filter的第二和第三行,第二行中有个at -2,这里为啥是-2,这是因为我们匹配的以太网头部的类型,我们之前说过at的起点位置是以太网尾部,而以太网尾部最后2字节就是以太网的数据类型,所以这里at是-2,然后mpls的数据类型是8847,所以这里是8847,arp是0806,然后我们看filter的第三行,这里是at 20,为啥是20呢,因为mpls头部占4字节,目的ip地址在ip头部的第16字节,所以16加4为20,ip地址占4字节,然后我们按照前面讲的对下下面的回显看对不对得上。这里还有一个知识点就是我们可以写多个匹配项,他们之间是与的关系,只有全部都匹配上了才算是真的匹配。

下面是一些包头的结构,用作参考:

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5694889.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存