• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 簡易網絡嗅探器的實現

    發表于:2007-06-23來源:作者:點擊數: 標簽:
    本文介紹一個用C語言和 網絡 數據包分析 開發 工具實現的簡易網絡Sniffer。 目前,已經有不少的Sniff工具軟件,如Windows環境下,最富盛名的工具是Netxray和Sniffer pro,用它們在 Windows環境下抓包來分析,非常方便。在 UNIX 環境下如Sniffit,Snoop,Tcpd

       

    本文介紹一個用C語言和網絡數據包分析開發工具實現的簡易網絡Sniffer。目前,已經有不少的Sniff工具軟件,如Windows環境下,最富盛名的工具是Netxray和Sniffer pro,用它們在 Windows環境下抓包來分析,非常方便。在UNIX環境下如Sniffit,Snoop,Tcpdump,Dsniff 等都是比較常見的。這里介紹一個用C語言和網絡數據包和分析開發工具libpcap及winpcap實現的簡易網絡Sniffer。

    網絡嗅探器程序框圖

    首先給出流程如圖1所示。

    簡易網絡嗅探器的實現



    圖1 流程圖

     網絡嗅探器程序實現

    在c環境下編程,源碼如下:

    clearcase/" target="_blank" >cc66 width="90%" align=center bgColor=#e6e4dd border=1>
    /* June 2nd,2002

    * Project for graduation qualification By Bby Team 19 */

    #include <stdio.h>

    #include <conio.h>

    //必須加路徑,必須把頭文件packet32.h包含進去

    #include "....Includepacket32.h"

    #include "....Includentddndis.h"

    #define Max_Num_Adapter 10

    // Prototypes原形

    //發包

    void PrintPackets(LPPACKET lpPacket);

    //設備列表

    char AdapterList[Max_Num_Adapter][1024];

    // 主程序開始

    int main()

    {

     //define a pointer to an ADAPTER structure設備指針

     LPADAPTER lpAdapter = 0;

     //define a pointer to a PACKET structure包指針

     LPPACKET lpPacket;

     int i;

     DWORD dwErrorCode;

     DWORD dwVersion;

     DWORD dwWindowsMajorVersion;

     //Unicode strings (WinNT)

     WCHAR AdapterName[8192]; //網絡適配器設備列表

     WCHAR *temp,*temp1;

     //ASCII strings (Win9x)

     char AdapterNamea[8192]; //網絡適配器設備列表

     char *tempa,*temp1a;

     int AdapterNum=0,Open;

     ULONG AdapterLength;

     char buffer[256000]; // 容納來自驅動器的數據的緩沖區

     struct bpf_stat stat;

     // 獲得本機網卡名

     AdapterLength=4096;

     printf("Packet.dll test application. Library version:%sn", PacketGetVersion());

     printf("Adapters installed:n");

     i=0;


    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月
    下面這段代碼是用來在不同版本下得到網絡適配器名:

    Win9x 和WinNT中的網卡名稱是分別用ASCII和UNICODE實現的,

    所以首先要得到本地操作系統

    的版本號:

    dwVersion=GetVersion();

    dwWindowsMajorVersion= (DWORD)(LOBYTE(LOWORD(dwVersion)));


    這里首先用到的Packet.dll函數是PacketGetAdapterNames(PTSTR pStr,

    PULONG BufferSize,通常它是與驅動程序通信并被調用的第一個函數,

    它將返回的用戶本地系統中安裝

    的網絡適配器的名字放在

    緩沖區pStr中;BufferSize是緩沖區的長度:

    if (!(dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4))

    {

      //是Windows NT

      // 找不到設備列表

      if(PacketGetAdapterNames(AdapterName,&AdapterLength)==FALSE){

    printf("Unable to retrieve the list of the adapters!n");

    return -1;

      }

      // 找到設備列表

      temp=AdapterName;

      temp1=AdapterName;

      while ((*temp!='')||(*(temp-1)!=''))

      {

    if (*temp=='')

    {

      memcpy(AdapterList[i],temp1,(temp-temp1)*2);

      temp1=temp+1;

      i++;

    }

    temp++;

      }

      // 顯示適配器列表

      AdapterNum=i;

      for (i=0;i<AdapterNum;i++)

    wprintf(L"n%d- %sn",i+1,AdapterList[i]);

    printf("n");

      }

      else //否則就是windows 9x,獲取適配器名的方法同WinNT下

      {

    if(PacketGetAdapterNames(AdapterNamea,&AdapterLength)==FALSE){

      printf("Unable to retrieve the list of the adapters!n");

      return -1;

      }

      tempa=AdapterNamea;

      temp1a=AdapterNamea;

      while ((*tempa!='')||(*(tempa-1)!=''))

      {

    if (*tempa=='')

    {

      memcpy(AdapterList[i],temp1a,tempa-temp1a);

      temp1a=tempa+1;

      i++;

    }

    tempa++;

      }

      AdapterNum=i;

      for (i=0;i<AdapterNum;i++)

    printf("n%d- %sn",i+1,AdapterList[i]);

    printf("n");

    }


    下面這段代碼就是讓用戶選擇監聽的網絡適配器號:

    // 選擇設備

    do

    {

      printf("Select the number of the adapter to open : ");

      scanf("%d",&Open);

      if (Open>AdapterNum)

    printf("nThe number must be smaller than %d",AdapterNum);

    } while (Open>AdapterNum);



    然后,將所選擇的設備打開,這里可以設置為“混雜”模式打開,

    也可以是“直接”模式打開。

    代碼如下:

    // 打開設備

    lpAdapter = PacketOpenAdapter(AdapterList[Open-1]);

    // 當設備無法打開時,出示錯誤信息:

    if (!lpAdapter || (lpAdapter->hFile == INVALID_HANDLE_VALUE))

    {

      dwErrorCode=GetLastError();

      printf("Unable to open the adapter, Error Code : %lxn",dwErrorCode);

      return -1;

    }


    將網卡設置為“混雜”模式,代碼如下:

    這里用到函數PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter),

    它在到來的包上設置了一個硬件過濾器,如操作成功,返回TRUE。

    AdapterObject是過濾器所在的網卡

    設備指針;過濾器的常量Filter定義在頭文件ntddndis.h 中,包括有:

    ·NDIS-PACKET-TYPE-PROMISCUOUS:設置混雜模式,每個到來的包都會被網卡接受;

    ·NDIS-PACKET-TYPE-DIRECTED:只有直接到主機網卡的包才會被接受;

    ·NDIS-PACKET-TYPE-BROADCAST:只接受廣播包;

    ·NDIS-PACKET-TYPE-MULTICAST:只接受到主機所在的組的多播包;

    ·NDIS-PACKET-TYPE-ALL-MULTICAS:接受每個多播的包。

    // set the network adapter in promiscuous mode

    // 如果混雜模式設置失敗,提示錯誤:

    if(PacketSetHwFilter(lpAdapter,NDIS_PACKET_TYPE_PROMISCUOUS)==FALSE){

    printf("Warning: unable to set promiscuous mode!n");

    }


    然后在driver中置512K的緩沖:

    這里用到函數PacketSetBuff(LPADAPTER AdapterObject,int dim),

    它被用于設置AdapterObject指向的網卡的驅動程序的緩沖區,成功則返回TRUE。

    Dim是新的緩沖區的大小,

    當它被設定時,舊緩沖區中的數據將被丟棄,其中存儲的包也會失去。

    需要注意的地方:驅動器緩沖區的大小設置是否恰當,將影響截包進程的性能,

    設置應能保證運行快且不會丟包。這里設置的是512000Byte。

    // set a 512K buffer in the driver

    // 當無法設置緩沖區時,提示錯誤:

    if(PacketSetBuff(lpAdapter,512000)==FALSE){

      printf("Unable to set the kernel buffer!n");

      return -1;

    }



    PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout)

    函數的功能是,設置與AdapterObject指定網卡綁定的讀操作超時的值,timeout以毫秒為單位,

    0表示沒有超時,

    當沒有包到時,read就不返回。

    // set a 1 second read timeout

    // 設置1秒的讀取操作超時

    if(PacketSetReadTimeout(lpAdapter,1000)==FALSE){

      printf("Warning: unable to set the read tiemout!n");

    }


  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>