winpCap调用源码方法(C++)

winpCap调用源码方法(C++),第1张

winpCap调用源码方法(C++)

WinPcap相关文件地址WinPcap_4_1_3免安装版.zip_winpcap-C++文档类资源-CSDN下载

请先确保下面的x64和x86中的存在 

这些是依赖文件,实在找不到,就去这个地址下载吧(64条消息) WinPcap_4_1_3的依赖文件-C++文档类资源-CSDN文库

下面是具体的使用方法

//调用代码的方法,WM_USER+8899这个定时器是用来显示每秒流量是多少
#ifdef USE_WPCAP
	//创建一个实时监控网速的线程
	std::thread netSpeedThread(NetTrafficMonitorThread);
	netSpeedThread.detach();
	SetTimer(GetHWND(), WM_USER + 8899, 1000, NULL);
#endif


//流量分为上传和下载,这里是WM_USER+8899定时器内的相关代码
if (wParam == WM_USER + 8899)
{
	int nUpValuesTemp = g_nUpValues - g_nOldUpValues;
	int nDownValuesTemp = g_nDownValues - g_nOldDownValues;
	if (g_nOldUpValues == 0 || g_nOldDownValues == 0)
	{
		g_nOldUpValues = g_nUpValues;
		g_nOldDownValues = g_nDownValues;

		bHandled = true;
		return S_OK;
	}
	g_nOldUpValues = g_nUpValues;
	g_nOldDownValues = g_nDownValues;

	CStringW strUploadText;
	if (nUpValuesTemp / (1024 * 1024) >= 1)
	{
		strUploadText.Format(_T("%.2fM/s "), nUpValuesTemp / (1024 * 1024.00));
	}
	else
	{
		strUploadText.Format(_T("%.2fK/s "), nUpValuesTemp / 1024.00);
	}
	CString strDownloadText;
	if (nDownValuesTemp / (1024 * 1024) >= 1)
	{
		strDownloadText.Format(_T("%.2fM/s "), nDownValuesTemp / (1024 * 1024.00));
	}
	else
	{
		strDownloadText.Format(_T("%.2fK/s "), nDownValuesTemp / 1024.00);
	}
	down_net_label_->SetText(strDownloadText.GetBuffer());//显示下载速度
	up_net_label_->SetText(strUploadText.GetBuffer());//显示上传速度
}



//下面的具体的NetTrafficMonitorThread线程源码,


int g_nUpValues = 0;
int g_nDownValues = 0;
int g_nOldUpValues = 0;
int g_nOldDownValues = 0;
bool g_bStartWpcapSuccess = false;//记录是否开启Wpcap成功

string toIp(DWORD ip)
{
	size_t a = ip >> 24 & 0xFF;
	size_t b = ip >> 16 & 0xFF;
	size_t c = ip >> 8 & 0xFF;
	size_t d = ip & 0xFF;

	// 数据是大端就用 abcd,小端dcba
	return string(to_string(d) + "." + to_string(c) + "." + to_string(b) + "." + to_string(a));
}

//BOOL eachTCP(DWORD pid, vector* connectNets)
//{
//	PMIB_TCPTABLE2 pTcpTable = nullptr;
//	ULONG ulSize = 0;
//	DWORD dwRetVal = 0;
//
//	// 第一次获取大小,初始化pTcpTable
//	if ((dwRetVal = GetTcpTable2(pTcpTable, &ulSize, TRUE)) ==
//		ERROR_INSUFFICIENT_BUFFER) {
//		pTcpTable = (MIB_TCPTABLE2*)MALLOC(ulSize);
//		if (pTcpTable == NULL) return 0;
//	}
//
//	// 第二次获取数据
//	if ((dwRetVal = GetTcpTable2(pTcpTable, &ulSize, TRUE)) == NO_ERROR) {
//		if (pTcpTable == NULL) return 0;
//
//		for (size_t i = 0; i < pTcpTable->dwNumEntries; i++) {
//			auto it = pTcpTable->table[i];
//			if (pid != it.dwOwningPid && pid != 0) continue;
//			string state = "";
//			switch (it.dwState) {
//			case MIB_TCP_STATE_CLOSED:
//				state = "CLOSED";
//				break;
//			case MIB_TCP_STATE_LISTEN:
//				state = "LISTEN";
//				break;
//			case MIB_TCP_STATE_SYN_SENT:
//				state = ("SYN-SENT");
//				break;
//			case MIB_TCP_STATE_SYN_RCVD:
//				state = ("SYN-RECEIVED");
//				break;
//			case MIB_TCP_STATE_ESTAB:
//				state = ("ESTABLISHED");
//				break;
//			case MIB_TCP_STATE_FIN_WAIT1:
//				state = ("FIN-WAIT-1");
//				break;
//			case MIB_TCP_STATE_FIN_WAIT2:
//				state = ("FIN-WAIT-2");
//				break;
//			case MIB_TCP_STATE_CLOSE_WAIT:
//				state = ("CLOSE-WAIT");
//				break;
//			case MIB_TCP_STATE_CLOSING:
//				state = ("CLOSING");
//				break;
//			case MIB_TCP_STATE_LAST_ACK:
//				state = ("LAST-ACK");
//				break;
//			case MIB_TCP_STATE_TIME_WAIT:
//				state = ("TIME-WAIT");
//				break;
//			case MIB_TCP_STATE_DELETE_TCB:
//				state = ("DELETE-TCB");
//				break;
//			default:
//				state = ("UNKNOWN dwState value");
//				break;
//			}
//
//			ConnectNet net;
//			net.proto = 6;
//			net.src = toIp(it.dwLocalAddr);
//			net.sport = ntohs((u_short)it.dwLocalPort);
//			net.dst = toIp(it.dwRemoteAddr);
//			net.dport = ntohs((u_short)it.dwRemotePort);
//			net.state = state;
//			net.pid = it.dwOwningPid;
//			connectNets->push_back(net);
//		}
//	}
//	else {
//		FREE(pTcpTable);
//		return FALSE;
//	}
//
//	if (pTcpTable != NULL) {
//		FREE(pTcpTable);
//		pTcpTable = NULL;
//	}
//	return TRUE;
//}

BOOL eachUDP(DWORD pid, vector* connectNets)
{
	MIB_UDPTABLE_OWNER_PID* pUdpTable = nullptr;
	ULONG ulSize = 0;
	DWORD dwRetVal = 0;

	// 第一次获取大小,初始化pTcpTable
	if ((dwRetVal = GetExtendedUdpTable(pUdpTable, &ulSize, TRUE, AF_INET, UDP_TABLE_CLASS::UDP_TABLE_OWNER_PID, 0)) ==
		ERROR_INSUFFICIENT_BUFFER) {
		pUdpTable = (MIB_UDPTABLE_OWNER_PID*)MALLOC(ulSize);
		if (pUdpTable == NULL) return 0;
	}

	// 第二次获取数据
	if ((dwRetVal = GetExtendedUdpTable(pUdpTable, &ulSize, TRUE, AF_INET, UDP_TABLE_CLASS::UDP_TABLE_OWNER_PID, 0)) == NO_ERROR) {
		if (pUdpTable == NULL) return 0;

		for (size_t i = 0; i < pUdpTable->dwNumEntries; i++) {
			auto it = pUdpTable->table[i];
			if (it.dwOwningPid != pid && pid != 0) continue;

			ConnectNet net;
			net.proto = 17;
			net.src = toIp(it.dwLocalAddr).c_str();
			net.sport = ntohs((u_short)it.dwLocalPort);
			net.dst = "*";
			net.dport = 0;
			net.state = "";
			net.pid = it.dwOwningPid;
			connectNets->push_back(net);
		}
	}
	else {
		FREE(pUdpTable);
		return FALSE;
	}

	if (pUdpTable != NULL) {
		FREE(pUdpTable);
		pUdpTable = NULL;
	}
	return TRUE;
}

BOOL getNetTable(DWORD pid, vector* connectNets)
{
	//if (!eachTCP(pid, connectNets)) return FALSE;
	return eachUDP(pid, connectNets);
}

map m_mapNetPortInfo; //int表示本地端口
int		m_nTryGetUdpTimes = 0;//获取udp端口次数

void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
#ifdef USE_WPCAP
	struct tm *ltime;
	ip_header *ih;
	udp_header *uh;
	u_int ip_len;
	u_short sport, dport;
	time_t local_tv_sec;

	
	(VOID)(param);

	
	local_tv_sec = header->ts.tv_sec;
	ltime = localtime(&local_tv_sec);
	char timestr[16];
	strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);

	
	//printf("%s.%.6d len:%d ", timestr, header->ts.tv_usec, header->len);

	
	ih = (ip_header *)(pkt_data + 14); //length of ethernet header

	
	ip_len = (ih->ver_ihl & 0xf) * 4;
	uh = (udp_header *)((u_char*)ih + ip_len);

	
	sport = ntohs(uh->sport);
	dport = ntohs(uh->dport);

	//判断是否是爱加进程的UDP端口
	if (m_mapNetPortInfo.size() <= 1 && m_nTryGetUdpTimes <= 10)
	{
		Sleep(500);
		m_mapNetPortInfo.clear();
		
		vector r;
		if (getNetTable(0, &r))
		{
			gLocker.Lock();
			for (auto it : r)
			{
				if (it.proto == 17 && it.pid == g_nMainProcess)
				{
					m_mapNetPortInfo[it.sport] = g_nMainProcess;
					WriteNormalLog(L"本次视频通信的UDP端口为:" + to_wstring(it.sport));
				}
			}
			gLocker.Unlock();
		}

		if (m_mapNetPortInfo.size() > 2)
		{
			WriteNormalLog(L"获取UDP端口时得到" + to_wstring(m_mapNetPortInfo.size()) + L"个, 将清空重新获取!当前获取次数为" + to_wstring(m_nTryGetUdpTimes));
			if (m_nTryGetUdpTimes < 10)
				m_mapNetPortInfo.clear();
			else
			{
				wstring strLog = L"本次视频获取UDP端口结束! 当前监视的端口为";
				for (auto itor : m_mapNetPortInfo)
					strLog += to_wstring(itor.first) + L", ";
				WriteNormalLog(strLog);
			}
		}
		else if (m_mapNetPortInfo.size() == 2)
		{
			wstring strLog = L"--------本次视频通信的UDP端口为:";
			for (auto itor : m_mapNetPortInfo)
			{
				strLog += to_wstring(itor.first) + L", ";
			}
			WriteNormalLog(strLog);
		}
		m_nTryGetUdpTimes++;
	}

	gLocker.Lock();
	for (auto itor : m_mapNetPortInfo)
	{
		if (sport == itor.first || dport == itor.first)
		{
			if (sport == itor.first)
			{
				g_nUpValues += (header->len - 20);
			}
			else
				g_nDownValues += header->len - 20;//这里减20是ip信息头
		}
	}
	gLocker.Unlock();
#endif
}

MIB_IFTABLE* m_pIfTable;
int m_connection_selected = 0;
string m_connection_name;
vector m_connections;	//保存获取到的所有网络连接
pcap_t* m_Pcap_t;
void AutoSelect()
{
	unsigned int max_in_out_bytes{};
	unsigned int in_out_bytes;
	//m_connection_selected = m_connections[0].index;
	m_connection_selected = 0;
	//自动选择连接时,查找已发送和已接收字节数之和最多的那个连接,并将其设置为当前查看的连接
	for (size_t i{}; itable[m_connections[i].index].dwOperStatus == IF_OPER_STATUS_OPERATIONAL)		//只选择网络状态为正常的连接
		{

			in_out_bytes = m_pIfTable->table[m_connections[i].index].dwInOctets + m_pIfTable->table[m_connections[i].index].dwOutOctets;
			if (in_out_bytes > max_in_out_bytes)
			{
				max_in_out_bytes = in_out_bytes;
				m_connection_selected = i;
			}
		}
	}
	m_connection_name = m_connections[m_connection_selected].adapterName;
}

void IniConnection()
{
	//为m_pIfTable开辟所需大小的内存
	free(m_pIfTable);
	DWORD m_dwSize = sizeof(MIB_IFTABLE);
	m_pIfTable = (MIB_IFTABLE *)malloc(m_dwSize);
	int rtn;
	rtn = GetIfTable(m_pIfTable, &m_dwSize, FALSE);
	if (rtn == ERROR_INSUFFICIENT_BUFFER)	//如果函数返回值为ERROR_INSUFFICIENT_BUFFER,说明m_pIfTable的大小不够
	{
		free(m_pIfTable);
		m_pIfTable = (MIB_IFTABLE *)malloc(m_dwSize);	//用新的大小重新开辟一块内存
	}
	//获取当前所有的连接,并保存到m_connections容器中
	GetIfTable(m_pIfTable, &m_dwSize, FALSE);

	//获取当前所有的连接,并保存到m_connections容器中
	CAdapterCommon::GetAdapterInfo(m_connections);
	CAdapterCommon::GetIfTableInfo(m_connections, m_pIfTable);

	//选择网络连接
	AutoSelect();
}

static bool IsWin64(void)
{
	SYSTEM_INFO si = { 0 };
	typedef void (WINAPI *LPFN_PGNSI)(LPSYSTEM_INFO);
	LPFN_PGNSI pGNSI = (LPFN_PGNSI)GetProcAddress(GetModuleHandleA(("kernel32.dll")), "GetNativeSystemInfo");
	if (pGNSI)
		pGNSI(&si);
	if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
	{
		return true;
	}
	return false;
}

void NetTrafficMonitorThread()
{
	g_bStartWpcapSuccess = false;
	m_mapNetPortInfo.clear();
	m_nTryGetUdpTimes = 0;

#ifdef USE_WPCAP
	pcap_if_t *alldevs;
	char errbuf[PCAP_ERRBUF_SIZE];
	u_int netmask;
	char packet_filter[] = "ip and udp";
	struct bpf_program fcode;

	//判断system32下是否有wpcap.dll和packet.dll, system32drivers下是否有npf.sys
	//如果电脑是64位,则同时还需要判断SysWOW64下是否有wpcap.dll和packet.dll
	wchar_t path_x86[256] = { 0 };
	wchar_t path_x64[256] = { 0 };
	if (IsWin64())
	{
		WriteNormalLog(L"64位系统!");

		typedef BOOL(APIENTRY *PWow64EnableWow64FsRedirection)(BOOL);
		PWow64EnableWow64FsRedirection pf = (PWow64EnableWow64FsRedirection)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "Wow64EnableWow64FsRedirection");

		//移动64位的wpcap.dll和packet.dll到system32下,移动npf.sys到system32drivers下
		wstring strWpcapDllPath64 = bc::Path::GetAppPath() + L"WinPcap\x64\wpcap.dll";
		wstring strPacketDllPath64 = bc::Path::GetAppPath() + L"WinPcap\x64\packet.dll";
		if (_waccess(strWpcapDllPath64.c_str(), 0) != -1 && _waccess(strPacketDllPath64.c_str(), 0) != -1)
		{
			SHGetSpecialFolderPath( NULL,	// 保留
				path_x64,						// 接受文件路径的字符串指针
				CSIDL_SYSTEM,				// CSIDL 宏
				FALSE						// 如果文件夹不存在,则不创建文件夹
				);
			wstring strWpcapDll = (wstring)path_x64 + L"\wpcap.dll";
			wstring strPacketDll = (wstring)path_x64 + L"\packet.dll";
			if (_waccess(strWpcapDll.c_str(), 0) == -1)
			{
				//关闭重定向
				if (pf(FALSE))//关闭重定向
				{
					BOOL bRet = CopyFile(strWpcapDllPath64.c_str(), strWpcapDll.c_str(), TRUE);
					pf(TRUE);//恢复重定向
					if (!bRet)
					{
						WriteErrorLog(L"复制wpcap.dll失败!GetLastError=" + to_wstring(GetLastError()));
						return;
					}
				}
			}
			if (_waccess(strPacketDll.c_str(), 0) == -1)
			{
				if (pf(FALSE))//关闭重定向
				{
					BOOL bRet = CopyFile(strPacketDllPath64.c_str(), strPacketDll.c_str(), TRUE);
					pf(TRUE);//恢复重定向
					if (!bRet)
					{
						WriteErrorLog(L"复制packet.dll失败!GetLastError=" + to_wstring(GetLastError()));
						return;
					}
				}
			}

			//移动npf.sys到system32drivers下
			wstring strNpfPath = bc::Path::GetAppPath() + L"WinPcap\x64\npf.sys";
			if (_waccess(strNpfPath.c_str(), 0) != -1)
			{
				wstring strNpf = (wstring)path_x64 + L"\drivers\npf.sys";
				if (_waccess(strNpf.c_str(), 0) == -1)
				{
					if (pf(FALSE))//关闭重定向
					{
						BOOL bRet = CopyFile(strNpfPath.c_str(), strNpf.c_str(), TRUE);
						pf(TRUE);//恢复重定向
						if (!bRet)
						{
							int nError = GetLastError();
							if (nError != 0 && nError != 80)
								WriteErrorLog(L"复制npf.sys失败!GetLastError=" + to_wstring(nError));
							//return;
						}
					}
				}
			}
		}

		//移动32位的wpcap.dll和packet.dll到SysWOW64下
		wstring strWpcapDllPath32 = bc::Path::GetAppPath() + L"WinPcap\x86\wpcap.dll";
		wstring strPacketDllPath32 = bc::Path::GetAppPath() + L"WinPcap\x86\packet.dll";
		if (_waccess(strWpcapDllPath32.c_str(), 0) != -1 && _waccess(strPacketDllPath32.c_str(), 0) != -1)
		{
			SHGetSpecialFolderPath(NULL,	// 保留
				path_x86,						// 接受文件路径的字符串指针
				CSIDL_SYSTEMX86,			// CSIDL 宏
				FALSE						// 如果文件夹不存在,则不创建文件夹
				);
			wstring strWpcapDll = (wstring)path_x86 + L"\wpcap.dll";
			wstring strPacketDll = (wstring)path_x86 + L"\packet.dll";
			if (_waccess(strWpcapDll.c_str(), 0) == -1)
			{
				BOOL bRet = CopyFile(strWpcapDllPath32.c_str(), strWpcapDll.c_str(), TRUE);
				if (!bRet)
				{
					WriteErrorLog(L"复制wpcap.dll失败!GetLastError=" + to_wstring(GetLastError()));
					return;
				}
			}
			if (_waccess(strPacketDll.c_str(), 0) == -1)
			{
				BOOL bRet = CopyFile(strPacketDllPath32.c_str(), strPacketDll.c_str(), TRUE);
				if (!bRet)
				{
					WriteErrorLog(L"复制packet.dll失败!GetLastError=" + to_wstring(GetLastError()));
					return;
				}
			}
		}
	}
	else
	{
		WriteNormalLog(L"32位系统!");

		//移动32位的wpcap.dll和packet.dll到system32下,移动npf.sys到system32drivers下
		wstring strWpcapDllPath32 = bc::Path::GetAppPath() + L"WinPcap\x86\wpcap.dll";
		wstring strPacketDllPath32 = bc::Path::GetAppPath() + L"WinPcap\x86\packet.dll";
		if (_waccess(strWpcapDllPath32.c_str(), 0) != -1 && _waccess(strPacketDllPath32.c_str(), 0) != -1)
		{
			SHGetSpecialFolderPath(NULL,	// 保留
				path_x86,						// 接受文件路径的字符串指针
				CSIDL_SYSTEMX86,			// CSIDL 宏
				FALSE						// 如果文件夹不存在,则不创建文件夹
				);
			wstring strWpcapDll = (wstring)path_x86 + L"\wpcap.dll";
			wstring strPacketDll = (wstring)path_x86 + L"\packet.dll";
			if (_waccess(strWpcapDll.c_str(), 0) == -1)
			{
				BOOL bRet = CopyFile(strWpcapDllPath32.c_str(), strWpcapDll.c_str(), TRUE);
				if (!bRet)
				{
					WriteErrorLog(L"复制wpcap.dll失败!GetLastError=" + to_wstring(GetLastError()));
					return;
				}
			}

			//移动npf.sys到system32drivers下
			wstring strNpfPath = bc::Path::GetAppPath() + L"WinPcap\x86\npf.sys";
			if (_waccess(strNpfPath.c_str(), 0) != -1)
			{
				wstring strNpf = (wstring)path_x86 + L"\drivers\npf.sys";
				if (_waccess(strNpf.c_str(), 0) == -1)
				{
					BOOL bRet = CopyFile(strNpfPath.c_str(), strNpf.c_str(), TRUE);
					if (!bRet)
					{
						WriteErrorLog(L"复制npf.sys失败!GetLastError=" + to_wstring(GetLastError()));
						return;
					}
				}
			}

			if (_waccess(strPacketDll.c_str(), 0) == -1)
			{
				BOOL bRet = CopyFile(strPacketDllPath32.c_str(), strPacketDll.c_str(), TRUE);
				if (!bRet)
				{
					WriteErrorLog(L"复制packet.dll失败!GetLastError=" + to_wstring(GetLastError()));
					return;
				}
			}
		}
	}

	wstring strNpfPath = bc::Path::GetAppPath() + L"WinPcap\";
	if (_waccess(strNpfPath.c_str(), 0) == -1)
	{
		return;
	}

	//判断对应文件夹下是否已存在对应的wpcap.dll和packet.dll以及npf.sys文件
	if (IsWin64())
	{
		typedef BOOL(APIENTRY *PWow64EnableWow64FsRedirection)(BOOL);
		PWow64EnableWow64FsRedirection pf = (PWow64EnableWow64FsRedirection)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "Wow64EnableWow64FsRedirection");
		if (pf(FALSE))//关闭重定向
		{
			wstring strNpf_x64 = (wstring)path_x64 + L"\drivers\npf.sys";
			wstring strWpcapDll_x64 = (wstring)path_x64 + L"\wpcap.dll";
			wstring strPacketDll_x64 = (wstring)path_x64 + L"\packet.dll";
			wstring strWpcapDll_x86 = (wstring)path_x86 + L"\wpcap.dll";
			wstring strPacketDll_x86 = (wstring)path_x86 + L"\packet.dll";
			if (_waccess(strNpf_x64.c_str(), 0) == -1
				|| _waccess(strWpcapDll_x64.c_str(), 0) == -1
				|| _waccess(strPacketDll_x64.c_str(), 0) == -1
				|| _waccess(strWpcapDll_x86.c_str(), 0) == -1
				|| _waccess(strPacketDll_x86.c_str(), 0) == -1)
			{
				WriteErrorLog(L"64位系统下,wpcap.dll、packet.dll或npf.sys中有文件不存在!GetLastError=" + to_wstring(GetLastError()));
				pf(TRUE);//恢复重定向
				return;
			}
			pf(TRUE);//恢复重定向
		}
	}
	else
	{
		wstring strNpf_x86 = (wstring)path_x86 + L"\drivers\npf.sys";
		wstring strWpcapDll_x86 = (wstring)path_x86 + L"\wpcap.dll";
		wstring strPacketDll_x86 = (wstring)path_x86 + L"\packet.dll";
		if (_waccess(strNpf_x86.c_str(), 0) == -1
			|| _waccess(strWpcapDll_x86.c_str(), 0) == -1
			|| _waccess(strPacketDll_x86.c_str(), 0) == -1)
		{
			WriteErrorLog(L"32位系统下,wpcap.dll、packet.dll或npf.sys中有文件不存在!GetLastError=" + to_wstring(GetLastError()));
			return;
		}
	}

	//列出当前所有可用的网络设备(网卡)
	if (pcap_findalldevs(&alldevs, errbuf) == -1)
	{
		char buffer[1024] = { 0 };
		sprintf_s(buffer, 1024, "Error in pcap_findalldevs: %s!", errbuf);
		WriteErrorLog(ToWchar(buffer));
		return;
	}
	//打印所有网络设备(网卡)
	pcap_if_t *d;
	int i = 0;
	map _mapNetInfo;
	for (d = alldevs; d; d = d->next)
	{
		++i;
		_mapNetInfo[i] = d->name;
		wstring strLog = to_wstring(i) + L" " + ToWchar(d->name) + L" ";
		if (d->description)
			strLog += ToWchar(d->description);
		else
			strLog += L"(No description available)";
		WriteNormalLog(strLog);	
	}
	if (i == 0)
	{
		WriteErrorLog(L"No interfaces found! Make sure WinPcap is installed.");
		return;
	}
	int inum = 0;
	if (i == 1)
		inum = 1;
	else
	{
		//自动选择网卡(查找已发送和已接收字节数之和最多的那个连接,并将其设置为当前查看的连接)
		IniConnection();

		for (auto it : _mapNetInfo)
		{
			int nPos = it.second.find(m_connection_name);
			if (nPos != string::npos)
			{
				inum = it.first;
				break;
			}	
		}
	}

	
	if (inum < 1 || inum > i)
	{
		WriteErrorLog(L"Adapter number out of range.");
		pcap_freealldevs(alldevs);	
		return;
	}
	
	for (d = alldevs, i = 0; i< inum - 1; d = d->next, i++);

	//获取一个包捕捉句柄,类似文件 *** 作函数使用的文件句柄
	if ((m_Pcap_t = pcap_open_live(d->name,	// name of the device
		65536,			// portion of the packet to capture. 65536 grants that the whole packet will be captured on all the MACs.
		1,				// promiscuous mode (nonzero means promiscuous)
		1000,			// read timeout
		errbuf			// error buffer
		)) == NULL)
	{
		char buffer[1024] = { 0 };
		sprintf_s(buffer, 1024, "Unable to open the adapter. %s is not supported by WinPcap!", errbuf);
		WriteErrorLog(ToWchar(buffer));	
		pcap_freealldevs(alldevs);
		return;
	}

	
	if (pcap_datalink(m_Pcap_t) != DLT_EN10MB)
	{
		WriteErrorLog(L"This program works only on Ethernet networks.");
		
		pcap_freealldevs(alldevs);
		return;
	}

	if (d->addresses != NULL)
		
		netmask = ((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
	else
		
		netmask = 0xffffff;

	//该函数用于解析过滤规则串
	if (pcap_compile(m_Pcap_t, &fcode, packet_filter, 1, netmask) <0)
	{
		WriteErrorLog(L"Unable to compile the packet filter. Check the syntax.");
		
		pcap_freealldevs(alldevs);
		return;
	}
	//在捕获过程中绑定一个过滤器
	if (pcap_setfilter(m_Pcap_t, &fcode)<0)
	{
		WriteErrorLog(L"Error setting the filter.");
		
		pcap_freealldevs(alldevs);
		return;
	}
	
	pcap_freealldevs(alldevs);

	g_bStartWpcapSuccess = true;
	
	pcap_loop(m_Pcap_t, 0, packet_handler, NULL);
#endif
}

void EndNetLoopThread()
{
#ifdef USE_WPCAP
	if (m_Pcap_t != nullptr)
	{
		pcap_breakloop(m_Pcap_t);
		pcap_close(m_Pcap_t);
		m_Pcap_t = nullptr;
	}
	WriteNormalLog(L"结束UDP端口监听!");
#endif
	
	m_mapNetPortInfo.clear();
	m_nTryGetUdpTimes = 0;
	g_nUpValues = 0;
	g_nDownValues = 0;
	g_nOldUpValues = 0;
	g_nOldDownValues = 0;
}



欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5714120.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存