Winpcap笔记3之打开适配器并捕获数据包

2023-05-16

上一讲中知道了如何获取适配的信息,这一将我们讲写一个程序蒋每一个通过适配器的数据包打印出来。

打开设备的函数是pcap_open().函数原型是

pcap_t* pcap_open(const char* source,int snaplen,int flags,int read_timeout,struct pcap_rmtauth *auth,char * errbuf);‘

pcap_rmatauth

{

  int type.

     char *username;;//Zero-terminated string containing the username that has to be used on the remote machine for authentication

     char *password;

}

snaplen:snaplen 制定要捕获数据包中的哪些部分。 在一些操作系统中 (比如 xBSD 和 Win32), 驱动可以被配置成只捕获数据包的初始化部分: 这样可以减少应用程序间复制数据的量,从而提高捕获效率。本例中,我们将值定为65535,它比我们能遇到的最大的MTU还要大。因此,我们确信我们总能收到完整的数据包。

flags: 最最重要的flag是用来指示适配器是否要被设置成混杂模式。 一般情况下,适配器只接收发给它自己的数据包, 而那些在其他机器之间通讯的数据包,将会被丢弃。 相反,如果适配器是混杂模式,那么不管这个数据包是不是发给我的,我都会去捕获。也就是说,我会去捕获所有的数据包。 这意味着在一个共享媒介(比如总线型以太网),WinPcap能捕获其他主机的所有的数据包。 大多数用于数据捕获的应用程序都会将适配器设置成混杂模式,所以,我们也会在下面的范例中,使用混杂模式。

                    PCAP_OPENFLAG_PROMISCUOUS:1,它定义了适配器(网卡)是否进入混杂模式(promiscuous mode)。   

      PCAP_OPENFLAG_DATATX_UDP:2,它定义了数据传输(假如是远程抓包)是否用UDP协议来处理。

          PCAP_OPENFLAG_NOCAPTURE_RPCAP:4,它定义了远程探测器是否捕获它自己产生的数据包。

to_ms 指定读取数据的超时时间,以毫秒计(1s=1000ms)。在适配器上进行读取操作(比如用 pcap_dispatch() 或 pcap_next_ex()) 都会在 to_ms 毫秒时间内响应,即使在网络上没有可用的数据包。 在统计模式下to_ms 还可以用来定义统计的时间间隔。 将 to_ms 设置为0意味着没有超时,那么如果没有数据包到达的话,读操作将永远不会返回。 如果设置成-1,则情况恰好相反,无论有没有数据包到达,读操作都会立即返回。

 

read_timeout:以毫秒为单位。read timeout被用来设置在遇到一个数据包的时候读操作不必立即返回,而是等待一段时间,让更多的数据包到来后从OS内核一次读多个数据包。并非所有的平台都支持read timeout;在不支持read timeout的平台上它将被忽略。

auth:一个指向’struct pcap_rmtauth’的指针,保存当一个用户登录到某个远程机器上时的必要信息。假如不是远程抓包,该指针被设置为NULL。

errbuf:一个指向用户申请的缓冲区的指针,存放当该函数出错时的错误信息。

返回值是一个’pcap_t’指针,它可以作为下一步调用(例如pcap_compile()等)的参数,并且指定了一个已经打开的Winpcap会话。在遇到问题的情况下,它返回NULL并且’errbuf’变量保存了错误信息。

 

 

函数1:

 

int pcap_loop(  pcap_t*           p,

 

int                   cnt,

 

pcap_hander    callback,

 

u_char*           user

 

)

 

    收集一群数据包。pcap_loop()与pcap_dispatch()类似,但是它会一直保持读数据包的操作直到cnt包被处理或者发生了错误。当有活动的读超时(read timeout)时它并不返回。然而,对pcap_open_live()指定一个非0的读超时(read timeout),当发生超时的时候调用pcap_dispatch()来接收并处理到来的所有数据包更好。Cnt指明了返回之前要处理数据包的最大数目。如果cnt为负值,pcap_loop()将一直循环(直到发生错误才停止)。如果出错时返回-1;如果cnt用完时返回0;如果在任何包被处理前调用pcap_breakloop()来中止循环将返回-2。所以,如果程序中使用了pcap_breakloop(),必须准确的来判断返回值是-1还是-2,而不能简单的判断<0。

 

 

 

函数2:

 

hypedef void (* pcap_handler)(u_char* user,

 

const struct pcap_pkthdr* pkt_header,

 

const u_char* pkt_data)

 

    接收数据包的回调函数原型。当用户程序使用pcap_dispatch()或者pcap_loop(),数据包以这种回调的方法传给应用程序。用户参数是用户自己定义的包含捕获会话状态的参数,它必须跟pcap_dispatch()和pcap_loop()的参数相一致。pkt_hader是与抓包驱动有关的头。pkt_data指向包里的数据,包括协议头。

 

 

 

结构体1:

 

struct pcap_pkthdr {

 

      struct timeval ts;

 

      bpf_u_int32 caplen;

 

      bpf_u_int32 len;

 

}

 

ts:时间戳

struct timeval {
        long    tv_sec;         /* seconds */
        long    tv_usec;        /* and microseconds */
};

 

cpalen:当前分组的长度

 

len:数据包的长度

 

/*
* 截获数据包的试验。先打印出所有网络适配器的列表,然后选择
* 想在哪个适配器上截获数据包。然后通过pcap_loop()函数将截获
* 的数据包传给回调函数packet_handler()处理。

* 通过该程序初步了解了使用winpcap截获数据包的步骤以及一些在
* 截获数据包时非常重要的函数和结构体。
*/

 


 1 //打开适配器捕获数据包
 2 #include "pcap.h"
 3 
 4 /* packet handler 函数原型 */
 5 void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
 6 
 7 int main()
 8 {
 9     pcap_if_t *alldevs;
10     pcap_if_t *d;
11     int inum;
12     int i = 0;
13     pcap_t *adhandle;
14     char errbuf[PCAP_ERRBUF_SIZE];
15 
16     /* 获取本机设备列表 */
17     if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
18     {
19         fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
20         exit(1);
21     }
22 
23     /* 打印列表 */
24     for (d = alldevs; d; d = d->next)
25     {
26         printf("%d. %s", ++i, d->name);
27         if (d->description)
28             printf(" (%s)\n", d->description);
29         else
30             printf(" (No description available)\n");
31     }
32 
33     if (i == 0)
34     {
35         printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
36         return -1;
37     }
38 
39     printf("Enter the interface number (1-%d):", i);
40     scanf("%d", &inum);
41 
42     if (inum < 1 || inum > i)
43     {
44         printf("\nInterface number out of range.\n");
45         /* 释放设备列表 */
46         pcap_freealldevs(alldevs);
47         return -1;
48     }
49 
50     /* 跳转到选中的适配器 */
51     for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);
52 
53     /* 打开设备 */
54     if ((adhandle = pcap_open(d->name,          // 设备名
55         65536,            // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容
56         PCAP_OPENFLAG_PROMISCUOUS,    // 混杂模式
57         1000,             // 读取超时时间
58         NULL,             // 远程机器验证
59         errbuf            // 错误缓冲池
60         )) == NULL)
61     {
62         fprintf(stderr, "\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
63         /* 释放设备列表 */
64         pcap_freealldevs(alldevs);
65         return -1;
66     }
67 
68     printf("\nlistening on %s...\n", d->description);
69 
70     /* 释放设备列表 */
71     pcap_freealldevs(alldevs);
72 
73     /* 开始捕获 */
74     pcap_loop(adhandle, 0, packet_handler, NULL);
75 
76     return 0;
77 }
78 
79 
80 /* 每次捕获到数据包时,libpcap都会自动调用这个回调函数 */
81 void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
82 {
83     struct tm *ltime;
84     char timestr[16];
85     time_t local_tv_sec;
86 
87     /* 将时间戳转换成可识别的格式 */
88     local_tv_sec = header->ts.tv_sec;
89     ltime = localtime(&local_tv_sec);
90     strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);
91 
92     printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
93 
94 }  

 

 

当适配器被打开,捕获工作就可以用 pcap_dispatch() 或 pcap_loop()进行。 这两个函数非常的相似,区别就是 pcap_ dispatch() 当超时时间到了(timeout expires)就返回 (尽管不能保证) ,而 pcap_loop() 不会因此而返回,只有当 cnt 数据包被捕获,所以,pcap_loop()会在一小段时间内,阻塞网络的利用。pcap_loop()对于我们这个简单的范例来说,可以满足需求,不过, pcap_dispatch() 函数一般用于比较复杂的程序中。

这两个函数都有一个 回调 参数, packet_handler指向一个可以接收数据包的函数。 这个函数会在收到每个新的数据包并收到一个通用状态时被libpcap所调用 ( 与函数 pcap_loop() 和 pcap_dispatch() 中的 user 参数相似),数据包的首部一般有一些诸如时间戳,数据包长度的信息,还有包含了协议首部的实际数据。 注意:冗余校验码CRC不再支持,因为帧到达适配器,并经过校验确认以后,适配器就会将CRC删除,与此同时,大部分适配器会直接丢弃CRC错误的数据包,所以,WinPcap没法捕获到它们。

 

上面的程序将每一个数据包的时间戳和长度从 pcap_pkthdr 的首部解析出来,并打印在屏幕上。

 

请注意,使用 pcap_loop() 函数可能会遇到障碍,主要因为它直接由数据包捕获驱动所调用。因此,用户程序是不能直接控制它的。另一个实现方法(也是提高可读性的方法),是使用 pcap_next_ex() 函数。有关这个函数的使用,我们将在下一讲为您展示。 (不用回调方法捕获数据包).

 

转载于:https://www.cnblogs.com/lanjianhappy/p/6667254.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Winpcap笔记3之打开适配器并捕获数据包 的相关文章

  • Winpcap笔记3之打开适配器并捕获数据包

    上一讲中知道了如何获取适配的信息 xff0c 这一将我们讲写一个程序蒋每一个通过适配器的数据包打印出来 打开设备的函数是pcap open 函数原型是 pcap t pcap open const char source int snapl
  • Winpcap数据包的抓取及还原

    winpcap技术手册 xff0c 除了安装文件里doc文件下有个帮助 xff0c 这里在给一个 xff1a http www ferrisxu com WinPcap html index html 这里我们用pcap next ex 函
  • MFC使用winpcap 抓包 pcap_compile使用

    使用Winpcap编写 xff1a 最近工作需要抓取傻瓜交换机的MAC xff0c 由于没有IP只能使用Winpcap抓包工具来实现 本人初学者 xff0c 大佬请绕行 a 先获取电脑的网卡信息 在SwithCheckMacDlg h文件中
  • Winpcap教程(高级应用)

    循序渐进学习使用WINPCAP xff08 五 xff09 WinPcap或libpca最强大的特点之一就是数据流的过滤引擎 它提供一种高效的方法来只捕获网络数据流的某些数据而且常常和系统的捕获机制相集成 过滤数据的函数是pcap comp
  • WinPcap实战(一)——发送ARP包

    ARP包的结构 ARP包格式 物理帧头 14B ARP帧结构 28B 填充数据 18B CRC 4B 这里给出一张图 图中没有18字节的填充数据和4字节的校验位 物理帧头 14B 目的MAC 6B 源MAC 6B 类型 2B ARP帧 0x
  • Intellij IDEA 安装jnetpcap开发环境与 no jnetpcap in java.library.path 的解决方案

    jnetpcap是libpcap的一个java完整封装 这篇博客就是讲解如何能够使用Intellij IDEA来编写jnetpcap 这篇博客分为四个部分 安装必要的开发环境 添加jnetpcap的jar包 测试导入包 解决java lan
  • VS 2008配置Winpcap环境

    写在前面的话 这篇博客主要是写给小白看的 因为自己也是一个小白 之前从没有接触过网络嗅探器这些东西 如果说基础的话就是学习过计算机网络 对于计算机网络有一点点了解 再就是对于编程语言基础语法还算熟悉吧 这学期选修了网络攻击与防范这门课程 老
  • 如何将指向成员函数的指针传递给 C 函数? [复制]

    这个问题在这里已经有答案了 可能的重复 使用 C 类成员函数作为 C 回调函数 我正在使用 C 库 winpcap 编写一个面向对象的库 我需要传递网络数据包到达时调用的回调函数作为函数指针 我想将成员函数指针传递给 winpcap 以保持
  • 在Windows 64位上编译gopacket

    我正在尝试使用gopacket在我的 Windows 10 上 我用它来嗅探数据包并将数据包直接注入到网卡或从网卡注入数据包 我可以使用 GOARCH 386 轻松编译和运行我的代码 但不能在 GOARCH amd64 中编译和运行我的代码
  • 如何使用 winpcap 修改 HTTP 响应数据包?

    这里有两个问题 如果内容被编码 gzip 我是否还需要更改标头部分以使 HTTP 数据包有效 校验和 如果有的话 UPDATE 有实际经验的人可以详细说明一下涉及的步骤吗 我在用着winpcap和BPFtcp and src port 80
  • 获取机器的 MAC 地址——好的解决方案吗?

    我听说我当前的 winpcap 库不可能实现这一点 这是真的吗 我在网上看到很多例子 但随后评论说 这不起作用 获取本地计算机的 MAC 地址的最佳方法是什么 一种常见的方法是使用 UUID 中的位 但这并不完全可靠 例如 即使在没有网络适
  • 使用 WinPcap 获取原始 WiFi 数据包

    考虑简单的 C 代码发送单个原始数据包与WinPcap 与构建数据包标头相关的行以以下注释开头 假设在以太网上 将 mac 目标设置为 1 1 1 1 1 1 因此 您可能会猜测 为了发送原始 WiFi 数据包 您应该相应地更改此代码块 然
  • 如何在 Windows 中挂钩 TCP 堆栈来嗅探和修改数据包?

    我想为 Windows 编写一个数据包嗅探器和编辑器 我希望能够查看进入和离开我的系统的所有数据包的内容 并可能对其进行修改 任何语言都可以 但我希望它运行得足够快 以免给系统带来负担 我读过一些有关 WinPcap 的内容 但文档声称您不
  • 有人可以推荐一个好的 C++ 数据包嗅探器类吗? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有人可以推荐一个好的 C 数据包嗅探器类吗 寻找一个可以在我的 C 程序中使用的简单可插入类 没什么复
  • Winpcap 开发人员使用 Cygwin C++ 和 Netbeans IDE

    希望让 Winpcap 开发人员包 4 1 2 在 Windows 7 64 位上运行 我正在 Netbeans IDE 中使用 Cygwin 4 1 10 编译器使用 C C 进行编程 我想直接从 UDP 数据包中提取一些 GPS 数据
  • pcap_pkthdr 是做什么用的?

    代码片段来自here https www winpcap org docs docs 40 2 html group wpcap tut6 html void packet handler u char param const struct
  • 如何安装和使用WinPcap?

    我今天访问 winpcap org 下载了安装程序 并在我的 Windows 7 笔记本电脑上安装了 WinPcap 但是 安装它的文件夹仅包含安装日志 名为 rpcapd exe 的可执行文件和卸载可执行文件 当我运行 rpcapd ex
  • 如何在 Windows 上发送自定义 tcp 数据包?

    我想发送一个数据包 我定义了IP地址 端口 数据等 起初我想也许我可以在Windows上使用原始套接字 但在谷歌搜索一段时间后 我发现MS似乎禁用了原始套接字从XP SP2 是真的吗 现在我不知道该怎么办 有人告诉我用winPcap 然后我
  • .NET 写入 PCAP 文件

    All 我花了一天的大部分时间查看各种 PCAP 库 在我承诺编写 PCAP 编写器之前 我想描述一下我的场景并征求意见 我有一个客户要求我提供一项服务来读取 pcap 文件并将数据包写入他们选择的数据库中 然后 客户端可以查询数据库 日期
  • Scapy、Npcap、WinPcap 等库如何绕过 Window 对发送原始 TCP 数据包的限制?

    在尝试自己用 Python 执行 TCP 握手之后 我惨痛地了解到现代 Windows 机器不允许通过原始套接字发送 TCP 数据 然而 Python 库 Scapy 似乎能够很好地做到这一点 其他库 如 Npcap 和 WinPcap 似

随机推荐

  • js计算器(正则)

    lt doctype html gt lt html gt lt head gt lt meta charset 61 34 utf 8 34 gt lt title gt 我的计算器 lt title gt lt style gt mar
  • MySQL 分组后取每组前N条数据

    与oracle的 rownumber over partition by xxx order by xxx 语句类似 xff0c 即 xff1a 对表分组后排序 创建测试emp表 DROP TABLE IF EXISTS emp CREAT
  • archlinux 安装搜狗输入法

    安装可能需要 archlinuxcn 的源 xff0c 我这里已经配置好了 一 安装 fcitx fcitx configtool fcitx im pacman S fcitx fcitx configtool fcitx im 二 在
  • MongoDB——JavaAPI详解

    环境配置 引入MongoDB驱动 xff1a span class token tag span class token tag span class token punctuation lt span dependency span sp
  • 练习题||并发编程

    线程 进程 队列 IO多路模型 操作系统工作原理介绍 线程 进程演化史 特点 区别 互斥锁 信号 事件 join GIL 进程间通信 管道 队列 生产者消息者模型 异步模型 IO多路复用模型 select poll epoll 高性能IO模
  • luogu P2078 朋友

    题目背景 小明在A公司工作 xff0c 小红在B公司工作 题目描述 这两个公司的员工有一个特点 xff1a 一个公司的员工都是同性 A公司有N名员工 xff0c 其中有P对朋友关系 B公司有M名员工 xff0c 其中有Q对朋友关系 朋友的朋
  • Debian 9 Stretch国内常用镜像源

    使用说明 一般情况下 xff0c 修改 etc apt sources list文件 xff0c 将Debian的默认源地址改成新的地址即可 xff0c 比如将http deb debian org改成https mirrors xxx c
  • ubuntu下编译ffmpeg并用eclipse调试

    一 下载ffnpeg源码 下载地址 xff1a http ffmpeg org download html 二 解决版本问题 可能之前你编译过ffmpeg xff0c 或者装过相关的库 xff0c 那都要先卸载掉 xff0c 否则用的时候会
  • 定时器初值计算

    1 定时器初值的计算 xff1a xff08 1 xff09 计算出机器周期 每次定时计算器加1所用的时间 xff08 2 xff09 根据你要定时的时间去算出初值 xff1a 假设你要定时Xms xff08 X lt 65 535ms x
  • ceph部署出现错误及解决

    ceph deploy new error hostname node1 is not resolvable 解决办法 xff0c 修改 etc hosts 127 0 0 1 localhost 127 0 1 1 ubuntu1 192
  • WordNet词网研究6——之JWI(Java Wordnet Interface)WordNet Java接口

    JWI the MIT Java Wordnet Interface is a Java library for interfacing with Wordnet JWI supports access to Wordnet version
  • SPI协议及其工作原理详解

    一 概述 SPI Serial Perripheral Interface 串行外围设备接口 是 Motorola 公司推出的一种同步串行接口技术 SPI 总线在物理上是通过接在外围设备微控制器 PICmicro 上面的微处理控制单元 MC
  • 通过修改qt设置,解决LINK : fatal error LNK1104: 无法打开文件“kernel32.lib”

    编译为知笔记源码的时候遇到的第一个错误 LINK fatal error LNK1104 无法打开文件 kernel32 lib 经研究发现是qt使用的本地编译连接工具cl exe找不到 windows sdk的lib文件导致 找到lib文
  • CF1042B 【Vitamins】(去重,状压搜索)

    由题意 我们其实会发现 对于每一种果汁 xff0c 其对应的状态只有可能有7种 VA VB VC VA 43 VB VA 43 VC VB 43 VC VA 43 VB 43 VC 这道题就大大简化了
  • SpringBoot——整合MongoDB详解

    引入依赖 span class token tag span class token tag span class token punctuation lt span dependency span span class token pun
  • 洛谷 P1991 无线通讯网/一本通OJ 1487【例 2】北极通讯网络

    要求用尽可能小的代价使图联通 xff0c 考虑最小生成树 如果不断加边 xff0c 将分散的点连结为 p s 个联通块 xff0c 则 s 个无线电站可以分布在每个联通块中的任意点 而此处要求的半径D是对于所有点的覆盖半径 xff0c 相当
  • Python&selenium&tesseract自动化测试随机码、验证码(Captcha)的OCR识别解决方案参考...

    在自动化测试或者安全渗透测试中 xff0c Captcha验证码的问题经常困扰我们 xff0c 还好现在OCR和AI逐渐发展起来 xff0c 在这块解决上越来越支撑到位 我推荐的几种方式 xff0c 一种是对于简单的验证码 xff0c 用开
  • debian 开启SSH

    1 修改sshd config文件 xff0c 命令为 xff1a vi etc ssh sshd config 2 将 PasswordAuthentication no的注释去掉 xff0c 并且将NO修改为YES 我的kali中默认是
  • 巧用Unicode控制字符破解Dz!论坛20字限制,百度贴吧禁用词语等

    巧用Unicode控制字符破解Dz 论坛20字限制 xff0c 百度贴吧禁用词语等 巧用Unicode控制字符破解Discuz 论坛回贴20字限制 xff0c 百度贴吧禁用词语 什么是Unicode字符 xff0c 有兴趣却还不知道的可以搜
  • Winpcap笔记3之打开适配器并捕获数据包

    上一讲中知道了如何获取适配的信息 xff0c 这一将我们讲写一个程序蒋每一个通过适配器的数据包打印出来 打开设备的函数是pcap open 函数原型是 pcap t pcap open const char source int snapl