一.JPCAP簡介
眾所周知,java語言雖然在TCP/UDP傳輸方面給予了良好的定義,但對于網絡層以下的控制,卻是無能為力的。JPCAP擴展包彌補了這一點。
JPCAP實際上并非一個真正去實現對數據鏈路層的控制,而是一個中間件,JPCAP調用wincap/libpcap,而給JAVA語言提供一個公共的接口,從而實現了平臺無關性。在官方網站上聲明,JPCAP支持FreeBSD 3.x, linux RedHat 6.1, Fedora Core 4, Solaris, and Microsoft windows 2000/XP等系統。
二.JPCAP機制
JPCAP的整個結構大體上跟wincap/libpcap是很相像的,例如NetworkInterface類對應wincap的typedef strUCt _ADAPTERADAPTER,getDeviceList()對應pcap_findalldevs()等等。 JPCAP有16個類,下面就其中最重要的4個類做說明。
1.NetworkInterface
該類的每一個實例代表一個網絡設備,一般就是網卡。這個類只有一些數據成員,除了繼續自java.lang.Object的基本方法以外,沒有定義其它方法。
數據成員 | |
| NetworkInterfaceAddress[] | |
| java.lang.String | datalink_description. 數據鏈路層的描述。描述所在的局域網是什么網。例如,以太網(Ethernet)、無線LAN網(wireless LAN)、令牌環網(token ring)等等。 |
| java.lang.String | datalink_name 該網絡設備所對應數據鏈路層的名稱。具體來說,例如Ethernet10M、100M、1000M等等。 |
| java.lang.String | description 網卡是XXXX牌子XXXX型號之類的描述。例如我的網卡描述:Realtek RTL8169/8110 Family Gigabit Ethernet NIC |
| boolean | Loopback 標志這個設備是否loopback設備。 |
| byte[] | mac_address 網卡的MAC地址,6個字節。 |
| java.lang.String | Name 這個設備的名稱。例如我的網卡名稱:/Device/NPF_{3CE5FDA5-E15D-4F87-B217-255BCB351CD5} |
數據成員 | |
| int | dropped_packets 拋棄的包的數目。 |
| PRotected int | ID 這個數據成員在官方文檔中并沒有做任何說明,查看JPCAP源代碼可以發現這個ID實際上在其JNI的C代碼部分傳進來的,這類本身并沒有做出定義,所以是供其內部使用的。實際上在對JpcapCator實例的使用中也沒有辦法調用此數據成員。 |
| protected staticboolean[] | instanciatedFlag 同樣在官方文檔中沒有做任何說明,估計其為供內部使用。 |
| protected staticint | MAX_NUMBER_OF_INSTANCE 同樣在官方文檔中沒有做任何說明,估計其為供內部使用。 |
| int | received_packets 收到的包的數目 |
方法成員 | |
| staticNetworkInterface[] | getDeviceList() 返回一個網絡設備列表。 |
| staticJpcapCaptor | openDevice(NetworkInterface interface, intsnaplen, booleanpromisc, intto_ms) 創建一個與指定設備的連接并返回該連接。注重,以上兩個方法都是靜態方法。 Interface:要打開連接的設備的實例; Snaplen:這個是比較輕易搞混的一個參數。其實這個參數不是限制只能捕捉多少數據包,而是限制每一次收到一個數據包,只提取該數據包中前多少字節; Promisc:設置是否混雜模式。處于混雜模式將接收所有數據包,若之后又調用了包過濾函數setFilter()將不起任何作用; To_ms:這個參數主要用于processPacket()方法,指定超時的時間; |
| void | Close() 關閉調用該方法的設備的連接,相對于openDivece()打開連接。 |
| JpcapSender | getJpcapSenderInstance() 該返回一個JpcapSender實例,JpcapSender類是專門用于控制設備的發送數據包的功能的類。 |
| Packet | getPacket() 捕捉并返回一個數據包。這是JpcapCaptor實例中四種捕捉包的方法之一。 |
| int | loopPacket(intcount, PacketReceiver handler) 捕捉指定數目的數據包,并交由實現了PacketReceiver接口的類的實例處理,并返回捕捉到的數據包數目。假如count參數設為-1,那么無限循環地捕捉數據。 這個方法不受超時的影響。還記得openDivice()中的to_ms參數么?那個參數對這個方法沒有影響,假如沒有捕捉到指定數目數據包,那么這個方法將一直阻塞等待。 PacketReceiver中只有一個抽象方法void receive(Packet p)。 |
| int | processPacket(intcount, PacketReceiver handler) 跟loopPacket()功能一樣,唯一的區別是這個方法受超時的影響,超過指定時間自動返回捕捉到數據包的數目。 |
| int | dispatchPacket(intcount, PacketReceiverhandler) 跟processPacket()功能一樣,區別是這個方法可以處于“non-blocking”模式工作,在這種模式下dispatchPacket()可能立即返回,即使沒有捕捉到任何數據包。 |
| void | setFilter(java.lang.Stringcondition, booleanoptimize) .condition:設定要提取的包的要害字。 Optimize:這個參數在說明文檔以及源代碼中都沒有說明,只是說這個參數假如為真,那么過濾器將處于優化模式。 |
| void | setNonBlockingMode(booleannonblocking) 假如值為“true”,那么設定為“non-blocking”模式。 |
| void | breakLoop() 當調用processPacket()和loopPacket()后,再調用這個方法可以強制讓processPacket()和loopPacket()停止。 |
方法成員 | |
| void | close() 強制關閉這個連接。 |
| staticJpcapSender | openRawSocket() 這個方法返回的JpcapSender實例發送數據包時將自動填寫數據鏈路層頭部分。 |
| void | sendPacket(Packet packet) JpcapSender最重要的功能,發送數據包。需要注重的是,假如調用這個方法的實例是由JpcapCaptor的getJpcapSenderInstance()得到的話,需要自己設定數據鏈路層的頭,而假如是由上面的openRawSocket()得到的話,那么無需也不能設置,數據鏈路層的頭部將由系統自動生成。 |
三.使用JPCAP實現監聽
1.監聽原理
在具體說用JPCAP實現網絡監聽實現前,先簡單介紹下監聽的原理。
局域網監聽利用的是所謂的“ARP欺騙”技術。在以前曾經一段階段,局域網的布局是使用總線式(或集線式)結構,要到達監聽只需要將網卡設定為混雜模式即可,但現在的局域網絡普遍采用的是交換式網絡,所以單純靠混雜模式來達到監聽的方法已經不可行了。所以為了達到監聽的目的,我們需要“欺騙”路由器、“欺騙”交換機,即“ARP欺騙”技術。
假設本機為A,監聽目標為B。
首先,偽造一個ARP REPLY包,數據鏈路層頭及ARP內容部分的源MAC地址填入A的MAC地址,而源IP部分填入網關IP,目的地址填入B的MAC、IP,然后將這個包發送給B,而B接收到這個偽造的ARP REPLY包后,由于源IP為網關IP,于是在它的ARP緩存表里刷新了一項,將(網關IP,網關MAC)刷新成(網關IP,A的MAC)。而B要訪問外部的網都需要經過網關,這時候這些要經過網關的包就通通流到A的機器上來了。
接著,再偽造一個ARP REPLY包,數據鏈路層頭及ARP內容部分的源MAC地址填入A的MAC地址,而源IP部分填入B的IP,目的地址填入網關MAC、IP,然后將這個包發給網關,網關接收到這個偽造的ARP REPLY包后,由于源IP為B的IP,于是在它的ARP緩存表里刷新了一項,將(B的IP,B的MAC)刷新成(B的IP,A的MAC)。這時候外部傳給B的數據包經過網關時,就通通轉發給A。
這樣還只是攔截了B的數據包而已,B并不能上網——解決方法是將接收到的包,除了目的地址部分稍做修改,其它原封不動的再轉發出去,這樣就達到了監聽的目的——在B不知不覺中瀏覽了B所有的對外數據包。
ARP數據包解析
單元:Byte
Ethernet頭部 | ARP數據部分 | |||||||||
6 | 6 | 2 | 2 | 2 | 2 | 2 | 4 | 6 | 4 | 6 |
目標MAC地址 | 源地MAC地址 | 類型號0x0800:ip 0x0806:ARP | 局域網類型 以太網0x0001 | 網絡協議類型 IP網絡0x0800 | MAC/IP地址長度,恒為0x06/04 | ARP包類型 REPLY 0x0002 | ARP目標IP地址 | ARP目標MAC 地址 | ARP源IP地址 | ARP源MAC地址 |
新聞熱點
疑難解答