基于winpcap的嗅探器设计与实现.docx

上传人:b****8 文档编号:11404369 上传时间:2023-02-28 格式:DOCX 页数:33 大小:464.29KB
下载 相关 举报
基于winpcap的嗅探器设计与实现.docx_第1页
第1页 / 共33页
基于winpcap的嗅探器设计与实现.docx_第2页
第2页 / 共33页
基于winpcap的嗅探器设计与实现.docx_第3页
第3页 / 共33页
基于winpcap的嗅探器设计与实现.docx_第4页
第4页 / 共33页
基于winpcap的嗅探器设计与实现.docx_第5页
第5页 / 共33页
点击查看更多>>
下载资源
资源描述

基于winpcap的嗅探器设计与实现.docx

《基于winpcap的嗅探器设计与实现.docx》由会员分享,可在线阅读,更多相关《基于winpcap的嗅探器设计与实现.docx(33页珍藏版)》请在冰豆网上搜索。

基于winpcap的嗅探器设计与实现.docx

基于winpcap的嗅探器设计与实现

计算机与信息学院

《计算机网络系统实践》报告

2013年9月25

一、设计要求

1.不限平台,可以使用Libpcap、WinPcap或Linux的原始套接字;

2.实现一个功能比较简单的、具有图形界面的Sniffer,主线程响应用户界面操作,工作线程完成抓包等工作;

3.能够解析出IP层和传输层的协议头,能够过滤TCP、UDP等数据包;

4.能够输出文本方式传送的数据包的内容;

5.能够进行简单的流量统计。

二、开发环境与工具

操作系统:

windows7

开发工具:

visualstudio

开发语言:

C++

附加库:

Winpcap

三、设计原理

网络嗅探器是一种常用的监听网络的工具。

所谓嗅探器(Sniffer),是一种利用计算机网络接口截获网络数据的软件或硬件,可用于网络管理、网络协议分析以及网络安全等众多方面。

嗅探器不同于一般的键捕获工具,后者只能捕获当地终端控制台上的按键内容,而嗅探器所“嗅”到的是动态的以信息包形式(如IP数据包或者以太网包)封装的信息流。

其中可能携带了重要数据或敏感信息。

可以将这些捕获到的信息包存档,以利用相应工具可以作进一步分析。

计算机网络的设计为嗅探器的使用创造了最基本的条件。

在目前的网络环境中,所有计算机节点都是共享传输介质,任意节点发出或发往任意节点的数据帧必将经过网内每一个节点的网络接口,此时只需对嗅探节点的网络接口(网卡)进行适当的设置便可为实现嗅探的做好准备工作。

在计算机网络系统中,网卡是用来接收网络上其他节点发来的数据帧,其内嵌的单片处理程序会检测数据帧来源的MAC地址,并根据网卡所设置的接收方式来是否接收处理数据,如果认为应该处理,则网卡就会产生中断信号通知中央处理器,接收该数据帧并传输给操作系统处理。

否则就简单丢弃,所对应节点的网卡就截断,计算机的中央处理器并不参与。

网卡是网络中节点主机的关键硬件设备。

对数据的接收一般有四种设置模式:

广播模式:

接收在网络中进行广播数据信息。

组播模式:

接收组播数据信息。

单播模式:

只有匹配的目的网卡才能接收数据信息。

混杂模式:

网卡能够可以接收一切通过它的数据信息。

4、系统功能描述及软件模块划分

系统功能设计

本系统的基本功能为实现网络数据包的捕获,并将其数据内容解析显示。

网络数据包捕获功能主要负责从网络中捕获和过滤数据,这可以通过调用winPcap提供的丰富的API函数来实现;数据解析及显示部分主要负责界面数据转化、解析、处理、格式化、协议分析等,这一部分主要通过MFC来设计一个单文档图形用户界面GUI,解析结果将通过MFC的类库显示到GUI中

系统总系结构

网络嗅探器的整体设计由三个模块组成,自底向上分别是嗅探器设置模块,数据包捕获模块,解析和显示模块。

嗅探器设置模块主要调用winPcaP提供的API,分为获取网络设备信息,设置并编译过滤器,打开网络设备三个步骤。

数据包捕获模块创建了新的线程,利用了winPcap的非回调函数Pcap_next_ex()函数从winPcap底层驱动的数据缓冲区中读取数据包,并将数据包存储在系统临时文件中,以便之后的分析。

用Pcap_open_offline()函数从离线文件中读取包。

读取到的任意一个符合捕获条件数据包,将其内容解析,并显示本数据包。

捕获完成后,进人解析和显示模块。

(嗅探器总体结构如图1)

图1.嗅探器总体结构

五、设计步骤

嗅探器的设置模块

a.获取已连接的网络设备列表,winPcap提供了pcap_findalldevs_ex()函数,这个函数返回一个PcaP-if结构的链表,每个这样的结构都包含了一个适配器的详细信息。

b.打开网络设备,winPcap提供了pcap_open()函数,该函数第一参数制定要捕获数据包的哪些部分,第二参数用来制定适配器是否为混杂模式,第三参数为读取数据的超时时间,当适配器被打开后,就可以进行捕获工作了;

c.设置过滤器,winPcap中用来过滤数据包的函数是pcap_compile()和pcap_setfilter()。

pcap_compile()它将一个高层的布尔过滤表达式编译成一个能够被过滤引擎所解释的低层的字节码。

pcap_setfilter()将一个过滤器与内核捕获会话相关联。

当pcap_set_filter()被调用时,这个过滤器将被应用到来自网络的所有数据包,并且,所有的符合要求的数据包(即那些经过过滤器以后,布尔表达式为真的包),将会立即复制给应用程序。

数据包的捕获模块

该部分创建了一个用于捕获数据包的线程,在该线程中调用winPcap提供的pcap_next_ex()函数从底层驱动数据缓冲区中读取数据包,该函数接受已打开的网络设备句柄,返回捕获数据包的实体,并用pcap_dump函数将每一个数据包写人临时文件中。

解析与显示模块

该部分在接收到用户发出的捕获完成消息后,将数据包从离线文件中逐条取出并进行解析和显示。

将解析完毕数据包中的各项内容填人已经预先声明的协议的数据结构中,包括(序号,捕获时间,以太帧长度,传输层协议,源IP地址,目的IP地址,源MAC地址,目的MAC地址),然后将数据结构添加到列表视图中

 

WinPcap是一个在Windows操作系统下的免费、公开的用于直接访问网络的开发工具包(编程API)。

大多数Windows网络应用程序都是通过Winsock API(Windows套接口)这类高级编程接口访问网络的。

这种方法允许在网络上进行简单的数据传送,因为操作系统的TCP/IP协议栈实现软件会处理底层细节(协议操作、流程重组等等),并提供一个类似于读写文件的函数接口。

 

然而,有时候“简便方法”并不能满足实际需要。

有些程序希望绕过TCP/IP协议栈,直接处理底层网络中的通信数据,它们需要对网络进行底层进行直接访问,即在没有类似协议栈(TCP/IP协议栈)的实体介入条件下对网络进行原始访问。

 

络程序实际上是绕开操作系统的TCP/IP协议栈直接通过底层网络发送数据,因此,网络程序可以实现一些更低级、更灵活的功能。

  

2、WinPcap的目的和用途 

开发WinPcap的目的是为Win32应用程序提供一种直接访问底层网络的能力。

通过WinPcap,网络应用程序可以实现如下功能:

 1) 捕获原始数据包,包括发送到本主机以及在共享网络上的数据包。

 

2) 数据过滤。

在将数据包发送给应用程序之前按照用户的规定对捕获的数据包进行过滤。

 

3) 发送原始数据包。

向网络发送原始数据包。

 4) 数据包统计。

对网络通信进行统计。

 

3、基于WinPcap可以开发的网络应用程序 

基于WinPcap可以开发很多网络应用程序,典型的包括:

 1) 网络和协议分析软件2) 网络监听软件 3) 网络通信量记录软件 4) 网络数据生成软件 5) 用户机网桥和路由器 6) 网络入侵探测系统 7) 网络扫描软件 8) 网络安全工具

 

 

二、WinPcap的体系结构分析 

1、WinPcap的组成与结构 

如图2.1,WinPcap由一个数据包监听设备驱动程序(NPF)、一个底层的动态连接库(packet.dll)和一个高层的不依赖于操作系统的静态库(wpcap.dll)共三个部分构成。

这里,NPF在操作系统的内核级,packet.dll、wpcap.dll在用户级。

 

 4 

向9x系统的概念和NT系统的非常相似,只是在某些实现上有点差异,比如说9x只支持ANSI编码,而NT系统则提倡使用Unicode编码。

  

简单来讲,WinPcap典型的开发和运行环境是windows NT/2000/XP。

当然,早期的WinPcap也支持windows 95/98/Me,但是,我们不推荐在windows 95/98/Me下开发和运行基于WinPcap的网络应用。

 

二、WinPcap的体系结构分析 

1、WinPcap的组成与结构 

如图2.1,WinPcap由一个数据包监听设备驱动程序(NPF)、一个底层的动态连接库(packet.dll)和一个高层的不依赖于操作系统的静态库(wpcap.dll)共三个部分构成。

这里,NPF在操作系统的内核级,packet.dll、wpcap.dll在用户级。

 

1)数据包监听设备驱动程序 技术实现上,为了实现抓包,系统必须

绕过操作系统的协议栈来访问在网络上传输的原始数据包(raw packet)。

这就要求WinPcap的一部分运行在操作系统核心内部,直接与网络接口驱动交互。

由于这个部分是系统依赖(system dependent)的,在Winpcap的解决方案中它被视为是一个设备驱动,称作NPF(Netgroup Packet Filter)。

Winpcap开发小组针对Windows95,Windows98,WindowsME,Windows NT 4,Windows2000和WindowsXP提供了不同版本的驱动(在Windows95/98/ME中是VXD文件,在WindowsNT/2000中是SYS文件)。

这些驱动不仅提供了基本的特性(例如抓包、发送原始数据包——注入数据包),还有更高级的特性(例如可编程的过滤器系统和监视引擎)。

前者可以被用来约束一个抓包会话只针对网络通信中的一个子集

概括地讲,数据包监听设备驱动程序直接从数据链路层抓取网络数据包并过滤,将数据包不加修改地传递给运行在用户层的应用程序。

它在不同的WINDOWS系统下是不同。

数据包监听设备驱动程序支持BPF过滤机制,可以灵活地设置过滤规则。

 

2)底层的动态连接库(packet.dll)和高层静态库(wpcap.dll) 为了方便编程,WinPcap必须提供一个编程接口(API),这就是WinPcap的底层的动态连接库(packet.dll)和高层静态库(wpcap.dll)。

这里,packet.dll提供了一个底层API,伴随着一个独立于Microsoft操作系统的编程接口,这些API可以直接用来访问驱动的函数;wpcap.dll导出了一组更强大的与libpcap一致的高层抓包函数库(capture primitives),这些函数使得数据包的捕获以一种与网络硬件和操作系统无关的方式进行

底层动态链接库运行在用户层,它将应用程序和数据包监听设备驱动程序隔离开来,使得应用程序可以不加修改地在不同的WINDOWS系统上运行。

高级的静态链接库和应用程序编译在一起,它使用低级动态链接库提供的服务,向应用程序提供完善的监听接口。

 

概括来讲,WinPcap包含了一个最优化的内核模式驱动——称作Netgroup Packet Filter(NPF),和一套与libpcap兼容的用户级函数库。

WinPcap使Unix平台下的应用程序能方便的移植到Win32平台下,并且它能使一套很大的Unix函数库只需通过简单的重新编译就立刻在Win32平台下使用。

而且,由于网络监听的重要性,WinPcap还为此提供了特殊的系统调用函数。

实际上,Windows环境下的WinPcap与Unix环境下的Berkeley Packet Filter(BPF)在体系架构上是基本一致的。

在Unix环境下,程序员只需要了解Libpcap提供的编程接口即可,Libpcap将应用程序与操作系统内核之间的相互作用隐藏起来,提供了一套与用户程序联系的函数和强大的捕获数据包的抽象接口。

在Windows环境下,程序员主要基于wpcap.dll提供的编程接口开发应用程序。

当然,程序要也可以使用packet.dll、NPF提供的编程接口,只是后者提供的API更加底层。

 

六、关键问题及其解决方法

界面初始化

BOOLCzszhangDlg:

:

OnInitDialog()

{

CDialog:

:

OnInitDialog();

ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX<0xF000);

CMenu*pSysMenu=GetSystemMenu(FALSE);

if(pSysMenu!

=NULL)

{

CStringstrAboutMenu;

strAboutMenu.LoadString(IDS_ABOUTBOX);

if(!

strAboutMenu.IsEmpty())

{

pSysMenu->AppendMenu(MF_SEPARATOR);

pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);

}

}

SetIcon(m_hIcon,TRUE);//设置大图标

SetIcon(m_hIcon,FALSE);//设置小图标

ShowWindow(SW_MINIMIZE);

m_listCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);

m_listCtrl.InsertColumn(0,_T("编号"),3,30);//1表示右,表示中,表示左

m_listCtrl.InsertColumn(1,_T("时间"),3,130);

m_listCtrl.InsertColumn(2,_T("长度"),3,72);

m_listCtrl.InsertColumn(3,_T("源MAC地址"),3,140);

m_listCtrl.InsertColumn(4,_T("目的MAC地址"),3,140);

m_listCtrl.InsertColumn(5,_T("协议"),3,70);

m_listCtrl.InsertColumn(6,_T("源IP地址"),3,145);

m_listCtrl.InsertColumn(7,_T("目的IP地址"),3,145);

m_combobox.AddString(_T("请选择一个网卡接口(必选)"));

m_comboBoxRule.AddString(_T("请选择过滤规则(可选)"));

if(sniffer_initCap()<0)

returnFALSE;/*初始化接口列表*/

for(dev=alldev;dev;dev=dev->next)

{

if(dev->description)

m_combobox.AddString(CString(dev->description));

}

/*初始化过滤规则列表*/

m_comboBoxRule.AddString(_T("tcp"));

m_comboBoxRule.AddString(_T("udp"));

m_comboBoxRule.AddString(_T("ip"));

m_comboBoxRule.AddString(_T("icmp"));

m_comboBoxRule.AddString(_T("arp"));

m_combobox.SetCurSel(0);

m_comboBoxRule.SetCurSel(0);

m_buttonStop.EnableWindow(FALSE);

m_buttonSave.EnableWindow(FALSE);

returnTRUE;//除非将焦点设置到控件,否则返回TRUE

}

捕获数据包

//开始捕获

intCzszhangDlg:

:

sniffer_startCap()

{

intif_index,filter_index,count;

u_intnetmask;

structbpf_programfcode;

CStringNcard;

sniffer_initCap();

//获得接口和过滤器索引

if_index=this->m_combobox.GetCurSel();

filter_index=this->m_comboBoxRule.GetCurSel();

if(0==if_index||CB_ERR==if_index)

{

MessageBox(_T("请选择一个合适的网卡接口"));

return-1;

}

if(CB_ERR==filter_index)

{

MessageBox(_T("过滤器选择错误"));

return-1;

}

/*获得选中的网卡接口*/

dev=alldev;

for(count=0;count

dev=dev->next;

if((adhandle=pcap_open_live(dev->name,//设备名

65536,//捕获数据包长度

1,//混杂模式(非意味着是混杂模式)

1000,//读超时设置

errbuf//错误信息

))==NULL)

{

MessageBox(_T("无法打开接口:

"+CString(dev->description)));

pcap_freealldevs(alldev);

return-1;

}

/*检查是否为以太网*/

if(pcap_datalink(adhandle)!

=DLT_EN10MB)

{

MessageBox(_T("这不适合于非以太网的网络!

"));

pcap_freealldevs(alldev);

return-1;

}

if(dev->addresses!

=NULL)

netmask=((structsockaddr_in*)(dev->addresses->netmask))->sin_addr.S_un.S_addr;

else

netmask=0xffffff;

//编译过滤器

if(0==filter_index)

{

charfilter[]="";

if(pcap_compile(adhandle,&fcode,filter,1,netmask)<0)

{

MessageBox(_T("语法错误,无法编译过滤器"));

pcap_freealldevs(alldev);

return-1;

}

}else{

CStringstr;

char*filter;

intlen,x;

this->m_comboBoxRule.GetLBText(filter_index,str);

len=str.GetLength()+1;

filter=(char*)malloc(len);

for(x=0;x

{

filter[x]=str.GetAt(x);

}

if(pcap_compile(adhandle,&fcode,filter,1,netmask)<0)

{

MessageBox(_T("语法错误,无法编译过滤器"));

pcap_freealldevs(alldev);

return-1;

}

}

//设置过滤器

if(pcap_setfilter(adhandle,&fcode)<0)

{

MessageBox(_T("设置过滤器错误"));

pcap_freealldevs(alldev);

return-1;

}

/*设置数据包存储路径*/

CFileFindfile;

charthistime[30];

structtm*ltime;

memset(filepath,0,512);

memset(filename,0,64);

if(!

file.FindFile(_T("SavedData")))

{

CreateDirectory(_T("SavedData"),NULL);

}

time_tnowtime;

time(&nowtime);

ltime=localtime(&nowtime);

strftime(thistime,sizeof(thistime),"%Y%m%d%H%M%S",ltime);

strcpy(filepath,"SavedData\\");

strcat(filename,thistime);

strcat(filename,".zsz");

strcat(filepath,filename);

dumpfile=pcap_dump_open(adhandle,filepath);

if(dumpfile==NULL)

{

MessageBox(_T("文件创建错误!

"));

return-1;

}

pcap_freealldevs(alldev);

/*接收数据,新建线程处理*/

LPDWORDthreadCap=NULL;

m_ThreadHandle=CreateThread(NULL,0,sniffer_CapThread,this,0,threadCap);

if(m_ThreadHandle==NULL)

{

intcode=GetLastError();

CStringstr;

str.Format(_T("创建线程错误,代码为%d."),code);

MessageBox(str);

return-1;

}

return1;

}

数据包处理

DWORDWINAPIsniffer_CapThread(LPVOIDlpParameter)

{

intres,nItem;

structtm*ltime;

CStringtimestr,buf,srcMac,destMac;

time_tlocal_tv_sec;

structpcap_pkthdr*header;//数据包头

constu_char*pkt_data=NULL,*pData=NULL;//网络中收到的字节流数据

u_char*ppkt_data;

CzszhangDlg*pthis=(CzszhangDlg*)lpParameter;

if(NULL==pthis->m_ThreadHandle)

{

MessageBox(NULL,_T("线程句柄错误"),_T("提示"),MB_OK);

return-1;

}

while((res=pcap_next_ex(pthis->adhandle,&header,&pkt_data))>=0)

{

if(res==0)//超时

continue;

structdatapkt*data=(structdatapkt*)malloc(sizeof(struct

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1