新闻详情

新闻详情

首页 / 资讯中心 / 详情

VC++抓包实战:WinPcap截取网卡数据包与协议解析

发布时间:2026/10/1 11:34:26来源:尧图网络
VC++抓包实战:WinPcap截取网卡数据包与协议解析
简介这是一份面向网络编程初学者与安全方向开发者的 VC 网络抓包程序源代码基于 WinPcap 的 Packet32 驱动库实现网卡数据包嗅探与截取可用于学习底层协议解析、网卡混杂模式设置及数据包过滤等核心技能。压缩包共 44 个文件约 78KB以 16 个 .h 头文件与 8 个 .cpp 源文件为主体涵盖协议定义、IP 地址处理、过滤对话框与主框架等模块另含 dsw/dsp 工程文件、vxd 虚拟驱动、dll 动态库、ico/bmp 图标位图资源及 readme 说明工程结构完整可直接编译运行。目前已有 780 人学习下载。读者可从中获取一套可运行的嗅探器完整实现理解 Packet32 驱动调用、网卡数据捕获与过滤逻辑并借助现成工程快速搭建自己的抓包实验环境适合作为课程设计或网络协议分析的参考范例。1. 从一份 VC 抓包源码说起网卡数据包到底怎么被“截”下来的很多人第一次拿到“vc sniff 截取网卡数据包”这类源码压缩包时最直接的反应是双击 .sln 编译然后运行结果发现列表里空空如也或者抓到的全是本机回环流量于是怀疑代码是假的。其实问题不在代码而在于没搞清楚 Windows 下抓包的底层链路网卡默认只接收目的 MAC 是自己的帧你要“截”别人的包必须先把网卡切到混杂模式再通过 NDIS 中间层驱动或者 WinPcap/Npcap 这类抓包驱动把数据从内核态搬到用户态。这份源码解决的正是这件事——它用 VC 写了一个基于 WinPcap 的用户态抓包程序能枚举网卡、开启混杂、实时解析以太网帧、IP 头和 TCP/UDP 头并把结果打到列表控件里。适合两类人一是想搞懂协议栈实际长什么样的网络初学者二是需要在自己工具里嵌入抓包能力的 VC 开发者。下面我不复述那份源码的每一行而是按“能跑起来、能改得动、能排得错”的顺序把这类程序从环境到代码到坑完整走一遍。2. 环境与选型为什么 WinPcap 仍是 VC 抓包最稳的起点2.1 抓包驱动三选一WinPcap、Npcap、原始套接字在 Windows 上做网卡数据包截取能走的路其实只有三条。第一条是原始套接字Raw Socket用SOCK_RAWSIO_RCVALL直接收 IP 层数据。优点是系统自带、不用装驱动缺点是只能收到 IP 包拿不到以太网帧头也看不到 ARP 这类非 IP 流量而且从 Vista 之后微软对原始套接字的发送和接收做了严格限制很多场景下只能收到本机相关流量。第二条是 NDIS 中间层驱动自己写一个过滤驱动挂在协议栈里性能最好、能拿到最原始的数据但开发门槛极高需要 WDK、签名、调试稍有不慎就是蓝屏。第三条就是 WinPcap/Npcap 这类抓包驱动它在内核层用 NDIS 协议驱动抓包再通过一个用户态 DLLwpcap.dll暴露pcap_*接口给 VC 调用。对绝大多数“vc sniff 截取网卡数据包”的需求来说WinPcap 是性价比最高的选择接口简单、资料多、源码里通常直接#include pcap.h就能编。Npcap 是 WinPcap 的现代替代品支持 Win10/Win11 和环回抓包API 基本兼容新项目建议直接上 Npcap。原始套接字只适合“我只要 IP 层、不想装任何驱动”的极简场景。2.2 开发环境搭建VS2017/VS2019 WinPcap SDK 的四个步骤热词里“vs2017 vc安装”“vc运行库”出现频率很高说明很多人卡在环境上。下面是我在 VS2017 和 VS2019 上都验证过的配置流程。第一步装 WinPcap 运行库。去官网下载WinPcap_4_1_3.exe安装后会得到C:\Windows\System32\wpcap.dll和Packet.dll。注意如果你用的是 Npcap安装时勾选“WinPcap API 兼容模式”否则老代码里的pcap_open_live可能找不到入口。第二步下载 WinPcap Developers Pack4.1.3 版本解压后得到Include和Lib两个目录。把Include下的pcap.h、pcap-namedb.h等头文件路径记下来Lib下根据你的目标平台选x64或x86里的wpcap.lib和Packet.lib。第三步在 VS 项目属性里配置。右键项目 → 属性 → C/C → 常规 → 附加包含目录加入 Developers Pack 的Include路径链接器 → 常规 → 附加库目录加入Lib\x64链接器 → 输入 → 附加依赖项填入wpcap.lib;Packet.lib;ws2_32.lib。ws2_32.lib不能少因为解析 IP 地址时会用到inet_ntoa之类的函数。第四步把目标平台改成 x64。很多老源码默认 Win32而新版 WinPcap 的库是分平台的混用会报LNK2019 无法解析的外部符号。改完平台后重新生成如果还报错检查pcap.h是否被正确包含以及是否在#include pcap.h之前定义了WPCAP和HAVE_REMOTE。// stdafx.h 或 pch.h 里加这两行顺序不能反 #define WPCAP #define HAVE_REMOTE #include pcap.h #include winsock2.h #pragma comment(lib, ws2_32.lib) #pragma comment(lib, wpcap.lib)这段代码的作用是告诉pcap.h启用远程抓包相关声明并提前链接 Winsock 和 WinPcap 的导入库。参数上WPCAP是必须的HAVE_REMOTE如果你不用pcap_open_remote可以不加但加了不会出错。#pragma comment是 MSVC 特有的链接指令等价于在项目属性里手动加依赖项适合源码分发时减少配置步骤。提示如果你编译时遇到pcap.h里struct timeval重定义说明winsock2.h被包含了两次把#include winsock2.h提到#include windows.h之前即可。3. 核心代码拆解枚举网卡、开混杂、抓包、解析四步走3.1 用 pcap_findalldevs 枚举网卡并打印可读名称抓包程序启动后第一件事是让用户选网卡。WinPcap 提供pcap_findalldevs返回一个pcap_if_t链表每个节点包含网卡名、描述和地址列表。网卡名是\Device\NPF_{GUID}这种形式直接显示给用户没法看所以要用描述字段。pcap_if_t *alldevs, *d; char errbuf[PCAP_ERRBUF_SIZE]; if (pcap_findalldevs(alldevs, errbuf) -1) { fprintf(stderr, 枚举网卡失败: %s\n, errbuf); return -1; } int i 0; for (d alldevs; d ! NULL; d d-next) { printf(%d. %s\n, i, d-description ? d-description : d-name); // 把 d-name 存到数组里后面 pcap_open_live 要用 } if (i 0) { printf(没有找到可用网卡确认 WinPcap/Npcap 服务已启动\n); pcap_freealldevs(alldevs); return -1; }逻辑说明pcap_findalldevs返回 0 表示成功-1 表示失败错误信息在errbuf里。d-description是网卡的人类可读名称比如“Intel(R) Ethernet Connection I219-V”d-name是设备路径。参数上errbuf至少PCAP_ERRBUF_SIZE256字节。遍历完后如果i 0通常是 WinPcap 的npf服务没启动去服务管理器里把 “NPF” 或 “npcap” 服务设为自动并启动。3.2 pcap_open_live 的 snaplen、promisc、timeout 三个参数怎么定选好网卡后调用pcap_open_live打开设备。这个函数的四个参数直接决定抓包行为很多人抓不到包就是这里设错了。pcap_t *adhandle; // snaplen65536 抓完整帧promisc1 开混杂timeout1000 毫秒 adhandle pcap_open_live(d-name, 65536, 1, 1000, errbuf); if (adhandle NULL) { fprintf(stderr, 打开网卡失败: %s\n, errbuf); pcap_freealldevs(alldevs); return -1; }snaplen是每个包最多抓多少字节。设 65536 能覆盖绝大多数以太网帧最大 1518 字节巨型帧也就 9000 左右设太小会截断解析 IP 头时可能越界。promisc设为 1 表示混杂模式网卡会接收所有经过它的帧而不只是发给自己的如果你只想抓本机流量设 0 也行但“截取网卡数据包”通常要 1。timeout是内核缓冲区等待超时单位毫秒设 1000 表示即使没包也会每秒返回一次方便程序响应退出信号设 0 会一直阻塞到有包为止界面容易卡死。注意混杂模式只在交换机环境下能抓到“经过本网卡”的包跨交换机的流量抓不到这是网络拓扑决定的不是代码问题。3.3 抓包主循环与以太网帧、IP、TCP 头的逐层解析打开网卡后进入pcap_next_ex循环。它返回 1 表示抓到包0 表示超时-1 表示出错-2 表示读到离线文件末尾。每个包用pcap_pkthdr描述时间戳和长度数据指针指向原始帧。struct pcap_pkthdr *header; const u_char *pkt_data; int res; while ((res pcap_next_ex(adhandle, header, pkt_data)) 0) { if (res 0) continue; // 超时继续 // 以太网帧头 14 字节目的 MAC(6) 源 MAC(6) 类型(2) if (header-caplen 14) continue; u_short eth_type ntohs(*(u_short*)(pkt_data 12)); if (eth_type ! 0x0800) continue; // 只处理 IPv4 // IP 头从第 14 字节开始 const u_char *ip pkt_data 14; int ip_header_len (ip[0] 0x0F) * 4; u_char protocol ip[9]; if (protocol ! 6 protocol ! 17) continue; // 只看 TCP/UDP // 源 IP 和目的 IP 在 IP 头偏移 12 和 16 struct in_addr src, dst; memcpy(src, ip 12, 4); memcpy(dst, ip 16, 4); printf([%s - %s] proto%d len%d\n, inet_ntoa(src), inet_ntoa(dst), protocol, header-len); }逻辑说明ntohs把网络字节序转成主机字节序以太网类型 0x0800 是 IPv40x0806 是 ARP0x86DD 是 IPv6。IP 头长度字段在第一个字节的低 4 位单位是 4 字节所以乘 4。协议字段偏移 96 是 TCP17 是 UDP。源 IP 和目的 IP 各占 4 字节分别偏移 12 和 16。参数上header-caplen是实际抓到的长度header-len是帧的原始长度两者在没截断时相等。如果你要解析 TCP 端口继续往后偏移ip_header_len就是 TCP 头前 2 字节源端口接着 2 字节目的端口。3.4 把抓到的包写进 MFC 列表控件线程与刷新频率如果源码是 MFC 对话框程序抓包循环不能直接跑在 UI 线程里否则界面假死。常见做法是开一个AfxBeginThread工作线程在线程里跑pcap_next_ex每抓到一个包就PostMessage给主窗口主窗口收到消息后往CListCtrl插入行。// 工作线程里 CString str; str.Format(_T(%s - %s), CString(inet_ntoa(src)), CString(inet_ntoa(dst))); pMainDlg-PostMessage(WM_ADD_PACKET, (WPARAM)new CString(str), 0); // 主窗口消息处理 LRESULT CMainDlg::OnAddPacket(WPARAM wParam, LPARAM lParam) { CString *pStr (CString*)wParam; int n m_list.InsertItem(m_list.GetItemCount(), *pStr); delete pStr; return 0; }逻辑说明PostMessage是异步的不会阻塞抓包线程用new CString把数据传到 UI 线程UI 线程负责delete避免跨线程访问 MFC 对象。参数上WM_ADD_PACKET是自定义消息用WM_USER 100定义。刷新频率上如果流量很大每个包都插列表会卡常见优化是攒够 50 个包或每 200 毫秒批量刷新一次。4. 避坑与排查抓不到包、编译报错、混杂模式失效的 5 个血泪记录4.1 现象编译报 LNK2019 无法解析 pcap_open_live原因链接器没找到wpcap.lib或者平台位数不匹配。VS 项目是 x64但附加库目录指向了Lib而不是Lib\x64或者wpcap.lib是 32 位的。解决检查项目属性 → 链接器 → 常规 → 附加库目录确认路径末尾是\Lib\x64再检查链接器 → 输入 → 附加依赖项里wpcap.lib拼写正确。如果用的是 Npcap SDK库文件名可能是wpcap.lib和Packet.lib路径在Npcap SDK\Lib\x64。4.2 现象程序运行后网卡列表为空原因WinPcap/Npcap 的驱动服务没启动或者当前用户没有管理员权限。pcap_findalldevs需要访问\\.\npf设备普通用户可能被拒绝。解决以管理员身份运行程序去服务管理器确认 “NPF” 或 “npcap” 服务状态是“正在运行”启动类型设为“自动”。如果服务不存在重新安装 WinPcap/Npcap安装时勾选“安装驱动”。4.3 现象能抓到本机包但抓不到局域网其他机器的包原因混杂模式没生效或者网络拓扑是交换机。交换机只会把帧转发到目的端口除非你做端口镜像否则本网卡物理上收不到别人的流量。解决确认pcap_open_live第三个参数是 1确认网卡属性里“混杂模式”没被驱动禁用。如果拓扑是交换机且没有镜像口任何软件都抓不到这不是代码能解决的。4.4 现象解析 IP 头时程序崩溃或打印乱码原因没有检查header-caplen是否足够长直接按固定偏移读。比如只抓到 20 字节的帧却去读偏移 16 的目的 IP越界访问。解决在每一层解析前加长度判断。以太网帧至少 14 字节IPv4 头至少 20 字节TCP 头至少 20 字节。用if (header-caplen 14 20) continue;这类守卫。4.5 现象抓包线程退出时程序卡死或崩溃原因pcap_next_ex阻塞在超时等待线程无法及时退出或者 UI 线程已经销毁工作线程还在PostMessage。解决设一个volatile bool m_bStop标志线程循环里检查pcap_open_live的 timeout 设 1000 而不是 0让循环每秒有机会检查标志。退出时先置m_bStop true再WaitForSingleObject等线程结束最后pcap_close。5. 进阶技巧用 pcap_compile pcap_setfilter 做内核级过滤抓到包之后如果全丢给用户态解析流量一大 CPU 就飙。WinPcap 支持在驱动层设置 BPF 过滤规则只有匹配的包才会被复制到用户态这是提升性能最直接的手段。用法分三步编译过滤表达式、设置过滤器、再进抓包循环。struct bpf_program fcode; // 只抓 80 端口的 TCP 包且源或目的 IP 是 192.168.1.100 const char *filter_str tcp port 80 and host 192.168.1.100; if (pcap_compile(adhandle, fcode, filter_str, 1, 0xffffff) 0) { fprintf(stderr, 编译过滤规则失败: %s\n, pcap_geterr(adhandle)); return -1; } if (pcap_setfilter(adhandle, fcode) 0) { fprintf(stderr, 设置过滤器失败: %s\n, pcap_geterr(adhandle)); return -1; } pcap_freecode(fcode); // 设置完就可以释放编译结果 // 之后 pcap_next_ex 只会返回匹配的包逻辑说明pcap_compile把人类可读的过滤表达式编译成 BPF 字节码第四个参数optimize设 1 开启优化第五个参数是子网掩码不关心就填0xffffff。pcap_setfilter把字节码下发给驱动。pcap_freecode释放编译占用的内存但过滤器已经生效不影响后续抓包。参数上过滤表达式支持host、net、port、portrange、tcp、udp、icmp以及and、or、not组合写法和 tcpdump 完全一致。我自己的习惯是程序启动时先不设过滤让用户看到所有流量等用户输入过滤条件后再pcap_setfilter动态更新。这样既灵活又不会一上来就漏包。另外如果你要抓的是 HTTP 请求内容过滤规则写tcp port 80就够了但解析 HTTP 时要注意 TCP 流可能分片一个 HTTP 请求可能跨多个包需要自己做流重组这是另一个话题了。最后说一个我踩过的坑pcap_compile的过滤表达式里如果用了host但 DNS 解析失败编译会报错。生产环境里尽量用 IP 而不是域名避免运行时依赖 DNS。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

SDD与Harness驾驭工程:从氛围编码到可控AI编程实战 2026/10/1 13:02:16

SDD与Harness驾驭工程:从氛围编码到可控AI编程实战

1. 从“氛围编码”到可控工程:SDD 与 Harness 到底在解决什么“氛围编码”这个词,最早在开发者圈子里流行起来的时候,带着一种半调侃半惊喜的语气。你对着 AI 编程助手敲下一段模糊的需求,比如“帮我做一个用户登录页面&#xff0…

阅读更多 →
LLM输出失控怎么办?五层Guardrail护栏体系从格式校验到熔断兜底全解析 2026/10/1 13:02:15

LLM输出失控怎么办?五层Guardrail护栏体系从格式校验到熔断兜底全解析

上个月我们客服工单自动回复系统正式接入 LLM,结果三天之内生产环境出了两次事故。第一次是模型输出的 JSON 多了一个尾逗号,下游工单写入服务直接全红;第二次更麻烦,一条自动回复里夹带了另一个用户的订单号,隐私合规…

阅读更多 →
Skills Manager:统一管理54+ AI编程工具的Agent技能体系 2026/10/1 13:02:15

Skills Manager:统一管理54+ AI编程工具的Agent技能体系

AI 编程工具的爆发式增长,让一个很现实的问题浮出水面:每个工具都有自己的 Agent 技能体系,格式不同、目录不同、加载方式不同。你可能有 Cursor 的一套规则文件、Claude Code 的一套技能目录、Windsurf 的又一套配置,再加上各种 …

阅读更多 →
从GitHub日榜看开源新趋势:AI基建与开发者工具双轮驱动 2026/10/1 13:02:14

从GitHub日榜看开源新趋势:AI基建与开发者工具双轮驱动

1. 2026年9月25日的GitHub日榜:这九只项目正在闷声发大财 老实说,我现在每天起床后的第一件事,已经不是刷朋友圈了,而是先看一眼GitHub Trending。这个习惯坚持了快七年,从当初的每天花十分钟随便翻翻,到现…

阅读更多 →
DeepSeek本地部署实战:Ollama+Dify搭建内网私有知识库问答系统 2026/10/1 13:02:14

DeepSeek本地部署实战:Ollama+Dify搭建内网私有知识库问答系统

前天一位做企业内部知识库的朋友问我,能不能把 DeepSeek 这类开源模型部署到他们只有内网的测试环境里。他自己的笔记本是 16G 内存的 Windows,手头还有一台 32G 内存的旧服务器,想跑一个能给团队用的“私有问答机器人”。我给他的方案就是 O…

阅读更多 →
邢台资质齐全的GEO推荐机构、推荐一下GEO企业、有实力的GEO机构筛选名录 2026/10/1 13:02:08

邢台资质齐全的GEO推荐机构、推荐一下GEO企业、有实力的GEO机构筛选名录

行业科普:GEO推广与数字化营销的底层逻辑在数字化浪潮席卷各行各业的今天,企业获客方式正经历深刻变革。传统依赖展会、电话销售、老客转介绍的获客模式,已难以满足企业快速增长的需求。GEO推广,即生成式引擎优化,正成…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉