www.pudn.com > CapturePacket.rar > PacketMsg.cpp
// PacketMsg.cpp: implementation of the CPacketMsg class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CapturePacket.h"
#include "PacketMsg.h"
#include "CapturePacketDlg.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CPacketMsg::CPacketMsg()
{
alldevs=NULL;
packetCount=0;
}
CPacketMsg::~CPacketMsg()
{
}
BOOL CPacketMsg::getNetCardInfo()
{
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errBuf) == -1)
{
AfxMessageBox("Error in pcap_findalldevs!");
return FALSE;
}
pcap_if_t *d;
d=alldevs;
if(d==NULL)
{
AfxMessageBox("Can not find NetCard!");
return FALSE;
}
CCapturePacketDlg *dlg=(CCapturePacketDlg *)AfxGetApp()->m_pMainWnd;
while (d)
{
dlg->m_netCard.AddString(d->description);
d=d->next;
}
return TRUE;
}
BOOL CPacketMsg::getPacketInfo(int dev_num)
{
pcap_if_t *d;
int i;
pcap_t *adhandle;
int res;
struct tm *ltime;
char timestr[16];
struct pcap_pkthdr *header;
const u_char *pkt_data;
time_t local_tv_sec;
struct bpf_program fcode;
u_int netmask;
ip_header *ih;
udp_header *uh;
u_int ip_len;
u_short sport,dport;
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL,&alldevs,errBuf)==-1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n",errBuf);
return FALSE;
}
d=alldevs;
if (d==NULL)
{
AfxMessageBox("No interfaces found! Make sure WinPcap is installed.");
return FALSE;
}
/*if (dev_num<1)
{
return FALSE;
}*/
/* 跳转到已选中的适配器 */
for(d=alldevs, i=0;i< dev_num;d=d->next,i++);
/* 打开设备 */
if ( (adhandle= pcap_open(d->name, // 设备名
65536, // 要捕捉的数据包的部分
// 65535保证能捕获到不同数据链路层上的每个数据包的全部内容
PCAP_OPENFLAG_PROMISCUOUS, // 混杂模式
1000, // 读取超时时间
NULL, // 远程机器验证
errBuf // 错误缓冲池
) ) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
/* 释放设列表 */
pcap_freealldevs(alldevs);
return FALSE;
}
/* 检查数据链路层,为了简单,我们只考虑以太网 */
if(pcap_datalink(adhandle) != DLT_EN10MB)
{
fprintf(stderr,"\nThis program works only on Ethernet networks.\n");
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return FALSE;
}
if(d->addresses != NULL)
/* 获得接口第一个地址的掩码 */
netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
else
/* 如果接口没有地址,那么我们假设一个C类的掩码 */
netmask=0xffffff;
//编译过滤器
if (pcap_compile(adhandle, &fcode, "ip and udp", 1, netmask) <0 )
{
fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n");
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return FALSE;
}
//设置过滤器
if (pcap_setfilter(adhandle, &fcode)<0)
{
fprintf(stderr,"\nError setting the filter.\n");
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return -1;
}
/* 释放设备列表 */
pcap_freealldevs(alldevs);
/* 获取数据包 */
CCapturePacketDlg *dlg=(CCapturePacketDlg *)AfxGetApp()->m_pMainWnd;
while((res = pcap_next_ex( adhandle, &header, &pkt_data)) >= 0/*&&packetCount<10*/)
{
if(res == 0)
/* 超时时间到 */
continue;
/* 将时间戳转换成可识别的格式 */
local_tv_sec = header->ts.tv_sec;
ltime=localtime(&local_tv_sec);
strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
//printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
/* 获得IP数据包头部的位置 */
ih=(ip_header *)(pkt_data+14); //以太网头部长度
/* 获得UDP首部的位置 */
ip_len=(ih->ver_ihl&0xf)*4;
uh=(udp_header *)((u_char*)ih+ip_len);
/* 将网络字节序列转换成主机字节序列 */
sport=ntohs(uh->sport);
dport=ntohs(uh->dport);
//AfxMessageBox("abc");
packetCount++;
CString Msgstr;
int npos=dlg->m_packet.GetItemCount();
Msgstr.Format("%d",packetCount);
dlg->m_packet.InsertItem(npos,Msgstr);
dlg->m_packet.SetItemText(npos,1,timestr);
Msgstr.Format("%d.%d.%d.%d:%d",ih->saddr.byte1,ih->saddr.byte2,ih->saddr.byte3,ih->saddr.byte4,sport);
dlg->m_packet.SetItemText(npos,2,Msgstr);
Msgstr.Format("%d.%d.%d.%d:%d",ih->daddr.byte1,ih->daddr.byte2,ih->daddr.byte3,ih->daddr.byte4,dport);
dlg->m_packet.SetItemText(npos,3,Msgstr);
Msgstr.Format("%d",header->len);
dlg->m_packet.SetItemText(npos,4,Msgstr);
//PostMessage(dlg->m_packet,WM_VSCROLL, SB_BOTTOM, 0);
//dlg->m_packet.EnsureVisible(dlg->m_packet.GetItemCount()-1,FALSE);
dlg->m_packet.Scroll(CSize(0,20));
}
if(res == -1)
{
//printf("Error reading the packets: %s\n", pcap_geterr(adhandle));
return FALSE;
}
return TRUE;
}