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(&ltime, &local_tv_sec);

strftime(timestr, sizeof(timestr), "%H:%M:%S", &ltime);

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的函数可进一步了解。

posted @   风花赏秋月  阅读(85)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
点击右上角即可分享
微信分享提示