【原创】网络报文抓取研究
1???? 引言
網(wǎng)絡(luò)報(bào)文抓取是指通過(guò)對(duì)主機(jī)網(wǎng)絡(luò)設(shè)備的探測(cè),實(shí)現(xiàn)獲取該網(wǎng)絡(luò)當(dāng)前傳輸?shù)乃行畔?#xff0c;并根據(jù)信息的源主機(jī)、目標(biāo)主機(jī)、服務(wù)協(xié)議和端口等信息簡(jiǎn)單過(guò)濾掉不關(guān)心數(shù)據(jù),然后提交給上層應(yīng)用程序進(jìn)行進(jìn)一步處理。
2???? 網(wǎng)絡(luò)數(shù)據(jù)包捕獲原理
一個(gè)包捕獲機(jī)制包含三個(gè)主要部分
1) 包捕獲機(jī)制
不同的操作系統(tǒng)實(shí)現(xiàn)的底層包捕獲機(jī)制可能是不一樣的,但從形式上看大同小異。數(shù)據(jù)包常規(guī)的傳輸路徑依次為網(wǎng)卡、設(shè)備驅(qū)動(dòng)層、數(shù)據(jù)鏈路層、IP層、傳輸層、最后到達(dá)應(yīng)用程序。而包捕獲機(jī)制是在數(shù)據(jù)鏈路層增加一個(gè)旁路處理,對(duì)發(fā)送和接收到的數(shù)據(jù)包做過(guò)濾/緩沖等相關(guān)處理,最后直接傳遞到應(yīng)用程序。
2) 包過(guò)濾機(jī)制
包過(guò)濾機(jī)制是對(duì)所捕獲到的數(shù)據(jù)包根據(jù)用戶的要求進(jìn)行篩選,最終只把滿足過(guò)濾條件的數(shù)據(jù)包傳遞給用戶程序。
3) 用戶程序的接口
對(duì)用戶程序而言,包捕獲機(jī)制提供了一個(gè)統(tǒng)一的接口,使用戶程序只需要簡(jiǎn)單的調(diào)用若干函數(shù)就能獲得所期望的數(shù)據(jù)包。這樣一來(lái),針對(duì)特定操作系統(tǒng)的捕獲機(jī)制對(duì)用戶透明。
3???? 網(wǎng)絡(luò)數(shù)據(jù)包捕獲主要實(shí)現(xiàn)技術(shù)介紹
3.1??? SOCK_RAW? 原始套接字
我們常用的網(wǎng)絡(luò)編程都是在應(yīng)用層的報(bào)文的收發(fā)操作,也就是流式套接字(SOCK_STREAM)和數(shù)據(jù)包式套接字(SOCK_DGRAM)。而這些數(shù)據(jù)包都是由系統(tǒng)提供的協(xié)議棧實(shí)現(xiàn),用戶只需要填充應(yīng)用層報(bào)文即可,由系統(tǒng)完成底層報(bào)文頭的填充并發(fā)送。
原始套接字(SOCK_RAW)是一種不同于SOCK_STREAM、SOCK_DGRAM的套接字,它實(shí)現(xiàn)于系統(tǒng)核心。可以處理特殊的IPv4、ICMP、IGMP等網(wǎng)絡(luò)報(bào)文。總體來(lái)說(shuō),SOCK_RAW可以處理普通的網(wǎng)絡(luò)報(bào)文之外,還可以處理一些特殊協(xié)議報(bào)文以及操作IP層及其以上的數(shù)據(jù)。
3.1.1?? ?SOCK_RAW 抓包實(shí)現(xiàn)
1)??? 利用PF_INET協(xié)議族創(chuàng)建RAW SOCKET
socket(PF_INET,SOCK_RAW,IPPROTO_TCP|IPPROTO_UDP)
采用這樣的方法接收到的數(shù)據(jù)都是發(fā)往本機(jī)的數(shù)據(jù),不能接受從本機(jī)發(fā)出去的數(shù)據(jù)。第三個(gè)參數(shù)協(xié)議若是指定,只能接受符合指定協(xié)議的數(shù)據(jù)包:
IPPROTO_TCP:接收采用tcp傳輸?shù)臄?shù)據(jù)包。
IPPROTO_UDP:接受采用udp傳輸?shù)臄?shù)據(jù)包。
2)???? 利用PF_PACKET協(xié)議族創(chuàng)建RAW SOCKET
socket(PF_PACKET,SOCK_RAW,?htons(ETH_P_IP|ETH_P_ARP|ETH_P_ARP|ETH|RARP))
這種方法創(chuàng)建的套接字是在數(shù)據(jù)鏈路層直接抓取以太網(wǎng)幀。可以接收到發(fā)往本機(jī)和本機(jī)發(fā)出的數(shù)據(jù),第三個(gè)參數(shù)的協(xié)議類型有:
ETH_P_IP?0x0800?? :只接收發(fā)往本機(jī)mac的ip類型的數(shù)據(jù)幀
ETH_P_ARP?0x0806 ?:只接受發(fā)往本機(jī)mac的arp類型的數(shù)據(jù)幀
ETH_P_RARP?0x8035?:只接受發(fā)往本機(jī)mac的rarp類型的數(shù)據(jù)幀
ETH_P_ALL?0x0003?:接收發(fā)往本機(jī)mac的所有類型的數(shù)據(jù)幀, 和從本機(jī)發(fā)出的所有類型的數(shù)據(jù)幀。
3.2??? Libpcap
Libpcap是Packet Capture library的英文縮寫,是Unix/Linux平臺(tái)下的網(wǎng)絡(luò)數(shù)據(jù)包捕獲函數(shù)庫(kù),該庫(kù)提供的C函數(shù)接口用于捕獲經(jīng)過(guò)指定網(wǎng)絡(luò)接口(通過(guò)將網(wǎng)卡設(shè)置為混雜模式,可以捕獲所有經(jīng)過(guò)該網(wǎng)絡(luò)接口的數(shù)據(jù)包)的數(shù)據(jù)包。
Libpcap提供的接口函數(shù)主要實(shí)現(xiàn)和封裝了與數(shù)據(jù)包的采集、構(gòu)造、發(fā)送等有關(guān)的功能。著名的tcpdump就是在Libpcap的基礎(chǔ)上開(kāi)發(fā)完成的。
3.2.1?? ?Libpcap 工作原理
Libpcap是一個(gè)獨(dú)立于系統(tǒng)的用戶級(jí)數(shù)據(jù)包捕獲API接口,為底層網(wǎng)絡(luò)監(jiān)測(cè)提供了一個(gè)可以移植的框架。
Libpcap庫(kù)主要由三個(gè)部分組成,網(wǎng)絡(luò)分接頭、數(shù)據(jù)包過(guò)濾器和用戶API。
1)???? 網(wǎng)絡(luò)分接頭
網(wǎng)絡(luò)分接頭(Network Tap)一種鏈路層旁路機(jī)制,負(fù)責(zé)采集網(wǎng)卡數(shù)據(jù)包。
libpcap的包捕獲機(jī)制就是在數(shù)據(jù)鏈路層加一個(gè)旁路處理。當(dāng)一個(gè)數(shù)據(jù)包到達(dá)網(wǎng)絡(luò)接口時(shí),libpcap首先利用已經(jīng)創(chuàng)建的Socket從鏈路層驅(qū)動(dòng)程序中獲得該數(shù)據(jù)包的拷貝,再通過(guò)Tap函數(shù)將數(shù)據(jù)包發(fā)給BPF過(guò)濾器。
2)???? 數(shù)據(jù)包過(guò)濾器
數(shù)據(jù)包過(guò)濾器(Packet Filter) 針對(duì)數(shù)據(jù)包的一種過(guò)濾機(jī)制,在Libpcap中采用BPF(BSDPacket Filter)算法對(duì)數(shù)據(jù)包執(zhí)行過(guò)濾操作,這種算法的基本思想就是基于規(guī)則匹配,對(duì)符合條件的數(shù)據(jù)包進(jìn)行放行。
3)????用戶API
用戶API是Libpcap面向上層應(yīng)用程序提供的編程接口,用戶通過(guò)調(diào)用相關(guān)的函數(shù)實(shí)現(xiàn)數(shù)據(jù)包的捕獲或者發(fā)送。
其具體的工作流程如下圖所示:
?
3.2.2?? ?Libpcap 抓包框架
由于Libpcap是一種與系統(tǒng)無(wú)關(guān),采用分組捕獲機(jī)制的分組捕獲函數(shù)庫(kù),用于訪問(wèn)數(shù)據(jù)鏈路層,在不同的平臺(tái)上采用統(tǒng)一的編程接口,使用LibPcap編寫的程序可以自由地跨平臺(tái)使用。
Libpcap具體抓包流程如下圖所示:
?
3.2.3?? ?Libpcap 庫(kù)主要抓包函數(shù)
1)???? 打開(kāi)設(shè)備進(jìn)行嗅探
pcap_t*pcap_open_live(char *device, int snaplen, int promisc,
?int to_ms, char *ebuf)
2)???? 編譯過(guò)濾規(guī)則
int?pcap_compile?(?pcap_t?*?p,?struct?bpf_program?*?fp,?char?*?str,
int?optimize,?bpf_u_int32?netmask?)
3)???? 設(shè)置編譯后的過(guò)濾規(guī)則
intpcap_setfilter(pcap_t *p, struct bpf_program *fp)
4)???? 抓包
intpcap_loop(pcap_t *p, int cnt, pcap_handler callback,
u_char*user)
5)???? 回調(diào)函數(shù)
voidgot_packet(u_char *args, const struct pcap_pkthdr *header, const u_char*packet)
6)???? 關(guān)閉會(huì)話
voidpcap_close(pcap_t *p)
3.3??? WinPcap
WinPcap是LibPcap的Windows版本,它是一個(gè)基于Win32的捕獲數(shù)據(jù)包和網(wǎng)絡(luò)分析的體系結(jié)構(gòu),它包括一個(gè)內(nèi)核級(jí)的包過(guò)濾器,一個(gè)底層的動(dòng)態(tài)鏈接庫(kù)(Packet.dll),一個(gè)高層并且與系統(tǒng)無(wú)關(guān)的庫(kù)(WPcap.dll,基于LibPcap0.6.2版本)。WinPcap是集成于Windows95,98,ME,NT,2000和XP操作系統(tǒng)的設(shè)備驅(qū)動(dòng)程序,它可以從網(wǎng)卡捕獲或者發(fā)送原始數(shù)據(jù),同時(shí)能夠過(guò)濾并且倉(cāng)儲(chǔ)數(shù)據(jù)包。開(kāi)發(fā)WinPcap這個(gè)項(xiàng)目的目的在于為Win32應(yīng)用程序提供訪問(wèn)網(wǎng)絡(luò)底層的能力。
3.3.1??WinPcap內(nèi)部結(jié)構(gòu)
Winpcap是針對(duì)Win32平臺(tái)上的抓包和網(wǎng)絡(luò)分析的一個(gè)架構(gòu),它由內(nèi)核級(jí)的網(wǎng)絡(luò)組包過(guò)濾器(Netgroup Packet Filter,NPF)、用戶級(jí)的動(dòng)態(tài)鏈接庫(kù)Packet.dll和Wpcap.dlI等 3個(gè)模塊組成[7]。
1)網(wǎng)絡(luò)組包過(guò)濾器。它是運(yùn)行于操作系統(tǒng)內(nèi)核中的驅(qū)動(dòng)程序,它直接與網(wǎng)卡驅(qū)動(dòng)程序進(jìn)行交互,獲取在網(wǎng)絡(luò)上傳輸?shù)脑紨?shù)據(jù)包。NPF與操作系統(tǒng)有關(guān),WinPcap開(kāi)發(fā)組針對(duì)不同的Windows操作系統(tǒng)提供了不同版本的NPF。在Win95/98/ME系統(tǒng)中,它以VXD文件形式存在,在WindowsNT和Windows 2000系統(tǒng)中,它以SYS文件形式存在。該模塊提供了抓取數(shù)據(jù)包以及發(fā)送數(shù)據(jù)包的基本功能,此外還提供了一些高級(jí)功能,如數(shù)據(jù)包過(guò)濾系統(tǒng)和檢測(cè)引擎。
2)低級(jí)動(dòng)態(tài)鏈接庫(kù)。Pactet.dll用于在Win32平臺(tái)上為數(shù)據(jù)包驅(qū)動(dòng)程序提供一個(gè)公共的接口。不同的Windows版本在用戶態(tài)和內(nèi)核態(tài)之間提供互不相同的接口,而Pactet.dll可以屏蔽這些接口區(qū)別,提供一個(gè)與系統(tǒng)無(wú)關(guān)的API。基于Pactet.dll開(kāi)發(fā)的數(shù)據(jù)包截獲程序可以運(yùn)行于不同的Win32平臺(tái)而不必重新進(jìn)行編譯。Pactet.dll可以執(zhí)行如獲取適配器名稱、動(dòng)態(tài)驅(qū)動(dòng)器加載以及獲得主機(jī)掩碼及以太網(wǎng)沖突次數(shù)等低級(jí)操作。
3)高級(jí)動(dòng)態(tài)鏈接庫(kù)。Wpcap.dll模塊與Unix系統(tǒng)下的BSD截獲架構(gòu)提供的Libpcap庫(kù)完全兼容。它提供了一組功能強(qiáng)大且跨平臺(tái)的函數(shù),利用這些函數(shù)可以不去關(guān)心適配器和操作系統(tǒng)的類型。Wpcap.dll含有諸如產(chǎn)生過(guò)濾器、定義用戶級(jí)緩沖以及包注入等高級(jí)功能。編程人員既可以使用包含在Pactet.dll中的低級(jí)函數(shù)直接進(jìn)入內(nèi)核級(jí)調(diào)用,也可以使用由Wpcap.dll提供的高級(jí)函數(shù)調(diào)用,這樣功能更強(qiáng),使用也更為方便。Wpcap.dll的函數(shù)調(diào)用會(huì)自動(dòng)調(diào)用Pactet.dll中的低級(jí)函數(shù),并且可能被轉(zhuǎn)換成若干個(gè)NPF系統(tǒng)調(diào)用。
3.3.2 ?WinPcap的主要函數(shù)庫(kù)
Winpcap函數(shù)庫(kù)主要有如下函數(shù):
1)int ?pcap_findalldevs (pcap_if_t **,char *)
用來(lái)獲得網(wǎng)卡的列表
2)voidpcap_freealldevs (pcap_if_t *) ??
與int pcap_findalldevs (pcap_if_t **,char *)配套使用,當(dāng)不需要網(wǎng)卡列表時(shí),用此函數(shù)釋放空間
3)pcap_t ? ? *pcap_open_live(const char *, int, int,int, char *)
用來(lái)得到一個(gè)包抓取得描述符
4)Int ?pcap_loop(pcap_t *, int, pcap_handler, u_char*)
捕獲數(shù)據(jù)包,不會(huì)響應(yīng)pcap_open_live()中設(shè)置的超時(shí)時(shí)間
5)int ? ? pcap_dispatch(pcap_t *, int, pcap_handler,u_char *)
捕獲數(shù)據(jù)包。可以不被阻塞
6)int ? ? ? ? ?pcap_next_ex(pcap_t *, structpcap_pkthdr **, const u_char **)
捕獲數(shù)據(jù)包
7)int ? ? ? ? ?pcap_compile(pcap_t *, structbpf_program *, const char *, int, ?bpf_u_int32)
編譯一個(gè)過(guò)濾設(shè)備,與pcap _ setfilter () 配合使用
8)int ? ? pcap_setfilter(pcap_t *, struct bpf_program*)
用來(lái)聯(lián)系一個(gè)在內(nèi)核驅(qū)動(dòng)上過(guò)濾的過(guò)濾器,這時(shí)所有網(wǎng)絡(luò)數(shù)據(jù)包都將流經(jīng)過(guò)濾器,并拷貝到應(yīng)用程序中。
3.4??? JPcap
JPcap是一個(gè)能夠捕獲,發(fā)送網(wǎng)絡(luò)數(shù)據(jù)包的Java類庫(kù)包。這個(gè)包用到了LibPcap和WinPcap。使用時(shí)需要安裝LibPcap(UNIX平臺(tái)) 或者WinPcap(Windows平臺(tái))庫(kù)。
目前JPcap在FreeBSD 3.x,Linux RedHat 6.1,Solaris和Microsoft Windows 2000/XP系統(tǒng)上已經(jīng)做過(guò)測(cè)試,并且支持Ethernet,IPv4,IPv6,ARP/RARP,TCP,UDP,ICMPv4協(xié)議。JPcap是一個(gè)Java類集合,它為網(wǎng)絡(luò)數(shù)據(jù)包的捕獲提供接口和系統(tǒng)支持。JPCAP的類庫(kù)結(jié)構(gòu)
Jpcap0.4版本共有1個(gè)接口14個(gè)類,分別簡(jiǎn)介如下:
1、 接口綜述
JpcapHandler:這個(gè)接口用來(lái)定義分析被捕獲數(shù)據(jù)包的方法
2、 類綜述
ARPPacket:這個(gè)類描述了ARP/RARP包,繼承了Packet類?
DatalinkPacket:這個(gè)抽象類描述了數(shù)據(jù)鏈路層的包,它繼承了java.lang.Object
EthernetPacket:這個(gè)類描述了以太幀包,繼承DatalinkPacket類
ICMPPacket:這個(gè)類描述了ICMP包,繼承了IPPacket類
IPAddress:繼承了java.lang.Object,這個(gè)類描述了IPv4和IPv6地址,其中也包含了將IP地址轉(zhuǎn)換為域名的方法
IPPacket:這個(gè)類描述了IP包,繼承了Packet類,支持IPv4和IPv6
IPv6Option:它繼承了java.lang.Object,這個(gè)類描述了IPv6選項(xiàng)報(bào)頭
Jpcap:它用來(lái)捕獲數(shù)據(jù)包,繼承了java.lang.Object
Jpcap.JpcapInfo:Jpcap的內(nèi)部類,它包含被捕獲數(shù)據(jù)包的信息(在jpcap0.4修改部分BUG之后不再使用這個(gè)類)
JpcapSender:它用來(lái)發(fā)送一個(gè)數(shù)據(jù)包,繼承了java.lang.Object
JpcapWriter:它用來(lái)將一個(gè)被捕獲的數(shù)據(jù)包保存到文件,繼承了java.lang.Object
Packet:這個(gè)類是所有被捕獲的數(shù)據(jù)包的基類,繼承了java.lang.Object
TCPPacket:這個(gè)類描述TCP包,繼承了IPPacket類
UDPPacket:這個(gè)類描述了UDP包,繼承了IPPacket類
?
轉(zhuǎn)載于:https://www.cnblogs.com/xiaole10368/p/5383890.html
超強(qiáng)干貨來(lái)襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生總結(jié)
以上是生活随笔為你收集整理的【原创】网络报文抓取研究的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 用Curl测试POST
- 下一篇: 通过PowerShell查询本机IP地址