内核数据包处理_第1页
内核数据包处理_第2页
内核数据包处理_第3页
内核数据包处理_第4页
内核数据包处理_第5页
免费预览已结束,剩余14页可下载查看

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、内核数据包处理数据包处理的一些建议刖百我们大部分功能都需要解析数据,进行一系列的包匹配完成, 但是目前, 我们没有一个很好的框架来简化这个过程,大家处理数据包都是采用原生的linux内核接口, 并且没有统一的规范要求如何使用这些接口, 所以,存在大量的陷阱,一不留神就造成宕机。获取IP头部Wipn=ip_ndr(sKD);structsK_buffsK_buff_data_ttransport_header;/*Transportlayerheader*/1)_netif_receive_skb()在进入三层处理前就对network_header进行了设置。2) ip_rcv()中详细的检查保

2、证了IP头部到netfilter后是完整的。3) netfilter可以尽情使用ip头部。获取tcp头部错误1:tcph=tcp_hdr(skb);陷阱:netfilter的钩子点是属于TCP/IP协议栈的三层流程中,而四层的TCP头部此时还没有正确获取,只是初始化为IP头部的值,无法直接使用。错误2:tcph=(char*)iph+(iph-ihlihldata的偏移void*skb_header_pointer(struct-从skb的指定偏移取制定长度的数据, 如果要取的数据位于线性区,直接返回其开始指针,否则,则拷贝到buffer中,并将buffer指针返回。打印信息printk(%p

3、I4%d-%pI4%dlen:%dID:%dn”,&iph-saddr,ntohs(tcph-source),注意要点:1)IP地址输出Ipv4:%pI4%pi4IPv6:%pI6%pi62)MAC地址%pM%pm3)字节序的转换ntohs()ntohl()htons()htonl()_const_ntohl()_const_ntohs()const_htonl()const_htons()区别:const_*()是编译时处理的。获取TCP负载风险:payload=(char*)tcph+tcph-doff*-4;陷阱1:数据包可能是非线性的,同TCP头部。陷阱2:TCP头部数据有可能

4、是被篡改过的,tcph-doff如果很大怎么办?改进1:tcplen=skb-len-tcpoff;if(tcph-doff*4sizeof(structtcphdr)|tcplendoff*4)printk(Badtcp.n);returnNF_ACCEPT;接口介绍:-intskb_is_nonlinear(structsk_buff判断skb的数据是否是非线性的改进2:charpayload_buf1500;tcplen=skb-len-tcpoff;if(tcph-doff*4sizeof(structtcphdr)|tcplendoff*4)printk(Badtcp.n);retu

5、rnNF_ACCEPT;改进3:tcplen=skb-len-tcpoff;if(tcph-doff*4sizeof(structtcphdr)|tcplendoff*4)printk(Badtcp.n);returnNF_ACCEPT;if(skb_linearize(skb)接口介绍:4ntskb_linearize(structsk_buff将skb线性化解析数据1)判断数据包内容风险1:if(payload0!=G|payload1!=风险2:Hf(payload0=G-&payload1-=陷阱:如果payload的长度只有1个字节怎么办?改进:4f(payload_len-

6、3|payload0!=G2)查找数据包中的某个字符串风险:host=strstr(payload,Host:);陷阱:可能会越界,数据包不一定是以0结束。payload_len尸人、GIEITI-/|H|T|T|P烫|烫payload改进:host=strnstr(payload,Host:payload_len);一定要使用这一系列的函数:strnchrstrncpystrncatstrncmpstrnicmpstrnlenmemcpy3)移动指向数据包的指针风险:payload_lenGET/HTTPrnHrnpayloadhost=strnstr(payload,Host:payloa

7、d_len);if(host=NULL)return;陷阱:查找的字符串有可能是数据包的最后一部分payload_len入GET/HTTPrnHost4payload改进:host=strnstr(payload,Host:payload_len);if(host=NULL)return;host=host+sizeof(Host:)14)数据包操作错误:u32len;len=payload_len-512;if(len=0)陷阱:无符号数的强制类型转换,u32类型永远都是大于等于0的)当payload_len小于512时)判断就会不生效。改进:u32len;if(payload_len=51

8、2)return;或者intlen;len=payload_len-512;if(len=payload_len-2)综述:数据包处理要时刻保持警醒,它可能不是你想象的样子!内存分配风险:void*xxx_alloc(unsignedlongsize,gfp_tflags)陷阱1:如果需要申请的size是0会如何?陷阱2:多个cpu并发申请又会如何?改进:void*xxx_alloc(unsignedlongsize,gfp_tflags)(intmalloc_size=size+sizeof(unsignedlong);void*p;intuse;问题:kmalloc(0,.)返回值是什么?

9、建议:相同的内存反复申请释放的情况下,请使用kmem_cache_a110c建议的同步与互斥方法1)rcu锁使用场景:进程上下文用来配置,软中断上下文只读配置的情况好处:性能高,接口简单方法:hook函数读取配置,中断上下文:rcu_read_lock();data=rcu_dereference(global_data);/*基于proc文件等的配置下发,进程上下文:data=kmalloc(size,GFP_KERNEL);if(data=NULL)return;if(copy_from_user(data,user,len)return另一种方法:if(old_data)call_rcu(&old_data-rcu,data_free_rcu);注意1:synchronize_rcu()只能用于进程上下文,call_rcu()可以用于中断上下文。注意2:data_free_rcu的调用是软中断上下文,不能使用vfree。模块卸载:old_datarcu_dereference(global_data)rcu_assign_pointer(global_data,2)每CP晚量使用场景:在钩子函数中使用的临时缓存区,不用每次申请

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论