linux c libpcap统计流量,libpcap流量统计
最近老师让写一个流量监控程序,用到了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 8
u_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+FIN
u_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
linux c libpcap统计流量,libpcap流量统计相关推荐
- Linux中一行命令查看网卡流量、统计网络流量的各种实现方法
Linux中一行命令查看网卡流量.统计网络流量的各种实现方法. 方法一.nload工具 源码包路径: wget http://heanet.dl.sourceforge.net/project/nlo ...
- 演示:使用Sniffer统计与分析流量
演示:使用Sniffer统计与分析流量 Sniffer是统计与分析网络数据流量的一个很好的选择.因为Sniffer的"混杂"模式会接收到同一个物理网络内的所有数据帧,无论是广播帧还 ...
- Scala初级实践——统计手机耗费流量(1)
Scala初级实践--统计手机耗费流量(1) [实验描述] 本实验主要使用Scala语言来实现对手机流量的计算.在该实验中,共有四个需求: 1)统计每一个手机号耗费的总上行流量.下行流量.总流量 2) ...
- 统计每一个用户(手机号)所耗费的上行流量,下行流量,总流量
假设从数据运营商可以获取用户(通过手机号来区分)的上网信息: 1363157985066 13726230503 00-FD-07-A4-72-B8:CMCC 120.196.100.82 i02.c ...
- 流量多少 程序统计(已发电脑报)
目标手机软件 流量多少 程序统计 模仿功能:流量统计 模仿对象:手机QQ 2008 模仿进度:第二期 开发平台:Java平台 3G来了,可移动.联通收费还是按流量计算,像手机QQ 2008这种需要网络 ...
- android 流量统计换算,什么是流量?如何计算流量?流量的单位如何换算
什么是流量?如何计算流量?流量的单位如何换算 上网流量通常用"位"(bit),"字节"(Byte),KB,MB,GB,TB等来表示.它是计算机信息技术用于计量存 ...
- linux查看某个端口的流量_linux流量查看工具汇总
时时了解服务器的流量占用情况,是运维人员要掌握的一个入门技能.不过查看流量的情况的手段很多,工具也很多.如ifconfig脚本实现法.cacti.pnp4nagios.mrtg绘图查看以及iptraf ...
- 局域网网络流量监控_【干货】Linux网络安全运维:网络流量监控与分析工具Ntop和Ntopng...
本文授权转载自微信公众号:计算机与网络安全,转载请联系授权.对于单台服务器网络故障的排查,iftop工具可以轻松实现,但是在监控一个庞大的服务器网络,并且要分析每台主机以及端口的网络状态时,iftop ...
- Linux下使用Iptraf进行网络流量的分析
Linux下使用Iptraf进行网络流量的分析 Posted on 2011/06/15 下面的教程我个人安装的时候,总是失败,在/usr/local/bin目录里没有iptraf这个文件,没有办法直 ...
- Linux脚本实战之检测网卡流量
Linux脚本实战之检测网卡流量 一.脚本要求 二.脚本内容 三.运行脚本 一.脚本要求 1.检测网卡流量,并按规定格式记录在日志中,输出到/data/net.log/目录中以执行脚本时间命令的文件中 ...
最新文章
- YARN集群维护部分问题汇总
- JAVA SE学习day_03:包装类、文件操作——file
- VTK修炼之道30:图像重采样_降采样和升采样技术
- 圆桌对话:数字化升级,视频通信云赋能全行业
- c语言对中文字符串编码_Python || 学习笔记(1):数据类型字符串变量和编码
- Css fade()函数降低颜色变量透明度
- python在线包安装mysql_python安装mysql的依赖包mysql-python操作
- 线程安全的map_面试必问-几种线程安全的Map解析
- BZOJ——1614: [Usaco2007 Jan]Telephone Lines架设电话线
- 直接存储器存取(Direct Memory Access,DMA)详细讲解
- 为什么你的网站没流量?做不大!让我来告诉你。
- struts2中文乱码问题
- mac 下 hadoop、spark 的安装及配置
- 【机器学习】选择模型
- 安装SQL Server 2000 出现挂起文件,需要重启该如何解决?
- 项目管理学习总结(11)——项目管理怎么做
- UitableView 动态高度的优化 提高寻星效率
- php 微信授权 跨域,微信公众号支付 请求跳转code跨域
- freeswitch通过limit限制cps
- hello yocto