WinPcap捕获网络数据包
《网络程序设计》上机实验报告4
WinPcap捕获网络数据包
实验目的:了解WinPcap如何实现网络数据包的捕获
首先了解WinPcap的相关知识:比如下载安装等。
1.了解相关头文件pcap.h,里面有WinPcap提供的相关函数及数据结构
2.发现网络设备以及其信息(网卡)
BOOL CCapturePacket::FindDevice() // 查询网卡
{
if( m_AllDevs )
{
pcap_freealldevs(m_AllDevs);
m_AllDevs = NULL;
m_CurrDev = NULL;
m_hDev = NULL;
}
pcap_if_t *alldevs;
char errbuf[PCAP_ERRBUF_SIZE];
m_nDevNum = 0;
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
USES_CONVERSION;
TRACE(L"Error in pcap_findalldevs:%s\n", A2W(errbuf));
return FALSE;
}
pcap_if_t *d;
int i = 0;
for(d = alldevs; d; d = d->next)
{
i++;
}
if(i == 0)
{
TRACE(L"\nNo interfaces found! Make sure WinPcap is installed.\n");
return FALSE;
}
m_nDevNum = i;
m_AllDevs = alldevs;
return TRUE;
}
void CCapturePacket::EnumDevice(CStringList& devList) // 枚举网卡信息
{
if( m_AllDevs )
{
USES_CONVERSION;
pcap_if_t *d;
for(d = m_AllDevs; d; d=d->next)
{
CString strDev;
strDev.Format(L"%s", A2W(d->description));
devList.AddTail(strDev);
}
}
}
3.打开某网络设备(网卡)准备捕获数据包
BOOL CCapturePacket::OpentDevice(int nDevNo) // nDevNo - 0, 1, 2...
{
if( m_nDevNum <= 0 || m_AllDevs == NULL )
{
if( !FindDevice() ) return FALSE;
}
if( m_nDevNum <= 0 || m_AllDevs == NULL ) return FALSE;
if( nDevNo < 0 || nDevNo >= m_nDevNum ) return FALSE;
pcap_if_t *d;
int i = 0;
for(d = m_AllDevs; i< nDevNo ;d = d->next,i++);
char errbuf[PCAP_ERRBUF_SIZE];
if ( (m_hDev = ???????(d->name, //设备名
65535, //65535保证能捕获到不同数据链路层上的每个数据包的全部内容
TRUE, //混杂模式
1000, //读取超时时间(毫秒)
errbuf //错误缓冲
)) == NULL)
{
return FALSE;
}
if(pcap_datalink(m_hDev) != DLT_EN10MB)
{
return FALSE;
}
m_CurrDev = d;
return TRUE;
}
4.启动线程,在线程中捕获并显示数据包信息
void CCapturePacket::StartCapture()
{
HANDLE hThread = ::CreateThread(NULL, 0, Capturing, (LPVOID)this, 0, NULL);
::CloseHandle(hThread);
}
DWORD WINAPI CCapturePacket::Capturing(LPVOID p)
{
USES_CONVERSION;
CCapturePacket* pCapture = (CCapturePacket*)p;
????(pCapture->m_hDev,0, CCapturePacket::packet_handler, (u_char*)pCapture);
return 0;
}
// 线程处理函数
void CCapturePacket::packet_handler(u_char *param, const pcap_pkthdr *header, const u_char *pkt_data)
{
CCapturePacket* pCapture = (CCapturePacket*)param;
tm ltime;
char timestr[16];
ip_header *ih;
tcp_header *th;
u_int ip_len;
u_short sport,dport;
time_t local_tv_sec;
local_tv_sec = header->ts.tv_sec;
localtime_s(<ime, &local_tv_sec);
strftime(timestr, sizeof(timestr), "%H:%M:%S", <ime);
ih = (ip_header*) (pkt_data + 14);//以太网头部长度
ip_len = (ih->ver_ihl & 0xf) * 4;
th = (tcp_header*) ((u_char*)ih + ip_len);
sport = ntohs( th->sport );
dport = ntohs( th->dport );
char szPacket[200];
sprintf_s(szPacket, "%s %d.%d.%d.%d : %d -> %d.%d.%d.%d : %d 包长度:%d",
timestr,
ih->saddr.byte1,
ih->saddr.byte2,
ih->saddr.byte3,
ih->saddr.byte4,
sport,
ih->daddr.byte1,
ih->daddr.byte2,
ih->daddr.byte3,
ih->daddr.byte4,
dport,
header->len);
if( pCapture && pCapture->m_pView ) // 将信息通过发消息给界面,让界面显示
::SendMessage((HWND)pCapture->m_pView->GetSafeHwnd(),WM_SHOW_PACKET,(WPARAM)szPacket,(LPARAM)0);
}
5.停止捕获
void CCapturePacket::StopCapture() // 停止抓取
{
pcap_breakloop(m_hDev);
}
调试代码捕获网络数据包。
例如下图
然后对WinPcap的函数可进一步了解。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异