libpcap编程实例
#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> int main(int argc, char **argv)
{
char *dev;
char *net;
char *mask;
int ret;
char errbuf[PCAP_ERRBUF_SIZE];
bpf_u_int32 netp;
bpf_u_int32 maskp;
struct in_addr addr; dev = pcap_lookupdev(errbuf); if(dev == NULL)
{
printf("%s\n",errbuf);
exit();
} printf("DEV: %s\n",dev); ret = pcap_lookupnet(dev,&netp,&maskp,errbuf); if(ret == -)
{
printf("%s\n",errbuf);
exit();
} addr.s_addr = netp;
net = inet_ntoa(addr); if(net == NULL)
{
perror("inet_ntoa");
exit();
} printf("NET: %s\n",net); addr.s_addr = maskp;
mask = inet_ntoa(addr); if(mask == NULL)
{
perror("inet_ntoa");
exit();
} printf("MASK: %s\n",mask); return ;
}
然后gcc -o pcap_1 pcap_1.c -lpcap(一定要-lpcap参数)
编译ok~,执行./pcap_1,可以看到:
DEV: eth0
NET: 192.168.12.0
MASK: 255.255.255.0
好了,第一个pcap程序出炉了。。。。。 但是(当然有但是了,要不然我后面写啥),上面那个程序除了向我们展现pcap_lookupdev和pcap_lookupnet之外什么都没有干,好,我们接着来,动手编写我们的第一个抓包程序。 #include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h> int main(int argc, char **argv)
{
int i;
char *dev;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t* descr;
const u_char *packet;
struct pcap_pkthdr hdr;
struct ether_header *eptr; u_char *ptr; dev = pcap_lookupdev(errbuf); if(dev == NULL)
{
printf("%s\n",errbuf);
exit();
} printf("DEV: %s\n",dev); descr = pcap_open_live(dev,BUFSIZ,,-,errbuf); if(descr == NULL)
{
printf("pcap_open_live(): %s\n",errbuf);
exit();
} packet = pcap_next(descr,&hdr); if(packet == NULL)
{
printf("Didn't grab packet\n");
exit();
} printf("Grabbed packet of length %d\n",hdr.len);
printf("Recieved at ..... %s\n",ctime((const time_t*)&hdr.ts.tv_sec));
printf("Ethernet address length is %d\n",ETHER_HDR_LEN); eptr = (struct ether_header *) packet; if (ntohs (eptr->ether_type) == ETHERTYPE_IP)
{
printf("Ethernet type hex:%x dec:%d is an IP packet\n",
ntohs(eptr->ether_type),
ntohs(eptr->ether_type));
}else if (ntohs (eptr->ether_type) == ETHERTYPE_ARP)
{
printf("Ethernet type hex:%x dec:%d is an ARP packet\n",
ntohs(eptr->ether_type),
ntohs(eptr->ether_type));
}else {
printf("Ethernet type %x not IP", ntohs(eptr->ether_type));
exit();
} ptr = eptr->ether_dhost;
i = ETHER_ADDR_LEN;
printf(" Destination Address: ");
do{
printf("%s%x",(i == ETHER_ADDR_LEN) ? " " : ":",*ptr++);
}while(--i>);
printf("\n"); ptr = eptr->ether_shost;
i = ETHER_ADDR_LEN;
printf(" Source Address: ");
do{
printf("%s%x",(i == ETHER_ADDR_LEN) ? " " : ":",*ptr++);
}while(--i>);
printf("\n"); return ;
} 好了,编译运行!
[root@norman libpcap]# ./pcap_2
DEV: eth0
Grabbed packet of length
Recieved at time..... Mon Mar :: Ethernet address length is
Ethernet type hex: dec: is an IP packet
Destination Address: :::d1:e8:
Source Address: :a0:cc::c2:
[root@pepe libpcap]# 可能有人等了半天都没有一个包过来,有个好办法,再开一个控制台,ping一下某个网站,比如google~~,呵呵
马上就有反应了~~ 这个程序是一个老外写的,大家看看注释应该没有问题吧~
但是大家也发现了一个问题,就是上面的程序只能捕捉一个包,要不停的捕捉包怎么办,用循环??libpcap提供了一个更好的方法:
int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user);
这个函数能够不停的捕捉以太网的包,cnt就是捕捉的次数,callback是处理函数,这个处理函数怎么写,看看pcap_3.c就知道了。user参数是干什么的?不要问我,我也不知道。 #include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h> void my_callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char*
packet)
{
static int count = ;
fprintf(stdout,"%d, ",count);
if(count == )
fprintf(stdout,"Come on baby sayyy you love me!!! ");
if(count == )
fprintf(stdout,"Tiiimmmeesss!! ");
fflush(stdout);
count++;
} int main(int argc,char **argv)
{
int i;
char *dev;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t* descr;
const u_char *packet;
struct pcap_pkthdr hdr;
struct ether_header *eptr; if(argc != ){ fprintf(stdout,"Usage: %s numpackets\n",argv[]);return ;} dev = pcap_lookupdev(errbuf);
if(dev == NULL)
{ printf("%s\n",errbuf); exit(); } descr = pcap_open_live(dev,BUFSIZ,,-,errbuf);
if(descr == NULL)
{ printf("pcap_open_live(): %s\n",errbuf); exit(); } pcap_loop(descr,atoi(argv[]),my_callback,NULL); fprintf(stdout,"\nDone processing packets... wheew!\n");
return ;
} 运行./pcap_3
, , , , Come on baby sayyy you love me!!! , , , Tiiimmmeesss!!
Done processing packets... wheew! pcap_loop确实很好用,但是如果没有包包过来,只有干等在那里,pcap_dispatch就含有一个超时的功能,下面是man里面的一段话:
pcap_dispatch() is used to collect and process packets. cnt specifies the maximum number of packets to process before returning. A cnt of - processes all the packets received in one buffer. A cnt of processes all packets until an error occurs, EOF is reached, or the read times out (when doing live reads and a non-zero read timeout is specified). callback specifies a routine to be called with three arguments: a u_char pointer which is passed in from pcap_dispatch(), a pointer to the pcap_pkthdr struct (which precede the actual network headers and data), and a u_char pointer to the packet data. The number of packets read is returned. Zero is returned when EOF is reached in a ``savefile.'' A return of - indicates an error in which case pcap_perror() or pcap_geterr() may be used to display the error text. 另外的问题是,我们可能对抓取的包包太多而很头痛,可能很多都不是我们感兴趣的包,别急,pcap_compile和pcap_setfilter能帮我们解决问题。 #include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h> void my_callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char*
packet)
{
static int count = ;
fprintf(stdout,"%d, ",count);
fflush(stdout);
count++;
} int main(int argc,char **argv)
{
int i;
char *dev;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t* descr;
const u_char *packet;
struct pcap_pkthdr hdr;
struct ether_header *eptr;
struct bpf_program fp;
bpf_u_int32 maskp;
bpf_u_int32 netp; if(argc != ){ fprintf(stdout,"Usage: %s \"filter program\"\n"
,argv[]);return ;} dev = pcap_lookupdev(errbuf);
if(dev == NULL)
{ fprintf(stderr,"%s\n",errbuf); exit(); } pcap_lookupnet(dev,&netp,&maskp,errbuf); descr = pcap_open_live(dev,BUFSIZ,,-,errbuf);
if(descr == NULL)
{ printf("pcap_open_live(): %s\n",errbuf); exit(); } if(pcap_compile(descr,&fp,argv[],,netp) == -)
{ fprintf(stderr,"Error calling pcap_compile\n"); exit(); } if(pcap_setfilter(descr,&fp) == -)
{ fprintf(stderr,"Error setting filter\n"); exit(); } pcap_loop(descr,-,my_callback,NULL); return ;
} 运行./pcap_4.c "host www.google.com"
然后在另外一个控制台下面ping www.baidu.com
哈哈
没有反应吧
接着再ping www.google.com
就看到1, , , , , ,
ok
you got it!!
#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> int main(int argc, char **argv)
{
char *dev;
char *net;
char *mask;
int ret;
char errbuf[PCAP_ERRBUF_SIZE];
bpf_u_int32 netp;
bpf_u_int32 maskp;
struct in_addr addr; dev = pcap_lookupdev(errbuf); if(dev == NULL)
{
printf("%s\n",errbuf);
exit();
} printf("DEV: %s\n",dev); ret = pcap_lookupnet(dev,&netp,&maskp,errbuf); if(ret == -)
{
printf("%s\n",errbuf);
exit();
} addr.s_addr = netp;
net = inet_ntoa(addr); if(net == NULL)
{
perror("inet_ntoa");
exit();
} printf("NET: %s\n",net); addr.s_addr = maskp;
mask = inet_ntoa(addr); if(mask == NULL)
{
perror("inet_ntoa");
exit();
} printf("MASK: %s\n",mask); return ;
}
然后gcc -o pcap_1 pcap_1.c -lpcap(一定要-lpcap参数)
编译ok~,执行./pcap_1,可以看到:
DEV: eth0
NET: 192.168.12.0
MASK: 255.255.255.0
好了,第一个pcap程序出炉了。。。。。 但是(当然有但是了,要不然我后面写啥),上面那个程序除了向我们展现pcap_lookupdev和pcap_lookupnet之外什么都没有干,好,我们接着来,动手编写我们的第一个抓包程序。 #include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h> int main(int argc, char **argv)
{
int i;
char *dev;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t* descr;
const u_char *packet;
struct pcap_pkthdr hdr;
struct ether_header *eptr; u_char *ptr; dev = pcap_lookupdev(errbuf); if(dev == NULL)
{
printf("%s\n",errbuf);
exit();
} printf("DEV: %s\n",dev); descr = pcap_open_live(dev,BUFSIZ,1,0,errbuf); if(descr == NULL)
{
printf("pcap_open_live(): %s\n",errbuf);
exit();
} packet = pcap_next(descr,&hdr); if(packet == NULL)
{
printf("Didn't grab packet\n");
exit();
} printf("Grabbed packet of length %d\n",hdr.len);
printf("Recieved at ..... %s\n",ctime((const time_t*)&hdr.ts.tv_sec));
printf("Ethernet address length is %d\n",ETHER_HDR_LEN); eptr = (struct ether_header *) packet; if (ntohs (eptr->ether_type) == ETHERTYPE_IP)
{
printf("Ethernet type hex:%x dec:%d is an IP packet\n",
ntohs(eptr->ether_type),
ntohs(eptr->ether_type));
}else if (ntohs (eptr->ether_type) == ETHERTYPE_ARP)
{
printf("Ethernet type hex:%x dec:%d is an ARP packet\n",
ntohs(eptr->ether_type),
ntohs(eptr->ether_type));
}else {
printf("Ethernet type %x not IP", ntohs(eptr->ether_type));
exit();
} ptr = eptr->ether_dhost;
i = ETHER_ADDR_LEN;
printf(" Destination Address: ");
do{
printf("%s%x",(i == ETHER_ADDR_LEN) ? " " : ":",*ptr++);
}while(--i>);
printf("\n"); ptr = eptr->ether_shost;
i = ETHER_ADDR_LEN;
printf(" Source Address: ");
do{
printf("%s%x",(i == ETHER_ADDR_LEN) ? " " : ":",*ptr++);
}while(--i>);
printf("\n"); return ;
} 好了,编译运行!
[root@norman libpcap]# ./pcap_2
DEV: eth0
Grabbed packet of length
Recieved at time..... Mon Mar :: Ethernet address length is
Ethernet type hex: dec: is an IP packet
Destination Address: :::d1:e8:
Source Address: :a0:cc::c2:
[root@pepe libpcap]# 可能有人等了半天都没有一个包过来,有个好办法,再开一个控制台,ping一下某个网站,比如google~~,呵呵
马上就有反应了~~ 这个程序是一个老外写的,大家看看注释应该没有问题吧~
但是大家也发现了一个问题,就是上面的程序只能捕捉一个包,要不停的捕捉包怎么办,用循环??libpcap提供了一个更好的方法:
int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user);
这个函数能够不停的捕捉以太网的包,cnt就是捕捉的次数,callback是处理函数,这个处理函数怎么写,看看pcap_3.c就知道了。user参数是干什么的?不要问我,我也不知道。 #include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h> void my_callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char*
packet)
{
static int count = ;
fprintf(stdout,"%d, ",count);
if(count == )
fprintf(stdout,"Come on baby sayyy you love me!!! ");
if(count == )
fprintf(stdout,"Tiiimmmeesss!! ");
fflush(stdout);
count++;
} int main(int argc,char **argv)
{
int i;
char *dev;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t* descr;
const u_char *packet;
struct pcap_pkthdr hdr;
struct ether_header *eptr; if(argc != ){ fprintf(stdout,"Usage: %s numpackets\n",argv[]);return ;} dev = pcap_lookupdev(errbuf);
if(dev == NULL)
{ printf("%s\n",errbuf); exit(); } descr = pcap_open_live(dev,BUFSIZ,,-,errbuf);
if(descr == NULL)
{ printf("pcap_open_live(): %s\n",errbuf); exit(); } pcap_loop(descr,atoi(argv[]),my_callback,NULL); fprintf(stdout,"\nDone processing packets... wheew!\n");
return ;
} 运行./pcap_3
, , , , Come on baby sayyy you love me!!! , , , Tiiimmmeesss!!
Done processing packets... wheew! pcap_loop确实很好用,但是如果没有包包过来,只有干等在那里,pcap_dispatch就含有一个超时的功能,下面是man里面的一段话:
pcap_dispatch() is used to collect and process packets. cnt specifies the maximum number of packets to process before returning. A cnt of - processes all the packets received in one buffer. A cnt of processes all packets until an error occurs, EOF is reached, or the read times out (when doing live reads and a non-zero read timeout is specified). callback specifies a routine to be called with three arguments: a u_char pointer which is passed in from pcap_dispatch(), a pointer to the pcap_pkthdr struct (which precede the actual network headers and data), and a u_char pointer to the packet data. The number of packets read is returned. Zero is returned when EOF is reached in a ``savefile.'' A return of - indicates an error in which case pcap_perror() or pcap_geterr() may be used to display the error text. 另外的问题是,我们可能对抓取的包包太多而很头痛,可能很多都不是我们感兴趣的包,别急,pcap_compile和pcap_setfilter能帮我们解决问题。 #include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h> void my_callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char*
packet)
{
static int count = ;
fprintf(stdout,"%d, ",count);
fflush(stdout);
count++;
} int main(int argc,char **argv)
{
int i;
char *dev;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t* descr;
const u_char *packet;
struct pcap_pkthdr hdr;
struct ether_header *eptr;
struct bpf_program fp;
bpf_u_int32 maskp;
bpf_u_int32 netp; if(argc != ){ fprintf(stdout,"Usage: %s \"filter program\"\n"
,argv[]);return ;} dev = pcap_lookupdev(errbuf);
if(dev == NULL)
{ fprintf(stderr,"%s\n",errbuf); exit(); } pcap_lookupnet(dev,&netp,&maskp,errbuf); descr = pcap_open_live(dev,BUFSIZ,,-,errbuf);
if(descr == NULL)
{ printf("pcap_open_live(): %s\n",errbuf); exit(); } if(pcap_compile(descr,&fp,argv[],,netp) == -)
{ fprintf(stderr,"Error calling pcap_compile\n"); exit(); } if(pcap_setfilter(descr,&fp) == -)
{ fprintf(stderr,"Error setting filter\n"); exit(); } pcap_loop(descr,-,my_callback,NULL); return ;
} 运行./pcap_4.c "host www.google.com"
然后在另外一个控制台下面ping www.baidu.com
哈哈
没有反应吧
接着再ping www.google.com
就看到1, , , , , ,
ok
you got it!!
libpcap编程实例的更多相关文章
- PHP多进程编程实例
这篇文章主要介绍了PHP多进程编程实例,本文讲解的是在Linux下实现PHP多进程编程,需要的朋友可以参考下 羡慕火影忍者里鸣人的影分身么?没错,PHP程序是可以开动影分身的!想完成任务,又觉得一个进 ...
- c#摄像头编程实例 (转)
c#摄像头编程实例 摄像头编程 安装摄像头后,一般可以找到一个avicap32.dll文件 这是一个关于设想头的类 using system;using System.Runtime.Intero ...
- JAX-RS 2.0 REST客户端编程实例
JAX-RS 2.0 REST客户端编程实例 2014/01/28 | 分类: 基础技术, 教程 | 0 条评论 | 标签: JAX-RS, RESTFUL 分享到:3 本文由 ImportNew - ...
- Android studio 下JNI编程实例并生成so库
Android studio 下JNI编程实例并生成so库 因为公司需要为Android相机做美颜等图像后期处理,需要使用JNI编程,最近学了下JNI,并且在Android Studio下实现了一个小 ...
- hadoop2.2编程:使用MapReduce编程实例(转)
原文链接:http://www.cnblogs.com/xia520pi/archive/2012/06/04/2534533.html 从网上搜到的一篇hadoop的编程实例,对于初学者真是帮助太大 ...
- python学习_数据处理编程实例(二)
在上一节python学习_数据处理编程实例(二)的基础上数据发生了变化,文件中除了学生的成绩外,新增了学生姓名和出生年月的信息,因此将要成变成:分别根据姓名输出每个学生的无重复的前三个最好成绩和出生年 ...
- 请求转发:MVC设计模式、细节、请求域属性的编程实例、请求重定向和请求转发的区别
请求转发:MVC设计模式.细节.请求域属性的编程实例.请求重定向和请求转发的区别 MVC设计模式将一次请求的响应过程分成三个功能模块(一般称之为层)来协同完成,这三个模块分别是Model(模型层) ...
- Python进阶:函数式编程实例(附代码)
Python进阶:函数式编程实例(附代码) 上篇文章"几个小例子告诉你, 一行Python代码能干哪些事 -- 知乎专栏"中用到了一些列表解析.生成器.map.filter.lam ...
- The MySQL C API 编程实例
在网上找了一些MYSQL C API编程的文章,看了后认为还是写的不够充分,依据自己经验写了这篇<The MySQL C API 编程实例>,希望对须要调用到MYSQL的C的API的朋友有 ...
随机推荐
- Mac下docker搭建lnmp环境 + redis + elasticsearch
之前在windows下一直使用vagrant做开发, 团队里面也是各种开发环境,几个人也没有统一环境,各种上线都是人肉,偶尔还会有因为开发.测试.生产环境由于软件版本或者配置不一致产生的问题, 今年准 ...
- javascript基础-js函数
一.创建函数的方式 1)普通方式 function cal( num1, num2 ) { return num1+num2; } 2)使用变量初始化方式 var plus = function(nu ...
- Java-Runoob:Java 日期时间
ylbtech-Java-Runoob:Java 日期时间 1.返回顶部 1. Java 日期时间 java.util 包提供了 Date 类来封装当前的日期和时间. Date 类提供两个构造函数来实 ...
- DataTables warning: table id=DataTables_Table_0 - Requested unknown parameter '1' for row 0. For more information about this error, please see http://datatables.net/tn/4
今天在做后台的时候,考虑到会员模块和订单模块列表显示差不多,于是乎,偷了个懒,把会员列表显示页面的代码拷贝了过来,修改了一下,变成了订单模块.可是,在订单列表显示的时候老是报下面的错误,截图如下: 后 ...
- 小程序scroll-view组件使用时,子元素虽设置样式display:inline-flex;whit-space:nowrap
小程序scroll-view组件使用时,子元素虽设置样式display:inline-flex;whit-space:nowrap
- Jq将字符串复制粘贴到剪贴板
第一种: 自己测试时 只适合于input 和textarea 但是针对于其他标签的复制就不能用了.代码如下: <!DOCTYPE html> <html> <head ...
- 《C++ Primer》读书笔记
在C++中,基类必须指出希望派生类重新定义哪些函数,定义为virtual的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数. 引用和指针的静态类型与动态类型可以不同,这是C++ ...
- 【BZOJ】1878: [SDOI2009]HH的项链 (主席树)
题目 传送门:QWQ 分析 莫队也能做,但我想练练主席树. 求k-th一样维护第i个时候的线段树,线段树来维护区间不同数. 然后查询时可以通过上下界小优化一波. 但是我的代码丑陋无比,常数巨大(捂脸 ...
- Linux 上通过binlog文件 恢复mysql 数据库详细步骤
一.binlog 介绍 服务器的二进制日志记录着该数据库的所有增删改的操作日志(前提是要在自己的服务器上开启binlog),还包括了这些操作的执行时间.为了显示这些二进制内容,我们可以使用mysqlb ...
- OD 实验(十一) - 对一个程序的破解
程序: 点击安装程序 这是一个拼图程序 点击 Options -> Flash Sizes 程序会提示是未注册版本 点击一些选项的时候会提示该程序只给注册的用户 点击 Register 随便输入 ...