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开发包的应用!
学习的目的是成熟!~