当前位置:文档之家› 监控IP包流量-代码

监控IP包流量-代码

#include<iostream.h>#include<iomanip.h>#include<fstream.h>#include<stdlib.h>#include<stdio.h>#include<conio.h>#include<pcap.h>//等同于点击"Project-Setting-link"打开Object/library modules 编辑框后加入lib文件#pragma comment(lib,"Wpcap.lib")#pragma comment(lib,"Ws2_32.lib")//IP结点类,存放IP包的源IP地址和其发送的数据包个数class IPNode{private:long m_lIPAddress; //IP地址long m_lCount; //发送数据包个数public:IPNode * pNext; //指向下一个IP结点//构造函数IPNode(long sourceIP){m_lIPAddress=sourceIP;m_lCount=1; //初始化数据包个数为1}//数据包个数加1void addCount(){m_lCount++;}//返回数据包个数long getCount(){return m_lCount;}//返回IP地址long getIPAddress(){return m_lIPAddress;}};//结点链表class Nodelist{IPNode * pHead; //链表头IPNode * pTail; //链表尾public:Nodelist(){pHead=pTail=NULL; //初始化链表}~Nodelist(){if(pHead!=NULL){IPNode * pTemp=pHead;pHead=pHead->pNext;delete pTemp;}}//Ip结点加入链表void addNode(long sourceIP){if(pHead==NULL) //当链表为空时{// cout<<"the first node"<<endl; //测试用pTail=new IPNode(sourceIP);pHead=pTail;pTail->pNext=NULL;}else{for(IPNode * pTemp=pHead;pTemp;pTemp=pTemp->pNext){//如果链表中存在此IP,发送数据包个数加1if(pTemp->getIPAddress()==sourceIP){// cout<<"same sourceip "<<endl; //测试用pTemp->addCount();break;}}if(pTemp==NULL){// cout<<"a new sourceip"<<endl; //测试用pTail->pNext=new IPNode(sourceIP);pTail=pTail->pNext;pTail->pNext=NULL;}}}//输出IP结点,即IP地址和其发送的IP包个数void OutPut(){IPNode * pTemp=pHead;ofstream fout("login.txt",ios::app);fout<<"SourceIP"<<"\tpacket numbers"<<endl;while(pTemp!=NULL){long lTemp=pTemp->getIPAddress();fout<<inet_ntoa(*(in_addr*)&(lTemp))<<'\t';fout<<pTemp->getCount()<<endl;cout<<inet_ntoa(*(in_addr*)&(lTemp))<<'\t';cout<<pTemp->getCount()<<endl;pTemp=pTemp->pNext;fout<<inet_ntoa(*(in_addr*)&(lTemp))<<'\t';fout<<pTemp->getCount()<<endl;}return;}};//IP部结构struct ip_header{unsigned char ver_ihl; //版本号(4位)+头部长度(4位)unsigned char tos; //服务类型unsigned short tlen; //总长度unsigned short identification; //标识unsigned short flags_fo; //标志+片偏移unsigned char ttl; //生存时间unsigned char proto; //协议unsigned short crc; //校验和DWORD saddr; //源地址DWORD daddr; //目的地址unsigned int op_pad; //选项+填充};void main(int argc,char * argv[]){pcap_if_t * alldevs,* d; //网络设备结构pcap_t * fp; //网卡描述符char errbuf[PCAP_ERRBUF_SIZE]; //错误信息unsigned int netmask; //子网掩码char packet_filter[]="ip"; //过滤,选择IP协议struct bpf_program fcode;struct pcap_pkthdr * header;const unsigned char * pkt_data;//获取网络设备列表if(pcap_findalldevs(&alldevs,errbuf)==-1)/*找出所有网络设备,设备信息存储在alldevs中,-1表示失败,其将具体出错信息写在errbuf中0就表示pcap_findalldevs调用成功*/{cout<<"Error information"<<errbuf<<endl;exit(1);}d=alldevs;for(unsigned int i=1;d!=NULL;d=d->next){cout<<"第"<<i<<"#网络接口(网卡):"<<d->name<<endl;i++;}cout<<"共"<<i-1<<"个网络接口(网卡)"<<endl;/*在Windows2000平台上,基于winpcap一般至少有两网卡,第一通常是Winpcap虚拟,第二通常是真实的*/cout<<"请选择一个网络接口(1~"<<i-1<<")";unsigned int k=1;cin>>k;cout<<endl;d=alldevs;for(i=1;i<k;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<<"Unable to Open the device";//释放设备列表pcap_freealldevs(alldevs);exit(1);}//获取子网掩码if(d->addresses!=NULL)netmask=((struct sockaddr_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\tlistening on "<<d->description<<"..."<<endl<<"捕获时间为30秒,请等待……"<<endl;//释放设备列表pcap_freealldevs(alldevs);Nodelist link; //存储数据用链表time_t beg;time_t end;time(&beg);time(&end);int num=0;while(end-beg<30) //设置捕获数据报时间为30,如果未超时则继续捕获,超时则停止捕获。

相关主题