课程设计.docx
- 文档编号:30275824
- 上传时间:2023-08-13
- 格式:DOCX
- 页数:22
- 大小:441KB
课程设计.docx
《课程设计.docx》由会员分享,可在线阅读,更多相关《课程设计.docx(22页珍藏版)》请在冰豆网上搜索。
课程设计
南京工程学院
通信工程学院
课程设计说明书(论文)
题目:
监控IP数据包流量
课程名称:
现代网络技术设计
专业:
电子信息工程(传感网
班级:
传感121
学生姓名:
曾毛宁
学号:
208120707
设计地点:
信息处理技术实验室(C213)
指导老师:
刘婷婷
设计起止时间:
2013年12月30日至2014年1月3日
1、课程设计目的和要求以及设计平台
1、课程设计目的:
IP协议是TCP/IP协议簇中的核心协议。
熟悉IP协议对于理解TCP/IP结构具有重要的意义。
本次课程设计的主要目的是通过监控IP包流量,了解IP协议的工作原理与IP数据包的基本结构
2、课程设计要求:
根据后面介绍的IP数据包结构,编写程序监控IP数据包的流量。
(1)以命令行形式运行:
MonitorTrafffictime
其中MonitorTrafffic为程序名,time为设定的监控时间(单位为分钟)
(2)输出内容:
按源地址统计该时间段内发送的IP数据包的个数。
3、设计平台:
MicrosoftVisualC++6.0
2、课程设计内容
1、课程设计的内容:
(1)使用Winpcap,Winpcap的主要功能在于独立于主机协议(如TCP/IP)发送和接受原始数据包;
(2)列出网卡列表,让用户选择可用的网卡;
(3)使用过滤器捕获IP包,别的包都过滤掉;
(4)捕获IP包并按包的源地址进行统计(用链表结构进行实现)。
程序流程如图8-1所示。
2、相关的基础知识
(1)熟悉IP首部格式
(2)IP协议
IP是TCP/IP模型中的网络层协议,又称为互联网协议,是支持网间互连的数据报协议,它与TCP协议一起构成了TCP/IP协议族的核心。
它提供网间连接的完善功能,包括IP数据报规定互联网范围内的IP地址格式[2]。
在因特网中IP协议是能使连接到网上的所有计算机网络实现相互通信的一套规则,规定了计算机在因特网上进行通信时应当遵守的规则。
任何厂家生产的计算机系统,只要遵守IP协议就可以与因特网互连互通。
IP地址具有唯一性,根据用户性质的不同,可以分为不同的类别。
IP协议的特点如下:
(1)IP协议是一种不可靠、无连接的数据报传送协议。
(2)IP协议是点对点的网络层通信协议。
(3)IP协议向通信层隐藏了物理网络的差异。
(4)IP协议以一种数据报的形式传输数据,每个数据报独立传输,可能通过不同路径传输,因此可能不按顺序到达目的地,或者出现重复。
3、关于Winpcap
(a)、关于Winpcap库:
Winpcap(windowspacketcapture)是windows平台下一个买费的、公共的基于windows的网络接口API库。
主要为win32应用程序提供访问网络底层的能力。
Winpcap的主要功能在于独立于主机协议(如TCP/IP)发送和接收原始数据报。
也就是说,Winpcap不能阻塞、过滤或控制其他应用程序数据报的收发,它只是监听共享网络上传送的数据报。
因此,它不能用于QoS调度程序或个人防火墙。
其功能有:
(1)捕获原始数据包,包括在共享网络上各主机发送接收的以及相互之间交换的数据包;
(2)在数据包发往应用程序之前,按照自定义的规则将某些特殊的数据包过滤掉;
(3)在网络上发送原始数据包;
(4)收集网络通信过程中的统计信息。
Winpcap是针对win32平台上的抓包和网络分析的一个架构,它包括一个核心态的包过滤器,一个底层的动态链接库(packet.dll)和一个高层的不依赖于系统的库(wpcap.dll)。
它由Packet、NPF(NetgroupPacketFilter)、packet.dll、wpcap.dll、Application组成,首先,抓包系统必须绕过操作系统的协议来访问在网络上传输的原始数据包,这就要求一部分运行在操作系统核心内部,直接与网络接口驱动交互。
这个部分是系统依赖的,在Winpcap的解决方案里它被认为是一个设备驱动,称作NPF。
其次,抓包系统必须有用户级的程序接口,通过这些接口,用户程序可以利用内核驱动提供的高级特性。
Winpcap提供了两个不同的库:
packet.dll和wpcap.dll。
前者提供了一个底层API,伴随着一个独立于Microsoft操作系统的编程接口,这些API可以直接用来访问驱动的函数;后者导出了一组更强大的与libpcap一致的高层抓包函数库。
这些函数使得数据包的捕获以一种与网络硬件和操作系统无关的方式进行。
(b)、Winpcap的使用:
下载WinPcap_4_1_1.exe和WpdPack_4_1_1.zip,前者是Winpcap的开发程序,后者是inlude文件和lib文件,这些都是需要自己手动添加的,这里include和lib文件夹里的东西VC++6.0里面没有,添加步骤如下:
第一步:
点击菜单栏上的“工具”,再点击下拉菜单中的”选项“对话框
在“选项”分别在Includefiles和Libraryfiles中添加Winpcap文件夹下的lib文件和include文件。
第二步:
点击菜单栏里的工程——设置,选择连接
在对象/库模块中输入wpcap.lib和packet.lib,再点C/C++。
在“预处理程序定义”下输入WPCAP和HAVE_REMOTE,要用逗号隔开。
开始
核心流程图,
8—1
获取网卡列表
获取Ethernet网卡
打开网卡(混杂模式)
编译并设置过滤器
捕获IP包
将IP包源地
址加入链表
N是否
超时
Y
输出链表内容
结束
3、课程设计的核心知识
1、获取本机网卡信息
本课程设计要实现对数据包的捕获,首先就要获取并列出本机上的所有网卡信息,这个功能是通过Winpcap提供的pcap_findalldevs来实现的。
该函数原型如下:
intpcap_findalldevs(pcap_if_t**alldevs,char*errbuf)
pcap_if_t是一个用于描述网卡信息的结构体。
里面包含了网卡的名字,描述等信息。
通过这个函数可以得到一个网卡信息组成的链表。
函数错误则返回-1。
2、打开用户选定的网卡
得到网卡信息之后,可以通过列表框等形式显示出来,在用户选择后,通过pcap_open_live打开指定网卡:
pcap_t*pcap_open_live(char*device,intsnaplen,intpromisc,intto_ms,char*ebuf)
函数功能:
获得用于捕获网络数据包的数据包捕获描述字。
参数说明:
device参数为指定打开的网络设备名。
snaplen参数定义捕获数据的最大字节数。
promisc指定是否将网络接口置于混杂模式。
to_ms参数指*定超时时间(毫秒)。
ebuf参数则仅在pcap_open_live()函数出错返回NULL时用于传递错误消息。
这些参数中最重要的就是promisc参数,通过它可以将网卡监听设置为混杂模式,混杂模式是指不管网卡接收到的数据包是不是发给自己的,都向应用程序上传。
这样可以捕获一些广播信息。
本程序将监听模式设为混杂模式。
3、编译并设置过滤器
在打开网卡并得到网卡描述符后,可以编译并设置过滤器。
编译过滤器:
intpcap_compile(pcap_t* p,structbpf_program* fp,
char* str,int optimize,bpf_u_int32 netmask)
编译一个数据包过滤器,将一个能被核心态(kernel-level)过滤器引擎解
释的程序中的高层过滤表达式(filteringexpression)进行转化。
pcap_compile()被用来将字符串str编译进过滤器程序(fp),程序(fp)
是一个指向bpf_program结构体并被pcap_compile()赋值的指针。
Optimize
控制是否对目标代码(resultingcode)的性能进行优化。
Netmask表明IPv4
掩码,它仅在检查过滤器程序中的IPv4广播地址的时候被使用。
返回-1
表示发生了错误,此时,pcap_geterr()将被用来显示错误信息。
设置过滤器
intpcap_setfilter(pcap_t* p,structbpf_program*fp)
把一个过滤器同一次抓包关联起来。
pcap_setfilter被用来指定一
个过滤器程序。
fp是一个指向bpf_program结构体的指针,通常是
pcap_compile()执行的结果。
当失败时返回-1,此时,pcap_geterr()被用
来显示错误信息;返回0表示成功。
4、抓包:
接下来就是最后一步抓包,Winpcap提供的抓包接口主要有
pcap_next_ex和pcap_loop两种
pcap_loop直接由捕获数据包所调用,它在底层抓取到包时,直接调用
用户传入的处理函数,
本程序使用另一个函数pcap_next_ex:
pcap_next_ex(pcap_t*p,structpcap_pkthdr**pkt_header,const
u_char**pkt_data
功能:
从interface或其它离线文件中获取一个报文,
参数P:
已打开捕获实例的描述符
pkt_header:
报文头
pkt_data:
报文内容
返回值:
1:
成功;0:
获取报文超时
-1:
发生错误;-2:
获取到离线文件文件的最后一个报文。
4、实验源代码:
#include
#include
#include
#include
#include
#include
#include
//等同于点击“Project-Setting-link”打开Object/librarymodules编辑框后加入lib文件
#pragmacomment(lib,"Wpcap.lib")
#pragmacomment(lib,"Ws2_32.lib")
classIPNode//IP结点类,存放IP包的源IP地址和其发送的数据包个数
{
private:
longm_lIPAddress;//IP地址
longm_lCount;//发送数据包个数
public:
IPNode*pNext;//指向下一个IP结点
IPNode(longsourceIP)
{
m_lIPAddress=sourceIP;
m_lCount=1;//初始化数据包个数为1
}
//数据包个数加1
voidaddCount()
{
m_lCount++;
}
//返回数据包个数
longgetCount()
{
returnm_lCount;
}
//返回IP地址
longgetIPAddress()
{
returnm_lIPAddress;
}
};
//结点链表
classNodeList
{
IPNode*pHead;//链表头
IPNode*pTail;//链表尾
public:
NodeList()
{
pHead=pTail=NULL;//初始化链表
}
~NodeList()
{
if(pHead!
=NULL)
{
IPNode*pTemp=pHead;
pHead=pHead->pNext;
deletepTemp;
}
}
//Ip结点加入链表
voidaddNode(longsourceIP)
{
if(pHead==NULL)//当链表为空时
{
//cout<<"thefirstnode"< pTail=newIPNode(sourceIP); pHead=pTail; pTail->pNext=NULL; } else { for(IPNode*pTemp=pHead;pTemp;pTemp=pTemp->pNext) { //如果链表中存在此IP,发送数据包个数加1 if(pTemp->getIPAddress()==sourceIP) { //cout<<"samesourceip"< pTemp->addCount(); break; } } //如果链表中没有此IP,则加入链表 if(pTemp==NULL) { //cout<<"anewsourceip"< pTail->pNext=newIPNode(sourceIP); pTail=pTail->pNext; pTail->pNext=NULL; } } } //输出IP结点,即IP地址和其发送的IP包个数 voidOutPut() { IPNode*pTemp=pHead; while(pTemp! =NULL) { longlTemp=pTemp->getIPAddress(); cout< cout< pTemp=pTemp->pNext; } return; } }; //IP包头部结构 structip_header{ unsignedcharver_ihl;//版本号(4位)+头部长度(4位) unsignedchartos;//服务类型 unsignedshorttlen;//总长度 unsignedshortidentification;//标识 unsignedshortflags_fo;//标志+片偏移 unsignedcharttl;//生存时间 unsignedcharproto;//协议 unsignedshortcrc;//校验和 DWORDsaddr;//源地址 DWORDdaddr;//目的地址 unsignedintop_pad;//选项+填充 }; voidmain(intargc,char*argv[]) { pcap_if_t*alldevs,*d;//网络设备结构 pcap_t*fp;//网卡描述符 charerrbuf[PCAP_ERRBUF_SIZE];//错误信息 unsignedintnetmask;//子网掩码 charpacket_filter[]="ip";//过滤,选择IP协议 structbpf_programfcode; structpcap_pkthdr*header; constunsignedchar*pkt_data; //获取网络设备列表 if(pcap_findalldevs(&alldevs,errbuf)==-1) /*找出所有网络设备,设备信息存储在alldevs中, -1表示失败,其将具体出错信息写在errbuf中 0就表示pcap_findalldevs调用成功*/ { cout<<"Errorinformation"< exit (1); } d=alldevs; for(unsignedinti=1;d! =NULL;d=d->next) { cout<<"第"< "< i++; } cout<<"共"< /*在Windows2000平台上,基于winpcap一般至少有两张网卡, 第一张通常是Winpcap虚拟,第二张通常是真实的*/ cout<<"请选择一个网络接口(1~"< unsignedintk=1; cin>>k;cout< d=alldevs; for(i=1;i d=d->next; /*pcap_open_live用于打开d->name所指定的网络接口, 返回值为pcap_t类型,并存于fp中,该值将在pcap_next_ex 函数中使用*/ fp=pcap_open_live(d->name,65536,1,1000,errbuf); if(fp==NULL) { cout<<"UnabletoOpenthedevice"; //释放设备列表 pcap_freealldevs(alldevs); exit (1); } //获取子网掩码 if(d->addresses! =NULL) netmask=((structsockaddr_in*)(d->addresses->netmask))->sin_addr.s_addr; else //没有地址则假设为C类地址 netmask=0xffffff; //编辑过滤器 if(pcap_compile(fp,&fcode,packet_filter,1,netmask)<0) //参数说明: fp为pcap_open_live函数返回的指针;fcode传递给后边的pcap_setfilter函数;packet_filter是前边定的过滤条件,即"IP"。 该函数返回值为-1时表示出错 { cout<<"\n编辑过滤器失败\n"; pcap_freealldevs(alldevs);//释放设备列表 return; } //设置过滤器 if(pcap_setfilter(fp,&fcode)<0) //参数说明: fp为pcap_open_live函数返回的指针;fcodes是pcap_compile传递的参数; { cout<<"\n设置过滤器失败\n"; pcap_freealldevs(alldevs);//释放设备列表 return; } //显示提示信息 cout<<"\t\tlisteningon"< //释放设备列表 pcap_freealldevs(alldevs); NodeListlink;//存储数据用链表 time_tbeg; time_tend; time(&beg); time(&end); intnum=0; while(end-beg<30)//设置捕获数据报时间为30,如果未超时则继续捕获,超时则停止捕获。 { if(pcap_next_ex(fp,&header,&pkt_data)==1) { //num++; //cout< ip_header*ih; //找到IP头的位置 ih=(ip_header*)(pkt_data+14);//14为以太网帧头长度 link.addNode(ih->saddr);//将源Ip地址加入链表 } time(&end); } cout<<"SourseIP"<<'\t'<<"packetnumbers"< link.OutPut(); } 2、运行结果 五、课程设计感想: 为期一周的课程设计,在我们小组成员的努力下很快地结束了,在此期间我们在网上找了很多的资料进行学习、消化、吸收,通过老师的指导,网上资料的帮助我们了解了如何实现”监控IP数据包流量“,有了自己的一些想法。 而且老师的认真负责让我们不再马马乎乎对待这次的课程设计。 无论做任何事情都要认真负责,对自己负责同时也对别人负责。 在老师的指导之余我还认真学习了其它课本上未曾提到过的知识,比如说网络编程方面的知识,这是我们以前所没有接触过的,虽然说这给了我们很大的一个问题但是也同时给了我们一个很好的挑战自己的机会,以前从未听过Winpcap,现在我知道了它对于捕获网络上的一些数据信息很有帮助,从而丰富了我的知识,同时也知道了如何去利用它来为自己服务,这是一个很大的进步。 在自己查找资料的同时也锻炼了我及时捕获有用知识的能力,我想这是我现在乃至以后最大的一个财富,一个人最重要的就是要懂得如何去学,学习不是被动的,而是主动的,只有这样我们才能学得到对于我们自己有帮助的东西,用VC++编程实现IP数据报流量统计,开始这对于我来说是是一个很模糊的概念,但是当我在查找了很多资料之后我不再迷茫,而是慢慢跟着我所要找的资料来靠近我所要达到的目标。 这是我们每个人所要学会的。 这次的课程设计也使我意识到了理论与实践相结合的重要作用,学习到知识应该应用到实践中。 在此次的课程设计过程中,熟悉IP包格式和加深对IP协议的理解,告诉我们要不断地学习计算机方面的知识,精益求精,如今是信息化的时代,在Internet相当发达的今天,网络编程技术也变的越来越重要,我们更应不断地提高自己的水平,在每次的程序中能够有更多的领悟。 也让自己在程序的编译和应用上可以有更大一步的提高。 要更好的学习计算机网络和其他方便的有关知识,做到精益求精。 了解IP协议的基本内容,对于掌握TCP/IP协议的主要内容和学习网络课程是十分重要的,通过本次课程设计,有助于熟悉IP包格式和加深对IP协议的理解。 学好计算机及各种汇编语言会使我们受益匪浅。 在这次课程设计中我学到了很多知识,首先,要有理论做实践的指导才会很快很好地达到自己的目的,而且勤于学习和思考是一个很好的习惯,要将知识学得很扎实才会灵活运用,这同时也是我们所必须的,一切新科技的发现都是这样的;再次,一切事情都要勤于向有经验的人取经,这样才能少走弯路;最后,要珍惜和同学一起讨论和思考的机会,自己的同学是自己最好的帮手,在讨论和争辩中往往会使自己有了很好的想法。 虽然课程设计结束了,但是我们的学习还没结束,对知识的进一步学习还需要继续。 6、参考书目: [1]刘化君: 计算机网络与通信(第二版),高等教育出版社,2012,11 [2]谢希仁: 计算机网络(第五版),北京: 电子工业出版社,2010: 122 [3]Winpcap文档: http: //www.winpcap.org/docs/docs_412/html/main
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 课程设计