内核数据包处理文档格式.docx

上传人:b****1 文档编号:14108574 上传时间:2022-10-18 格式:DOCX 页数:14 大小:91.48KB
下载 相关 举报
内核数据包处理文档格式.docx_第1页
第1页 / 共14页
内核数据包处理文档格式.docx_第2页
第2页 / 共14页
内核数据包处理文档格式.docx_第3页
第3页 / 共14页
内核数据包处理文档格式.docx_第4页
第4页 / 共14页
内核数据包处理文档格式.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

内核数据包处理文档格式.docx

《内核数据包处理文档格式.docx》由会员分享,可在线阅读,更多相关《内核数据包处理文档格式.docx(14页珍藏版)》请在冰豆网上搜索。

内核数据包处理文档格式.docx

1)__netif_receive_skb()在进入三层处理前就对network_header进行了设置。

2)ip_rcv()中详细的检查保证了IP头部到netfilter后是完整的。

ﻩ3)netfilter可以尽情使用ip头部。

ﻩ获取tcp头部

错误1:

tcph=tcp_hdr(skb);

陷阱:

netfilter的钩子点是属于TCP/IP协议栈的三层流程中,而四层的TCP头部此时还没有正确获取,只是初始化为IP头部的值,无法直接使用。

ﻩ错误2:

tcph=(char*)iph+(iph->

ihl<

<

2);

陷阱:

数据包可能是非线性的

ﻩ改进:

tcpoff=skb_network_offset(skb)+(iph->

tcph=skb_header_pointer(skb,tcpoff,sizeof(_tcph),&

_tcph);

if(tcph==NULL)

return;

接口介绍:

skb_network_offset(structskb_buff*skb)

计算三层头部相对于skb->

data的偏移

void*skb_header_pointer(structsk_buff*skb,intoffset,intlen,void*buffer)

ﻩ从skb的指定偏移取制定长度的数据,如果要取的数据位于线性区,直接返回其开始指针,否则,则拷贝到buffer中,并将buffer指针返回。

printk("

%pI4%d----->

%pI4%dlen:

%dID:

%d\n"

&

iph->

saddr,

ntohs(tcph->

source),

daddr,

dest),

ntohs(iph->

tot_len),

id));

打印信息

注意要点:

ﻩ1)IP地址输出

ﻩﻩIpv4:

%pI4 %pi4

ﻩﻩIPv6:

%pI6 %pi6

2) MAC地址

ﻩ%pM %pm

ﻩ3)字节序的转换

ﻩﻩntohs() ntohl()htons() htonl()

ﻩﻩ__const_ntohl()__const_ntohs() __const_htonl()  __const_htons()

ﻩ区别:

__const_*()是编译时处理的。

获取TCP负载

风险:

payload=(char*)tcph+tcph->

doff*4;

陷阱1:

数据包可能是非线性的,同TCP头部。

陷阱2:

TCP头部数据有可能是被篡改过的,tcph->doff如果很大怎么办?

改进1:

tcplen=skb->

len-tcpoff;

if(tcph->

doff*4<

sizeof(structtcphdr)||tcplen<

tcph->

doff*4)

{

printk("

Badtcp.\n"

);

returnNF_ACCEPT;

if(skb_is_nonlinear(skb))

Nonlinearskb.\n"

payload_len=tcplen-tcph->

if(payload_len==0)

接口介绍:

intskb_is_nonlinear(structsk_buff*skb)

判断skb的数据是否是非线性的

ﻩ改进2:

charpayload_buf[1500];

if(payload_len>

sizeof(payload_buf))

payload=skb_header_pointer(skb,tcpoff+tcph->

doff*4,payload_len,payload_buf);

if(payload==NULL)

改进3:

if(skb_linearize(skb))

Cannotlinearizeskb.\n"

intskb_linearize(structsk_buff*skb)

ﻩ将skb线性化

解析数据

ﻩ1)判断数据包内容

风险1:

if(payload[0]!

='

G'

||payload[1]!

E'

||payload[2]!

T'

风险2:

if((payload[0]=='

&

&

payload[1]=='

payload[2]=='

)&

payload_len==3)

ﻩ如果payload的长度只有1个字节怎么办?

改进:

if(payload_len<

3||payload[0]!

ﻩ2)查找数据包中的某个字符串

ﻩ风险:

host=strstr(payload,"

Host:

"

可能会越界,数据包不一定是以'

\0'结束。

host=strnstr(payload,"

payload_len);

if(host==NULL)

return;

ﻩ一定要使用这一系列的函数:

strnchr

ﻩstrncpy

ﻩstrncat

strncmp

strnicmp

ﻩstrnlen

memcpy

3)移动指向数据包的指针

ﻩ风险:

host=host+sizeof("

)-1;

/*

*dealwithhost

*/

ﻩ查找的字符串有可能是数据包的最后一部分。

if(host>

=(payload+payload_len))

ﻩ4)数据包操作

错误:

u32len;

len=payload_len-512;

if(len<

=0)

memcpy(buf,payload,len);

ﻩ陷阱:

无符号数的强制类型转换,u32类型永远都是大于等于0的,当payload_len小于512时,判断就会不生效。

改进:

=512)

或者

intlen;

ﻩ5)

风险:

   

intlen=payload[1];

memcpy(buf,&

payload[2],len);

ﻩ可能是异常数据包,offset不是你想要的

ﻩ正确做法:

if(len>

=payload_len-2)

ﻩ综述:

数据包处理要时刻保持警醒,它可能不是你想象的样子!

ﻩ内存分配

void*xxx_alloc(unsignedlongsize,gfp_tflags)

intmalloc_size=size+sizeof(unsignedlong);

void*p;

if(memory_use+malloc_size>

memory_max)

return;

p=kmalloc(malloc_size,flags);

if(p==NULL)

returnNULL;

memory_u

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1