您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 基于libpcap的网络编程技术
第五章基于libpcap的网络编程技术5.1常见的包捕获机制简介包捕获就是利用以太网的介质共享的特性,通过将网络适配器设置为混杂模式的方法,接收到所有网络上的以太网帧。包捕获的机制大致可以分为两类:一类是由操作系统内核提供的捕获机制。另一类是由应用软件或系统开发包捕获驱动程序提供的捕获机制。常见的包捕获机制如表5-1所示。其中最主要的是下列4种:BPF(BerkeleyPacketFilter)DLPI(DataLinkProviderInterface)NIT(NetworkInterfaceTap)SOCK-PACKET类型套接口。BPF由基于BSD的Unix系统内核所实现。DLPI是Solaris(和其他SystemVUNIX)系统的内嵌子系统。NIT是SUNOS4系统的一部分,但在Solaris/SUNOS5中被DLPI所取代。Linux核心则实现了SOCK-PACKET的包捕获机制。从性能上看,BPF比DLPI和NIT好得多,SOCK-PACKET最弱。表5-1常用的包捕获机制由于现在很多局域网为NT网,其网络传输方式大多采用以太网标准,所以涉及的编程也是在Windows环境下实现的。Windows操作系统没有提供包捕获机制,只提供了数量很少并且功能有限的API调用。在Windows环境下由于其自身的封装性,很难对其底层进行编程。本章将对BSD系列的libpcap进行深入地介绍。包捕获机制系统平台备注BPFBSD系列BerkeleyPacketFilterDLPISolaris,HP-UXSCODataLinkProviderInterfaceNITSunOS3NetworkInterfaceTapSNOOPIRIXSNITSunOS4StreamsNITSOCK_PACKETLinuxLSF=Linux2.1.75LinuxSocketFilterDrainIRIX用于窃听系统丢弃的包5.2Libpcap与BPF(1)libpcap概述libpcap(PacketCapturelibrary),即数据包捕获函数库。该库提供的C函数接口可用于捕获经过网络接口(只要经过该接口,目标地址不一定为本机)的数据包。它是由洛仑兹伯克利试验室的研究人员StevenMcCanne和VanJacobson于1993年在Usenix'93会议上正式提出的一种用于Unix内核数据包过滤体制。该函数库支持Linux、Solaris和BSD系统平台。采用libpcap可以捕获本地网络数据链路层上的数据。libpcap库是基于BPF(BerkeleyPacketFilter:BSD包过滤器)系统的。BPF是BSD系统在的TCP/IP软件在实现的时候所提供的一个接口,通过这个接口,外部程序可以得到到达本机的数据链路层网络数据,同时也可以设置过滤器,嵌入到网络软件中,获得过滤后的数据包。(2)BPF结构及工作原理BPF或者BSDPacketFilter是一种由stevenMcCanne和VanJacobson提出的内核包捕获的体系结构,它使得UNIX下的应用程序通过一个高度优化的方法读取流经网图5-1BPF工作原理络适配器的数据包。winpcap的核心网络驱动程序也是采用这种结构的。它主要由两部分组成:Networktap和PacketFilter。Networktap是一个回调函数(callbackfunction),并不是直接由BPF执行,当一个新的数据包到达时,由网络适配器的设备驱动程序激活,它从网络拷贝每个数据包,并且将它们分发到对应的应用程序。Packetfilter来决定一个数据包是否需要进行接收和拷贝到相应的应用程序,同时还提供一种很复杂的功能,可以确定需要进行拷贝的数据的长度。BPF的工作原理如图5-1所示。由Networktap不断地从网络适配器获得数据包,通过packetfilter的判断后,拷贝数据到内核storebuffer,当storebuffer填满后,将和holdbuffer进行数据交换,再由holdbuffer将数据拷贝到处于用户层的userbuffer中。由于采用这种内核过滤、数据包双缓冲、数据包批拷贝的方式,减少了用户态进程调用内核的次数,极大地提高了数据包的处理能力。在系统实现的过程中可以充分利用BPF过滤模型的这种特性,通过根据不同的网络侦听的需求,如针对特定的协议、特定的机器等,设置内核过滤器,减少捕获的数据的大小,同时增加内核缓冲区的大小,使系统能够获得一个很好的性能。BPF的结构如图5-2所示。libpcap在BPF的基础上提供了实用的接口函数供其它程序调用,既可以捕获网络上的数据,也可以打开tcpdump和tcpslice格式的数据,进行分析。同时也可以根据需要,设置过滤器,获得感兴趣的数据包。可以编辑简单的BPF过滤器对数据进行过滤,获得指定的IP包、TCP包等。如下所示:可以用tcpdump的过滤表达式进行过滤:tcpdumptcp21表示获得FTP端口(21)的所有的TCP数据,即通过21端口进出的数据,其它的数据全部丢弃。图5-2BPF的结构Libpcap软件包可从下载,然后依此执行下列三条命令即可安装,但如果希望libpcap能在linux上正常工作,则必须使内核支持packet协议,也即在编译内核时打开配置选项CONFIG_PACKET(选项缺省为打开)。./configure./make应用程序1应用程序2应用程序N缓存过滤器缓存过滤器缓存过滤器TCP/IP等网络协议栈链路层驱动程序链路层驱动程序链路层驱动程序BPF内核内核网络网络监视器用户空间./makeinstall5.3libpcap库函数与数据结构(1)libpcap库函数libpcap所提供的主要函数如下:1)pcap_t*pcap_open_live();用于获取一个包捕获描述符2)char*pcap_lookupdev();返回一个适于pcap_open_live()和pcap_lookupnet()函数使用的指向网络设备的指针3)intpcap_lookupnet();用于判断与网络设备相关的网络号和掩码4)intpcap_dispatch()或intpcap_loop();收集和处理数据包5)voidpcap_dump();将一个包输出到由pcap_dump_open()打开的保存文件中6)intpcap_compile();用于将过滤规则字符串编译成一个内核过滤程序7)intpcap_setfilter();设定一个过滤程序8)intpcap_datalink();返回数据链路层类型,如10M以太网,SLIP,PPP,FDDI,ATM,IEEE802.3等9)voidpcap_close();关闭关联文件并回收资源10)intpcap_stats(pcap_t*,structpcap_stat*);11)intpcap_read(pcap_t*,intcnt,pcap_handler,u_char*);除了上面列出的主要函数外,libpcap还提供一些其他的函数,将在后面介绍。dump文件格式:文件头:structpcap_file_header{bpf_u_int32magic;//0xa1b2c3d4u_shortversion_major;u_shortversion_minor;bpf_int32thiszone;bpf_u_int32sigfigs;bpf_u_int32snaplen;bpf_u_int32linktype;};每一个包的包头和数据structpcap_pkthdr{structtimevalts;bpf_u_int32caplen;bpf_u_int32len;};其中数据部分的长度为caplen(2)libpcap数据结构相关的数据结构:typedefvoid(*pcap_handler)(u_char*,conststructpcap_pkthdr*,constu_char*);typedefstructpcappcap_t;structbpf_program{u_intbf_len;structbpf_insn*bf_insns;};(3)利用libpcap函数库开发应用程序的基本步骤图5-3说明了libpcap的应用步骤。图5-3libpcap的调用流程下面列出libpcap应用过程中的几个关键函数。获取设备名char*pcap_lookupdev(char*errbuf)该函数用于返回可被pcap_open_live()或pcap_lookupnet()函数调用的网络设备名(一个字符串指针)。如果函数出错,则返回NULL,同时errbuf中存放相关的错误消息。获取网络号和掩码intpcap_lookupnet(char*device,bpf_u_int32*netp,bpf_u_int32*maskp,char*errbuf)命令行中指定了要监视的网络设备查找可用的网络设备pcap_lookup_dev()打开网络设备或文件作为包捕获描述符pcap_open_live()/pcap_open_offline()判断与网络设备相关的网络号和掩码pcap_lookupnet()编译过滤规则为内核过滤程序pcap_compile()设置过滤程序pcap_setfilter()捕获并处理pcap_loop()或pcap_dispatch()关闭并返回pcap_close()YN获得指定网络设备的网络号和掩码。netp参数和maskp参数都是bpf_u_int32指针。如果函数出错,则返回-1,同时errbuf中存放相关的错误消息。打开设备pcap_t*pcap_open_live(char*device,intsnaplen,intpromisc,intto_ms,char*errbuf);获得用于捕获网络数据包的数据包捕获句柄,后续很多libpcap函数将使用该句柄,类似于文件操作函数频繁使用文件句柄。device参数为指定打开的网络设备名,比如eth0。snaplen参数定义捕获数据的最大字节数。promisc指定是否将网络接口置于混杂模式。to_ms参数指定超时时间(毫秒),测试下来的结论,0可能代表永不超时。errbuf参数则仅在pcap_open_live()函数出错返回NULL时用于传递错误消息。/usr/include/pcap.htypedefstructpcappcap_t;pcap-int.h里定义了structpcap{}structpcap{intfd;intsnapshot;intlinktype;inttzoff;/*timezoneoffset*/intoffset;/*offsetforproperalignment*/structpcap_sfsf;structpcap_mdmd;intbufsize;/*Readbuffer*/u_char*buffer;u_char*bp;intcc;u_char*pkt;/*Placeholderforpcap_next()*/structbpf_programfcode;/*Placeholderforfiltercodeifbpfnotinkernel.*/charerrbuf[PCAP_ERRBUF_SIZE];};编译、优化、调试过滤规则intpcap_compile(pcap_t*p,structbpf_program*fp,char*str,intoptimize,bpf_u_int32netmask);该函数用于解析过滤规则串,填写bpf_program结构。str指向过滤规则串,格式参看tcpdump的man手册,比如:tcpdump-x-vv-n-tipproto\\tcpanddst192.168.8.90andtcp[13]\&2=2这条过滤规则将捕捉所有携带SYN标志的到192.168.8.90的TCP报文。过滤规
本文标题:基于libpcap的网络编程技术
链接地址:https://www.777doc.com/doc-2570392 .html