ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Linux C 语言手写嗅探器,不依赖库也能抓包

Linux C 语言手写嗅探器,不依赖库也能抓包

为什么放弃 libpcap 直接操作原始套接字

在学习网络协议栈或开发嵌入式监控工具时,我们往往过度依赖libpcap这样的高级库。虽然它们封装良好、调用简单,但就像黑盒一样,屏蔽了数据包从网卡到用户空间的真实流转过程。对于希望深入理解 Linux 内核网络机制的开发者而言,直接使用 C 语言和原始套接字(Raw Socket)编写嗅探器,是打破这层抽象的最佳途径。

不依赖第三方库意味着我们需要亲手处理以太网帧的解析、IP 头部的拆解以及传输层协议的识别。这不仅能让程序体积更轻量,更适合资源受限的嵌入式环境,更能让我们直观地看到sk_buff在内核中是如何被层层剥离,最终变成用户态可见的数据流。本文将基于 Linux 环境,带你从零构建一个能够捕获 TCP/UDP 数据包的嗅探器,重点剖析PF_PACKET协议族的配置与手动解析流程。

核心机制:PF_PACKET 与混杂模式

在 Linux 内核中,想要绕过传输层直接抓取链路层数据,必须使用PF_PACKET协议族创建套接字。这与常见的AF_INET不同,后者只能接收发给本机的特定端口数据,而前者允许我们监听经过网卡的所有流量。

创建套接字的核心代码如下:

int sock_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (sock_fd < 0) { perror("Socket creation failed"); return -1; }

这里ETH_P_ALL表示捕获所有类型的以太网帧。然而,仅仅创建套接字还不够,默认情况下网卡只会接收目的 MAC 地址匹配本机或广播帧的数据。为了捕获流经该接口的所有数据包(包括发给其他主机的),必须将网卡设置为混杂模式(Promiscuous Mode)。

这需要通过bind绑定到具体接口,并利用setsockopt配置 PACKET_ADD_MEMBERSHIP:

struct sockaddr_ll sll; struct packet_mreq mr; // 绑定到指定接口(需先通过 ioctl 获取 ifr_ifindex) memset(&sll, 0, sizeof(sll)); sll.sll_family = AF_PACKET; sll.sll_ifindex = if_idx; // 假设已获取接口索引 sll.sll_protocol = htons(ETH_P_ALL); bind(sock_fd, (struct sockaddr *)&sll, sizeof(sll)); // 开启混杂模式 mr.mr_ifindex = if_idx; mr.mr_type = PACKET_MR_PROMISC; mr.mr_alen = 0; setsockopt(sock_fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr));

值得注意的是,执行上述操作通常需要root权限或具备CAP_NET_RAW能力,这是内核的安全限制,防止普通用户随意窃听网络流量。

手动拆解:从以太网帧到 IP 头部

当数据包被捕获到用户缓冲区后,它本质上是一段连续的字节流。我们需要按照协议规范,逐层偏移指针来解析内容。最外层是以太网帧头,紧接着是 IP 头,最后才是 TCP 或 UDP 头。

首先定义以太网头部结构(注意字节序和网络对齐):

struct eth_header { uint8_t dest_mac[6]; uint8_t src_mac[6]; uint16_t ether_type; };

读取数据后,先判断ether_type。若为0x0800,则表示载荷是 IPv4 数据包。接下来解析 IP 头部,重点关注协议字段以区分 TCP 还是 UDP:

struct ip_header { uint8_t ihl_version; uint8_t tos; uint16_t total_len; uint16_t id; uint16_t frag_off; uint8_t ttl; uint8_t protocol; // 6=TCP, 17=UDP uint16_t check; uint32_t src_ip; uint32_t dest_ip; }; // 解析示例 struct eth_header *eth = (struct eth_header *)buffer; if (ntohs(eth->ether_type) == 0x0800) { struct ip_header *ip = (struct ip_header *)(buffer + sizeof(struct eth_header)); // 提取源 IP 和目的 IP struct in_addr src = {.s_addr = ip->src_ip}; struct in_addr dst = {.s_addr = ip->dest_ip}; printf("IP: %s -> %s | Protocol: %d\n", inet_ntoa(src), inet_ntoa(dst), ip->protocol); // 根据 protocol 字段继续解析传输层 if (ip->protocol == 6) { // 解析 TCP 头部... } else if (ip->protocol == 17) { // 解析 UDP 头部... } }

在解析 TCP/UDP 头部时,同样需要计算偏移量。IP 头部的长度是可变的(由ihl_version低 4 位决定,单位是 4 字节),因此传输层头部的起始位置是以太网头大小 + IP 头长度。通过读取源端口和目的端口(需转换主机字节序),我们就能还原出完整的通信五元组信息。

性能优化:零拷贝与环形缓冲区

上述基于recvfrom的实现虽然逻辑清晰,但在高流量场景下存在性能瓶颈。每次系统调用都涉及内核态到用户态的数据拷贝,大量数据包会导致 CPU 上下文切换频繁,甚至丢包。

Linux 提供了TPACKET_V2或TPACKET_V3接口,支持基于共享内存的环形缓冲区(Ring Buffer),实现零拷贝抓包。其核心思路是通过mmap将内核分配的内存映射到用户空间,内核直接将数据包写入这块区域,用户程序只需轮询状态标志即可读取,无需额外的copy_to_user操作。

配置示例如下:

struct tpacket_req req; req.tp_block_size = 4096; // 块大小 req.tp_frame_nr = 1024; // 帧数量 req.tp_frame_size = 1514; // 单帧大小 req.tp_block_nr = 64; // 块数量 setsockopt(sock_fd, SOL_PACKET, PACKET_RX_RING, &req, sizeof(req)); void *mapped_buf = mmap(NULL, req.tp_block_size * req.tp_block_nr, PROT_READ | PROT_WRITE, MAP_SHARED, sock_fd, 0);

在这种模式下,开发者需要自行管理缓冲区的读写指针,检查帧状态头中的TP_STATUS_USER标志。虽然代码复杂度有所上升,但对于需要长期运行、高吞吐量的监控工具而言,这种机制能显著降低系统负载,确保在千兆甚至万兆网络环境下依然稳定工作。

通过亲手实现从套接字创建到协议解析的全过程,我们不仅掌握了一个轻量级嗅探器的写法,更深刻理解了 Linux 网络协议栈的数据流转逻辑。这种底层视角对于排查网络故障、设计高性能网关或开发嵌入式安全设备,都是不可或缺的基础能力。

网络安全的知识多而杂,怎么科学合理安排?

下面给大家总结了一套适用于网安零基础的学习路线,应届生和转行人员都适用,学完保底6k!就算你底子差,如果能趁着网安良好的发展势头不断学习,日后跳槽大厂、拿到百万年薪也不是不可能!

初级黑客

1、网络安全理论知识(2天)

①了解行业相关背景,前景,确定发展方向。

②学习网络安全相关法律法规。

③网络安全运营的概念。

④等保简介、等保规定、流程和规范。(非常重要)

2、渗透测试基础(一周)

①渗透测试 的流程、分类、标准

②信息收集技术:主动/被动信息搜集、Nmap工具、Google Hacking

③漏洞扫描、漏洞利用、原理,利用方法、工具(MSF)、绕过IDS和反病毒侦察

④主机攻防演练:MS17-010、MS08-067、MS10-046、MS12-20等

3、操作系统基础(一周)

①Windows系统常见功能和命令

②Kali Linux系统常见功能和命令

③操作系统安全(系统入侵排查/系统加固基础)

4、计算机网络基础(一周)

①计算机网络基础、协议和架构

②网络通信原理、OSI模型、数据转发流程

③常见协议解析(HTTP、TCP/IP、ARP等)

④网络攻击技术与网络安全防御技术

⑤Web漏洞原理与防御:主动/被动攻击、DDOS攻击、CVE漏洞复现

5、数据库基础操作(2天)

①数据库基础

②SQL语言基础

③数据库安全加固

6、Web渗透(1周)

①HTML、CSS和JavaScript简介

②OWASP Top10

③Web漏洞扫描工具

④Web渗透工具:Nmap、BurpSuite、SQLMap、其他(菜刀、漏扫等)

想要入坑黑客&网络安全的朋友,给大家准备了一份:282G全网最全的网络安全资料包免费领取

网络安全学习路线&学习资源

网络安全工程师企业级学习路线

很多小伙伴想要一窥网络安全整个体系,这里我分享一份打磨了4年,已经成功修改到4.0版本的《平均薪资40w的网络安全工程师学习路线图》对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

  1. 如图片过大被平台压缩导致看不清的话,大家记得点个关注,关注之后系统后台会自动发送给大家!到时候记得看后台消息就行了。


    学习资料工具包

    压箱底的好资料,全面地介绍网络安全的基础理论,包括逆向、八层网络防御、汇编语言、白帽子web安全、密码学、网络安全协议等,将基础理论和主流工具的应用实践紧密结合,有利于读者理解各种主流工具背后的实现机制。

    ​​​​​​

    网络安全源码合集+工具包

    ​​​​

    视频教程

    ​​​​

    视频配套资料&国内外网安书籍、文档&工具

    ​​​

    都放在这里啦

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进