开源项目之WinpCap 抓包

WinPcap是用于网络封包抓取的一套工具,可适用于32位的操作平台上解析网络封包,包含了核心的封包过滤,一个底层动态链接库,和一个高层系统函数库,及可用来直接存取封包的应用程序界面。 效果如图:



编译项目时需要用到WpdPack开发包(已放到源码包中)。

主要源码1:

void main()
{
	pcap_if_t *alldevs;
	pcap_if_t *d;
	int inum;
	int i=0;
	pcap_t *adhandle;
	char errbuf[PCAP_ERRBUF_SIZE];
	/* 获取设备列表 */  
	if (pcap_findalldevs(&alldevs, errbuf) == -1)
	{
		fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
		exit(1);
	}
	/* 数据列表 */  
	for(d=alldevs; d; d=d->next)
	{
		printf("%d. %s", ++i, d->name);
		if (d->description)
			printf(" (%s)\n", d->description);
		else
			printf(" (No description available)\n");
	}
	if(i==0)
	{
		printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
		return;  
	}
	printf("Enter the interface number (1-%d):",i);
	scanf("%d", &inum);
	if(inum < 1 || inum > i)
	{
		printf("\n 输入有误.\n");
		pcap_freealldevs(alldevs);
		return;
	}  
	/* 转到选择的设备 */  
	for(d=alldevs, i=0; i< inum-1;d=d->next, i++)
		;  
	/* 打开设备 */  
	if ( (adhandle= pcap_open_live(d->name, //设备名  
		65536, // 捕捉完整的数据包  
		1 , // 混在模式  
		1, // 读入超时  
		errbuf // 错误缓冲  
		) ) == NULL)
	{
		printf("Unable to open the adapter");
		pcap_freealldevs(alldevs);
		return;  
	}
	printf("\nlistening on %s...\n", d->description);
	/* 我们已经不需要设备列表了, 释放它 */
	pcap_freealldevs(alldevs);

	//hFile=CreateFile("C:\\aaa.txt",GENERIC_WRITE,0, NULL,CREATE_ALWAYS,0,NULL);
	
	pcap_loop(adhandle, 0, packet_handler, NULL);


	//CloseHandle(hFile);
	return;
} 

根据输入参数进行设备的选择!

主要源码2:

//开启捕捉
void CCapPackDlg::OnStartcap()
{
	BOOL temp;
	char FilePath[MAX_PATH];
	m_List1.DeleteAllItems();

	GetModuleFileName(0,FilePath,MAX_PATH-1);
	CapFilePath=FilePath;
	CapFilePath=CapFilePath.Left(CapFilePath.ReverseFind('\\'));
	CapFilePath+="\\CapData.CAP";

	hCapThread=AfxBeginThread(CapThread,(LPVOID)this);

	WaitForSingleObject(eThreadStart, INFINITE);
	EnterCriticalSection(&csThreadStop);
	temp=bThreadStop;
	LeaveCriticalSection(&csThreadStop);
	if(temp)//线程自动退出
	{
		return;
	}
	else
	{
		Status=1;
		GetDlgItem(IDC_EDIT1)->SetWindowText("");
		GetDlgItem(IDC_EDIT2)->SetWindowText("");
		this->SetMenuStatus();
	}
}
//停止捕捉
void CCapPackDlg::OnStopcap()
{
	DWORD result;

	EnterCriticalSection(&csThreadStop);
	bThreadStop=true;
	LeaveCriticalSection(&csThreadStop);
	result=WaitForSingleObject(hCapThread->m_hThread,3000);//可能在这行执行前线程就已退出
	if(result==WAIT_TIMEOUT )
	{
		MessageBox("工作线程超时不响应,强制结束!");
		TerminateThread(hCapThread->m_hThread,0);
	}

	Status=0;
	this->SetMenuStatus();

	//MessageBox("停止抓包");
}

//抓包线程
UINT CCapPackDlg::CapThread(LPVOID lpParameter)
{
	CCapPackDlg *this2;
	pcap_t *adhandle;
	char errbuf[PCAP_ERRBUF_SIZE];
	pcap_dumper_t *dumpfile;
	struct pcap_pkthdr *header;
	const u_char *data;
	DWORD res;
	bool bExit;
	static long i=0,j=0;
	bool bFilter=false;//true表示过滤掉

	ListData List;

	struct ether_header *eth;
	u_char* mac_string;
	struct iphead *IPHead;
	struct arphead *ARPHead;
	in_addr ipaddr;

	this2=(CCapPackDlg *)lpParameter;
	i=0;
	j=0;
	//开启设备
	if((adhandle= pcap_open_live(this2->AdapterName,65536,1 ,10,errbuf)) == NULL)
	{
		::MessageBox(0,"不能打开网络适配器,请在网卡设置中经行设置","错误",0);
		
		EnterCriticalSection(&(this2->csThreadStop));
		this2->bThreadStop=true;
		LeaveCriticalSection(&(this2->csThreadStop));
		SetEvent(this2->eThreadStart);

		return 0;  
	}

	dumpfile=pcap_dump_open(adhandle,this2->CapFilePath);
	if(dumpfile==NULL)
	{
		::MessageBox(0,"不能打开记录文件","错误",0);
		
		EnterCriticalSection(&(this2->csThreadStop));
		this2->bThreadStop=true;
		LeaveCriticalSection(&(this2->csThreadStop));
		SetEvent(this2->eThreadStart);
		return 0;
	}

	
	EnterCriticalSection(&(this2->csThreadStop));
	this2->bThreadStop=false;
	LeaveCriticalSection(&(this2->csThreadStop));
	SetEvent(this2->eThreadStart);

	//::MessageBox(0,"开始抓包","ok",0);
	while(1)
	{
		EnterCriticalSection(&(this2->csThreadStop));
		bExit=this2->bThreadStop;
		LeaveCriticalSection(&(this2->csThreadStop));
		if(bExit)	return 0;

		res = pcap_next_ex(adhandle,&header,&data);
		if(res==0)
		{
			Sleep(100);
			continue;
		}
		else if(res<0)
		{
			break;
		}
		pcap_dump((u_char *)dumpfile, header, data);

		eth=(ether_header *)data;
		mac_string=eth->ether_shost;
		sprintf(List.sMac,"%02X:%02X:%02X:%02X:%02X:%02X",*mac_string,*(mac_string+1),*(mac_string+2),*(mac_string+3),*(mac_string+4),*(mac_string+5));
		mac_string=eth->ether_dhost;
		sprintf(List.dMac,"%02X:%02X:%02X:%02X:%02X:%02X",*mac_string,*(mac_string+1),*(mac_string+2),*(mac_string+3),*(mac_string+4),*(mac_string+5));
		ltoa(header->caplen,List.Len,10);
		memcpy(List.Text,data,45);//数据不含以太网头
		List.Text[45]='\0';
		this2->DecodeChar(List.Text,45);

		switch(ntohs(eth->ether_type))
		{
		case ETHERTYPE_ARP:
			if(!this2->FilterSet.bAllProtocol && !this2->FilterSet.bArp){bFilter=true;break;}
			strcpy(List.Protocol,"ARP");
			ARPHead=(arphead *)(data+14);

			sprintf(List.sIP,"%d.%d.%d.%d",ARPHead->arp_source_ip_address[0],ARPHead->arp_source_ip_address[1],ARPHead->arp_source_ip_address[2],ARPHead->arp_source_ip_address[3]);
			sprintf(List.dIP,"%d.%d.%d.%d",ARPHead->arp_destination_ip_address[0],ARPHead->arp_destination_ip_address[1],ARPHead->arp_destination_ip_address[2],ARPHead->arp_destination_ip_address[3]);
			strcpy(List.sPort,"--");
			strcpy(List.dPort,"--");
			break;
		case ETHERTYPE_REVARP: 
			strcpy(List.Protocol,"RARP");
			break;
		case ETHERTYPE_IP:
			IPHead=(iphead *)(data+14);
			ipaddr=IPHead->ip_souce_address;
			sprintf(List.sIP,"%d.%d.%d.%d",ipaddr.S_un.S_un_b.s_b1,ipaddr.S_un.S_un_b.s_b2,ipaddr.S_un.S_un_b.s_b3,ipaddr.S_un.S_un_b.s_b4);
			IPHead->ip_destination_address;
			sprintf(List.dIP,"%d.%d.%d.%d",ipaddr.S_un.S_un_b.s_b1,ipaddr.S_un.S_un_b.s_b2,ipaddr.S_un.S_un_b.s_b3,ipaddr.S_un.S_un_b.s_b4);
			switch(IPHead->ip_protocol)
			{
			case 1:
				if(!this2->FilterSet.bAllProtocol && !this2->FilterSet.bIcmp){bFilter=true;break;}
				strcpy(List.Protocol,"ICMP");
				strcpy(List.sPort,"--");
				strcpy(List.dPort,"--");
				break;
			case 6:
				if(!this2->FilterSet.bAllProtocol && !this2->FilterSet.bTcp){bFilter=true;break;}
				strcpy(List.Protocol,"TCP");
				sprintf(List.sPort,"%d",ntohs( ((tcphead *)(data+16+20))->th_sport ));
				sprintf(List.dPort,"%d",ntohs( ((tcphead *)(data+16+20))->th_dport ));
				break;
			case 17:
				if(!this2->FilterSet.bAllProtocol && !this2->FilterSet.bUdp){bFilter=true;break;}
				strcpy(List.Protocol,"UDP");
				sprintf(List.sPort,"%d",ntohs( ((udphead *)(data+16+20))->udp_source_port ));
				sprintf(List.dPort,"%d",ntohs( ((udphead *)(data+16+20))->udp_destinanion_port ));
				break;
			default:
				strcpy(List.Protocol,"未知IP包");
				strcpy(List.sIP,"----------");
				strcpy(List.dIP,"----------");
				strcpy(List.sPort,"--");
				strcpy(List.dPort,"--");
				break;
			}

			break;
		case ETHERTYPE_PUP:
			strcpy(List.Protocol,"PUP");
			strcpy(List.sIP,"----------");
			strcpy(List.dIP,"----------");
			strcpy(List.sPort,"--");
			strcpy(List.dPort,"--");
			break;
		default:
			strcpy(List.Protocol,"未知以太包");
			strcpy(List.sIP,"----------");
			strcpy(List.dIP,"----------");
			strcpy(List.sPort,"--");
			strcpy(List.dPort,"--");
			break;
		}
		if(bFilter)
		{
			j++;
			List.Falg=true;
		}
		else
		{
			i++;j++;
			List.Falg=false;
		}
		ltoa(i,List.ID,10);
		ltoa(j,List.TotalPacket,10);
		SendMessageTimeout(this2->m_hWnd,WM_UPDATE_LIST,(WPARAM)&List,0,SMTO_BLOCK,1000,&res);
		bFilter=false;
	}
	return 0;
}

这只是对WpdPack开发包的应用!

学习的目的是成熟!~

源码下载(附带WpdPack开发包





  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值