1、 1)_netifreceive_b()在进入三层处理前就对nwor_heade进行了设置。 2)ipc()中详细的检查保证了IP头部到etfilte后是完整的。3)netfilr可以尽情使用ip头部。获取tcp头部 错误:tcph = tcp_hdr(skb); 陷阱: netfilr的钩子点是属于TPI协议栈的三层流程中,而四层的TC头部此时还没有正确获取,只是初始化为IP头部的值,无法直接使用。错误2:tcph = (char *)iph + (iph-ihl tcph = skb_header_pointer(skb, tcpoff, sizeof(_tcph), &_tcph);if
2、 (tcph = NULL) return; 接口介绍:skb_network_offset(struct skb_buff *skb) 计算三层头部相对于kb-data的偏移void * skb_header_pointer(struct sk_buff *skb, int offset, int len, void *buffer)从skb的指定偏移取制定长度的数据,如果要取的数据位于线性区,直接返回其开始指 针,否则,则拷贝到bffer中,并将bufer指针返回。printk(%pI4 %d - %pI4 %d len: %d ID: %dn, &iph-saddr, ntohs(tcp
3、h-source),daddr,dest), ntohs(iph-tot_len),id);打印信息 注意要点:1) IP地址输出Iv4:%pI4 %p4IP6:%pI %pi6 2)MAC地址 %pM %3)字节序的转换nths() ol() tns() honl()_con_nohl() _cons_ntohs() _nthtnl() _othtons() 区别:_ons*()是编译时处理的。获取C负载 风险:payload = (char *)tcph + tcph-doff * 4; 陷阱1: 数据包可能是非线性的,同TC头部。 陷阱2: CP头部数据有可能是被篡改过的,tc-dof如
4、果很大怎么办? 改进1:tcplen = skb-len - tcpoff;if (tcph-doff*4 sizeof(struct tcphdr) | tcplen doff*4) printk(Bad tcp.n); return NF_ACCEPT;if (skb_is_nonlinear(skb)Nonlinear skb.npayload_len = tcplen - tcph-if (payload_len = 0) 接口介绍:int skb_is_nonlinear(struct sk_buff *skb) 判断sb的数据是否是非线性的改进2:char payload_buf1
5、500;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)Can not linearize skb.nint skb_ linearize (struct sk_buff *skb)将kb线性化解析数据1)判断数据包内容 风险1:if (payload0 != G | payload1 !E | payload2 !T
6、) 风险2:if (payload0 = & payload1 = payload2 = ) & payload_len = 3)如果aoa的长度只有1个字节怎么办? 改进:if (payload_len = (payload + payload_len)4)数据包操作 错误:u32 len;len = payload_len - 512;if (len = payload_len - 2)综述:数据包处理要时刻保持警醒,它可能不是你想象的样子!内存分配void * xxx_alloc(unsigned long size, gfp_t flags) int malloc_size = size + sizeof(unsigned long); void *p; if (memory_use + malloc_size memory_max) return; p = kmalloc(malloc_size, flags); if (p = NULL) return NULL; memory_u
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1