版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【智能路由器】设备流量、网速统计及上下线提醒(基于netfilter编程)模块目的本文用户流量统计是统计路由器子网下每台设备的流量,下图展现了该模块具体是要实现怎样的功能内核模块依然是在netfilter的框架上进行数据捕获,分别监控每台子网设备流量信息。原理:在netfilter的pre_routing统计上传流量和上行速度以及在post_routing节点统计下载流量和下行速度,通过/proc文件系统提供给上层应用程序利用。流量拦截及统计关键代码如下/*目的:统计每个MAC的上传流量*/staticunsignedintflow_hook_out(unsignedinthooknum,structsk_buff*skb,conststructnet_device*in,conststructnet_device*out,int(*okfn)(structsk_buff*)){structethhdr*eth;structiphdr*ip;uint32_tip1,ip2;if(!skb)returnNF_ACCEPT;if(skb->protocol!=htons(0x0800))returnNF_ACCEPT;eth=eth_hdr(skb);if(!eth){printk("ethiserror!\n");returnNF_ACCEPT;}ip=ip_hdr(skb);if(!ip)returnNF_ACCEPT;if(!strnicmp(in->name,"br0",strlen("br0")))//流出流量,在pre_routing统计,统计源mac,ip{ip1=(ip->saddr)&0x00ffffff;ip2=(local_ip.IP)&0x00ffffff;if(ip1!=ip2)//subnet{returnNF_ACCEPT;}if(ip->saddr==local_ip.IP)//localreturnNF_ACCEPT;ip1=ip1&0xff000000;if(ntohl(ip1)==255)//broadcastreturnNF_ACCEPT;//mutex_lock(&visit_mutex_tx);add_maclist_data(Mac_flow_tableTX,eth->h_source,ip->saddr,ntohs(ip->tot_len));//mutex_unlock(&visit_mutex_tx);}returnNF_ACCEPT;}structnf_hook_opsflow_ops_out={//外出流量.list={NULL,NULL},.hook=flow_hook_out,.pf=PF_INET,.hooknum=NF_INET_PRE_ROUTING,//必须在NAT转发前统计.priority=NF_IP_PRI_FIRST+1//.hooknum=NF_INET_POST_ROUTING,//.priority=NF_IP_PRI_LAST-1};代码给出了上传流量的统计方法,下载流量统计代码如法炮制,不再贴出。代码思路步骤:1.代码首先剔除arp数据(提取ip包)2.过滤局域网外其他干扰设备数据、本地数据、广播数据3.添加到设备链表,这里做了一个单向链表用于存储设备mac、ip、流量、网速等信息。add_maclist_data()该函数用于向链表中添加数据设备网速计算及打印关键代码如下:intmac_func(void*data){uint32_tlen=0;uint32_tlenRx=0;while(!kthread_should_stop()){//ssleep(10);msleep(500);mutex_lock(&visit_mutex_tx);len=strlen(flow_buf)+40;if(len<1800)//上传流量{memset(flow_buf,0,len);//memset(flow_buf,0,sizeof(flow_buf));delete_macnode_by_ct(Mac_flow_tableTX);//clearofflinemacflow_format_and_clear(Mac_flow_tableTX,flow_buf);}else{free_maclist(Mac_flow_tableTX);//clearallmac,theremaybealotofinvalidmac!Mac_flow_tableTX=create_maclist();//anewlist}mutex_unlock(&visit_mutex_tx);msleep(500);mutex_lock(&visit_mutex_rx);lenRx=strlen(flow_bufRx)+40;if(lenRx<1800)//下发流量,只有ip{memset(flow_bufRx,0,lenRx);//memset(flow_bufRx,0,sizeof(flow_bufRx));delete_ipnode_by_ct(ip_flow_tableRx);ipflow_format_and_clear(ip_flow_tableRx,flow_bufRx);}else{free_iplist(ip_flow_tableRx);ip_flow_tableRx=create_iplist();}mutex_unlock(&visit_mutex_rx);}return1;}intk_threadinit(void){info_kthread=kthread_run(mac_func,NULL,"flow");if(NULL==info_kthread)return-1;return1;}intk_threadstop(void){kthread_stop(info_kthread);info_kthread=NULL;return1;}在内核创建了一个线程用于统计网速,维护设备链表。代码每秒统计一次设备网速,同时剔除一些已经下线的设备,防止输出缓冲区过满(删除整个链表然后重新建表)。将数据映射到/proc虚拟文件系统关键代码如下:staticintflow_read(char*page,char**start,off_toff,intcount,int*eof,void*data){intlen;mutex_lock(&visit_mutex_tx);len=strlen(flow_buf);if(off>len){mutex_unlock(&visit_mutex_tx);*eof=1;return0;}if(count>len-off){count=len-off;*eof=1;}memcpy(page,flow_buf,count);mutex_unlock(&visit_mutex_tx);*start=page+off;//*eof=1;//returnoff+count;returncount;}staticintflow_readRx(char*page,char**start,off_toff,intcount,int*eof,void*data){intlen;//printk("flow_readRx\n");mutex_lock(&visit_mutex_rx);len=strlen(flow_bufRx);if(off>len){mutex_unlock(&visit_mutex_rx);*eof=1;return0;}if(count>len-off){count=len-off;*eof=1;}memcpy(page,flow_bufRx,count);mutex_unlock(&visit_mutex_rx);*start=page+off;//*eof=1;//returnoff+count;returncount;}intinit_flowproc_moudle(void){intret=0;flow_root=proc_mkdir("flow_m",NULL);if(flow_root==NULL){printk("createdirflow_rootfail\n");return-1;}//Txproc_entry=create_proc_entry("flowwatchTx",0444,flow_root);if(proc_entry==NULL){printk("fortune:couldn'tcreateprocentry\n");ret=-2;returnret;}proc_entry->read_proc=flow_read;//Rxproc_entryRx=create_proc_entry("flowwatchRx",0444,flow_root);if(proc_entryRx==NULL){printk("fortune:couldn'tcreateprocentry\n");ret=-3;returnret;}proc_entryRx->read_proc=flow_readRx;returnret;}voidexit_flowproc_moudle(void){remove_proc_entry("flowwatchTx",flow_root);//删除文件remove_proc_entry("flowwatchRx",flow_root);remove_proc_entry("flow_m",NULL);//删除目录}代码在/proc下建立/flow_m文件夹,同时在/proc/flow_m下建立flowwatchTx和flowwatchRx文件,对这两个文件分别进行读取可以得到设备流量信息。应用层模块应用层模块对设备上传及下载流量进行了整合,同时具备设备上下线提醒功能。主要代码如下:typedefstd::list<Flow_Info>F_list;F_listFlow_table;/*name:cat_user_flowdescription:cat/proc/flow_m/flowwatchTxcat/proc/flow_m/flowwatchRx*/intcat_user_flow(HASH_TABLE*pMACtable){Flow_Infotemflow;charup_buf[80];chardown_buf[80];FILE*up_flow;FILE*down_flow;charflag=0;time_tcurrenttime;up_flow=fopen("flowwatchTx","r");down_flow=fopen("flowwatchRx","r");if(up_flow==NULL){std::cout<<"openfilefail!"<<std::endl;return-1;}if(down_flow==NULL){std::cout<<"openfilefail!"<<std::endl;return-1;}//readfirstlineanddropoutif(NULL==fgets(up_buf,sizeof(up_buf),up_flow)){//errororendoffilestd::cout<<"readfilefailed!"<<std::endl;fclose(up_flow);fclose(down_flow);return-2;}if(NULL==fgets(down_buf,sizeof(down_buf),down_flow)){//errororendoffilestd::cout<<"readfilefailed!"<<std::endl;fclose(up_flow);fclose(down_flow);return-2;}currenttime=time((time_t*)NULL);std::cout<<"currenttime:"<<currenttime<<std::endl;for(;;)//Tx{memset(up_buf,0,sizeof(up_buf));if(NULL==fgets(up_buf,sizeof(up_buf),up_flow))//errororendoffilebreak;memset(&temflow,0,sizeof(temflow));sscanf(up_buf,"%s%s%s%s",temflow.mac,temflow.ip,temflow.upload,temflow.totalup);if(strncmp(temflow.ip,"",strlen(""))==0)continue;//updatelistfor(F_list::iteratorf_list_iter=Flow_table.begin();f_list_iter!=Flow_table.end();f_list_iter++){if(0==strncmp((*f_list_iter).mac,temflow.mac,strlen(temflow.mac))){memcpy((*f_list_iter).ip,temflow.ip,strlen(temflow.ip)+1);//addadditionalanullcharactermemcpy((*f_list_iter).upload,temflow.upload,strlen(temflow.upload)+1);memcpy((*f_list_iter).totalup,temflow.totalup,strlen(temflow.totalup)+1);(*f_list_iter).loop=0;(*f_list_iter).alive=currenttime-(*f_list_iter).s_time;flag=1;break;}}if(!flag)//newonlinedevice{charbuf[12];NODE*MACdataNode=NULL;ElemTypeval=0;memset(buf,0,sizeof(buf));memcpy(buf,temflow.mac,8);//getlocaltimetemflow.s_time=time((time_t*)NULL);temflow.NewOnlineD=1;//onlineaction//std::cout<<"*-*-*-*-*-*-*-*"<<std::endl;val=(ElemType)(MAC_str_to10)(buf);MACdataNode=find_data_in_hash(pMACtable,val);if(MACdataNode==NULL){std::cout<<"findnodata!\n"<<std::endl;//unfound!memcpy(temflow.dev_name,"unknown",strlen("unknown"));memcpy(temflow.dev_type,"unknown",strlen("unknown"));}else//findsuccess{memcpy(temflow.dev_name,((Code_to_Str_t*)MACdataNode->data)->remark,strlen(((Code_to_Str_t*)MACdataNode->data)->remark)+1);memcpy(low.dev_type,((Code_to_Str_t*)MACdataNode->data)->type,strlen(((Code_to_Str_t*)MACdataNode->data)->type)+1);}Flow_table.push_back(temflow);}flag=0;}if(Flow_table.empty()){std::cout<<"Flow_tableisempty"<<std::endl;fclose(up_flow);fclose(down_flow);charbuf[4];memset(buf,0,sizeof(buf));write_info(buf,dev_info_file,"w+");return-3;}while(1)//combineTxwithRx{memset(down_buf,0,sizeof(down_buf));if(NULL==fgets(down_buf,sizeof(down_buf),down_flow))//errororendoffilebreak;memset(&temflow,0,sizeof(temflow));sscanf(down_buf,"%s%s%s",temflow.ip,temflow.download,temflow.totaldown);for(F_list::iteratorf_list_iter=Flow_table.begin();f_list_iter!=Flow_table.end();f_list_iter++)//compareip{if(0==strncmp((*f_list_iter).ip,temflow.ip,strlen(temflow.ip))){memcpy((*f_list_iter).download,temflow.download,strlen(temflow.download)+1);memcpy((*f_list_iter).totaldown,temflow.totaldown,strlen(temflow.totaldown)+1);(*f_list_iter).looprx=0;break;//thisipinsertok!}//ifnotfind,ignoreit!}}for(F_list::iteratorf_list_iter=Flow_table.begin();f_list_iter!=Flow_table.end();f_list_iter++){(*f_list_iter).loop=(*f_list_iter).loop+1;(*f_list_iter).looprx=(*f_list_iter).looprx+1;}fclose(up_flow);fclose(down_flow);/*for(F_list::iteratorf_list_iter=Flow_table.begin();f_list_iter!=Flow_table.end();f_list_iter++){std::cout<<"****************"<<std::endl;std::cout<<(*f_list_iter).mac<<""<<(*f_list_iter).ip<<""<<(*f_list_iter).totalup<<std::endl;}*/return0;}/*name:description:noticeothersomeinformation*/intwrite_dev_info(pid_tpid){charbuf[256];memset(buf,0,sizeof(buf));write_info(buf,dev_info_file,"w+");//cleardev_info_filefor(F_list::iteratorf_list_iter=Flow_table.begin();f_list_iter!=Flow_table.end();f_list_iter++){memset(buf,0,sizeof(buf));sprintf(buf,"%d,%s,%s,%s,%s,%s,%s,%s,%s,%ld,%d\n",Flow_table.size(),(*f_list_iter).mac,(*f_list_iter).ip,(*f_list_iter).upload,(*f_list_iter).download,(*f_list_iter).totalup,(*f_list_iter).totaldown,(*f_list_iter).dev_name,(*f_list_iter).dev_type,(*f_list_iter).alive,(*f_list_iter).loop);printf("\n%s\n",buf);write_info(buf,dev_info_file,"a+");if(((*f_list_iter).loop>5)&&((*f_list_iter).looprx>5))//offlinecheckandnotice{memset(buf,0,sizeof(buf));sprintf(buf,"%s,%s,%s\n",(*f_list_iter).mac,(*f_list_iter).dev_type,(*f_list_iter).dev_name);printf("*******\nofflinenotice:%s,%s,%s\n",(*f_list_iter).mac,(*f_list_iter).dev_type,(*f_list_iter).dev_na
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 网红营销策略研究
- 修理厂协议书(15篇)
- 代理合同 (集合15篇)
- 2025-2030智慧医疗健康数据平台建设市场价值投资市场规模评估分析规划研究报告
- 2025-2030智慧农业气象服务行业市场应用潜力与发展规划
- 2025-2030智慧农业无人机监测技术评估病虫害防治评估服务模式规划研究
- 2025-2030智慧农业大数据行业市场发展机遇与产业投资规划研究报告
- 供水设施维修服务协议书合同
- 2026年中药抗心衰拔高提升卷及答案(专升本版)
- 2026年控制系统中的区域性优化研究
- 2025年10月自考13658工业设计史论试题及答案
- 消防安全标准化建设协议书
- 白居易长恨歌
- 如何进行有效的授权
- 年产10万吨液态奶生产厂的设计-本科生毕业论文(设计)
- JJG 808-2014标准测力杠杆
- GB/T 17614.1-2015工业过程控制系统用变送器第1部分:性能评定方法
- 《大学信息技术》教学课件-大学信息技术第一章
- 肝性脑病的疾病查房课件
- 超声科晋升副高(正高)职称病例分析专题报告(超声诊断胎儿隔离肺病例分析)
- 参观监狱心得体会(10篇)精选
评论
0/150
提交评论