1.通过分析PF_RING源代码分析bpf filter过滤的实现
2.引用hyperscan正则表达式分析引擎.
int pfring_set_bpf_filter(pfring *ring,char *filter_buffer) {
int rc = PF_RING_ERROR_NOT_SUPPORTED;
if(!ring)
return -1;
if (!ring->force_userspace_bpf && ring->set_bpf_filter)
return ring->set_bpf_filter(ring,filter_buffer);
/* no in-kernel bpf support,setting up userspace bpf */
if (unlikely(ring->reentrant))
pthread_rwlock_wrlock(&ring->rx_lock);
rc = pfring_parse_bpf_filter(filter_buffer,ring->caplen,&ring->userspace_bpf_filter);
if(unlikely(ring->reentrant))
pthread_rwlock_unlock(&ring->rx_lock);
if (rc == 0)
ring->userspace_bpf = 1;
return rc;
}
pfring_set_bpf_filter函数调用 ring->set_bpf_filter(ring,filter_buffer);
set_bpf_filter是个函数指针类型的变量,具体的定义如下
int (*set_bpf_filter) (pfring *,char *);
set_bpf_filter变量被赋值成pfring_mod_set_bpf_filter函数,pfring_mod_set_bpf_filter函数的实现代码如下:
int pfring_mod_set_bpf_filter(pfring *ring,char *filter_buffer) {
int rc = -1;
#ifdef ENABLE_BPF
struct bpf_program filter;
struct sock_fprog fcode;
if(!filter_buffer)
return -1;
if(unlikely(ring->reentrant))
pthread_rwlock_wrlock(&ring->rx_lock);
if(pcap_compile_nopcap(ring->caplen,/* snaplen_arg */
DLT_EN10MB,/* linktype_arg */
&filter,/* program */
filter_buffer,/* const char *buf */
0,/* optimize */
0 /* mask */
) == -1) {
rc = -1;
goto pfring_mod_set_bpf_filter_exit;
}
if(filter.bf_insns == NULL) {
rc = -1;
goto pfring_mod_set_bpf_filter_exit;
}
fcode.len = filter.bf_len;
fcode.filter = (struct sock_filter *) filter.bf_insns;
rc = setsockopt(ring->fd,0,SO_ATTACH_FILTER,&fcode,sizeof(fcode));
pcap_freecode(&filter);
if(rc == -1)
pfring_mod_remove_bpf_filter(ring);
pfring_mod_set_bpf_filter_exit:
if(unlikely(ring->reentrant))
pthread_rwlock_unlock(&ring->rx_lock);
#endif
return rc;
}
流程如下:
1.pcap_compile_nopcap:将字符串类型的filter_buffer转化成bpf_program类型的过滤器.
2.设置struct sock_fprog 类型变量fcode的属性信息(如fcode.len和fcode.filter)
3.rc = setsockopt(ring->fd,sizeof(fcode));
设置ring专有套接字fd的属性.使其在底层抓包时,直接过滤掉不符合条件的数据包.
注意:此处的过滤属于硬件网卡层过滤,在网卡抓包时过滤数据包,和在应用层过滤有很大区别.
我想在应用层做规则匹配的话,还是考虑选型HyperScan,一个正则表达式的匹配引擎. 我马上好好研究下它. 加油.欧