最近老师让写一个流量监控程序,用到了libpcap编程。虽然很简单,但是前期也走了一些弯路。最初是直接从别人博客里面copy的代码,然后运行时就是结果就是不正确。本以为是系统问题,我又装了个双系统。。。
现在我把自己的代码分享出来吧,这些是我自己运行成功的,代码很简单,只是希望能给新人一些借鉴。首先:我们先得到我们的设备名称,因为之后我们需要根据名称指针来打开我们的设备,得到名称指针的方式如下:
    /*get our device name*/char *dev,errbuf[PCAP_ERRBUF_SIZE];dev = pcap_lookupdev(errbuf);printf("Device: %s\n",dev); /*print our device name*/
如果我们实现已经知道设备名称了,就不用在通过这个方式得到了。得到名称之后,我们根据名称指针打开我们的设备,这时候我们需要用到的函数是:
/*pcap_t *pcap_open_dev(char*device,int snaplen,int promisc,int to_ms,char*errbuf);*/
device是设备名称,snaplen是pcap将捕获的最大字节数,promisc是混合模式,to_ms是读取时的超时值,单位是毫秒,为0则一直嗅探直到错误发生,errbuf是出错之后信息的储存。
函数的返回值是一个句柄,在下面我们将会使用的到。
    /*open device and sniff*pcap_t *pcap_open_dev(char*device,int snaplen,int promisc,int to_ms,char*errbuf);**/pcap_t * open_dev = pcap_open_live(dev,65535,1,0,errbuf);if(!open_dev){printf("open device failed: %s",errbuf);}
打开设备之后,我们设置过滤条件,过滤掉我们不想要的包。设置过滤涉及到两个函数:
int pcap_compile(pcap_t *p,struct bpf_program *fp,char *str,int optimize,bpf_u_int32 netmask)
int pcap_setfilter(pcap_t *p, struct bpf_program *fp)pcap_compile的第一个参数就是刚刚我们打开设备的返回值,后面是我们存储被编译的过滤器版本的地址的引用。
str是我们的过滤条件。比如"tcp port 21"是指只抓取来自tcp协议,并且端口是21的包。optimize是一个定义表达式是否被优化的整形量,netmask是表示网络掩码。
pcap_setfilter则是用的都是pcap_compile里面已经出现过的函数。
好,现在我们开始设置过滤:
    struct bpf_program filter;char filter_exp[] = "port 80";/*filter expressiong*/bpf_u_int32 mask;           /*net mask*/pcap_compile(open_dev,&filter,filter_exp,0,mask);pcap_setfilter(open_dev,&filter);
接下来我们就开始循环捕获了,在这里我用到的函数是pcap_loop,下面是它的函数原型:
int pcap_loop(pcap_t *p,int cnt,pcap_hander callback,u_char *user)
其中:pcap_t还是我们的句柄,cnt是表示我们想要捕获多少个数据包,如果值为-1,则表示一直捕获,直到出错位置。pcap_hander则是我们回调函数的名称,user是我们想发送给回调函数的参数,如果没有,那么设置成NULL;
    pthread_attr_init(&attr);pthread_create(&tid,&attr,runner,NULL);//这两句是创建线程用的,为了每秒都显示流量情况。pcap_loop(open_dev,-1,got_packet,NULL);pcap_close(open_dev);
got_packet()是用户自定义的函数,可以根据自己的需要定义。下面是我定义的:
void got_packet(u_char *argv,const struct pcap_pkthdr *header,const u_char *packet){int len2 = (int)header->caplen;Ethernet *ethernet = (Ethernet *)(packet);Ip_header *ip = (Ip_header *)(packet + sizeof(Ethernet));if(ip->proto==(u_char)6){   //6是tcp协议tcp_count += len2;}else if(ip->proto == (u_char)17){ //17是代表使用的udp协议udp_count += len2;}count +=len2;  //count是为了统计总流量写的,在函数外面声明的,同理udp_count,tcp_count
}

Ethernet ,Ip_header是定义的结构体,这是为了进一步解析抓到的数据包用的。下面是结构体原型。(其中有些是直接网上copy的)

/**以太网帧的首部*/
typedef struct ethernet{u_char host1[6];u_char host2[6];u_short type;
}Ethernet;
/* IPv4 首部 */
typedef struct ip_header{u_char  ver_ihl;        // 版本 (4 bits) + 首部长度 (4 bits)u_char  tos;            // 服务类型(Type of service) u_short tlen;           // 总长(Total length) u_short identification; // 标识(Identification)u_short flags_fo;       // 标志位(Flags) (3 bits) + 段偏移量(Fragment offset) (13 bits)u_char  ttl;            // 存活时间(Time to live)u_char  proto;          // 协议(Protocol)u_short crc;            // 首部校验和(Header checksum)int  saddr;      // 源地址(Source address)int  daddr;      // 目的地址(Destination address)
}Ip_header;

当然,如果你想解析到更多的数据,那么你可能还需要另tcp_heaer,和udp_header。如下:

/* UDP 首部*/
typedef struct udp_header{u_short sport;          // 源端口(Source port)u_short dport;          // 目的端口(Destination port)u_short len;            // UDP数据包长度(Datagram length),the minimum is 8u_short crc;            // 校验和(Checksum)
}Udp_header;/*TCP首部*/
typedef struct tcp_header{u_short sport;//源端口u_short dPort;//目的端口unsigned int SequNum;//序号unsigned int AckNum;//确认号u_short sHeaderLenAndFlag;//数据偏移+保留+URG+ACK+RST+SYN+FINu_short WinSize;//窗口大小u_short CheckSum;//检验和u_short urgentPointer;//紧急指针
}Tcp_header;

这里面的代码是流量监控的大部分,完整的代码附件可以在这里下载,不需要积分。
http://download.csdn.net/detail/qq_27856623/9713803
编译的时候需要
gcc my.c -lpcap -lpthread
运行的时候需要sudo ./a.out

最后感谢http://blog.chinaunix.net/uid-21556133-id-120228.html这个博客,因为我大多的内容都是从这里学到的。

libpcap流量统计相关推荐

  1. linux c libpcap统计流量,libpcap流量统计

    最近老师让写一个流量监控程序,用到了libpcap编程.虽然很简单,但是前期也走了一些弯路.最初是直接从别人博客里面copy的代码,然后运行时就是结果就是不正确.本以为是系统问题,我又装了个双系统.. ...

  2. linux 进程流量统计,Linux进程网络流量统计方法及实现

    1 前言 在某些应用安全场景须要结合进程级网络链接.流入流出流量等数据直接分析出进程的异常.例如,在内网主机上是否存在持续恶意外传敏感数据的现象.在网络监控时发现服务器大量带宽被占用但不清楚由系统具体 ...

  3. Linux进程网络流量统计方法及实现

    1 前言 在某些应用安全场景需要结合进程级网络连接.流入流出流量等数据直接分析出进程的异常.例如,在内网主机上是否存在持续恶意外传敏感数据的现象.在网络监控时发现服务器大量带宽被占用但不清楚由系统具体 ...

  4. ArcGIS水文分析实战教程(9)雨量计算与流量统计

    ArcGIS水文分析实战教程(9)雨量计算与流量统计 本章导读:降水是水文循环中重要的一环,降水包括雨.雪.雾.露.雹等,本章介绍的是降雨的环节.通过雨量站与插值的方式,实现雨量的空间分布就算,为水文 ...

  5. linux 端口 流量统计,Linux下如何对端口流量进行统计

    在不修改源代码的情况下对程序暴露端口流量进行监控统计,可以利用Linux中自带的Iptable添加简单的规则让其起到端口流量统计的作用.但是需要注意的是在服务器重启.Iptable服务重启的时候统计数 ...

  6. 几个常用的流量统计工具比较

    最近试用了几个流量统计工具,粗略的比较了一下,不当之处望指正: 163流量统计 :(没全面测试) 优点:几乎没有看到广告,页面干净 转载于:https://blog.51cto.com/wingate ...

  7. Android流量统计TrafficStats类

    对于Android流量统计来说在2.2版中新加入了TrafficStats类可以轻松获取,其实本身TrafficStats类也是读取Linux提供的文件对象系统类型的文本进行解析. android.n ...

  8. php 开源 流量统计,5款开源的PHP网站流量统计应用程序

    下面是5款开源的PHP网站流量统计应用程序. piwik Piwik 是一套基于Php+MySQL技术构建的开源网站访问统计系统,前身是phpMyVisites.Piwik可以给你详细的统计信息,比如 ...

  9. 黄聪:PHP网站流量统计开源程序大全

    phpMyVisites phpMyVisites是一个网站流量统计系统,它能够提供非常详细的统计报告和高级图形报表.phpMyVisites不是一个Apache log分析工具,它建有自己的log. ...

最新文章

  1. 链表问题19——合并两个有序的单链表
  2. NLP模型超越人类水平?你可能碰到了大忽悠
  3. python控制台颜色输出以及字符串格式化输出
  4. AJAX技术入门 第五节 Javascript高级知识
  5. JS中setTimeout()的使用方法具体解释
  6. python编写下载器可暂停_python 并发下载器实现方法示例
  7. 新一代搜索引擎项目 ZeroSearch 设计探索
  8. Intellij Idea 多模块Maven工程中模块之间无法相互引用问题
  9. java----DBUtils知识点补充
  10. codechef Polo the Penguin and the Tree
  11. 【毕业设计】JSP数据库连接池的研究与实现(源代码+论文)
  12. HDU2073 无限的路【数学】
  13. 团队作业—第二阶段08
  14. 易筋SpringBoot 2.1 | 第十八篇:SpringBoot的JDBC异常
  15. 删除OSX中第三方的「偏好设置」程序(.prefPane)
  16. 如何在文件夹中打开DOS命令窗口
  17. 4. HTML 视频
  18. 【亲自动手试验过的】硬盘免光驱安装Fedora5
  19. Linux mmap 详解
  20. 数字化转型 — 新能源汽车 — 生产制造流程 — Overview

热门文章

  1. C#通过TCP实现 HL7医疗系统传输的协议,并使用MLLP协议发送HL7消息
  2. 5G uRLLC技术及其与TSN的融合
  3. 写给英语和数学都不怎么好的游戏开发爱好者
  4. 常用的MATLAB网络资源
  5. 创意卡通风格会员日海报
  6. document.getElementById与getElementsByName的区别(注意后者多个S)
  7. 《电路/电路原理》—戴维宁(南)定理实战演练
  8. 千克 磅 磅 千克 的转换
  9. 贪吃蛇-EasyX版
  10. Oracle 不能删除存储过程的处理