linux下libpcap抓包分析

2023-11-18

linux下libpcap抓包分析

一、首先下载libpcap包http://www.tcpdump.org/#latest-release

  然后安装,安装完成后进入安装根目录的tests文件夹,编译运行findalldevstest.c(编译时加上-libpcap),查看是否发现所有网络设备。

二、下载wireshark观察抓包软件的各种功能

三、熟悉libpcap工作原理:

四、了解libpcap抓包基本流程:

五、编程实现

未完待续。。。 

 

PS:整理了一下libpcap常用的数据类型定义

  • libpcap的类型定义:

0)、typedef int bpf_int32

1)、typedef u_int bpf_u_int32

    32bit 的无类型整形;

2)、typedef pcap pcap_t

    Descriptor of an open capture instance(一个打开的捕获实例的描述符?)这个结构对用户是不透明的。

3)、typedef pcap_dumper pcap_dumper_t

libpcap保存文件的描述符。

4)、typedef pcap_if pcap_if_t

网卡链表的一个元素;

5)、typedef pcap_addr pcap_addr_t

网卡地址的表示;

6)、typedef void (*pcap_handler)(u_char *args, const struct pcap_pkthdr *header,    const u_char *packet);

    其中agrs是从pcap_dispatch()函数传递过来的第四个形参 ,一般我们自己的包捕捉程序不需要提供它,总是为NULL ;header指向
pcap_pkthdr结构,该结构位于真正的物理帧前面,用于消除不同链路层支持的差异 ;packet指向所捕获报文的物理帧。

 

  • libpcap结构体

Libpcap库函数所必须的数据结构定义主要包含在pcap.h和pcap-int.h两个头文件中

1)、pcap结构在pcap-int.h头文件中被定义:
 编程时需要涉及到的成员有:int fd; 打开设备的描述符;u_char *buffer; 是指向所捕获到数据的缓冲区指针
struct pcap
{
   int fd; /* 文件描述字,实际就是 socket */

    int selectable_fd; /* 在 socket 上,可以使用 select() 和 poll() 等 I/O 复用类型函数 */

    int snapshot; /* 用户期望的捕获数据包最大长度 */

    int linktype; /* 设备类型 */

    int tzoff;         /* 时区位置,实际上没有被使用 */

    int offset;       /* 边界对齐偏移量 */

    int break_loop; /* 强制从读数据包循环中跳出的标志 */

    struct pcap_sf sf; /* 数据包保存到文件的相关配置数据结构 */

    struct pcap_md md; /* 具体描述如下 */

   

    int bufsize; /* 读缓冲区的长度 */

    u_char buffer; /* 读缓冲区指针 */

    u_char *bp;

    int cc;

    u_char *pkt;

    /* 相关抽象操作的函数指针,最终指向特定操作系统的处理函数 */

    int   (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *);

    int   (*setfilter_op)(pcap_t *, struct bpf_program *);

    int   (*set_datalink_op)(pcap_t *, int);

    int   (*getnonblock_op)(pcap_t *, char *);

    int   (*setnonblock_op)(pcap_t *, int, char *);

    int   (*stats_op)(pcap_t *, struct pcap_stat *);

    void (*close_op)(pcap_t *);

    /*如果 BPF 过滤代码不能在内核中执行,则将其保存并在用户空间执行 */

    struct bpf_program fcode;

    /* 函数调用出错信息缓冲区 */

    char errbuf[PCAP_ERRBUF_SIZE + 1];

   

    /* 当前设备支持的、可更改的数据链路类型的个数 */

    int dlt_count;

    /* 可更改的数据链路类型号链表,在 linux 下没有使用 */

    int *dlt_list;

    /* 数据包自定义头部,对数据包捕获时间、捕获长度、真实长度进行描述 [pcap.h] */

    struct pcap_pkthdr pcap_header;  

};

 

/* 包含了捕获句柄的接口、状态、过滤信息  [pcap-int.h] */

struct pcap_md {

/* 捕获状态结构  [pcap.h] */

struct pcap_stat stat; 

    int use_bpf; /* 如果为1,则代表使用内核过滤*/

    u_long    TotPkts;

    u_long    TotAccepted; /* 被接收数据包数目 */

    u_long    TotDrops;       /* 被丢弃数据包数目 */

    long TotMissed;      /* 在过滤进行时被接口丢弃的数据包数目 */

    long OrigMissed; /*在过滤进行前被接口丢弃的数据包数目*/

#ifdef linux

    int   sock_packet; /* 如果为 1,则代表使用 2.0 内核的 SOCK_PACKET 模式 */

    int   timeout;  /* pcap_open_live() 函数超时返回时间*/

    int   clear_promisc; /* 关闭时设置接口为非混杂模式 */

    int   cooked;          /* 使用 SOCK_DGRAM 类型 */

    int   lo_ifindex;      /* 回路设备索引号 */

    char *device;  /* 接口设备名称 */

   

/* 以混杂模式打开 SOCK_PACKET 类型 socket 的 pcap_t 链表*/

struct pcap *next;      

#endif

};

 

(2)bpf_program结构
 
该结构在pcap_compile()函数中被使用,在bpf.h头文件中定义。

/* [pcap-bpf.h] */

struct bpf_program {

u_int bf_len; /* BPF 代码中谓词判断指令的数目 */

struct bpf_insn *bf_insns; /* 第一个谓词判断指令 */

};

   

/* 谓词判断指令结构 */

struct bpf_insn {

u_short    code;

u_char    jt;

u_char    jf;

bpf_int32 k;

};

 (3)

/usr/include/net/bpf.h

/*
* Structure prepended to each packet.
*/

内核过滤器每输出一个包,将在输出的数据前加了20字节的数据,这就是 struct bpf_hdr
struct bpf_hdr
{
    struct timeval bh_tstamp;   /* time stamp                 */
    bpf_u_int32    bh_caplen;   /* length of captured portion数据长度*/
    bpf_u_int32    bh_datalen;  /* original length of packet 实际包长度 */
    u_short        bh_hdrlen;   /* length of bpf header (this struct
                                   plus alignment padding)    */
};

(4)pcap_stat结构
 调用函数 pcap_stats() 可以返回一个该结构
struct pcap_stat {
        u_int ps_recv; /* number of packets received */
        u_int ps_drop; /* number of packets dropped */
        u_int ps_ifdrop; /* drops by interface XXX not yet supported */
};

 

5)、

struct pcap_addr:网卡地址描述
{
pcap_addr *next;如果非空,指向链表中一个元素的指针;空表示链表中的最后一个元素
sockaddr  *addr;  指向包含一个地址的sockaddr的结构的指针
sockaddr *netmask;如果非空,指向包含相对于addr指向的地址的一个网络掩码的结构
sockaddr *broadaddr;如果非空,指向包含相对于addr指向的地址的一个网络掩码的结构
sockaddr *dstaddr; 如果非空,指向一个相对于addr指向的源地址的目的地址,如果网                       络不支持点对点通讯,则为空
};

6)、dump文件格式

首先是Dump文件头

struct pcap_file_header {
bpf_u_int32 magic;
u_short version_major;
u_short version_minor;
bpf_int32 thiszone; /* gmt to local correction */
bpf_u_int32 sigfigs; /* accuracy of timestamps */
bpf_u_int32 snaplen; /* max length saved portion of each pkt */
bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */

};

然后是每一个包的包头和数据

pcap_pkthdr结构
 
/usr/include/pcap.h

/*
* Each packet in the dump file is prepended with this generic header.
* This gets around the problem of different headers for different
* packet interfaces.
*/
/* 自定义头部在把数据包保存到文件中也被使用 */

struct pcap_pkthdr

{

           struct timeval ts; /* 捕获时间戳 */

           bpf_u_int32 caplen; /* 捕获到数据包的长度 */

           bpf_u_int32 len; /* 数据包的真正长度 */

}

 

/* 单个数据包结构,包含数据包元信息和数据信息 */

struct singleton [pcap.c]

{

struct pcap_pkthdr hdr; /* libpcap 自定义数据包头部 */

const u_char * pkt; /* 指向捕获到的网络数据 */

};

 

 

7)、pcap_if (libpcap 自定义的接口信息链表 [pcap.h])

 

struct pcap_if

{

struct pcap_if *next;

char *name; /* 接口设备名 */

char *description; /* 接口描述 */

          

/*接口的 IP 地址, 地址掩码, 广播地址,目的地址 */

struct pcap_addr addresses;

bpf_u_int32 flags;      /* 接口的参数 */

};


教程在


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

linux下libpcap抓包分析 的相关文章

  • Linux、ARM:为什么仅当启动时存在 I2C GPIO 扩展器时才创建 gpiochip

    在 imx6sx 硬件平台 NXP 嵌入式 ARM 上使用 Linux 3 14 52 问题是设备树中指定的 PCF8575 I2C GPIO 扩展器不会实例化为 sys class gpio 结构中的设备 除非它们在内核启动期间存在 这些
  • 是否从页面缓存中的脏页面进行文件读取?

    当字节写入文件时 内核不会立即将这些字节写入磁盘 而是将这些字节存储在页缓存中的脏页中 回写缓存 问题是 如果在脏页刷新到磁盘之前发出文件读取 则将从缓存中的脏页提供字节 还是首先将脏页刷新到磁盘 然后进行磁盘读取以提供字节 将它们存储在进
  • 如何通过代理将套接字连接到http服务器?

    最近 我使用 C 语言编写了一个程序 用于连接到本地运行的 HTTP 服务器 从而向该服务器发出请求 这对我来说效果很好 之后 我尝试使用相同的代码连接到网络上的另一台服务器 例如 www google com 但我无法连接并从网络中的代理
  • 如何从类似于 eclipse 的命令行创建可运行的 jar 文件

    我知道 eclipse 会生成一个可运行的 jar 文件 其中提取并包含在该 jar 文件中的所有库 jar 文件 从命令提示符手动创建 jar 文件时如何执行类似的操作 我需要将所有 lib jar 解压到类文件夹中吗 目前我正在使用 j
  • CentOS目录结构是树形的吗?

    CentOS 上有相当于树的东西吗 如果你的 Centos 系统上没有安装 tree 无论如何我通常建议服务器设置使用最小安装磁盘 你应该在命令行中输入以下内容 yum install tree y 如果没有安装 那是因为您没有正确的存储库
  • Linux 上的 Python 3.6 tkinter 窗口图标错误

    我正在从 Python GUI 编程手册 学习 Python GUI 某项任务要求我通过将以下代码添加到我的配方中来更改窗口图标 Change the main windows icon win iconbitmap r C Python3
  • 为 Linux 安装 R 包时出错

    我试图在 R 3 3 上安装一个名为 rgeos 的包 但是当我输入 install packages rgeos 但它返回给我以下错误 其他包也会发生同样的情况 但不是所有包 gt installing source package rg
  • python:numpy 运行脚本两次

    当我将 numpy 导入到 python 脚本中时 该脚本会执行两次 有人可以告诉我如何阻止这种情况 因为我的脚本中的所有内容都需要两倍的时间 这是一个例子 usr bin python2 from numpy import print t
  • 如何从linux命令行运行.exe可执行文件? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我在 Windows 中有一个 abc exe 可执行文件 我可以使用 DOS 命令提示来执行此应用程序 并为其提供一些运行时变量 我想从
  • 套接字:监听积压并接受

    listen sock backlog 在我看来 参数backlog限制连接数量 这是我的测试代码 server initialize the sockaddr of server server sin family AF INET ser
  • 如何让 clangd 转向 c++20

    当没有其他信息时 如何让 clangd 回退到 c 20 例如 在第一次构建之前 cmake 可以生成一个 这是在带有最新 LLVM 的 Arch Linux 上 这是通过 Emacs LSP 运行的 但这应该没有什么区别 你可以加 Com
  • gentoo crontab:为什么这个简单的 crontab 不起作用?

    我使用 GENTOO 发行版 crontab e 35 12 root php5 home www cron php 当我手动运行时 php5 php5 home www cron php 这有效 它向我发送了一封电子邮件 然后我检查日期
  • 为什么在 Linux 上字符串文字的内存地址与其他字符串文字的内存地址如此不同?

    我注意到字符串文字在内存中的地址与其他常量和变量 Linux 操作系统 非常不同 它们有许多前导零 未打印 Example const char h Hi int i 1 printf p n void h printf p n void
  • 为 Qt 应用程序创建 Linux 安装

    我刚刚用 Qt Creator 制作了一个很棒的程序 我对自己很满意 如何将其从台式机移至笔记本电脑 那么 最好的方法是安装程序 对吗 对于 Ubuntu 这是一个 Debian 软件包 对吗 我怎么做 有人这样做过吗 他们可以分享 QT
  • 在Linux中断上下文中运行用户线程

    我正在编写一些定制的应用程序 并允许更改 Linux 内核中的中断处理程序代码 我有一个用户线程正在等待中断发生 如果发生中断 那么我要做的第一件事就是执行该用户线程 有什么办法让它发挥作用吗 Thanks 创建一个字符设备 这就是内核所做
  • 适用于 KDE 和 Gnome 的 Gui [重复]

    这个问题在这里已经有答案了 我想为一个现在是 CLI 的应用程序编写一个 gui 它需要在 KDE 和 Gnome DE 中 看起来不错 充分利用用户的外观设置 如果我选择 Qt 或 GTK 我能够做到这一点吗 它们与两个 DE 集成良好吗
  • 从多线程程序中调用 system()

    我们正在开发一个用 C 编写的多线程内存消耗应用程序 我们必须执行大量的 shellscript linux 命令 并获取返回码 读完之后article http www linuxprogrammingblog com threads a
  • 劫持系统调用

    我正在编写一个内核模块 我需要劫持 包装一些系统调用 我正在暴力破解 sys call table 地址 并使用 cr0 来禁用 启用页面保护 到目前为止一切顺利 一旦完成 我将公开整个代码 因此如果有人愿意 我可以更新这个问题 无论如何
  • Linux shell 脚本中的 while 循环超时

    这工作正常 无限循环 while TRUE do printf done 我在尝试着timeout this while loop与timeout命令 所有这些都不起作用 timeout 5 while TRUE do printf don
  • 在 /dev/input/eventX 中写入事件需要哪些命令?

    我正在开发一个android需要将触摸事件发送到 dev input eventX 的应用程序 我知道C执行此类操作的代码结构如下 struct input event struct timeval time unsigned short

随机推荐

  • 【spring boot logback】日志颜色渲染,使用logback-spring.xml自定义的配置文件后,日志没有颜色了...

    接着spring boot日志logback解析之后 发现使用logback spring xml自定义的配置文件后 日志没有颜色了 怎么办 官网处理日志链接 https logback qos ch manual layouts html
  • BeautifulSoup库

    BeautifulSoup安装 1 以管理员运行cmd 2 输入 pip install beautifulsoup4 BeautifulSoup库的基本元素 BeautifulSoup库的理解 BeautifulSoup库是解析 遍历 维
  • 【分享干货】Mac系统IDEA 安装教程

    IEEA 安装 什么是idea idea 介绍 idea官网 https www jetbrains com 外链图片转存失败 源站可能有防盗链机制 建议将图片保存下来直接上传 img Pynu6DTk 1654592966880 User
  • Java封装性(包含this关键字,构造器等)

    目录 一 封装性的含义 二 封装性的作用 三 封装性的体现 3 1 四种权限修饰符的介绍 3 2 分装性具体的实现 四 构造器的解释 4 1 构造器的作用 4 2 注意事项 4 3 构造器的举例说明 五 this关键字的使用 5 1 thi
  • jdk8的十大新特性

    了解jdk8的新特性首先要了解jdk7的新特新都有哪些方面增强 1 jdk语法上 1 1二进制变量的表示 支持将整数类型用二进制来表示 用Ob开头 1 2Switch语句支持String类型 1 3Try with resource语句 注
  • 欢欢喜喜: 在lenovo网站购T61的经历

    1月3日 在lenovo网站购T61的经历 一直以来对IBM的小黑情有独钟 不过考虑国内昂贵的价格和需求的迫切性不高 所以 也只是观望中 上次去米果的时候 看到lenovo网上卖的T61笔记本 标的价格比平时都低300 于是动了心 开始在
  • 使用 PullToRefresh 的总结

    前言 关于下拉刷新 上拉加载的框架现在有很多 这里奉上别人收集的一些框架 下拉刷新框架收集 但是笔者一直还在使用 PullToRefresh 个人觉得 PullToRefresh 使用起来还是比较简洁方便的 关于 PullToRefresh
  • unity-ugui-eventsystem

    EventSystem对象的说明 当我们在场景中创建任一UI对象后 Hierarchy面板中都可以看到系统自动创建了对象EventSystem 可以看到该对象下有三个组件 EventSystem StandaloneInputModule
  • 七天引爆社交新零售(助你提高十倍业绩)——前言

    2019年对于中小企业主 创业者 实体店主最大的机遇就是社交新零售 为什么这么说呢 随着日益上涨房租成本 人工成本的上升 实体生意利润空间越来越小了 而传统线上电商企业流量广告费也越来越贵了 大家一直在探索有没有一种低成本高收益的销售方式出
  • stream()转map转list、distinct()去重、判断空值、sorted排序正序多字段排序

    package demo io import demo api JavaBean Student import org junit platform commons util StringUtils import java util imp
  • 镜头快速精准反馈位置硬件环境搭建

    目录 概述 一 检测部分 1 原理图 2 PCB板 二 驱动部分 1 原理图 2 PCB板 概述 本篇只要介绍 硬件电路搭建 这次是项目的需要 重新捡起好多年没使用 Altium Designer 软件了 熟悉又陌生 经过2 3天时间 终于
  • 想要精通算法和SQL的成长之路 - 最长回文子序列

    想要精通算法和SQL的成长之路 最长回文子序列 前言 一 最长回文子序列 前言 想要精通算法和SQL的成长之路 系列导航 一 最长回文子序列 原题链接 首先 我们看下动态规划方程的定义 我们用dp i j 来代表 字符串s在下标区间为 i
  • Django连接MySQL数据库时出错:django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module: No mo

    基于python3解释器的虚拟环境中创建的Django项目 Django中默认连接的是SQLite3数据库 现更改为MySQL数据库 执行迁移文件时报错 django core exceptions ImproperlyConfigured
  • html5 调用本地街景,H5案例分享:在移动端调用腾讯街景

    在移动端调用腾讯街景 腾讯地图街景组件可以通过多种方式调起 来展示3D街景信息 腾讯街景API 是构建在v2版本上的全新应用接口 对于目的地 可以让用户足不出户 得到更直观 更真切 的身临其境的体验 比如 您可以就用在 房产 酒店 餐饮 娱
  • 使用Java 8函数式编程生成字母序列

    在 Java 8 中使用函数式编程生成字母序列是一个很大的挑战 Lukas Eder 愉快地接受了这个挑战 他将告诉我们如何使用 Java 8 来生成ABC的序列 当然 肯定不是一种蹩脚的方式 我被 Stack Overflow 上网友 m
  • C++ xml库的选择

    自从触及xml文件的读写 一直以来都是用的tinyxml2 接口简单 然而近期项目频繁出错 跟踪调试发现 问题出在了xml文件的读写上 当节点数超过百万级别的时候 内存暴增到G的当量 很显然程序会由于内存申请不足崩掉了 果断寻找替代品 百度
  • Android开源框架之Picasso(图片加载框架)

    简介 Picasso是Square公司出品的一个强大的图片下载和缓存图片库 在adapter中需要取消已经不在视野范围的ImageView图片资源的加载 否则会导致图片错位 Picasso已经解决了这个问题 使用复杂的图片压缩转换来减少内存
  • ue4 蓝图通信的几种方式

    一 设置公有变量 完成通信 1 蓝图类Door bp中声明变量NewVar 1 为公有 确定好变量类型 编译 2 关卡视口中选中这个蓝图类Door bp的实例 世界大纲视图下的细节面板中 默认下出现公有变量名称NewVar 1 用吸管吸取关
  • springboot+poi开发excel导出 加载Excel模板导出 Excel导出详解

    提到Excel导出功能 可能很多人都使用springmvc框架做过 笔者今天要给大家分享的是基于springBoot开发Excel复杂模板导出功能 所谓复杂模板指在模板里的特定表头里有不同的单元格合并以及背景色 字体颜色的填充 文本内容的对
  • linux下libpcap抓包分析

    linux下libpcap抓包分析 一 首先下载libpcap包http www tcpdump org latest release 然后安装 安装完成后进入安装根目录的tests文件夹 编译运行findalldevstest c 编译时