1、XX理工大学 计算机科学与技术学院 课程设计报告 2012— 2013学年第一学期 课程名称 网络安全 设计题目 网络嗅探器设计与实现 姓 名 xxxxxxxxxx 学 号 XXXXXXXXXXX 专业班级 XXXXXXXXXX 指导教师 xxxxxxxxxxx 2013 年 1 月 2 日 简单的网络嗅探器 摘 要 计算机网络嗅探器是可以窃听计算机程序在网络上发送和接收到的数据,程序实现了对抓取到的本机在网络中的通信数据的协议类型
2、源地址、目的地址、端口和数据包的大小加以简单的分析,改程序应用C#语言编写,实现了一个简单的网络嗅探功能。。网络嗅探器具有两面性,攻击者可以用它来监听网络中数据,达到非法获得信息的目的,网络管理者可以通过使用嗅探器捕获网络中传输的数据包并对其进行分析,分析结果可供网络安全分析之用。本文对网络嗅探技术进行了简要分析,研究了网络数据包的捕获机制。文中首先分析了嗅探的原理和危害并介绍了几种常见的嗅探器,然后研究了入侵检测系统中使用的包捕获技术.利用原始套接字在windows 平台下实现了一个网络嗅探器程序,完成了对数据包进行解包、分析数据包的功能。 关键词:网络嗅探器;发送和接受到的数据;协议类
3、型;源地址;目地地址;端口和数据包;分析;C#言语 目录 一 引言 1。1 基本原理 二 基本原理 2.1概述 2.2作用 2。3分类 2.4可能造成的危害 2.5基本工作原理 2。6工作环境 三需求分析 3.1需求说明 3。2需求分析 四概要设计 4。1编程环境 4。2模块分析 五详细设计 5。1嗅探器的具体实现过 5。2主要数据结构 六嗅探器的实现与测试 6。1实现与测试 6.2实验体会 七附录(主要代码) 一、 引言 1。1基本原理 网络安全的现状随着各种新的网络技术的不断出现、应用和发展,计算机网络的应用越来越广泛,其作用也
4、越来越重要.但是由于计算机系统中软硬件的脆弱性和计算机网络的脆弱性以及地理分布的位置、自然环境、自然破坏以及人为因素的影响,不仅增加了信息存储、处理的风险,也给信息传送带来了新的问题。计算机网络安全问题越来越严重,网络破坏所造成的损失越来越大。Internet 的安全已经成为亟待解决的问题 二、网络嗅探器的基本原理 2.1概述 网络嗅探器又称为网络监听器,简称为Sniffer子系统,放置于网络节点处,对网络中的数据帧进行捕获的一种被动监听手段,是一种常用的收集有用数据的方法,这些数据可以是用户的账号和密码,可以是一些商用机密数据等等。他广泛地应用于流量分析、安全监控、网管分析
5、防火墙等的实现中。 Sniffer是利用计算机的网络接口截获目的地为其他计算机的数据报文的一种工具。Sniffer的正当用处主要是分析网络的流量,以便找出所关心的网络中潜在的问题.例如,假设网络的某一段运行得不是很好,报文的发送比较慢,而我们又不知道问题出在什么地方,此时就可以用嗅探器截获网络中的数据包,分析问题的所在。而嗅探器也可作为攻击工具被黑客所利用为其发动进一步的攻击提供有价值的信息。 2.2作用 嗅探器是网络的抓包工具,可以对网络中大量数据抓取,从而方便使用者对网络中用户的一些信息进行分析,所以,通常被黑客运用于网络攻击.我们如果也能掌握网络嗅探器的原理和设计,可以将
6、它运用与网络故障检测、网络状况的监视,还可以加强企业信息安全防护。 2。3分类 Sniffer分为软件和硬件两种,软件的Sniffer有NetXray、Packetboy、Netmonitor等,其优点是物美价廉,易于学习使用,同时也易于交流;缺点是无法抓取网络上所有的传输,某些情况下也就无法真正了解网络的故障和运行情况。硬件的Sniffer通常称为协议分析仪,一般都是商业性的,价格也比较贵。 实际上本文中所讲的Sniffer指的是软件。它把包抓取下来,然后打开并查看其中的内容,可以得到密码等。Sniffer只能抓取一个物理网段内的包,就是说,你和监听的目标中间不能有路由或其他屏
7、蔽广播包的设备,这一点很重要。所以,对一般拨号上网的用户来说,是不可能利用Sniffer来窃听到其他人的通信内容的。 2。4可能造成的危害 sniffing是作用在网络基础结构的底层。通常情况下,用户并不直接和该层打交道,有些甚至不知道有这一层存在.所以,应该说snffer的危害是相当之大的,通常,使用sniffer是在网络中进行欺骗的开始。它可能造成的危害: 嗅探器能够捕获口令.这大概是绝大多数非法使用sniffer的理由,sniffer可以记录到明文传送的userid和passwd。 能够捕获专用的或者机密的信息.比如金融帐号,许多用户很放心在网上使用自己的信用卡或现金
8、帐号,然而sniffer可以很轻松截获在网上传送的用户姓名、口令、信用卡号码、截止日期、帐号和pin.比如偷窥机密或敏感的信息数据,通过拦截数据包,入侵者可以很方便记录别人之间敏感的信息传送,或者干脆拦截整个的email会话过程。 可以用来危害网络邻居的安全,或者用来获取更高级别的访问权限。窥探低级的协议信息。这是很可怕的事,通过对底层的信息协议记录,比如记录两台主机之间的网络接口地址、远程网络接口IP地址、IP路由信息和TCP连接的字节顺序号码等。这些信息由非法入侵的人掌握后将对网络安全构成极大的危害,通常有人用sniffer收集这些信息只有一个原因:他正要进行一次欺骗(通常的IP地址
9、欺骗就要求你准确插入TCP连接的字节顺序号).事实上,如果你在网络上存在非授权的嗅探器就意味着你的系统已经暴露在别人面前了。 简单的放置一个嗅探器并将其放到随便什么地方将不会起到什么作用.将嗅探器放置于被攻击机器或网络附近,这样将捕获到很多口令,还有一个比较好的方法就是放在网关上。sniffer通常运行在路由器,或有路由器功能的主机上。这样就能对大量的数据进行监控。sniffer属第二层次的攻击。通常是攻击者已经进入了目标系统,然后使用sniffer这种攻击手段,以便得到更多的信息.如果这样的话就能捕获网络和其他网络进行身份鉴别的过程 2。5基本工作原理 网络嗅探器利用的是共享式的网
10、络传输介质。共享即意味着网络中的一台机器可以嗅探到传递给本网段(冲突域)中的所有机器的报文.网络嗅探器通过将网卡设置为混杂模式来实现对网络的嗅探。 一个实际的主机系统中,数据的收发是由网卡来完成的,当网卡接收到传输来的数据包时,网卡内的单片程序首先解析数据包的目的网卡物理地址,然后根据网卡驱动程序设置的接收模式判断该不该接收,认为该接收就产生中断信号通知CPU,认为不该接收就丢掉数据包,所以不该接收的数据包就被网卡截断了,上层应用根本就不知道这个过程。CPU如果得到网卡的中断信号,则根据网卡的驱动程序设置的网卡中断程序地址调用驱动程序接收数据,并将接收的数据交给上层协议软件处理。 下面给出
11、一个简单的图示,简单理解数据传送的原理: _________ /.。.。...。。\ /。.Internet。\ +——-——++-———+.。.。..。..。.。。+———-—+ UserA -—--— 路由 ..........。。。 UserB +---——+^+----+。。.。.。。。。。。。.+—————+ \...。.。。.。。./ \-————--——/ +——--—-+ 嗅探器 +—---——+ UserAIP地址:10。0.0.23 UserBIP地址:192。168.100。54
12、 现在知道UserA要于UserB进行计算机通讯,UserA需要为10.0.0。23到192。168.100.54的通讯建立一个IP包。这个IP包在网络上传输,它必须能够穿透路由器。因此,UserA必须首先提交这个包给路由器。由每个路由器考查目地IP地址然后决定传送路径。UserA所知道的只是本地与路由的连接,和UserB的IP地址。UserA并不清楚网络的结构情况和路由走向.UserA必须告诉路由预备发送的数据包的情况,以太网数据传输结构大概是这样的: +--+——+-—+—-+-—+——+ 目标MAC +—-+—-+——+--+--+-—+ 源MAC
13、 +-—+——+——+—-+—-+-—+ 0800 +—-+——+———-——--—-—+ .。 。IP包。 。. +——+—-+—-+——+-———-+ CRC校验 +—-+-—+-—+——+ 理解一下这个结构,UserA的计算机建立了一个包假设它由100个字节的长度(我们假设一下,20个字节是IP信息,20个字节是TCP信息,还有60个字节为传送的数据)。现在把这个包发给以太网,放14个字节在目地MAC地址之前,源MAC地址,还要置一个0x0800的标记,他指示出了TCP/IP栈后的数据结构。同时,也附加了4个字
14、节用于做CRC校验(CRC校验用来检查传输数据的正确性)。 现在发送数据到网络.所有在网内的计算机通过适配器都能够发现这个数据片,其中也包括路由适配器,嗅探器和其他一些机器。通常,适配器都具有一块芯片用来做结构比较的,检查结构中的目地MAC地址和自己的MAC地址,如果不相同,则适配器会丢弃这个结构.这个操作会由硬件来完成,所以,对于计算机内的程序来说,整个过程时毫无察觉的。 当路由器的以太网适配器发现这个结构后,它会读取网络信息,并且去掉前14个字节,跟踪4个字节。查找0x8000标记,然后对这个结构进行处理(它将根据网络状况推测出下一个最快路由节点,从而最快传送数据到预定的目标地址)
15、 设想,只有路由机器能够检查这个结构,并且所有其他的机器都忽略这个结构,则嗅探器无论如何也无法检测到这个结构的。 sniffer工作在网络环境中的底层,它会拦截所有的正在网络上传送的数据,并且通过相应的软件处理,可以实时分析这些数据的内容,进而分析所处的网络状态和整体布局。值得注意的是:sniffer是极其安静的,它是一种消极的安全攻击。 2。6工作环境 snifffer就是能够捕获网络报文的设备。嗅探器的正当用处在于分析网络的流量,以便找出所关心的网络中潜在的问题。例如,假设网络的某一段运行得不是很好,报文的发送比较慢,而我们又不知道问题出在什么地方,此时就可以用嗅探器来作出精
16、确的问题判断。 嗅探器在功能和设计方面有很多不同.有些只能分析一种协议,而另一些可能能够分析几百种协议。一般情况下,大多数的嗅探器至少能够分析下面的协议: 1.标准以太网 2.TCP/IP 3.IPX 4.DECNet 三需求分析 3.1需求说明 实现Sniffer的基本功能。Sniffer是一种用于监测网络性能、使用情况的工具。 能够侦听所有进出本主机的数据包,完整显示数据包网络层和传输层(ICMP、IP、TCP和UDP)的头信息。比如,对IP头而言,需要显示版本、头长度、服务类型、数据包长度、标识、DF/MF标志、段内偏移、生存期、协议类型、源目的IP
17、地址、选项内容。要求显示数据的实际含义; 侦听来源于指定IP地址的数据,显示接收到的TCP数据包的全部实际内容.需要考虑一个TCP包划分为多个IP包传输的情况; 功能验证手段:在运行Sniffer的同时,执行标准的Ping、Telnet和浏览网页等操作,检查Sniffier能否返回预期的结果。 3.2 需求分析 有于水平有限,不可能实现像Sniffer或者影音神探那样复杂的设置和分析,所以我们只对抓取到的本机在网络中的通信数据(如协议类型,源、目的地址和端口、数据包的大小等)加以分析,实现一个简单的网络嗅探器。一个窗体显示主页面,另一个页面显示详细的包信息。 详细信息页面,我们显示一
18、下信息: 开始时间:嗅探器抓取数据包的时间; 源端口:源目的IP地址+端口号; 目的端口:目的IP地址+端口号; 协议类型:只分析一下类型,GPG,ICMP,IDP,IGMP,IP,ND,PUP,TCP,UDP,其他的不再分析; 版本信息:协议的版本; 生存时间:; 报头大小:报文报首部大小; 报文总长:整个数据报的大小; 优先级别:提供七个级别,分别是Routine=0,Priority=1,Immediate=2,Flash=3,FlashOverride=4,CRITICECP=5,InternetworkControl=6,NetworkControl=7; 延迟:
19、NormalDelay=0、LowDelay=1; 吞吐量:NormalThroughput=0,HighThroughput=1; 可靠性:NormalReliability=0,HighReliability=1; 四、概要设计 4.1编程环境 本软件是在VC++环境下编写,使用WinPcap中定义的头文件和lib文件为支持,运用WinPcap提供的数据包捕获程序执行核心操作。 4。2模块分析 (1)本软件使用的主要模块及其功能如下: 1. 线程控制模块 2. 抓包模块 3. 数据包分析模块 (2)模块间的调用关系如下: 开启线程 关闭线程 抓包
20、 解包 五、详细设计 5.1嗅探器的具体实现过程 程序在执行过程中有两个核心的工作,一是调用Winpcap函数库实现下层抓包。二是对抓到的包文进行分析。下面分别列出两个核心过程的基本算法与相关的实现代码。 抓包算法: 第一:初始化Winpcap开发库 第二:获得当前的网卡列表,同时要求用户指定要操作的网卡 第三:获得当前的过滤规则,可为空 第四:调用库函数,pcap_loop(),同时并指定其回调函数,其中其回调函数为数据包分析过程。 分析算法: 第一:得到数据包,先将其转存到内存里,以备以后再用。 第二:分析当前的数据包,分析过程如下: 1. 数据
21、包的前14个字节(Byte)代表数据链路层的报文头,其报文格式是前6Byte为目的MAC地址,随后的6个Byte为源Mac地址,最后的2Byte代表上层协议类型这个数据很重要,是我们分析上层协议的依据. 2. 根据1所分析到的协议类型进行类似1的迭代分析。这样就可以得到各层中的报文头信息和数据信息。 第三:结束本次分析。 5。2主要模块清单 我们使用了MFC人机交互界面完成该功能的设置,其主要函数如下(详细代码见附录): AdapaterSelection.cpp//网卡配置选择函数 ARPPacket.cpp//ARP协议包函数 CapturePacket。cpp//捕获包协议
22、 CapturePacketDlg.cpp//捕获包协议对话框 DirDialog.cpp//目标文件函数 FilterDl。cpp//文件协议函数 FramePacket。cpp//表格包函数 ICMPPacket.cpp//ICMP报文协议包函数 IPPacket。cpp//IP报文协议函数 OutputDataDlg.cpp//数据导出包函数 RARPPacket。cpp//RARP协议包函数 StdAfx.cpp//头文件 TCPPacket。cpp//TCP报文协议函数 TestDlg。cpp//测试对话框函数 UDPPacket.cpp// UDP报文协议对
23、话框 六嗅探器的实现与测试 6。1实现与测试 1。在操作菜单中选中启动,便可以使程序进行抓包状态。其运行效果图如下所示 2.统计量是程序对当前网络数据包按协议类型进行的简单的计数,通过查看界面上如图所示的位置便可以清楚的看到数据包的分类情况. 6。2实验体会 实验中的遇到的问题: 在本次实验中我认为有一个问题比较麻烦,就是对抓到的包进行分析并提取出相应的位填充到对应的数据类型中,对于这个问题采用的是查看相应的协议书,并从网上看了一下流行的处理办法。 实验中的收获:一定程度上加深了对TCP/IP协议的理解,对课程学习打下了一个比较好的基础;用一些设计模式在一定程度能提高开发效能,降
24、低开发的复杂度; 七附录(具体实现代码请见电子版) 主要源代码如下: 网卡配置 //AdapaterSelection。cpp:implementationfile BOOLCAdapaterSelection::OnInitDialog() {CDialog::OnInitDialog(); //初始化树形选择 HTREEITEMroot=m_treeAdapater。InsertItem(_T("网络适配器")); if(pcap_findalldevs(&m_pAllDevs,m_strErrorBuf)==—1) returnFALSE; for(m_pD
25、ev=m_pAllDevs;m_pDev!=NULL;m_pDev=m_pDev->next) {chartemp[400]; CStringstrText; HTREEITEMhSubItem=m_treeAdapater。InsertItem(m_pDev->name,root); if(m_pDev—〉description!=NULL) {strText.Format("网卡描述信息:%s",m_pDev—〉description); m_treeAdapater.InsertItem(strText,hSubItem); } else
26、 {m_treeAdapater.InsertItem("网卡描述信息:空",hSubItem);} if(m_pDev—>addresses!=NULL&&m_pDev—>addresses->addr!=NULL) {iptos(((structsockaddr_in*)m_pDev—>addresses—>addr)->sin_addr。s_addr,temp); strText。Format(”IP地址:%s",temp); m_treeAdapater。InsertItem(strText,hSubItem); } else {m_
27、treeAdapater。InsertItem("IP地址:空”,hSubItem);} if(m_pDev—〉addresses!=NULL&&m_pDev—>addresses->broadaddr!=NULL) {iptos(((structsockaddr_in*)m_pDev->addresses->broadaddr)—>sin_addr.s_addr,temp); strText.Format(”广播地址:%s",temp); m_treeAdapater。InsertItem(strText,hSubItem); } else {m_treeA
28、dapater。InsertItem(”广播地址:无",hSubItem);} if(m_pDev->addresses!=NULL&&m_pDev->addresses->netmask!=NULL) {iptos(((structsockaddr_in*)m_pDev-〉addresses—>netmask)-〉sin_addr.s_addr,temp); strText.Format("子网掩码:%s”,temp); m_treeAdapater.InsertItem(strText,hSubItem); } else {m_treeAdap
29、ater.InsertItem(”子网掩码:空”,hSubItem);} if(m_pDev->addresses!=NULL&&m_pDev—〉addresses—>dstaddr!=NULL) {iptos(((structsockaddr_in*)m_pDev->addresses—〉dstaddr)—>sin_addr.s_addr,temp); strText.Format(”目地地址:%s",temp); m_treeAdapater。InsertItem(strText,hSubItem); } else {m_treeAdapater。I
30、nsertItem(”目地地址:无”,hSubItem);} } m_pDev=NULL; m_treeAdapater.Expand(root,TVE_EXPAND); returnTRUE;//returnTRUEunlessyousetthefocustoacontrol //EXCEPTION:OCXPropertyPagesshouldreturnFALSE } voidCAdapaterSelection::OnDblclkTreeNetworkadapters(NMHDR*pNMHDR,LRESULT*pResult) { HTREEITEMhSubI
31、tem=m_treeAdapater.GetSelectedItem(); if(m_treeAdapater。GetParentItem(hSubItem)==NULL) return; elseif(m_treeAdapater。GetItemText(m_treeAdapater。GetParentItem(hSubItem))!=”网络适配器”) hSubItem=m_treeAdapater.GetParentItem(hSubItem); m_pDev=m_pAllDevs; while(strcmp(m_pDev—>name,m_treeAdapater.G
32、etItemText(hSubItem))!=0) { //找到被选中网卡 m_pDev=m_pDev->next; } *pResult=0; } ARP协议包 //ARPPacket。cpp:implementationoftheCARPPacketclass。 CARPPacket::CARPPacket(constunsignedchar*buf,constunsignedintbuflen) {unsignedchar*pos=(unsignedchar*)buf; m_nHaddrtype=(*pos)*0x100+(*(pos+1)); pos+=
33、2; 。。..。。 } CStringCARPPacket::GetHaddrtype() {returnGetData(m_nHaddrtype);//硬件地址类型} 。。。。。. 捕获包 //CapturePacket。cpp:Definestheclassbehaviorsfortheapplication. BEGIN_MESSAGE_MAP(CCapturePacketApp,CWinApp) ON_COMMAND(ID_HELP,CWinApp::OnHelp) END_MESSAGE_MAP() CCapturePacketApptheApp; 目标文
34、件 //DirDialog。cpp:implementationoftheCDirDialogclass。 staticint__stdcallBrowseCtrlCallback(HWNDhwnd,UINTuMsg, LPARAMlParam,LPARAMlpData) {CDirDialog*pDirDialogObj=(CDirDialog*)lpData; if(uMsg==BFFM_INITIALIZED) {if(!pDirDialogObj->m_strSelDir.IsEmpty()) ::SendMessage(hwnd,BFFM_SETSELECTION,TR
35、UE, (LPARAM)(LPCTSTR)(pDirDialogObj—〉m_strSelDir)); } ::SendMessage(hwnd,BFFM_ENABLEOK,0,TRUE); return0; } intCDirDialog::DoBrowse(CWnd*pwndParent) {if(!m_strSelDir。IsEmpty()) {m_strSelDir。TrimRight(); if(m_strSelDir。Right(1)=="\\"||m_strSelDir.Right(1)=="//") m_strSelDir=m_strSelDir.Left(
36、m_strSelDir。GetLength()-1); } LPMALLOCpMalloc; if(SHGetMalloc(&pMalloc)!=NOERROR) returnFALSE; BROWSEINFObInfo; LPITEMIDLISTpidl; ZeroMemory((PVOID)&bInfo,sizeof(BROWSEINFO)); if(!m_strInitDir。IsEmpty()) {OLECHARolePath[MAX_PATH]; ULONGchEaten; ULONGdwAttributes; HRESULThr; LPSHELLFOLDE
37、RpDesktopFolder; if(SUCCEEDED(SHGetDesktopFolder(&pDesktopFolder))) {MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,m_strInitDir。GetBuffer(MAX_PATH),—1, olePath,MAX_PATH); m_strInitDir.ReleaseBuffer(-1); hr=pDesktopFolder->ParseDisplayName(NULL, NULL, olePath, &chEaten, &pidl, &dwAttributes);
38、if(FAILED(hr)) { pMalloc->Free(pidl); pMalloc-〉Release(); returnFALSE; } bInfo.pidlRoot=pidl; } } bInfo.hwndOwner=pwndParent==NULL?NULL:pwndParent->GetSafeHwnd(); bInfo.pszDisplayName=m_strPath。GetBuffer(MAX_PATH); bInfo。lpszTitle=m_strWindowTitle; bInfo.ulFlags=BIF_RETURNFSANCESTORS |B
39、IF_RETURNONLYFSDIRS |(FALSE/*m_bStatus*/?BIF_STATUSTEXT:0); bInfo。lpfn=BrowseCtrlCallback; bInfo.lParam=(LPARAM)this; if((pidl=::SHBrowseForFolder(&bInfo))==NULL) {returnFALSE;} m_strPath。ReleaseBuffer(); m_iImageIndex=bInfo.iImage; if(::SHGetPathFromIDList(pidl,m_strPath.GetBuffer(MAX_PATH)
40、)==FALSE) {pMalloc->Free(pidl); pMalloc—〉Release(); returnFALSE; } m_strPath.ReleaseBuffer(); pMalloc-〉Free(pidl); pMalloc->Release(); returnTRUE; } 文件协议 //FilterDl.cpp:implementationfile CFilterDl::CFilterDl(CWnd*pParent/*=NULL*/) :CDialog(CFilterDl::IDD,pParent){} voidCFilterDl::DoD
41、ataExchange(CDataExchange*pDX) {CDialog::DoDataExchange(pDX); DDX_Control(pDX,IDC_TAB_CTR,m_tCtr); } BEGIN_MESSAGE_MAP(CFilterDl,CDialog) ON_NOTIFY(TCN_SELCHANGE,IDC_TAB_CTR,OnSelchangeTabCtr) END_MESSAGE_MAP() BOOLCFilterDl::OnInitDialog() {CDialog::OnInitDialog(); TCITEMitem; item.m
42、ask=TCIF_TEXT; item。pszText=”第一页"; m_tCtr。InsertItem(0,&item); item.pszText=”第二页”; m_tCtr。InsertItem(1,&item); m_dlg1。Create(IDD_ABOUTBOX,&m_tCtr); m_dlg2.Create(IDD_DIALOG_OUTPUTDATA,&m_tCtr); m_dlg1。SetWindowPos(NULL,10,30,400,100,SWP_SHOWWINDOW); m_dlg2。SetWindowPos(NULL,10,30,400,10
43、0,SWP_HIDEWINDOW); returnTRUE; } voidCFilterDl::OnSelchangeTabCtr(NMHDR*pNMHDR,LRESULT*pResult) {*pResult=0;} 表格包 //FramePacket。cpp:implementationoftheCFramePacketclass。 CFramePacket::CFramePacket(constunsignedchar*buf,intbuflen) {unsignedchar*pPos; pPos=(unsignedchar*)buf; for(inti=0;i〈
44、6;i++) {m_nDestAddr[i]=*pPos; pPos++; } for(i=0;i<6;i++) {m_nSrcAddr[i]=*pPos; pPos++; } m_nType=(*pPos)*0x100+(*(pPos+1)); } voidCFramePacket::GetMacSrcAddr(char*str) {sprintf(str,"%02X-%02X-%02X—%02X—%02X-%02X",m_nSrcAddr[0],m_nSrcAddr[1],m_nSrcAddr[2],m_nSrcAddr[3],m_nSrcAddr[4
45、],m_nSrcAddr[5]); } CStringCFramePacket::GetMacSrcAddr() {CStringstr; str.Format("%02X-%02X-%02X-%02X—%02X—%02X”,m_nSrcAddr[0],m_nSrcAddr[1],m_nSrcAddr[2],m_nSrcAddr[3],m_nSrcAddr[4],m_nSrcAddr[5]); returnstr; } 。。。。。。 intCFramePacket::GetType() {returnm_nType;} ICMP报文协议包 //ICMPPacket.c
46、pp:implementationoftheCICMPPacketclass. CICMPPacket::CICMPPacket(){} CICMPPacket::~CICMPPacket(){} IP报文协议包 //IPPacket.cpp:implementationoftheCIPPacketclass。 //用于初始化IP头信息 CIPPacket::CIPPacket(constunsignedchar*buf,intbuflen) {unsignedchar*pos; pos=(unsignedchar*)buf; m_nVersion=*pos/16;
47、m_nHeaderLength=*pos%16; pos++; m_nServiceType=*pos; m_nPrecedence=(*pos&16)*4+(*pos&8)*2+(*pos&4); if(*pos&16)m_bDelay=true; elsem_bDelay=false; .。.。。。 m_nFragOffSet=(*pos%32)*256+(*(pos+1)); pos+=2; m_nTTL=*pos; pos++; m_nProtocol=*pos; pos++; m_nCheckSum=(*pos)*256+(*(pos+1)
48、 pos+=2; m_lSrcIP=(*pos)*0x1000000+(*(pos+1))*0x10000+(*(pos+2))*0x100+(*(pos+3)); pos+=4; m_lDestIP=(*pos)*0x1000000+(*(pos+1))*0x10000+(*(pos+2))*0x100+(*(pos+3)); if(m_nHeaderLength〉5) {pos+=4; m_nOptLength=(m_nHeaderLength-5)*4; m_pOptions=newunsignedchar[m_nOptLength]; memcp
49、y(m_pOptions,buf+20,m_nOptLength); } else {m_nOptLength=0; m_pOptions=NULL; } pos=(unsignedchar*)(buf+m_nHeaderLength*4); m_nDataLength=m_uTotalLength—m_nHeaderLength*4; if(m_nDataLength>0) {m_pData=newunsignedchar[m_nDataLength]; memcpy(m_pData,buf+m_nHeaderLength*4,m_nDataLen
50、gth); } Elsem_pData=NULL; } CStringCIPPacket::GetProtocol() {CStringstr; switch(m_nProtocol) {case6:str。Format(”TCP”);break; case17:str.Format(”UDP”);break; case1:str。Format("ICMP”);break; case89:str。Format("OSPF");break; default:str。Format(”%d",m_nProtocol); } returnstr;






