Chinaunix首页 | 论坛 | 博客
  • 博客访问: 181948
  • 博文数量: 64
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 616
  • 用 户 组: 普通用户
  • 注册时间: 2015-06-09 20:25
文章分类

全部博文(64)

文章存档

2016年(25)

2015年(39)

我的朋友

分类: LINUX

2015-09-11 17:57:41

Libpcap

Libpcap是一个网络包捕捉函数库,linuxtcpdump是以它为基础的。可以用之来实现网络嗅探器sniffer

Libcap数据报捕捉函数库,独立于系统的用户层包捕捉API接口。为底层网络监测提供了一个可移植的框架。

Libpcap主要有两部分。网络分接头(Network Tap)和数据过滤器(Packet Filter),网络分接头从网络设备驱动程序中收集数据拷贝,过滤器决定是否接收该数据包,libpcap利用BSD Packet FilterBPF)算法对网卡接收到的链路层数据包进行过滤。BPF算法的基本思想是在有BPF监听的网络中,网卡驱动将即受到的网络包赋值一份给BPF过滤器。过滤器根据用户定义的规则决定是否接受此数据报以及靠背该数据报的内容,然后将过滤后的数据给与过滤器相关联的上层应用程序。

Libpcap的包捕获机制就是在数据链路层加一个旁路处理,当一个数据包到达网络接口时,libpcap首先利用已经创建的Socket从链路层驱动程序中获得该数据报的拷贝,再通过Tap幻术将数据报发给BPF过滤器。BPF过滤器根据用户已经定义好的过滤规则对数据报进行逐一匹配。匹配成功则放入内核缓冲区,并传递给用户缓冲区,匹配失败则直接丢弃,如果没有设置过滤规则,所有数据报豆浆放入内核缓冲区。并传递给用户层缓冲区。

 

Libpcap的抓包框架

Pcap_lookupdev()函数用于查找网络设备,返回可悲pcap_open_live()函数调用的网络设备名指针。

Pcap_open_live()函数可用于打开网络设备,并且返回用于捕获网络数据报的数据报捕捉描述子,对于此网络设备的操作都要基于此网络设备描述字。

Pacp_lookupnet()函数获得指定网络设备的网络号和掩码。

Pcap_compile()函数用于将用户指定的过滤策略编译到过滤程序中。

Pcap_setfilter()函数用于设置过滤器

Pcap_loop()函数pacp_dispatch()函数用于捕捉数据包,捕捉后还可以进行处理。此外pcap_next()pcap_next_ex()两个函数也可以用来捕获数据报

Pcap_close()函数用于关闭网络设备,释放资源。

Pcap的应用程序格式,可以分为5部分

1.       决定从哪个接口进行嗅探开始,在linux下,可能是eth0,在BSD系统中可能是X11,也可以用一个字符串来定义这个设备。或者用pcap提供的接口名来处理。

2.       初始化pcap,要告诉pcap对什么设备进行嗅探。可以嗅探多个设备,那么怎么区分它们呢,使用文件句柄,就像打开一个文件进行读写一样,必须明明我们的嗅探“会话”,以此使它们各自区别开来。

3.       假如我们只想嗅探特定的传输(如TCP/IP包,发送端口23的包等),必须创建一个规则几何,编译并且使用它,这个过程分三个相互紧密关联的阶段。规则几何被置于一个字符内,并且被转换成能被pcap读的格式(因此编译它),编译实际上就是在我们的程序里调出一个不被外部程序使用的函数,接下来我们告诉pcap使用它来过滤我们想要的那一个会话。

4.       最后,我们告诉pcap进入它的主体执行循环,在这个阶段内pcap一直工作到它接收了所有我们想要的包为止,每当它收到一个包就调用另一个已经定义好的函数,这个函数可以做我们想要的任何工作,他可以剖析所捕获的包并打印出结果,

5.       在修谈到所需的数据后,我们要关闭会话并结束。

三、实现libpcap的每一个步骤

1)设置设备,有两种方法设置想要嗅探的设备

 

用户通过传递给程序的第一个参数来指定设备。字符串”dev”pcap理解的格式保存了我们要嗅探的接口和名字(同时,用户必须给我们一个真正存在的接口)


打开设备进行嗅探,创建一个嗅探会话的任务比较简单,为此,我们使用pcap_open_live()函数,此函数的原型是:

Pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)

其中第一个参数是指定的设备,snaplen是整形的,定义了被pcap捕捉的最大字节数,当promisc设为true时将置指定接口为混杂模式,然而,当它置为false时接口仍处在混杂模式的非凡情况下也是可能的)。To_ms是读取时的超时值,单位是毫秒()。Ebuf是我们可以存入任何错误信息的字符串,一如errbuf,此函数返回其绘画句柄。

混杂模式和非混杂模式的区别:这两种方式区别比较大,非混杂模式的嗅探器中,主机仅嗅探那些跟它直接有关的通信。如发向它的,从它发出的。或经过它的路由等都会被嗅探器捕捉。在混杂模式中,嗅探传输线路上的所有通信,在非交换式网络中,将是整个网络的通信,这样做最明显的优点是使得更多的包被修谈到,他们因你嗅探网络的原因或者对你有帮助,或者没有。但是混杂模式是可悲探测到的。一个主机可以通过高强度的测试判定另一台主机是否正在进行混杂模式的嗅探。其次,它尽在非交换式的网络环境中有效工作(如空想哦啊勉强哦。极品总金额口岸评价没在家拍卖行的ARP层面)。再次,在高负载的网络中,主机的系统资源将消耗的非常严重。

过滤通信

实现这一过程由pcap_compile()pcap_setfilter()这两个函数完成

在使用我们自己的过滤器前必须编译它,过滤表达式被保存在一个字符串中(字符数组)。器具发在tcpdump的手册中被证实非常好用,但是我们使用简单的测试表达式。这样你可能很轻易理解

调用pcap_compile()来编译它

Int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_iut32 netmask )

第一个参数是会话句柄,第二个是存储被编译的过滤器版本的地址的引用。第三个是表达式本身,存储在规定的字符串格式里。第四个是一个定义表达式是否被优化的整形量(0false1true)第四个是指定应用此过滤器的网络掩码,函数返回-1为失败,其他任何值为成功。

表达式被编译后,可以使用,在进入pacap_setfilter(),按照pcap的格式,先来看下pcap_setfilter()的原型。

Int pcap_setfilter(pcap_t *p, struct bpf_program *fp)

第一个参数是会话句柄,第二个参数是被搬移表达式版本的引用。

Pcap_compile()第二个参数相同

这个程序使嗅探器嗅探经路由端口23的所有通信,使用混杂模式,设备是eth0

实际的嗅探

1.       两种手段捕捉包,我们可以一次只捕捉一个包,也可以进入一个循环,等捕捉到多个包再进行处理。使用pcap_next()

Pcap_next()的原型是

u_char  *pcap_nextpcap_t  *pstrict  pcap_pkthdr  *h

第一个参数是会话句柄,第二个参数是指向一个包括了当前数据包总体信息(被捕捉时的事件,包的长度,其被指定的部分长度)的结构体的指针(在这里只有一个片段),pcap_next()返回一个u_char指针给被这个结构体描述的包。

这个程序嗅探被pcap_lookupdev()返回的设备并将它置为混杂模式,它发现第一个包经过端口23telnet)并且告诉用户此包的大小(以字节为单位)。这个程序包含一个新的调用pcap_close()

实际上的嗅探程序很少用到pcap_next(),通常他们使用pcap_loop()或者pcap_dispatch(实际上也是pcaploop)

Int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)

第一个参数是会话句柄,接下来是一个整形,告诉pcap_loop()在返回前捕捉多少个数据报(若为负值则是工作直至错误发生)。第三个参数是毁掉函数的名称(标示符所指),最后一个参数有些应用利用,一般为NULL,假设我们自己想送往回调函数送参数,还有pcap_loop()也需要用它,必须是一个u_char类型的指针以确保结果正确。Pcap使用u_char指针的形式传递信息,pcap_dispatch()用法相同,唯一不同的是他们处理超时,pcap_loop()忽略超时而pcap_dispatch()不。

阅读(776) | 评论(0) | 转发(0) |
0

上一篇:TCP/IP学习篇

下一篇:TPID

给主人留下些什么吧!~~