网络程序设计IP数据包流量统计_第1页
网络程序设计IP数据包流量统计_第2页
网络程序设计IP数据包流量统计_第3页
网络程序设计IP数据包流量统计_第4页
网络程序设计IP数据包流量统计_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、一、 题目及要求(一)题目:IP数据包流量统计(二)要求:编制程序,监控网络,捕获一段时间内网络上的IP数据包,按IP数据包的源地址统计出该源地址在该时间段内发出的IP包的个数,将其写入日志文件中或用图形表示出来(建议用图形表示出统计结果)。用命令行运行:IPSta time logfile;其中IPSta是程序名,time是设定的统计时间间隔,logfil表示统计结果写入的日志文件名(若用图形表示统计结果则可以不选这个参数)。或在此基础上用图形化界面实现上述功能。二、 系统概要设计(一) 流量统计主要功能模块图取得网络适配器列表选择要监控的网络适配器编译并设置过滤器将网络适配器设置为统计模式

2、开始主循环调用回调函数显示网络流量统计图中取得网络适配器列表主要是得到网卡的相关信息,即网卡的个数、连接情况等,选择要监听的网络适配器就是要用户选择网卡,编译并设置过滤器是为了只捕获网络数据流的某些数据,将网络适配器设置为统计模式就是接受所有经过网卡的数据包,包括不是发给本机的数据包,接下来的任务就是开始主循环调用回调函数来显示网络流量了。(二) 程序流程图选取Ethermet网卡获取网卡列表打开网卡(混杂模式)编译设置过滤器捕获IP包将IP 包源地址加入链表NY输出链表内容超时否?结束开始图中获取网卡列表是为了得到网卡的相关信息,以便于用户进行选择,选取Ethermet网卡是用户所选择的网卡

3、类型,编译设置过滤器是为了编译并设置过滤器是为了只捕获网络数据流的某些数据,打开网卡既将网卡设置为混杂(统计)模式是为了接受所有经过网卡的数据包,包括不是发给本机的数据包,开始主循环以是否超时为判断条件,循环体内主要有捕获IP 数据包、将IP包的源地址加入链表、条件判断,循环结束后输出链表内容,程序至此结束。三、系统详细设计1. 取得网络适配器列表/取得网络适配器列表步骤中,alldevs是pcap_if_it指针,指向链表头,errbuf是char类型数组,存储错误信息3。pcap_findalldevs(&alldevs,errbuf);cout<<”网络适配器列表:”

4、<<n;for(d=alldevs;d;d=d->next) cout<<+i<<":"<<d->name;if (d->description) cout<<""<<d->description; else cout<<"No description available!"<<'n' 2. 指定要监听的网络适配器并打开cout<<”输入要监听的网络适配器号:”<<I;cin&

5、gt;>inum;for(d=alldevs,i=0;i<inum-1;d=d->next,i+);fp=pcap_open_live(d->name,65536,1,1000,errbuf); 3. 编译并设置过滤器/编译过滤器,fp指向打开的网络适配器,fcode为编译完成后的过滤器存储地址,“tcp“给出了过滤条件,下一个参数表示是否被优化(0为false,1为true),最后一个参数给出了子网掩码。pcap_compile(fp,&fcode,”tcp”,1,netmask)pcap_setfilter(fp,&fcode) 4.设置网络适配器为

6、统计模式 if(pcap_setmode(fp,MODE_STAT)<0) cout<<”n设置网络适配器模式错误!n”; pcap_close(fp); 5.开始主循环,调用回调函数显示网络流量统计信息/pcap_loop由Winpcap库定义,对每个采集来的数据包都用ProcessPacket函数进行处理,fp指向打开的网络适配器4pcap_loop(fp,0,dispatcher_handler,(PUCHAR)&st_ts);pcap_close(fp); 6.回调函数的实现/对于捕获到的每一个数据包应用此回调函数void dispatcher_handler

7、(u_char *state,const struct pcap_pkthdr *header,const u_char *pkt_data) struct timeval *old_ts=(struct timeval *)state; u_int delay; LARGE_INTEGER Bps,Pps; struct tm *ltime; char timestr16; time_t local_tv_sec;/计算距上一个数据包的时间延迟,以ms为单位/这个值是从与一个数据包相关的时间戳中截获的delay=(header->ts.tv_sec-old_ts->tv_sec)

8、*1000000-old_ts->tv_usec+header->ts.tv_usec;/获得每秒的比特数 Bps.QuadPart=(*(LONGLONG*)(pkt_data+8)*8*1000000)/(delay); /获得每秒的数据包数Pps.QuadPart=(*(LONGLONG*)(pkt_data)*1000000)/(delay);/将时间戳转变位可读的标准格式ltime=localtime(&header->ts.tv_sec);strftime(timestr,sizeof timestr,"%H:%M:%S",ltime)

9、;/Print timestampprintf("%s",timestr);/Print the samplesprintf("BPS=%I64u",Bps.QuadPart);printf("PPS=%I64un",Pps.QuadPart);/store current timestampold_ts->tv_sec=header->ts.tv_sec;old_ts->tv_usec=header->ts.tv_usec;运行结果:四、课程设计总结这次的课程设计也使我意识到了理论与实践相结合的重要作用,学习

10、到知识应该应用到实践中。在此次的课程设计过程中,熟悉IP包格式和加深对IP协议的理解,告诉我们要不断地学习网络方面的知识,精益求精,我们应不断地提高自己的水平,在每次的编程中能够有所领悟,让自己在程序的编译和应用上可以有更大一步的提高。更好的学习计算机网络和其他方便的有关知识,做到精益求精。指导教师评语:成绩: 指导教师: 年 月 日附录一:程序代码/ NodeList.h: interface for the CNodeList class./#if !defined(AFX_NODELIST_H_9781C411_82DF_47F7_A449_3054B18A550E_INCLUDED_)

11、#define AFX_NODELIST_H_9781C411_82DF_47F7_A449_3054B18A550E_INCLUDED_#if _MSC_VER > 1000#pragma once#endif / _MSC_VER > 1000#include<iostream>#include<fstream>#include<iomanip>#include<winsock2.h>#include "IPNode.h"using namespace std;/ 结点链表类CNodeListclass CNo

12、deList private:CIPNode * pHead;/ 链表头CIPNode * pTail;/ 链表尾public:/ Default constructorCNodeList();/ Default destructorvirtual CNodeList();/ 把新捕获的IP数据包加入链表void addNode(unsigned long, unsigned long, unsigned char);/ 输出链表ostream& print(ostream&);#endif / !defined(AFX_NODELIST_H_9781C411_82DF_47F

13、7_A449_3054B18A550E_INCLUDED_)/ IPNode.h: interface for the CIPNode class./#if !defined(AFX_IPNODE_H_1366A568_424A_4BDF_8E76_9AF5BA10D449_INCLUDED_)#define AFX_IPNODE_H_1366A568_424A_4BDF_8E76_9AF5BA10D449_INCLUDED_#if _MSC_VER > 1000#pragma once#endif / _MSC_VER > 1000/ 结点类CIPNodeclass CIPNod

14、e private:unsigned long m_dwSourIPAddr;/ 源IP地址unsigned long m_dwDestIPAddr;/ 目的IP地址unsigned char m_chProtocol;/ IP包的协议类型unsigned long m_dwCouter;/ 数据包的数量public:CIPNode * pNext;/ 指向下一类IP结点CIPNode();virtual CIPNode();/ 构造函数CIPNode(unsigned long, unsigned long, unsigned char);/ 增加数据包的数量void addCount();

15、/ 取得数据包数量unsigned long getCount();/ 取得源IP地址unsigned long getSourIPAddr();/ 取得目的IP地址unsigned long getDestIPAddr();/ 取得协议类型unsigned char getProtocol();/ 取得协议名称(TCP,UDP,ICMP.)char * getProtocol_String();#endif / !defined(AFX_IPNODE_H_1366A568_424A_4BDF_8E76_9AF5BA10D449_INCLUDED_)#include<iostream&g

16、t;#include<fstream>#include<winsock2.h>#include<ws2tcpip.h>#include<stdio.h>#include<stdlib.h>#include<math.h>#include<time.h>using namespace std;#include "IPNode.h"#include "NodeList.h"#pragma comment(lib, "Ws2_32.lib")/ 定义IP头部

17、typedef struct IPHeaderunsigned charVersion_HeaderLength;/ 版本(4位)+首部长度(4位)unsigned char TypeOfService;/ 服务类型unsigned short TotalLength;/ 总长度unsigned short Identification;/ 标识unsigned short Flags_FragmentOffset;/ 标志(3位)+分片偏移(13位)unsigned char TimeToLive;/ 生存时间unsigned char Protocal;/ 协议unsigned short

18、 HeaderChecksum;/ 首部校验和unsigned long SourceAddress;/ 源IP地址unsigned long DestAddress;/ 目的IP地址IPHEADER;#include "IPMonitor.h"#define BURRER_SIZE 65535void main(int argc,char * argv)/ 判断输入的命令行格式是否正确if (argc != 2)cout << "请按以下格式输入命令行: IPMonitor duration_time"<< endl <&

19、lt; " 其中duration_time为监控时间, 单位为秒"<<endl;return;WSADATA wsData;/ 初始化Winsock DLLif (WSAStartup(MAKEWORD(2,2),&wsData) != 0)cout << "WSAstartup failed!" << endl;return;/ 创建Raw SocketSOCKET sock;if ( (sock = WSASocket(AF_INET, SOCK_RAW, IPPROTO_IP, NULL, 0, WSA_

20、FLAG_OVERLAPPED) = INVALID_SOCKET )cout << "Create socket failed!" << endl;return;/ 设置IP头操作选项,表示用户可以亲自对IP头进行处理BOOL bFlag = TRUE;if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&bFlag, sizeof(bFlag) = SOCKET_ERROR)cout << "Setsockopt failed!" << en

21、dl;return;/ 获取本地主机名char pHostName128;if (gethostname(pHostName, 100) = SOCKET_ERROR)cout << "Gethostname failed!" << endl;return;/ 通过本地主机名获取本地IP地址hostent * pHostIP;if(pHostIP = gethostbyname(pHostName) = NULL)cout<<"Gethostbyname failed!"<<endl;return;/ 填充

22、sockaddr_in结构sockaddr_in addr_in;addr_in.sin_addr = *(in_addr *)pHostIP->h_addr_list0; / 设定IP地址addr_in.sin_family = AF_INET;/ 设定地址类型addr_in.sin_port = htons(8000);/ 设定端口/ 把原始套接字绑定到本机地址上if(bind(sock,(PSOCKADDR)&addr_in,sizeof(addr_in) = SOCKET_ERROR)cout << "Bind failed!" <&

23、lt; endl;return;/ 把网卡设置为混杂模式,以便接收所有的IP包#define IO_RCVALL _WSAIOW(IOC_VENDOR,1)unsigned long pBufferLen10;unsigned long dwBufferInLen = 1;unsigned long dwBytesReturned = 0;if (WSAIoctl(sock, IO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen), &pBufferLen,sizeof(pBufferLen), &dwBytesReturned

24、, NULL, NULL) = SOCKET_ERROR)cout<<"Ioctlsocket failed!"<<endl;return;/ 把socket设置为非阻塞模式unsigned long dwTemp = 1; ioctlsocket(sock, FIONBIO, &dwTemp);/ 设置接收缓冲区char pBufferBURRER_SIZE;/ 定义存放IP数据包的链表CNodeList IpList;double dwDuration = atof(argv1);/ 输入参数为捕获时间time_t beg;time_t end;time(&beg);/ 获得当前系统时间/ 输出本地IP地址cout << endl;cout << "本机IP:" << inet_ntoa(*(in_a

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论