用户登录  |  用户注册
首 页商业源码原创产品编程论坛
当前位置:PB创新网文章中心编程技巧计算机网络

一个简易网络嗅探器的实现

减小字体 增大字体 作者:佚名  来源:本站整理  发布时间:2009-01-10 10:07:54
【本文由PB创新网为您整理】

摘    要:本文介绍一个用C语言和网络数据包分析开发工具实现的简易网络Sniffer。

      关 键 词:网络;数据包;Sniffer

1 引言
    目前,已经有不少的Sniff工具软件,如Windows环境下,最富盛名的工具是Netxray和Sniffer pro,用它们在 Windows环境下抓包来分析,非常方便。在UNIX环境下如Sniffit,Snoop,Tcpdump,Dsniff 等都是比较常见的。这里介绍一个用C语言和网络数据包和分析开发工具libpcap及winpcap实现的简易网络Sniffer。

2网络嗅探器程序实现
在c环境下编程,源码如下:
/*  June 2nd,2002
 *   Project for graduation qualification By Bby  Team 19   */
#include <stdio.h>
#include <conio.h> 
//必须加路径,必须把头文件packet32.h包含进去
#include "../../Include/packet32.h"
#include "../../Include/ntddndis.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:%s/n", PacketGetVersion());
     printf("Adapters installed:/n");
     i=0;     
下面这段代码是用来在不同版本下得到网络适配器名:
     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!='/0')(*(temp-1)!='/0'))
           {
                 if (*temp=='/0')
                 {
                       memcpy(AdapterList,temp1,(temp-temp1)*2);
                       temp1=temp+1;
                       i++;
           }
         temp++;
           }
      // 显示适配器列表
        AdapterNum=i;
           for (i=0;i<AdapterNum;i++)
                 wprintf(L"/n%d- %s/n",i+1,AdapterList);
           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!='/0')(*(tempa-1)!='/0'))
           {
                 if (*tempa=='/0')
                 {
                       memcpy(AdapterList,temp1a,tempa-temp1a);
                       temp1a=tempa+1;
                       i++;
                 }
                 tempa++;
           }
           AdapterNum=i;
           for (i=0;i<AdapterNum;i++)
                 printf("/n%d- %s/n",i+1,AdapterList);
           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 : %lx/n",dwErrorCode);
           return -1;
     }     
    将网卡设置为“混杂”模式,代码如下:
这里用到函数PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter),它在到来的包上设置了一个硬件过滤器,如操作成功,返回TRUE。AdapterObject是过滤器所在的网卡设备指针;过滤器的常量Filter定义在头文件ntddndis.h 中,包括有:
•NDIS-PACKET-TYPE-PROMISCUOUS:设置混杂模式,每个到来的包都会被网卡接受;
•NDIS-P

[1] [2]  下一页

Tags:

作者:佚名

文章评论评论内容只代表网友观点,与本站立场无关!

   评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
PB创新网ourmis.com】Copyright © 2000-2009 . All Rights Reserved .
页面执行时间:23,500.00000 毫秒
Email:ourmis@126.com QQ:2322888 蜀ICP备05006790号