• PACP学习笔记三:PCAP方法说明


    pcap方法说明

    pcap_create - 创建实时捕获句柄

    #include <pcap/pcap.h>
    
    char errbuf[PCAP_ERRBUF_SIZE];
    
    pcap_t *pcap_create(const char *source, char *errbuf);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    描述

    pcap_create() 用于创建数据包捕获句柄(handle)以查看网络上的数据包。 source 是一个字符串,指定要打开的网络设备;在具有 2.2 或更高版本内核的 Linux 系统上,可以使用“any”或 NULL 的源参数来捕获来自所有接口的数据包。
    返回的句柄必须先用 pcap_activate(3PCAP) 激活,然后才能用它捕获数据包;捕获的选项,例如混杂模式,可以在激活之前在句柄上设置。

    返回值

    pcap_create() 成功时返回 pcap_t *,失败时返回 NULL。如果返回 NULL,则 errbuf 会填充适当的错误消息。假设 errbuf 至少能够保存 PCAP_ERRBUF_SIZE (自己设置)字符。

    pcap_activate - 激活捕获句柄

    说明

    #include <pcap/pcap.h>
    
    int pcap_activate(pcap_t *p);
    
    • 1
    • 2
    • 3

    描述

    pcap_activate() 用于激活数据包捕获句柄以查看网络上的数据包,并且在句柄上设置的选项生效。

    返回值

    pcap_activate() 成功且没有警告返回0,成功有警告返回非0正值,错误时返回负值;非零返回值指示发生了什么警告或错误情况。

    具体参考:https://www.tcpdump.org/manpages/pcap_activate.3pcap.html

    pcap_datalink - 获取链路层标头类型

    说明

    #include <pcap/pcap.h>
    
    int pcap_datalink(pcap_t *p);
    
    • 1
    • 2
    • 3

    描述

    pcap_datalink() 返回由 p 指定的实时捕获或“保存文件”的链路层标头类型。
    它不能在 pcap_create(3PCAP) 创建的 pcap_activate(3PCAP) 尚未激活的 pcap 描述符上调用。
    https://www.tcpdump.org/linktypes.html 列出了 pcap_datalink() 可以返回的值,并描述了与这些值对应的数据包格式。

    不要假设给定捕获或“保存文件”的数据包将具有任何给定的链路层标头类型,例如以太网的 DLT_EN10MB。例如,Linux 上的“any”设备将具有 DLT_LINUX_SLL 或 DLT_LINUX_SLL2 的链路层标头类型,即使在打开“any”设备时系统上的所有设备都具有一些其他数据链路类型,例如 DLT_EN10MB 用于以太网。

    返回值

    pcap_datalink()成功时返回链路层标头类型,如果在已创建但未激活的捕获句柄上调用会抛出 PCAP_ERROR_NOT_ACTIVATED

    参考地址:https://www.tcpdump.org/manpages/libpcap-1.10.1/pcap_datalink.3pcap.html

    创建嗅探会话 pcap_open_live

    创建嗅探会话的任务非常简单。为此,我们使用 pcap_open_live(3PCAP)。这个函数的原型如下:

    pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms,
        char *ebuf)
    
    • 1
    • 2
    参数字段说明
    第一个参数第一个参数是我们在上一节中指定的设备。
    第二个参数snaplen 是一个整数,它定义了 pcap 捕获的最大字节数。
    第三个参数promisc,当设置为 true 时,使接口进入混杂模式(然而,即使它设置为 false,在特定情况下,接口也可能处于混杂模式,无论如何)。
    第四个参数to_ms 是以毫秒为单位的读取超时时间(值 0 表示没有超时;至少在某些平台上,这意味着您可能要等到足够数量的数据包到达才能看到任何数据包,因此您应该使用非零暂停)
    第五个参数ebuf 是一个字符串,我们可以在其中存储任何错误消息(就像我们在上面使用 errbuf 所做的那样)。
    返回值该函数返回我们的会话处理程序

    编译程序 pcap_compile

    为了编译程序,我们调用 pcap_compile()。原型将其定义为:

    int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, int optimize,
        bpf_u_int32 netmask)
    
    • 1
    • 2
    参数字段说明描述
    第一个参数第一个参数是我们的会话句柄(pcap_t *handle 在我们之前的例子中)。
    第二个参数我们将存储 过滤器编译版本的位置引用。
    第三个参数表达式本身;格式:常规字符串
    第四个参数是一个整数,它决定表达式是否应该“优化”(0 为假,1 为真——标准内容)。
    第五个参数我们必须指定过滤器应用到的网络的网络掩码。
    返回值失败返回-1,其他值都是成功

    设置过滤器 pcap_setfilter

    表达式编译完成后,就可以应用它了。输入 pcap_setfilter()。按照我们解释 pcap 的格式,我们来看看原型:

    int pcap_setfilter(pcap_t *p, struct bpf_program *fp)
    
    • 1
    参数说明描述
    第一个参数我们的会话处理程序
    第二个参数是对表达式的编译版本的引用(可能与 pcap_compile() 的第二个参数相同的变量)

    抓包函数 pcap_next

    从 pcap_t 读取下一个数据包

    一次捕获一个数据包

    # u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)
    const u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h);
    
    • 1
    • 2
    参数具体说明说明
    第一个参数session handler
    第二个参数是一个指向结构的指针,该结构包含有关数据包的一般信息,特别是它被嗅探的时间、该数据包的长度以及该特定部分的长度(例如,如果它被分段)。
    返回值返回指向此结构描述的数据包的 u_char 指针

    pcap_loop() – 处理来自实时捕获或保存文件的数据包

    进入循环

    typedef void (*pcap_handler)(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes);
    int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
    
    • 1
    • 2
    参数具体说明说明
    第一个参数第一个参数是我们会话句柄
    第二个参数是一个整数,它告诉 pcap_loop() 在返回之前它应该嗅探多少数据包(负值意味着它应该嗅探直到发生错误)
    第三个参数是回调函数的名称(只是它的标识符,没有括号)
    第四个参数最后一个参数在某些应用程序中很有用,但很多时候只是简单地设置为 NULL。假设除了 pcap_loop() 发送的参数之外,我们还有自己希望发送给回调函数的参数

    说明

    pcap_loop() 处理来自实时捕获或“保存文件”的数据包,直到处理完 cnt 数据包,从“保存文件”读取时到达“保存文件”的末尾,调用 pcap_breakloop(3PCAP),或发生错误。当实时数据包缓冲区超时发生时,它不会返回。 cnt 的值 -1 或 0 等价于无穷大,因此数据包将一直处理,直到出现另一个结束条件。

    pcap_dispatch()

    pcap_dispatch() 的用法几乎和pcap_loop相同。这两个函数之间的唯一区别是 pcap_dispatch() 将只处理它从系统接收到的第一批数据包,而 pcap_loop() 将继续处理数据包或批量数据包,直到数据包计数用完。有关它们之间差异的更深入讨论,请参见手册页

    pcap_geterr, pcap_perror - 获取或打印 libpcap 错误消息文本

    说明

    #include <pcap/pcap.h>
    
    char *pcap_geterr(pcap_t *p);
    void pcap_perror(pcap_t *p, const char *prefix);
    
    • 1
    • 2
    • 3
    • 4

    描述

    pcap_geterr() 返回与最后一个 pcap 库错误有关的错误文本。
    注意:在传递给它的 pcap_t 关闭后,它返回的指针将不再指向有效的错误消息字符串;您必须在关闭 pcap_t 之前使用或复制该字符串。

    pcap_perror() 在 stderr 上打印最后一个 pcap 库错误的文本,前缀为 prefix。

    参考地址:

    pcap
    https://www.tcpdump.org/manpages/libpcap-1.10.1/

  • 相关阅读:
    前端实现菜单&按钮级权限
    驱动开发:内核取ntoskrnl模块基地址
    【文末附gpt升级秘笈】AI热潮降温与AGI场景普及的局限性
    android 创建桌面快捷方式 ShortCut
    我的创作纪念日
    ARM开发初级-STM32F4寄存器-学习笔记03
    Win7显示屏幕亮度在哪里可以调节
    Spring动态代理的两种方式
    安装OCP集群
    C# 压缩质量可自己控制的JPEG的几种方式
  • 原文地址:https://blog.csdn.net/u013066244/article/details/125541100