Chinaunix

标题: PF_PACKET捕获数据包能用BPF过滤规则代码不? [打印本页]

作者: zuii    时间: 2008-09-19 20:41
标题: PF_PACKET捕获数据包能用BPF过滤规则代码不?
这个问题似乎问的有点奇怪~  但是确实没搞明白

大多数介绍说的是PF_PACKET的套接字和BPF都是一种过滤器,但有的文献说的是可以把代码加进去,只是就那么一两句话,也不知道怎么用

希望知道的给解释下,尽量详细一点,或者给点资料什么的~ 不是很清楚的也可以来一起讨论下~

=============解决后,结果如下================

答案是,可以在linux packet filter中应用BPF过滤规则~
推荐一篇文章(英文):http://www.linuxjournal.com/article/4659

如果嫌英文不好看,那么看代码吧,一看就知道怎么回事了~下面下载~换成C格式的哦~呵呵

[ 本帖最后由 zuii 于 2008-9-20 00:14 编辑 ]

lpf.tar.gz

1.88 KB, 下载次数: 173


作者: blizzard213    时间: 2008-09-19 21:12
原帖由 zuii 于 2008-9-19 20:41 发表
这个问题似乎问的有点奇怪~  但是确实没搞明白

大多数介绍说的是PF_PACKET的套接字和BPF都是一种过滤器,但有的文献说的是可以把代码加进去,只是就那么一两句话,也不知道怎么用

希望知道的给解释下,尽量 ...

PF_PACKET是使用socket函数创建可访问数据链路层套接字的参数
创建PF_PACKET时 调用socket的第2个参数可以是SOCK_RAW 表示完整的数据链路层分组(以太网帧)
也可以是SOCK_DGRAM表示扣除链路层头部的分组

BPF是BSD分组过滤器 它本身是一个虚拟机 你说的加代码 是过滤语言 也就是BPF虚拟器的汇编语言。。。

参考libpcap 参考unp
作者: flw2    时间: 2008-09-19 22:14
static int create_packetfd()
{
                int fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

                struct sockaddr_ll sll;

                memset(&sll, 0, sizeof(sll));

                struct sock_filter filters[] = {
                        /* tcpdump -dd arp or udp port 137 */
                        { 0x28, 0, 0, 0x0000000c },
                        { 0x15, 17, 0, 0x00000806 },
                        { 0x15, 0, 6, 0x000086dd },
                        { 0x30, 0, 0, 0x00000014 },
                        { 0x15, 0, 15, 0x00000011 },
                        { 0x28, 0, 0, 0x00000036 },
                        { 0x15, 12, 0, 0x00000089 },
                        { 0x28, 0, 0, 0x00000038 },
                        { 0x15, 10, 11, 0x00000089 },
                        { 0x15, 0, 10, 0x00000800 },
                        { 0x30, 0, 0, 0x00000017 },
                        { 0x15, 0, 8, 0x00000011 },
                        { 0x28, 0, 0, 0x00000014 },
                        { 0x45, 6, 0, 0x00001fff },
                        { 0xb1, 0, 0, 0x0000000e },
                        { 0x48, 0, 0, 0x0000000e },
                        { 0x15, 2, 0, 0x00000089 },
                        { 0x48, 0, 0, 0x00000010 },
                        { 0x15, 0, 1, 0x00000089 },
                        { 0x6, 0, 0, 0x00000060 },
                        { 0x6, 0, 0, 0x00000000 },
                };


                struct sock_fprog  fprog = {
                                .len = sizeof(filters)/sizeof(struct sock_filter),
                                .filter = filters
                };

                setsockopt(fd,  SOL_SOCKET,  SO_ATTACH_FILTER, &fprog, sizeof(struct sock_fprog));

                return fd;
}


libpcap为把"arp or udp port 137" 这样的串编译为内核为某个socket收到包时执行的虚拟机的指令
setsockopt就是安装指令了
把-dd 换成-d可以得到如下

(000) ldh      [12]
(001) jeq      #0x806           jt 19        jf 2//arp?ok
(002) jeq      #0x86dd          jt 3        jf 9
(003) ldb      [20]
(004) jeq      #0x11            jt 5        jf 20
(005) ldh      [54]
(006) jeq      #0x89            jt 19        jf 7
(007) ldh      [56]
(00 jeq      #0x89            jt 19        jf 20
(009) jeq      #0x800           jt 10        jf 20
(010) ldb      [23]
(011) jeq      #0x11            jt 12        jf 20
(012) ldh      [20]
(013) jset     #0x1fff          jt 20        jf 14
(014) ldxb     4*([14]&0xf)
(015) ldh      [x + 14]
(016) jeq      #0x89            jt 19        jf 17
(017) ldh      [x + 16]
(01 jeq      #0x89            jt 19        jf 20
(019) ret      #96
(020) ret      #0

这个就是这些指令的汇编格式

关于BPF,参考这个文档
bpf-usenix9.pdf (122.7 KB, 下载次数: 276)
作者: zuii    时间: 2008-09-19 22:59
感谢LS~
我也在看一些英文的资料
英语不是很好  比较慢~~ 谢谢了
作者: zuii    时间: 2008-09-20 00:00
刚看了个资料~还不错,大概知道了步骤了~HOHO
作者: siyu_yangyang    时间: 2014-04-23 22:13
牛逼,大家可不可以见一个群,这样互相讨论方便,也能够互补!
作者: siyu_yangyang    时间: 2014-04-28 08:31
回复 3# flw2


     struct sock_filter filters[] = {
                        /* tcpdump -dd arp or udp port 137 */
                        { 0x28, 0, 0, 0x0000000c },
                        { 0x15, 17, 0, 0x00000806 },
                        { 0x15, 0, 6, 0x000086dd },
                        { 0x30, 0, 0, 0x00000014 },
                        { 0x15, 0, 15, 0x00000011 },
                        { 0x28, 0, 0, 0x00000036 },
                        { 0x15, 12, 0, 0x00000089 },
                        { 0x28, 0, 0, 0x00000038 },
                        { 0x15, 10, 11, 0x00000089 },
                        { 0x15, 0, 10, 0x00000800 },
                        { 0x30, 0, 0, 0x00000017 },
                        { 0x15, 0, 8, 0x00000011 },
                        { 0x28, 0, 0, 0x00000014 },
                        { 0x45, 6, 0, 0x00001fff },
                        { 0xb1, 0, 0, 0x0000000e },
                        { 0x48, 0, 0, 0x0000000e },
                        { 0x15, 2, 0, 0x00000089 },
                        { 0x48, 0, 0, 0x00000010 },
                        { 0x15, 0, 1, 0x00000089 },
                        { 0x6, 0, 0, 0x00000060 },
                        { 0x6, 0, 0, 0x00000000 },
                };


                struct sock_fprog  fprog = {
                                .len = sizeof(filters)/sizeof(struct sock_filter),
                                .filter = filters
                };

编译不过去呀





欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2