欢迎来到天天文库
浏览记录
ID:21990988
大小:57.00 KB
页数:6页
时间:2018-10-26
《linux下libpcap源码分析及包过滤机制(4)》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库。
1、WORD资料下载可编辑过滤代码的安装前面我们曾经提到,在内核空间过滤数据包对整个捕获机制的效率是至关重要的。早期使用SOCK_PACKET方式的Linux不支持内核过滤,因此过滤操作只能在用户空间执行(请参阅函数pcap_read_packet()代码),在《UNIX网络编程(第一卷)》(参考资料B)的第26章中对此有明确的描述。不过现在看起来情况已经发生改变,Linux在PF_PACKET类型的socket上支持内核过滤。Linux内核允许我们把一个名为LPF(LinuxPacketFilter)的过滤器直接放到PF_PACKET
2、类型socket的处理过程中,过滤器在网卡接收中断执行后立即执行。LSF基于BPF机制,但两者在实现上有略微的不同。实际代码如下:/*在包捕获设备上附加BPF代码[pcap-Linux.c]*/staticintpcap_setfilter_Linux(pcap_t*handle,structbpf_program*filter){#ifdefSO_ATTACH_FILTERstructsock_fprogfcode;intcan_filter_in_kernel;interr=0;#endif/*检查句柄和过滤器结构的正确性*/i
3、f(!handle)return-1;if(!filter){strncpy(handle->errbuf,"setfilter:Nofilterspecified",sizeof(handle->errbuf));return-1;}/*具体描述如下*/if(install_bpf_program(handle,filter)<0)return-1;/*缺省情况下在用户空间运行过滤器,但如果在内核安装成功,则值为1*/handle->md.use_bpf=0;/*尝试在内核安装过滤器*/#ifdefSO_ATTACH_FILTER
4、#ifdefUSHRT_MAXif(handle->fcode.bf_len>USHRT_MAX){技术资料专业分享WORD资料下载可编辑/*过滤器代码太长,内核不支持*/fprintf(stderr,"Warning:Filtertoocomplexforkerneln");fcode.filter=NULL;can_filter_in_kernel=0;}else#endif/*USHRT_MAX*/{/*Linux内核设置过滤器时使用的数据结构是sock_fprog,而不是BPF的结构bpf_program,因此应做结构之间的
5、转换*/switch(fix_program(handle,&fcode)){/*严重错误,直接退出*/case-1:default:return-1;/*通过检查,但不能工作在内核中*/case0:can_filter_in_kernel=0;break;/*BPF可以在内核中工作*/case1:can_filter_in_kernel=1;break;}}/*如果可以在内核中过滤,则安装过滤器到内核中*/if(can_filter_in_kernel){if((err=set_kernel_filter(handle,&fcod
6、e))==0){/*安装成功!!!*/handle->md.use_bpf=1;}elseif(err==-1)/*出现非致命性错误*/{if(errno!=ENOPROTOOPT&&errno!=EOPNOTSUPP){fprintf(stderr,"Warning:Kernelfilterfailed:%sn",pcap_strerror(errno));}}}技术资料专业分享WORD资料下载可编辑/*如果不能在内核中使用过滤器,则去掉曾经可能在此socket上安装的内核过滤器。主要目的是为了避免存在的过滤器对数据包过滤的干扰*
7、/if(!handle->md.use_bpf)reset_kernel_filter(handle);[pcap-Linux.c]#endif}/*把BPF代码拷贝到pcap_t数据结构的fcode上*/intinstall_bpf_program(pcap_t*p,structbpf_program*fp){size_tprog_size;/*首先释放可能已存在的BPF代码*/pcap_freecode(&p->fcode);/*计算过滤代码的长度,分配内存空间*/prog_size=sizeof(*fp->bf_insns)*
8、fp->bf_len;p->fcode.bf_len=fp->bf_len;p->fcode.bf_insns=(structbpf_insn*)malloc(prog_size);if(p->fcode.bf_insns==NULL
此文档下载收益归作者所有