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; 
}