C语言实现TcpDump

news2025/4/15 9:49:48

一、

在 C 语言中实现 TCP 抓包功能,通常可以使用 libpcap 库。libpcap 是一个广泛使用的网络抓包库,它提供了捕获网络数据包的接口。
libpcap 是一个广泛使用的 C 语言库,用于捕获和过滤网络数据包。它提供了一个通用接口,用于访问数据链路层的协议,使用户能够在各种平台上实现网络流量捕获功能。

二、准备

安装 libpcap:在 Linux 系统中,可以使用以下命令安装

sudo apt-get install libpcap-dev

或者
下载、编译源码

git clone https://github.com/the-tcpdump-group/libpcap

可以查看官方文档

https://www.tcpdump.org/

三、代码

#include <stdio.h>
#include <stdlib.h>
#include <pcap/pcap.h>//头文件包含

#define SNAP_LEN 65535
#define PROMISC  1
#define TIMEOUT  1000             // ms
#define BUFSIZE  4 * 1024 * 1024  // 4MB

typedef struct {
    pcap_dumper_t *dumper;  // 用于保存数据包的句柄
    time_t start_time;       // 记录当前文件的起始时间
    long written_bytes;      // 当前文件已写入的字节数
    int file_index;          // 文件索引,用于防止同一秒生成两个文件
} capture_context_t;

//抓到包后具体的处理,根据带入的参数和自己需要的规则进行编写功能
void packet_handler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes) {
    capture_context_t *ctx = (capture_context_t *)user;
    time_t now = time(NULL);
    long packet_size = h->caplen;

    // 更新写入字节数
    ctx->written_bytes += packet_size;

    // 计算是否需要切换文件
    if (difftime(now, ctx->start_time) >= MAX_DURATION_SEC ||
        ctx->written_bytes >= MAX_FILE_SIZE) {

        // 关闭旧文件
        pcap_dump_close(ctx->dumper);

        // 打开新文件
        char filename[256];
        ctx->file_index += 1;
        generate_filename(filename, sizeof(filename), ctx->file_index);
        ctx->dumper = pcap_dump_open(ctx->handle, filename);
        ctx->start_time = now;
        ctx->written_bytes = 0;

        printf("🆕 Switched to new file: %s\n", filename);
    }

    // 写入当前包
    pcap_dump((u_char *)ctx->dumper, h, bytes);
}

int main() {
    char errbuf[PCAP_ERRBUF_SIZE];//存放错误打印
    pcap_t *handle;
    pcap_dumper_t *dumper;
    struct bpf_program fp;
    bpf_u_int32 net = 0, mask = 0;

	//查找当前系统中一个默认的抓包网络设备名,需要确认是否有权限
    const char *dev = pcap_lookupdev(errbuf);
    if (!dev) {
        fprintf(stderr, "Device not found: %s\n", errbuf);
        return 1;
    }

    const char *filter_exp = "tcp port 80"; // 设置过滤器的规则,可以换成 "udp", "ip", "host 192.168.1.1", 等等
    const char *outfile = "output.pcap";    // 输出文件

    printf("Using device: %s\n", dev);

	// 获取网络地址 & 掩码(用于过滤器编译)
    if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
        fprintf(stderr, " Could not get netmask for %s: %s\n", dev, errbuf);
        net = 0;
        mask = 0;
    }

	//创建并配置抓包句柄
    handle = pcap_create(dev, errbuf);
    if (!handle) {
        fprintf(stderr, " pcap_create failed: %s\n", errbuf);
        return 1;
    }

	//设置抓包长度
    pcap_set_snaplen(handle, SNAP_LEN);
    //混杂模式,当网络接口处于混杂模式时,它会接收所有经过的数据包,而不仅仅是发送给它的包。
    pcap_set_promisc(handle, PROMISC);
    //设置捕获数据包的超时时间,以毫秒为单位,表示在没有接收到数据包的情况下,等待的最长时间
    pcap_set_timeout(handle, TIMEOUT);
    //设置缓冲区大小,增大缓冲区可以提高捕获性能,尤其是在高流量环境中,可以防止数据包丢失。
    pcap_set_buffer_size(handle, BUFSIZE);

	//激活刚刚设置的参数
    if (pcap_activate(handle) != 0) {
        fprintf(stderr, " pcap_activate failed: %s\n", pcap_geterr(handle));
        return 1;
    }

	//编译 BPF(Berkeley Packet Filter)过滤器表达式,将过滤规则转化为库格式
    if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
        fprintf(stderr, " Couldn't parse filter: %s\n", pcap_geterr(handle));
        return 1;
    }

	//应用过滤规则
    if (pcap_setfilter(handle, &fp) == -1) {
        fprintf(stderr, " Couldn't install filter: %s\n", pcap_geterr(handle));
        return 1;
    }

    // 打开输出文件
    dumper = pcap_dump_open(handle, outfile);
    if (!dumper) {
        fprintf(stderr, " Couldn't open dump file: %s\n", pcap_geterr(handle));
        return 1;
    }

    capture_context_t ctx = { .dumper = dumper };

    printf(" Saving packets to: %s\n", outfile);
    //抓多少包,抓到的包怎么处理packet_handler
    pcap_loop(handle, 10, packet_handler, (u_char *)&ctx); // 抓 10 个包
 
    // 清理资源
    pcap_dump_close(dumper);
    pcap_freecode(&fp);
    pcap_close(handle);

    printf(" Capture complete. Output saved to: %s\n", outfile);
    return 0;
}

编译、需要进行库的链接,以及操作权限

gcc -o pcap_loop_example pcap_loop_example.c -lpcap
sudo ./pcap_loop_example

#四、Shell 脚本(自动添加权限)
可以当做自启动脚本

#!/bin/bash
# file: grant_pcap_cap.sh

TARGET="./pcap_loop_example "

if [ ! -f "$TARGET" ]; then
    echo "❌ $TARGET not found. Please compile it first."
    exit 1
fi

echo "🔧 Adding capability to $TARGET ..."
sudo setcap cap_net_raw,cap_net_admin=eip $TARGET

echo "✅ Done. You can now run it as a normal user:"
echo "   $TARGET"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2334399.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【STM32】STemWin库,使用template API

目录 CubeMX配置 工程文件配置 Keil配置 STemwin配置 GUIConf.c LCDConf.c 打点函数 修改屏幕分辨率 GUI_X.c 主函数 添加区域填充函数 移植过程中需要一些参考手册&#xff0c;如下 STemwin使用指南 emWin User Guide & Reference Manual CubeMX配置 参考驱…

Matlab Add Legend To Graph-图例添加到图

Add Legeng To Graph: Matlab的legend&#xff08;&#xff09;函数-图例添加到图 将图例添加到图 ,图例是标记绘制在图上的数据序列的有用方法。 下列示例说明如何创建图例并进行一些常见修改&#xff0c;例如更改位置、设置字体大小以及添加标题。您还可以创建具有多列的图…

2025年七星棋牌跨平台完整源码解析(200+地方子游戏+APP+H5+小程序支持,附服务器镜像导入思路)

目前市面上成熟的棋牌游戏源码很多&#xff0c;但能做到平台全覆盖、地方玩法丰富、交付方式标准化的系统却不多。今天这套七星棋牌2023完整源码具备安卓/iOS/H5/微信小程序端四端互通能力&#xff0c;附带200多款地方子游戏&#xff0c;还配备了后台管理与自动热更系统&#x…

Go语言--语法基础4--基本数据类型--整数类型

整型是所有编程语言里最基础的数据类型。 Go 语言支持如下所示的这些整型类型。 需要注意的是&#xff0c; int 和 int32 在 Go 语言里被认为是两种不同的类型&#xff0c;编译器也不会帮你自动做类型转换&#xff0c; 比如以下的例子会有编译错误&#xff1a; var value2 in…

智慧乡村数字化农业全产业链服务平台建设方案PPT(99页)

1. 农业全产业链概念 农业全产业链是依托数字化、电子商务、云计算等技术&#xff0c;整合规划咨询、应用软件设计与开发等服务&#xff0c;推动农业产业升级和价值重塑&#xff0c;构建IT产业融合新生态。 2. 产业链技术支撑 利用云计算、大数据、区块链等技术&#xff0c;为…

信息系统项目管理师-软考高级(软考高项)​​​​​​​​​​​2025最新(二)

个人笔记整理---仅供参考 第二章信息技术发展 2.1信息技术及其发展 2.1.1计算机软硬件 2.1.2计算机网络 2.1.3存储和数据库 2.1.4信息安全 公钥公开&#xff0c;私钥保密 2.1.5信息技术的发展 2.2新一代信息技术及应用 2.2.1物联网 2.2.2云计算 2.2.3大数据 2.2.4区块链 2.2.5…

基于Springboot+Mysql的闲一品(含LW+PPT+源码+系统演示视频+安装说明)

系统功能 管理员功能&#xff1a;首页、个人中心、用户管理、零食分类管理、零食信息管理、订单评价管理、系统管理、订单管理。用户功能&#xff1a;首页、个人中心、订单评价管理、我的收藏管理、订单管理。前台首页功能&#xff1a;首页、零食信息、零食资讯、个人中心、后…

stm32week11

stm32学习 八.stm32基础 2.stm32内核和芯片 F1系统架构&#xff1a;4个主动单元和4个被动单元 AHB是内核高性能总线&#xff0c;APB是外围总线 总线矩阵将总线和各个主动被动单元连到一起 ICode总线直接连接Flash接口&#xff0c;不需要经过总线矩阵 AHB&#xff1a;72MHz&am…

从三次方程到复平面:复数概念的奇妙演进(二)

注&#xff1a;本文为 “复数 | 历史 / 演进” 相关文章合辑。 因 csdn 篇幅限制分篇连载&#xff0c;此为第二篇。 生料&#xff0c;不同的文章不同的点。 机翻&#xff0c;未校。 History of Complex Numbers 复数的历史 The problem of complex numbers dates back to …

基于视觉语言模型的机器人实时探索系统!ClipRover:移动机器人零样本视觉语言探索和目标发现

作者&#xff1a;Yuxuan Zhang 1 ^{1} 1, Adnan Abdullah 2 ^{2} 2, Sanjeev J. Koppal 3 ^{3} 3, and Md Jahidul Islam 4 ^{4} 4单位&#xff1a; 2 , 4 ^{2,4} 2,4佛罗里达大学电气与计算机工程系RoboPI实验室&#xff0c; 1 , 3 ^{1,3} 1,3佛罗里达大学电气与计算机工程系F…

LabVIEW往复式压缩机管路故障诊断系统

往复式压缩机作为工业领域的关键设备&#xff0c;广泛应用于石油化工、能源等行业&#xff0c;承担着气体压缩的重要任务。然而&#xff0c;其管路故障频发&#xff0c;不仅降低设备性能、造成能源浪费&#xff0c;还可能引发严重安全事故。因此&#xff0c;开发精准高效的管路…

springboot 项目 jmeter简单测试流程

测试内容为 主机地址随机数 package com.hainiu.example;import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotat…

算法思想之位运算(二)

欢迎拜访&#xff1a;雾里看山-CSDN博客 本篇主题&#xff1a;算法思想之位运算(二) 发布时间&#xff1a;2025.4.13 隶属专栏&#xff1a;算法 目录 滑动窗口算法介绍六大基础位运算符常用模板总结 例题判定字符是否唯一题目链接题目描述算法思路代码实现 汉明距离题目链接题目…

【计网】网络交换技术之报文交换(复习自用,了解,重要3)

复习自用的&#xff0c;处理得比较草率&#xff0c;复习的同学或者想看基础的同学可以看看&#xff0c;大佬的话可以不用浪费时间在我的水文上了 另外两种交换技术可以直接点击链接访问相关笔记&#xff1a; 电路交换 分组交换 一、报文交换的定义 报文交换&#xff08;Me…

【动态规划】深入动态规划:背包问题

文章目录 前言01背包例题一、01背包二、分割等和子集三、目标和四、最后一块石头的重量|| 完全背包例题一、完全背包二、 零钱兑换三、零钱兑换||四、完全平方数 前言 什么是背包问题&#xff0c;怎么解决算法中的背包问题呢&#xff1f; 背包问题 (Knapsack problem) 是⼀种组…

BUUCTF-web刷题篇(25)

34.the mystery of ip 给出链接&#xff0c;输入得到首页&#xff1a; 有三个按钮&#xff0c;flag点击后发现页面窃取客户端的IP地址&#xff0c;通过给出的github代码中的php文件发现可以通过XFF或Client-IP传入值。使用hackbar或BP 使用XSS&#xff0c;通过github给出的目录…

StringBuilder类基本使用

文章目录 1. 基本介绍2. StringBuilder常用方法3. String、StringBuffer 和 StringBuilder 的比较4. String、StringBuffer 和 StringBuilder 的效率测试5. String、StringBuffer 和 StringBuilder 的选择 1. 基本介绍 一个可变的字符序列。此类提供一个与StringBuffer兼容的A…

设计模式 --- 访问者模式

访问者模式是一种行为设计模式&#xff0c;它允许在不改变对象结构的前提下&#xff0c;定义作用于这些对象元素的新操作。 优点&#xff1a; 1.​​符合开闭原则&#xff1a;新增操作只需添加新的访问者类&#xff0c;无需修改现有对象结构。 ​​2.操作逻辑集中管理​​&am…

HashTable,HashMap,ConcurrentHashMap之间的区别

文章目录 线程安全方面性能方面总结 线程安全方面 HashMap线程不安全&#xff0c;HashMap的方法没有进行同步&#xff0c;多个线程同时访问HashMap&#xff0c;并至少有一个线程修改了其内容&#xff0c;则必须手动同步。 HashTable是线程安全的&#xff0c;在HashMap的基础上…

LeetCode.225. 用队列实现栈

用队列实现栈 题目解题思路1. push2. pop3. empty CodeQueue.hQueue.cStack.c 题目 225. 用队列实现栈 请你仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、pop 和 empty&#xff09;。 实现…