1、设置设备

这是很简单的。有两种方法设置想要嗅探的设备。

第一种,我们可以简单的让用户告诉我们。考察下面的程序:

#include
#include
int main(int argc, char *argv[])
{char *dev = argv[1];printf("Device: %s", dev);return(0);
}

用户通过传递给程序的第一个参数来指定设备。字符串“dev”以pcap能“理解”的格式保存了我们要嗅探的接口的名字(当然,用户必须给了我们一个真正存在的接口)。

另一种也是同样的简单。来看这段程序:

//gcc -o lookup lookup.c -I ./../include -L./../lib -lpcap
#include <stdio.h>
#include <pcap.h>
/*
char *pcap_lookupdev(char *errbuf)用于返回可被pcap_open_live()或pcap_lookupnet()函数调用的网络设备名指针。如果函数出错,则返回NULL,同时errbuf中存放相关的错误消息。
*/
int main()
{char *dev, errbuf[PCAP_ERRBUF_SIZE];dev = pcap_lookupdev(errbuf);printf("Device: %s\n", dev);return(0);
}

2、打开设备进行嗅探

创建一个嗅探会话的任务真的非常简单。为此,我们使用pcap_open_live()函数。此函数的原型(根据pcap的手册页)如下:

   pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)

其第一个参数是我们在上一节中指定的设备,snaplen是整形的,它定义了将被pcap捕捉的最大字节数。当promisc设为true时将置指定接口为混杂模式(然而,当它置为false时接口仍处于混杂模式的非凡情况也是有可能的)。to_ms是读取时的超时值,单位是毫秒(假如为0则一直嗅探直到错误发生,为-1则不确定)。最后,ebuf是一个我们可以存入任何错误信息的字符串(就像上面的errbuf)。此函数返回其会话句柄。

混杂模式与非混杂模式的区别:这两种方式区别很大。一般来说,非混杂模式的嗅探器中,主机仅嗅探那些跟它直接有关的通信,如发向它的,从它发出的,或经它路由的等都会被嗅探器捕捉。而在混杂模式中则嗅探传输线路上的所有通信。在非交换式网络中,这将是整个网络的通信。这样做最明显的优点就是使更多的包被嗅探到,它们因你嗅探网络的原因或者对你有帮助,或者没有。但是,混杂模式是可被探测到的。一个主机可以通过高强度的测试判定另一台主机是否正在进行混杂模式的嗅探。其次,它仅在非交换式的网络环境中有效工作(如集线器,或者交换中的ARP层面)。再次,在高负荷的网络中,主机的系统资源将消耗的非常严重。

3、过滤通信

实现这一过程由pcap_compile()与pcap_setfilter()这两个函数完成。

在使用我们自己的过滤器前必须编译它。过滤表达式被保存在一个字符串中(字符数组)。其句法在tcpdump的手册页中被证实非常好。我建议你亲自阅读它。但是我们将使用简单的测试表达式,这样你可能很轻易理解我的例子。

我们调用pcap_compile()来编译它,其原型是这样定义的:

   int pcap_compile(pcap_t *p, strUCt bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask)

第一个参数是会话句柄。接下来的是我们存储被编译的过滤器版本的地址的引用。再接下来的则是表达式本身,存储在规定的字符串格式里。再下边是一个定义表达式是否被优化的整形量(0为false,1为true,标准规定)。最后,我们必须指定应用此过滤器的网络掩码。函数返回-1为失败,其他的任何值都表明是成功的。

表达式被编译之后就可以使用了。现在进入pcap_setfilter()。仿照我们介绍pcap的格式,先来看一看pcap_setfilter()的原型:

   int pcap_setfilter(pcap_t *p, struct bpf_program *fp)

这非常直观,第一个参数是会话句柄,第二个参数是被编译表达式版本的引用(可推测出它与pcap_compile()的第二个参数相同)。

下面的代码示例可能能使你更好的理解:

  

//gcc -o filter filter.c -I ./../include -L./../lib -lpcap/*
pcap_t *pcap_open_live(char *device, int snaplen,int promisc, int to_ms, char *ebuf)获得用于捕获网络数据包的数据包捕获描述字。device参数为指定打开的网络设备名。snaplen参数定义捕获数据的最大字节数。promisc指定是否将网络接口置于混杂模式。to_ms参数指定超时时间(毫秒)。ebuf参数则仅在pcap_open_live()函数出错返回NULL时用于传递错误消息。
int pcap_lookupnet(char *device, bpf_u_int32 *netp,bpf_u_int32 *maskp, char *errbuf)获得指定网络设备的网络号和掩码。netp参数和maskp参数都是bpf_u_int32指针。如果函数出错,则返回-1,同时errbuf中存放相关的错误消息。
int pcap_compile(pcap_t *p, struct bpf_program *fp,char *str, int optimize, bpf_u_int32 netmask)将str参数指定的字符串编译到过滤程序中。fp是一个bpf_program结构的指针,在pcap_compile()函数中被赋值。optimize参数控制结果代码的优化。netmask参数指定本地网络的网络掩码。
int pcap_setfilter(pcap_t *p, struct bpf_program *fp)指定一个过滤程序。fp参数是bpf_program结构指针,通常取自pcap_compile()函数调用。出错时返回-1;成功时返回0。*/
#include <pcap.h>
#include <stdio.h>
int main()
{int ret32 = -1;pcap_t *handle = NULL; /* 会话的句柄 */char dev[] = "eth0"; /* 执行嗅探的设备 */char errbuf[PCAP_ERRBUF_SIZE]; /* 存储错误 信息的字符串 */struct bpf_program filter; /*已经编译好的过滤表达式*/char filter_app[] = "port 23"; /* 过滤表达式*/bpf_u_int32 mask; /* 执行嗅探的设备的网络掩码 */bpf_u_int32 net; /* 执行嗅探的设备的IP地址 */ret32 = pcap_lookupnet(dev, &net, &mask, errbuf);if(ret32 < 0){printf("pcap_lookupnet return %d, errbuf:%s\n", ret32, errbuf);}printf("sizeof(mask) = %d, mask:%#x, net:%#x\n",sizeof(mask), mask, net);handle = pcap_open_live(dev, 1024, 1, 0, errbuf);if(handle == NULL){printf("pcap_open_live return err,errbuf:%s...\n", errbuf);return -1;}ret32 = pcap_compile(handle, &filter, filter_app, 0, net);if(ret32 < 0){printf("pcap_compile return %d, errbuf:%s\n", ret32, errbuf);return -1;}ret32 = pcap_setfilter(handle, &filter);if(ret32 < 0){printf("pcap_setfilter return %d, errbuf:%s\n", ret32, errbuf);return -1;}printf("libpcap API test ok...\n");return 0;
}

这个程序使嗅探器嗅探经由端口23的所有通信,使用混杂模式,设备是eth0。

4、实际的嗅探

有两种手段捕捉包。我们可以一次只捕捉一个包,也可以进入一个循环,等捕捉到多个包再进行处理。我们将先看看怎样去捕捉单个包,然后再看看使用循环的方法。为此,我们使用函数pcap_next()。

pcap_next()的原型及其简单:

   u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)

第一个参数是会话句柄,第二个参数是指向一个包括了当前数据包总体信息(被捕捉时的时间,包的长度,其被指定的部分长度)的结构体的指针(在这里只有一个片断,只作为一个示例)。pcap_next()返回一个u_char指针给被这个结构体描述的包。我们将稍后讨论这种实际读取包本身的手段。

   这里有一个演示怎样使用pcap_next()来嗅探一个包的例子:

  

/*
//gcc -o pcap pcap.c -I ./../include -L./../lib -lpcap
u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)返回指向下一个数据包的u_char指针。
*/
#include <pcap.h>
#include <stdio.h>
int main()
{int ret32 = -1;pcap_t *handle = NULL; /* 会话的句柄 */char dev[] = "eth0"; /* 执行嗅探的设备 */char errbuf[PCAP_ERRBUF_SIZE]; /* 存储错误 信息的字符串 */struct bpf_program filter; /*已经编译好的过滤表达式*/char filter_app[] = "port 22"; /* 过滤表达式*/bpf_u_int32 mask; /* 执行嗅探的设备的网络掩码 */bpf_u_int32 net; /* 执行嗅探的设备的IP地址 */u_char *packet; /* 实际的包 */struct pcap_pkthdr header; /* 由pcap.h定义 */ret32 = pcap_lookupnet(dev, &net, &mask, errbuf);if(ret32 < 0){printf("pcap_lookupnet return %d, errbuf:%s\n", ret32, errbuf);}printf("sizeof(mask) = %d, mask:%#x, net:%#x\n",sizeof(mask), mask, net);handle = pcap_open_live(dev, 1024, 1, 0, errbuf);if(handle == NULL){printf("pcap_open_live return err,errbuf:%s...\n", errbuf);return -1;}#if 0ret32 = pcap_compile(handle, &filter, filter_app, 0, net);if(ret32 < 0){printf("pcap_compile return %d, errbuf:%s\n", ret32, errbuf);return -1;}ret32 = pcap_setfilter(handle, &filter);if(ret32 < 0){printf("pcap_setfilter return %d, errbuf:%s\n", ret32, errbuf);return -1;}#endif /* 截获一个包 */packet = pcap_next(handle, &header);if(packet){/* 打印它的长度 */printf("Jacked a packet with length of [%d]\n", header.len);}/* 关闭会话 */pcap_close(handle);return 0;
}

这个程序嗅探被pcap_lookupdev()返回的设备并将它置为混杂模式。它发现第一个包经过端口23(telnet)并且告诉用户此包的大小(以字 节为单位)。这个程序又包含了一个新的调用pcap_close(),我们将在后面讨论(尽管它的名字就足够证实它自己的作用)。

实际上很少有嗅探程序会真正的使用pcap_next()。通常,它们使用pcap_loop()或者 pcap_dispatch()。

Libpcap二 libpcap抓包基本流程相关推荐

  1. 使用libpcap tcpdump wireshark抓包

    作者 QQ群:852283276 微信:arm80x86 微信公众号:青儿创客基地 B站:主页 https://space.bilibili.com/208826118 参考 tcpdump & ...

  2. 计算机网络抓包参考文献,计算机网络课程设计二(网络抓包与分析)

    <计算机网络课程设计二(网络抓包与分析)>由会员分享,可在线阅读,更多相关<计算机网络课程设计二(网络抓包与分析)(9页珍藏版)>请在人人文库网上搜索. 1.课程设计课程名称: ...

  3. Linux下使用libpcap进行网络抓包并保存到文件

    libpcap是一个抓取网络数据报文的C语言函数库,使用这个库可以非常方便的抓取网络上的报文,方便我们分析经过我们设备上的各种报文: 1.libpcap安装 下载文件:libpcap-x.x.x.ta ...

  4. linux 抓包生成文件,Linux下使用libpcap进行网络抓包并保存到文件(函数介绍)

    libpcap是一个抓取网络数据报文的C语言函数库,使用这个库可以非常方便的抓取网络上的报文,方便我们分析经过我们设备上的各种报文: 使用libcap库编译时都要在后面加上-lpcap选项 使用pca ...

  5. linux 网卡包存储,Linux下使用libpcap进行网络抓包并保存到文件-Go语言中文社区

    libpcap是一个抓取网络数据报文的C语言函数库,使用这个库可以非常方便的抓取网络上的报文,方便我们分析经过我们设备上的各种报文: 1.libpcap安装 下载文件:libpcap-x.x.x.ta ...

  6. Charles 抓包工具教程(二) Charles 抓包HTTPS请求

    本文为在霍格沃兹测试开发学社中学习到的一些技术,写出来分享给大家,希望有志同道合的小伙伴可以一起交流技术,一起进步~ Charles 抓包HTTPS请求 一.MacOS 安装 Chares 证书 二. ...

  7. 小白日记22:kali渗透测试之提权(二)--抓包嗅探

    抓包嗅探 通过抓包嗅探目标机器的流量,发现账号密码. Windows系统 1.Wirehshark 2.Omnipeek 3.commview 4.Sniffpass 只会抓取识别传输密码的明文协议, ...

  8. fiddler的web端抓包配置流程

    目录 ​ 1.fiddler的web端抓包的配置​ 最后会弹出两个弹框,点击"yes"和"是" ,需要重启后才能使用 2.打开fiddler自带的浏览器搜索内容 ...

  9. libpcap/tcpdump—3—抓包结论(3 packets captured,3 packets received by filter,0 packets dropped by kernel)

    每次在退出tcpdump的时候,终端上都会显示上图这样的3行信息.本篇文章就是想讲解这3个数值的相关信息. 我会尽量写的详细,但能力有限,核心地方无法点到本质. 这条信息是tcpdump.c中info ...

最新文章

  1. 解题报告:luoguP6685 可持久化动态仙人掌的直径问题
  2. linux mysql删除root_Linux下误删MySQL的root用户解决方法
  3. 公式免费转 LaTex 代码,截图、转换一气呵成,每月 1000 次全免费
  4. 原字体_在包装上玩转字体
  5. 屏幕坏点检测图片_电视屏幕出现坏点?行家会这样做!
  6. 一对一,一对多,多对多查询 (注解写法)
  7. 如何过上简单的生活(转)
  8. 官宣!VS Code Python 全新功能全球首发!
  9. LeetCode 537. Complex Number Multiplication
  10. linux mysql 查看字符集_Linux中查看和设置MySQL数据库字符集 一
  11. go中break continue的使用:示例
  12. 为什么中国的数字是四位一进,而西方的是三位一进?
  13. API网关之-协议转换原理
  14. 基于神经网络的房价预测,BP神经网络预测房价
  15. 计算机演示文稿实验报告,演示文稿实验报告
  16. layui layer 自定义皮肤真香警告
  17. Docker_使用DockerFile监本构建镜像
  18. EXCEL表格使用VBA编程设置绘图区尺寸
  19. 将投影矩阵P利用QR分解分解出摄像机内外参数(Opencv)
  20. iamp是什么意思计算机网络,pop3和imap什么意思

热门文章

  1. MoviePy,利用 Python 自动剪辑 tiktok 视频
  2. 2021年赤小豆(红小豆)发展现状分析:红小豆价格整体上涨,农户种植积极性提高[图]
  3. 湖南发现3例不明肺炎 不排除感染禽流感
  4. Kafka的Streams
  5. typescript keyof 和 typeof 用法
  6. 炸裂!MySQL 82 张图带你飞
  7. 通过XPDF抽取PDF中的中文文本
  8. php实现stripos,PHP stripos
  9. 概率笔记7——数学期望
  10. 科研必备各专业全套模型:水文水资源、大气科学、农林生态、地信遥感、统计分析、编程语言等...