采用天朝流行的话,“由于种种原因”本人已接近一年半没有写博客了,最近回想起来,很多东西即便再小也得慢慢积累,更何况前两章之后就没有了,很多网友表示比较期待后面的文字,不能做一个太监了事,打算还是继续写完,给被吊了胃口这么久的朋友表示深深地歉意。
这一章要讲的是winpcap核心编程,首先来看一下sniffer程序的整体框架,程序主要由三个部分构成,其示意图如下:
其中,winpcap对数据的捕获主要在cmcf6Dlg.cpp中完成(偷了些懒,就没有把界面与这部分程序分开了,我得承认这不是一个好习惯),一些功能函数如解析数据包等程序在utilities.cpp中完成,协议包数据结构及类型定义在Protocol.h完成。
winpcap的主要流程如下:
1) 调用pcap_findalldevs()获得网卡接口信息,一台计算机上可能有很多个网卡接口,知道有哪些接口是非常有必要的。
//初始化winpcap
int Cmcf6Dlg::lixsniff_initCap()
{
devCount = 0;
if(pcap_findalldevs(&alldev, errbuf) ==-1)
return -1;
for(dev=alldev;dev;dev=dev->next)
devCount++; //记录设备数
return 0;
}
其中 alldev与dev声明如下,主要是用来记录查找到的网卡设备
pcap_if_t *alldev;
pcap_if_t *dev;
2) 在获取了网卡接口信息后,即可调用pcap_open_live()打开指定网卡接口,winpcap将在此接口上侦听数据
if ((adhandle= pcap_open_live(dev->name, // 设备名
65536, //捕获数据包长度
1, // 混杂模式 (非0意味着是混杂模式)
1000, // 读超时设置
errbuf // 错误信息
)) == NULL)
{
MessageBox(_T("无法打开接口:"+CString(dev->description)));
pcap_freealldevs(alldev);
return -1;
}
3) 调用pcap_datalink()、pcap_compile()、pcap_setfilter()分别检查是否是以太网,并对过滤器进行设置。网络中过来的数据有些可能不是以太网数据,这样的数据我们处理不了,所以首先要进行一个检查;而过滤器是什么呢,简单的说,网络中过来的数据是不同层次、不同协议的,过滤器的作用就是可以设定一些的规则来查看你想要的数据包,如指定只需要TCP包。
/*检查是否为以太网*/
if(pcap_datalink(adhandle)!=DLT_EN10MB)
{
MessageBox(_T("这不适合于非以太网的网络!"));
pcap_freealldevs(alldev);
return -1;
}
/*编译过滤器*/
if(0==filter_index)
{
char filter[] = "";
if (pcap_compile(adhandle, &fcode, filter, 1, netmask) <0 )
{
MessageBox(_T("语法错误,无法编译过滤器"));
pcap_freealldevs(alldev);
return -1;
}
}else{
CString str;
char *filter;
int len,x;
this->m_comboBoxRule.GetLBText(filter_index,str);
len = str.GetLength()+1;
filter = (char*)malloc(len);
for(x=0;x
4) 调用pcap_dump_open()先创建一个文件,捕获的数据将会存储到此文件中,后面捕获的数据包将会实时地写入一个临时文件,文件默认存储在工程中的SaveData文件中,文件名为存储时的时间,如在2010年10月10日14:15:16存储的,那么其文件名即为20101010141516,在捕获数据结束时,用户可以选择将此文件存储于指定路径。
dumpfile = pcap_dump_open(adhandle, filepath);
if(dumpfile==NULL)
{
MessageBox(_T("文件创建错误!"));
return -1;
}
5) 完成以上设置后,即可开始捕获数据包了。调用CreateThread()创建一个新的线程,调用lixsinff_CapThread()函数在线程中完成数据包的捕获工作。为什么要新建一个线程来完成这项工作?那是因为我们的主进程是一个Dialog(对话框),它主要的任务是处理界面交互,而数据捕获是一项后台工作,将数据包的捕获与界面进程分离,可以提高程序效率,避免了二者的干扰。
/*接收数据,新建线程处理*/
LPDWORD threadCap=NULL;
m_ThreadHandle=CreateThread(NULL,0,lixsinff_CapThread,this,0,threadCap);
if(m_ThreadHandle==NULL)
{
int code=GetLastError();
CString str;
str.Format(_T("创建线程错误,代码为%d."),code);
MessageBox(str);
return -1;
}
6)在lixsinff_CapThread()中调用pcap_next_ex()函数进行数据包捕获,每到达一个数据包,调用自定义的包处理函数analyze_frame()完成对捕获数据的解析
。注:对于analyze_frame()函数将在第五章专门介绍其工作流程。
while((res = pcap_next_ex( pthis->adhandle, &header, &pkt_data)) >= 0)
{
if(res == 0) //超时
continue;
struct datapkt *data = (struct datapkt*)malloc(sizeof(struct datapkt));
memset(data,0,sizeof(struct datapkt));
if(NULL == data)
{
MessageBox(NULL,_T("空间已满,无法接收新的数据包"),_T("Error"),MB_OK);
return -1;
}
//分析出错或所接收数据包不在处理范围内
if(analyze_frame(pkt_data,data,&(pthis->npacket))<0)
continue;
…….(以下省略)
}
7) 经过analyze_frame()函数处理后将相关数据更新到GUI。这一点第六章会讲到。
以下是cmcf6Dlg.h以及cmcf6Dlg.cpp的源代码,也就是我们的主程序代码,在代码中可以看到完整的实现过程,实际上对于如何将数据写到GUI上已经大体从这里可以看得出来了:)
下一章:要想从此过,留下协议头——各层网络协议头的实现
cmcf6Dlg.h:
// mcf6Dlg.h : 头文件
//
#pragma once
#include "afxcmn.h"
#include "afxwin.h"
#include"pcap.h"
#include "Protocol.h"
#include "utilities.h"
// Cmcf6Dlg 对话框
class Cmcf6Dlg : public CDialog
{
// 构造
public:
Cmcf6Dlg(CWnd* pParent = NULL); // 标准构造函数
/////////////////////////////////////////////[my fuction]//////////////////////////////////////////////
int lixsniff_initCap();
int lixsniff_startCap();
int lixsniff_updateTree(int index);
int lixsniff_updateEdit(int index);
int lixsniff_updateNPacket();
int lixsniff_saveFile();
int lixsniff_readFile(CString path);
//////////////////////////////////////////////[my data]/////////////////////////////////////////////
int devCount;
struct pktcount npacket; //各类数据包计数
char errbuf[PCAP_ERRBUF_SIZE];
pcap_if_t *alldev;
pcap_if_t *dev;
pcap_t *adhandle;
pcap_dumper_t *dumpfile;
char filepath[512]; // 文件保存路径
char filename[64]; // 文件名称
HANDLE m_ThreadHandle; //线程
CPtrList m_pktList; //捕获包所存放的链表
// 对话框数据
enum { IDD = IDD_MCF6_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
CListCtrl m_listCtrl;
CComboBox m_comboBox;
CComboBox m_comboBoxRule;
CTreeCtrl m_treeCtrl;
CEdit m_edit;
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton2();
CButton m_buttonStart;
CButton m_buttonStop;
CPtrList m_localDataList; //保存被本地化后的数据包
CPtrList m_netDataList; //保存从网络中直接获取的数据包
CBitmapButton m_bitButton ; //图片按钮
int npkt;
afx_msg void OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult);
CEdit m_editNTcp;
CEdit m_editNUdp;
CEdit m_editNIcmp;
CEdit m_editNIp;
CEdit m_editNArp;
CEdit m_editNHttp;
CEdit m_editNOther;
CEdit m_editNSum;
afx_msg void OnNMCustomdrawList1(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnBnClickedButton5();
CButton m_buttonSave;
CButton m_buttonRead;
afx_msg void OnBnClickedButton4();
CEdit m_editNIpv4;
CEdit m_editIcmpv6;
};
cmcf6Dlg.cpp:
// mcf6Dlg.cpp : 实现文件
//
#include "stdafx.h"
#include "mcf6.h"
#include "mcf6Dlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
DWORD WINAPI lixsinff_CapThread(LPVOID lpParameter);
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// Cmcf6Dlg 对话框
Cmcf6Dlg::Cmcf6Dlg(CWnd* pParent /*=NULL*/)
: CDialog(Cmcf6Dlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void Cmcf6Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST1, m_listCtrl);
DDX_Control(pDX, IDC_COMBO1, m_comboBox);
DDX_Control(pDX, IDC_COMBO2, m_comboBoxRule);
DDX_Control(pDX, IDC_TREE1, m_treeCtrl);
DDX_Control(pDX, IDC_EDIT1, m_edit);
DDX_Control(pDX, IDC_BUTTON1, m_buttonStart);
DDX_Control(pDX, IDC_BUTTON2, m_buttonStop);
DDX_Control(pDX, IDC_EDIT2, m_editNTcp);
DDX_Control(pDX, IDC_EDIT3, m_editNUdp);
DDX_Control(pDX, IDC_EDIT4, m_editNIcmp);
DDX_Control(pDX, IDC_EDIT5, m_editNIp);
DDX_Control(pDX, IDC_EDIT6, m_editNArp);
DDX_Control(pDX, IDC_EDIT7, m_editNHttp);
DDX_Control(pDX, IDC_EDIT8, m_editNOther);
DDX_Control(pDX, IDC_EDIT9, m_editNSum);
DDX_Control(pDX, IDC_BUTTON5, m_buttonSave);
DDX_Control(pDX, IDC_BUTTON4, m_buttonRead);
DDX_Control(pDX, IDC_EDIT10, m_editNIpv4);
DDX_Control(pDX, IDC_EDIT11, m_editIcmpv6);
}
BEGIN_MESSAGE_MAP(Cmcf6Dlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON1, &Cmcf6Dlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, &Cmcf6Dlg::OnBnClickedButton2)
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &Cmcf6Dlg::OnLvnItemchangedList1)
ON_NOTIFY(NM_CUSTOMDRAW, IDC_LIST1, &Cmcf6Dlg::OnNMCustomdrawList1)
ON_BN_CLICKED(IDC_BUTTON5, &Cmcf6Dlg::OnBnClickedButton5)
ON_BN_CLICKED(IDC_BUTTON4, &Cmcf6Dlg::OnBnClickedButton4)
END_MESSAGE_MAP()
// Cmcf6Dlg 消息处理程序
BOOL Cmcf6Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
ShowWindow(SW_MINIMIZE);
// TODO: 在此添加额外的初始化代码
m_listCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
m_listCtrl.InsertColumn(0,_T("编号"),3,30); //1表示右,2表示中,3表示左
m_listCtrl.InsertColumn(1,_T("时间"),3,130);
m_listCtrl.InsertColumn(2,_T("长度"),3,72);
m_listCtrl.InsertColumn(3,_T("源MAC地址"),3,140);
m_listCtrl.InsertColumn(4,_T("目的MAC地址"),3,140);
m_listCtrl.InsertColumn(5,_T("协议"),3,70);
m_listCtrl.InsertColumn(6,_T("源IP地址"),3,145);
m_listCtrl.InsertColumn(7,_T("目的IP地址"),3,145);
m_comboBox.AddString(_T("请选择一个网卡接口(必选)"));
m_comboBoxRule.AddString(_T("请选择过滤规则(可选)"));
if(lixsniff_initCap()<0)
return FALSE;
/*初始化接口列表*/
for(dev=alldev;dev;dev=dev->next)
{
if(dev->description)
m_comboBox.AddString(CString(dev->description)); //////////////////////////////Problem 1字符集问题
}
/*初始化过滤规则列表*/
m_comboBoxRule.AddString(_T("tcp"));
m_comboBoxRule.AddString(_T("udp"));
m_comboBoxRule.AddString(_T("ip"));
m_comboBoxRule.AddString(_T("icmp"));
m_comboBoxRule.AddString(_T("arp"));
m_comboBox.SetCurSel(0);
m_comboBoxRule.SetCurSel(0);
m_buttonStop.EnableWindow(FALSE);
m_buttonSave.EnableWindow(FALSE);
//m_bitButton.RedrawWindow();
/////////////////////////////////////////////////////////////////////////////////////////////////listControl用法
//int nitem = m_listCtrl.InsertItem(0,_T("hello"));
/*char buf[5];
itoa(nitem,buf,10);
MessageBox(CString(buf));*/
/*m_listCtrl.SetItemText(nitem,1,_T("jak"));
m_listCtrl.SetItemText(nitem,2,_T("bub"));
m_listCtrl.SetItemText(nitem,3,_T("coco"));
m_listCtrl.SetItemText(nitem,4,_T("haha"));*/
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void Cmcf6Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void Cmcf6Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR Cmcf6Dlg::OnQueryDragIcon()
{
return static_cast(m_hIcon);
}
/////////////////////////////////////////[事件函数]///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//开始按钮
void Cmcf6Dlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
//如果已经有数据了,提示保存数据
if(this->m_localDataList.IsEmpty() == FALSE)
{
if(MessageBox(_T("确认不保存数据?"),_T("警告"),MB_YESNO)==IDNO)
{
this->lixsniff_saveFile();
}
}
this->npkt =1; //重新计数
this->m_localDataList.RemoveAll(); //每次一开始就将以前存的数据清空掉
this->m_netDataList.RemoveAll();
memset(&(this->npacket),0,sizeof(struct pktcount));
this->lixsniff_updateNPacket();
if(this->lixsniff_startCap()<0)
return;
this->m_listCtrl.DeleteAllItems();
this->m_treeCtrl.DeleteAllItems();
this->m_edit.SetWindowTextW(_T(""));
this->m_buttonStart.EnableWindow(FALSE);
this->m_buttonStop.EnableWindow(TRUE);
this->m_buttonSave.EnableWindow(FALSE);
}
//结束按钮
void Cmcf6Dlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
if(NULL == this->m_ThreadHandle )
return;
if(TerminateThread(this->m_ThreadHandle,-1)==0)
{
MessageBox(_T("关闭线程错误,请稍后重试"));
return;
}
this->m_ThreadHandle = NULL;
this->m_buttonStart.EnableWindow(TRUE);
this->m_buttonStop.EnableWindow(FALSE);
this->m_buttonSave.EnableWindow(TRUE);
}
//列表
void Cmcf6Dlg::OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
int index;
index = this->m_listCtrl.GetHotItem();
if(index>this->m_localDataList.GetCount()-1)
return;
this->lixsniff_updateEdit(index);
this->lixsniff_updateTree(index);
*pResult = 0;
}
//保存按钮
void Cmcf6Dlg::OnBnClickedButton5()
{
// TODO: 在此添加控件通知处理程序代码
if(this->lixsniff_saveFile()<0)
return;
}
//读取按钮
void Cmcf6Dlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
//读取之前将ListCtrl清空
this->m_listCtrl.DeleteAllItems();
this->npkt =1; //列表重新计数
this->m_localDataList.RemoveAll(); //每次一开始就将以前存的数据清空掉
this->m_netDataList.RemoveAll();
memset(&(this->npacket),0,sizeof(struct pktcount));//各类包计数清空
//打开文件对话框
CFileDialog FileDlg(TRUE ,_T(".lix"),NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT);
FileDlg.m_ofn.lpstrInitialDir=_T("c:\\");
if(FileDlg.DoModal()==IDOK)
{
int ret = this->lixsniff_readFile(FileDlg.GetPathName());
if(ret < 0)
return;
}
}
//改变ListCtrl每行颜色
void Cmcf6Dlg::OnNMCustomdrawList1(NMHDR *pNMHDR, LRESULT *pResult)
{
//LPNMCUSTOMDRAW pNMCD = reinterpret_cast(pNMHDR);
LPNMLVCUSTOMDRAW pNMCD = (LPNMLVCUSTOMDRAW)pNMHDR;
*pResult = 0;
// TODO: 在此添加控件通知处理程序代码
if(CDDS_PREPAINT==pNMCD->nmcd.dwDrawStage)
{
*pResult = CDRF_NOTIFYITEMDRAW;
}else if(CDDS_ITEMPREPAINT ==pNMCD->nmcd.dwDrawStage){
COLORREF crText;
char buf[10];
memset(buf,0,10);
POSITION pos = this->m_localDataList.FindIndex(pNMCD->nmcd.dwItemSpec);
struct datapkt * local_data = (struct datapkt *)this->m_localDataList.GetAt(pos);
strcpy(buf,local_data->pktType);
if(strcmp(buf,"IPV6")==0)
crText = RGB(111,224,254);
else if(strcmp(buf,"UDP")==0)
crText = RGB(194,195,252);
else if(strcmp(buf,"TCP")==0)
crText = RGB(230,230,230);
else if(strcmp(buf,"ARP")==0)
crText = RGB(226,238,227);
else if(strcmp(buf,"ICMP")==0)
crText = RGB(49,164,238);
else if(strcmp(buf,"HTTP")==0)
crText = RGB(238,232,180);
else if(strcmp(buf,"ICMPv6")==0)
crText = RGB(189,254,76);
pNMCD->clrTextBk =crText;
*pResult = CDRF_DODEFAULT;
}
}
//////////////////////////////////////////[功能函数]///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//初始化winpcap
int Cmcf6Dlg::lixsniff_initCap()
{
devCount = 0;
if(pcap_findalldevs(&alldev, errbuf) ==-1)
return -1;
for(dev=alldev;dev;dev=dev->next)
devCount++;
return 0;
}
//开始捕获
int Cmcf6Dlg::lixsniff_startCap()
{
int if_index,filter_index,count;
u_int netmask;
struct bpf_program fcode;
lixsniff_initCap();
//获得接口和过滤器索引
if_index = this->m_comboBox.GetCurSel();
filter_index = this->m_comboBoxRule.GetCurSel();
if(0==if_index || CB_ERR == if_index)
{
MessageBox(_T("请选择一个合适的网卡接口"));
return -1;
}
if(CB_ERR == filter_index)
{
MessageBox(_T("过滤器选择错误"));
return -1;
}
/*获得选中的网卡接口*/
dev=alldev;
for(count=0;countnext;
if ((adhandle= pcap_open_live(dev->name, // 设备名
65536, //捕获数据包长度
1, // 混杂模式 (非0意味着是混杂模式)
1000, // 读超时设置
errbuf // 错误信息
)) == NULL)
{
MessageBox(_T("无法打开接口:"+CString(dev->description)));
pcap_freealldevs(alldev);
return -1;
}
/*检查是否为以太网*/
if(pcap_datalink(adhandle)!=DLT_EN10MB)
{
MessageBox(_T("这不适合于非以太网的网络!"));
pcap_freealldevs(alldev);
return -1;
}
if(dev->addresses!=NULL)
netmask=((struct sockaddr_in *)(dev->addresses->netmask))->sin_addr.S_un.S_addr;
else
netmask=0xffffff;
//编译过滤器
if(0==filter_index)
{
char filter[] = "";
if (pcap_compile(adhandle, &fcode, filter, 1, netmask) <0 )
{
MessageBox(_T("语法错误,无法编译过滤器"));
pcap_freealldevs(alldev);
return -1;
}
}else{
CString str;
char *filter;
int len,x;
this->m_comboBoxRule.GetLBText(filter_index,str);
len = str.GetLength()+1;
filter = (char*)malloc(len);
for(x=0;xm_ThreadHandle)
{
MessageBox(NULL,_T("线程句柄错误"),_T("提示"),MB_OK);
return -1;
}
while((res = pcap_next_ex( pthis->adhandle, &header, &pkt_data)) >= 0)
{
if(res == 0) //超时
continue;
struct datapkt *data = (struct datapkt*)malloc(sizeof(struct datapkt));
memset(data,0,sizeof(struct datapkt));
if(NULL == data)
{
MessageBox(NULL,_T("空间已满,无法接收新的数据包"),_T("Error"),MB_OK);
return -1;
}
//分析出错或所接收数据包不在处理范围内
if(analyze_frame(pkt_data,data,&(pthis->npacket))<0)
continue;
//将数据包保存到打开的文件中
if(pthis->dumpfile!=NULL)
{
pcap_dump((unsigned char*)pthis->dumpfile,header,pkt_data);
}
//更新各类数据包计数
pthis->lixsniff_updateNPacket();
//将本地化后的数据装入一个链表中,以便后来使用
ppkt_data = (u_char*)malloc(header->len);
memcpy(ppkt_data,pkt_data,header->len);
pthis->m_localDataList.AddTail(data);
pthis->m_netDataList.AddTail(ppkt_data);
/*预处理,获得时间、长度*/
data->len = header->len; //链路中收到的数据长度
local_tv_sec = header->ts.tv_sec;
ltime = localtime(&local_tv_sec);
data->time[0] = ltime->tm_year+1900;
data->time[1] = ltime->tm_mon+1;
data->time[2] = ltime->tm_mday;
data->time[3] = ltime->tm_hour;
data->time[4] = ltime->tm_min;
data->time[5] = ltime->tm_sec;
/*为新接收到的数据包在listControl中新建一个item*/
buf.Format(_T("%d"),pthis->npkt);
nItem = pthis->m_listCtrl.InsertItem(pthis->npkt,buf);
/*显示时间戳*/
timestr.Format(_T("%d/%d/%d %d:%d:%d"),data->time[0],
data->time[1],data->time[2],data->time[3],data->time[4],data->time[5]);
pthis->m_listCtrl.SetItemText(nItem,1,timestr);
//pthis->m_listCtrl.setitem
/*显示长度*/
buf.Empty();
buf.Format(_T("%d"),data->len);
pthis->m_listCtrl.SetItemText(nItem,2,buf);
/*显示源MAC*/
buf.Empty();
buf.Format(_T("%02X-%02X-%02X-%02X-%02X-%02X"),data->ethh->src[0],data->ethh->src[1],
data->ethh->src[2],data->ethh->src[3],data->ethh->src[4],data->ethh->src[5]);
pthis->m_listCtrl.SetItemText(nItem,3,buf);
/*显示目的MAC*/
buf.Empty();
buf.Format(_T("%02X-%02X-%02X-%02X-%02X-%02X"),data->ethh->dest[0],data->ethh->dest[1],
data->ethh->dest[2],data->ethh->dest[3],data->ethh->dest[4],data->ethh->dest[5]);
pthis->m_listCtrl.SetItemText(nItem,4,buf);
/*获得协议*/
pthis->m_listCtrl.SetItemText(nItem,5,CString(data->pktType));
/*获得源IP*/
buf.Empty();
if(0x0806== data->ethh->type)
{
buf.Format(_T("%d.%d.%d.%d"),data->arph->ar_srcip[0],
data->arph->ar_srcip[1],data->arph->ar_srcip[2],data->arph->ar_srcip[3]);
}else if(0x0800 == data->ethh->type) {
struct in_addr in;
in.S_un.S_addr = data->iph->saddr;
buf = CString(inet_ntoa(in));
}else if(0x86dd ==data->ethh->type ){
int n;
for(n=0;n<8;n++)
{
if(n<=6)
buf.AppendFormat(_T("%02x:"),data->iph6->saddr[n]);
else
buf.AppendFormat(_T("%02x"),data->iph6->saddr[n]);
}
}
pthis->m_listCtrl.SetItemText(nItem,6,buf);
/*获得目的IP*/
buf.Empty();
if(0x0806 == data->ethh->type)
{
buf.Format(_T("%d.%d.%d.%d"),data->arph->ar_destip[0],
data->arph->ar_destip[1],data->arph->ar_destip[2],data->arph->ar_destip[3]);
}else if(0x0800 == data->ethh->type){
struct in_addr in;
in.S_un.S_addr = data->iph->daddr;
buf = CString(inet_ntoa(in));
}else if(0x86dd ==data->ethh->type ){
int n;
for(n=0;n<8;n++)
{
if(n<=6)
buf.AppendFormat(_T("%02x:"),data->iph6->daddr[n]);
else
buf.AppendFormat(_T("%02x"),data->iph6->daddr[n]);
}
}
pthis->m_listCtrl.SetItemText(nItem,7,buf);
/*对包计数*/
pthis->npkt++;
}
return 1;
}
//更新信息
int Cmcf6Dlg::lixsniff_updateEdit(int index)
{
POSITION localpos,netpos;
localpos = this->m_localDataList.FindIndex(index);
netpos = this->m_netDataList.FindIndex(index);
struct datapkt* local_data = (struct datapkt*)(this->m_localDataList.GetAt(localpos));
u_char * net_data = (u_char*)(this->m_netDataList.GetAt(netpos));
CString buf;
print_packet_hex(net_data,local_data->len,&buf);
//this-
this->m_edit.SetWindowText(buf);
return 1;
}
//更新统计数据
int Cmcf6Dlg::lixsniff_updateNPacket()
{
CString str_num;
str_num.Format(_T("%d"),this->npacket.n_arp);
this->m_editNArp.SetWindowText(str_num);
str_num.Format(_T("%d"),this->npacket.n_http);
this->m_editNHttp.SetWindowText(str_num);
str_num.Format(_T("%d"),this->npacket.n_icmp);
this->m_editNIcmp.SetWindowText(str_num);
str_num.Format(_T("%d"),this->npacket.n_ip6);
this->m_editNIp.SetWindowText(str_num);
str_num.Format(_T("%d"),this->npacket.n_other);
this->m_editNOther.SetWindowText(str_num);
str_num.Format(_T("%d"),this->npacket.n_sum);
this->m_editNSum.SetWindowText(str_num);
str_num.Format(_T("%d"),this->npacket.n_tcp);
this->m_editNTcp.SetWindowText(str_num);
str_num.Format(_T("%d"),this->npacket.n_udp);
this->m_editNUdp.SetWindowText(str_num);
str_num.Format(_T("%d"),this->npacket.n_ip);
this->m_editNIpv4.SetWindowText(str_num);
str_num.Format(_T("%d"),this->npacket.n_icmp6);
this->m_editIcmpv6.SetWindowText(str_num);
return 1;
}
//更新树形控件
int Cmcf6Dlg::lixsniff_updateTree(int index)
{
POSITION localpos;
CString str;
int i;
this->m_treeCtrl.DeleteAllItems();
localpos = this->m_localDataList.FindIndex(index);
struct datapkt* local_data = (struct datapkt*)(this->m_localDataList.GetAt(localpos));
HTREEITEM root = this->m_treeCtrl.GetRootItem();
str.Format(_T("接收到的第%d个数据包"),index+1);
HTREEITEM data = this->m_treeCtrl.InsertItem(str,root);
/*处理帧数据*/
HTREEITEM frame = this->m_treeCtrl.InsertItem(_T("链路层数据"),data);
//源MAC
str.Format(_T("源MAC:"));
for(i=0;i<6;i++)
{
if(i<=4)
str.AppendFormat(_T("%02x-"),local_data->ethh->src[i]);
else
str.AppendFormat(_T("%02x"),local_data->ethh->src[i]);
}
this->m_treeCtrl.InsertItem(str,frame);
//目的MAC
str.Format(_T("目的MAC:"));
for(i=0;i<6;i++)
{
if(i<=4)
str.AppendFormat(_T("%02x-"),local_data->ethh->dest[i]);
else
str.AppendFormat(_T("%02x"),local_data->ethh->dest[i]);
}
this->m_treeCtrl.InsertItem(str,frame);
//类型
str.Format(_T("类型:0x%02x"),local_data->ethh->type);
this->m_treeCtrl.InsertItem(str,frame);
/*处理IP、ARP、IPv6数据包*/
if(0x0806 == local_data->ethh->type) //ARP
{
HTREEITEM arp = this->m_treeCtrl.InsertItem(_T("ARP协议头"),data);
str.Format(_T("硬件类型:%d"),local_data->arph->ar_hrd);
this->m_treeCtrl.InsertItem(str,arp);
str.Format(_T("协议类型:0x%02x"),local_data->arph->ar_pro);
this->m_treeCtrl.InsertItem(str,arp);
str.Format(_T("硬件地址长度:%d"),local_data->arph->ar_hln);
this->m_treeCtrl.InsertItem(str,arp);
str.Format(_T("协议地址长度:%d"),local_data->arph->ar_pln);
this->m_treeCtrl.InsertItem(str,arp);
str.Format(_T("操作码:%d"),local_data->arph->ar_op);
this->m_treeCtrl.InsertItem(str,arp);
str.Format(_T("发送方MAC:"));
for(i=0;i<6;i++)
{
if(i<=4)
str.AppendFormat(_T("%02x-"),local_data->arph->ar_srcmac[i]);
else
str.AppendFormat(_T("%02x"),local_data->arph->ar_srcmac[i]);
}
this->m_treeCtrl.InsertItem(str,arp);
str.Format(_T("发送方IP:"),local_data->arph->ar_hln);
for(i=0;i<4;i++)
{
if(i<=2)
str.AppendFormat(_T("%d."),local_data->arph->ar_srcip[i]);
else
str.AppendFormat(_T("%d"),local_data->arph->ar_srcip[i]);
}
this->m_treeCtrl.InsertItem(str,arp);
str.Format(_T("接收方MAC:"),local_data->arph->ar_hln);
for(i=0;i<6;i++)
{
if(i<=4)
str.AppendFormat(_T("%02x-"),local_data->arph->ar_destmac[i]);
else
str.AppendFormat(_T("%02x"),local_data->arph->ar_destmac[i]);
}
this->m_treeCtrl.InsertItem(str,arp);
str.Format(_T("接收方IP:"),local_data->arph->ar_hln);
for(i=0;i<4;i++)
{
if(i<=2)
str.AppendFormat(_T("%d."),local_data->arph->ar_destip[i]);
else
str.AppendFormat(_T("%d"),local_data->arph->ar_destip[i]);
}
this->m_treeCtrl.InsertItem(str,arp);
}else if(0x0800 == local_data->ethh->type){ //IP
HTREEITEM ip = this->m_treeCtrl.InsertItem(_T("IP协议头"),data);
str.Format(_T("版本:%d"),local_data->iph->version);
this->m_treeCtrl.InsertItem(str,ip);
str.Format(_T("IP头长:%d"),local_data->iph->ihl);
this->m_treeCtrl.InsertItem(str,ip);
str.Format(_T("服务类型:%d"),local_data->iph->tos);
this->m_treeCtrl.InsertItem(str,ip);
str.Format(_T("总长度:%d"),local_data->iph->tlen);
this->m_treeCtrl.InsertItem(str,ip);
str.Format(_T("标识:0x%02x"),local_data->iph->id);
this->m_treeCtrl.InsertItem(str,ip);
str.Format(_T("段偏移:%d"),local_data->iph->frag_off);
this->m_treeCtrl.InsertItem(str,ip);
str.Format(_T("生存期:%d"),local_data->iph->ttl);
this->m_treeCtrl.InsertItem(str,ip);
str.Format(_T("协议:%d"),local_data->iph->proto);
this->m_treeCtrl.InsertItem(str,ip);
str.Format(_T("头部校验和:0x%02x"),local_data->iph->check);
this->m_treeCtrl.InsertItem(str,ip);
str.Format(_T("源IP:"));
struct in_addr in;
in.S_un.S_addr = local_data->iph->saddr;
str.AppendFormat(CString(inet_ntoa(in)));
this->m_treeCtrl.InsertItem(str,ip);
str.Format(_T("目的IP:"));
in.S_un.S_addr = local_data->iph->daddr;
str.AppendFormat(CString(inet_ntoa(in)));
this->m_treeCtrl.InsertItem(str,ip);
/*处理传输层ICMP、UDP、TCP*/
if(1 == local_data->iph->proto ) //ICMP
{
HTREEITEM icmp = this->m_treeCtrl.InsertItem(_T("ICMP协议头"),data);
str.Format(_T("类型:%d"),local_data->icmph->type);
this->m_treeCtrl.InsertItem(str,icmp);
str.Format(_T("代码:%d"),local_data->icmph->code);
this->m_treeCtrl.InsertItem(str,icmp);
str.Format(_T("序号:%d"),local_data->icmph->seq);
this->m_treeCtrl.InsertItem(str,icmp);
str.Format(_T("校验和:%d"),local_data->icmph->chksum);
this->m_treeCtrl.InsertItem(str,icmp);
}else if(6 == local_data->iph->proto){ //TCP
HTREEITEM tcp = this->m_treeCtrl.InsertItem(_T("TCP协议头"),data);
str.Format(_T(" 源端口:%d"),local_data->tcph->sport);
this->m_treeCtrl.InsertItem(str,tcp);
str.Format(_T(" 目的端口:%d"),local_data->tcph->dport);
this->m_treeCtrl.InsertItem(str,tcp);
str.Format(_T(" 序列号:0x%02x"),local_data->tcph->seq);
this->m_treeCtrl.InsertItem(str,tcp);
str.Format(_T(" 确认号:%d"),local_data->tcph->ack_seq);
this->m_treeCtrl.InsertItem(str,tcp);
str.Format(_T(" 头部长度:%d"),local_data->tcph->doff);
HTREEITEM flag = this->m_treeCtrl.InsertItem(_T(" +标志位"),tcp);
str.Format(_T("cwr %d"),local_data->tcph->cwr);
this->m_treeCtrl.InsertItem(str,flag);
str.Format(_T("ece %d"),local_data->tcph->ece);
this->m_treeCtrl.InsertItem(str,flag);
str.Format(_T("urg %d"),local_data->tcph->urg);
this->m_treeCtrl.InsertItem(str,flag);
str.Format(_T("ack %d"),local_data->tcph->ack);
this->m_treeCtrl.InsertItem(str,flag);
str.Format(_T("psh %d"),local_data->tcph->psh);
this->m_treeCtrl.InsertItem(str,flag);
str.Format(_T("rst %d"),local_data->tcph->rst);
this->m_treeCtrl.InsertItem(str,flag);
str.Format(_T("syn %d"),local_data->tcph->syn);
this->m_treeCtrl.InsertItem(str,flag);
str.Format(_T("fin %d"),local_data->tcph->fin);
this->m_treeCtrl.InsertItem(str,flag);
str.Format(_T(" 紧急指针:%d"),local_data->tcph->urg_ptr);
this->m_treeCtrl.InsertItem(str,tcp);
str.Format(_T(" 校验和:0x%02x"),local_data->tcph->check);
this->m_treeCtrl.InsertItem(str,tcp);
str.Format(_T(" 选项:%d"),local_data->tcph->opt);
this->m_treeCtrl.InsertItem(str,tcp);
}else if(17 == local_data->iph->proto){ //UDP
HTREEITEM udp = this->m_treeCtrl.InsertItem(_T("UDP协议头"),data);
str.Format(_T("源端口:%d"),local_data->udph->sport);
this->m_treeCtrl.InsertItem(str,udp);
str.Format(_T("目的端口:%d"),local_data->udph->dport);
this->m_treeCtrl.InsertItem(str,udp);
str.Format(_T("总长度:%d"),local_data->udph->len);
this->m_treeCtrl.InsertItem(str,udp);
str.Format(_T("校验和:0x%02x"),local_data->udph->check);
this->m_treeCtrl.InsertItem(str,udp);
}
}else if(0x86dd == local_data->ethh->type){ //IPv6
HTREEITEM ip6 = this->m_treeCtrl.InsertItem(_T("IPv6协议头"),data);
//////////////////////////////////////////////////////////////////////////////////////////
str.Format(_T("版本:%d"),local_data->iph6->flowtype);
this->m_treeCtrl.InsertItem(str,ip6);
str.Format(_T("流类型:%d"),local_data->iph6->version);
this->m_treeCtrl.InsertItem(str,ip6);
///////////////////////////////////////////////////////////////////////////////////////////
str.Format(_T("流标签:%d"),local_data->iph6->flowid);
this->m_treeCtrl.InsertItem(str,ip6);
str.Format(_T("有效载荷长度:%d"),local_data->iph6->plen);
this->m_treeCtrl.InsertItem(str,ip6);
str.Format(_T("下一个首部:0x%02x"),local_data->iph6->nh);
this->m_treeCtrl.InsertItem(str,ip6);
str.Format(_T("跳限制:%d"),local_data->iph6->hlim);
this->m_treeCtrl.InsertItem(str,ip6);
str.Format(_T("源地址:"));
int n;
for(n=0;n<8;n++)
{
if(n<=6)
str.AppendFormat(_T("%02x:"),local_data->iph6->saddr[n]);
else
str.AppendFormat(_T("%02x"),local_data->iph6->saddr[n]);
}
this->m_treeCtrl.InsertItem(str,ip6);
str.Format(_T("目的地址:"));
for(n=0;n<8;n++)
{
if(n<=6)
str.AppendFormat(_T("%02x:"),local_data->iph6->saddr[n]);
else
str.AppendFormat(_T("%02x"),local_data->iph6->saddr[n]);
}
this->m_treeCtrl.InsertItem(str,ip6);
/*处理传输层ICMPv6、UDP、TCP*/
if(0x3a== local_data->iph6->nh ) //ICMPv6
{
HTREEITEM icmp6 = this->m_treeCtrl.InsertItem(_T("ICMPv6协议头"),data);
str.Format(_T("类型:%d"),local_data->icmph6->type);
this->m_treeCtrl.InsertItem(str,icmp6);
str.Format(_T("代码:%d"),local_data->icmph6->code);
this->m_treeCtrl.InsertItem(str,icmp6);
str.Format(_T("序号:%d"),local_data->icmph6->seq);
this->m_treeCtrl.InsertItem(str,icmp6);
str.Format(_T("校验和:%d"),local_data->icmph6->chksum);
this->m_treeCtrl.InsertItem(str,icmp6);
str.Format(_T("选项-类型:%d"),local_data->icmph6->op_type);
this->m_treeCtrl.InsertItem(str,icmp6);
str.Format(_T("选项-长度%d"),local_data->icmph6->op_len);
this->m_treeCtrl.InsertItem(str,icmp6);
str.Format(_T("选项-链路层地址:"));
int i;
for(i=0;i<6;i++)
{
if(i<=4)
str.AppendFormat(_T("%02x-"),local_data->icmph6->op_ethaddr[i]);
else
str.AppendFormat(_T("%02x"),local_data->icmph6->op_ethaddr[i]);
}
this->m_treeCtrl.InsertItem(str,icmp6);
}else if(0x06 == local_data->iph6->nh){ //TCP
HTREEITEM tcp = this->m_treeCtrl.InsertItem(_T("TCP协议头"),data);
str.Format(_T(" 源端口:%d"),local_data->tcph->sport);
this->m_treeCtrl.InsertItem(str,tcp);
str.Format(_T(" 目的端口:%d"),local_data->tcph->dport);
this->m_treeCtrl.InsertItem(str,tcp);
str.Format(_T(" 序列号:0x%02x"),local_data->tcph->seq);
this->m_treeCtrl.InsertItem(str,tcp);
str.Format(_T(" 确认号:%d"),local_data->tcph->ack_seq);
this->m_treeCtrl.InsertItem(str,tcp);
str.Format(_T(" 头部长度:%d"),local_data->tcph->doff);
HTREEITEM flag = this->m_treeCtrl.InsertItem(_T("标志位"),tcp);
str.Format(_T("cwr %d"),local_data->tcph->cwr);
this->m_treeCtrl.InsertItem(str,flag);
str.Format(_T("ece %d"),local_data->tcph->ece);
this->m_treeCtrl.InsertItem(str,flag);
str.Format(_T("urg %d"),local_data->tcph->urg);
this->m_treeCtrl.InsertItem(str,flag);
str.Format(_T("ack %d"),local_data->tcph->ack);
this->m_treeCtrl.InsertItem(str,flag);
str.Format(_T("psh %d"),local_data->tcph->psh);
this->m_treeCtrl.InsertItem(str,flag);
str.Format(_T("rst %d"),local_data->tcph->rst);
this->m_treeCtrl.InsertItem(str,flag);
str.Format(_T("syn %d"),local_data->tcph->syn);
this->m_treeCtrl.InsertItem(str,flag);
str.Format(_T("fin %d"),local_data->tcph->fin);
this->m_treeCtrl.InsertItem(str,flag);
str.Format(_T(" 紧急指针:%d"),local_data->tcph->urg_ptr);
this->m_treeCtrl.InsertItem(str,tcp);
str.Format(_T(" 校验和:0x%02x"),local_data->tcph->check);
this->m_treeCtrl.InsertItem(str,tcp);
str.Format(_T(" 选项:%d"),local_data->tcph->opt);
this->m_treeCtrl.InsertItem(str,tcp);
}else if(0x11== local_data->iph6->nh){ //UDP
HTREEITEM udp = this->m_treeCtrl.InsertItem(_T("UDP协议头"),data);
str.Format(_T("源端口:%d"),local_data->udph->sport);
this->m_treeCtrl.InsertItem(str,udp);
str.Format(_T("目的端口:%d"),local_data->udph->dport);
this->m_treeCtrl.InsertItem(str,udp);
str.Format(_T("总长度:%d"),local_data->udph->len);
this->m_treeCtrl.InsertItem(str,udp);
str.Format(_T("校验和:0x%02x"),local_data->udph->check);
this->m_treeCtrl.InsertItem(str,udp);
}
}
return 1;
}
int Cmcf6Dlg::lixsniff_saveFile()
{
CFileFind find;
if(NULL==find.FindFile(CString(filepath)))
{
MessageBox(_T("保存文件遇到未知意外"));
return -1;
}
//打开文件对话框
CFileDialog FileDlg(FALSE,_T(".lix"),NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT);
FileDlg.m_ofn.lpstrInitialDir=_T("c:\\");
if(FileDlg.DoModal()==IDOK)
{
CopyFile(CString(filepath),FileDlg.GetPathName(),TRUE);
}
return 1;
}
int Cmcf6Dlg::lixsniff_readFile(CString path)
{
int res,nItem,i ;
struct tm *ltime;
CString timestr,buf,srcMac,destMac;
time_t local_tv_sec;
struct pcap_pkthdr *header; //数据包头
const u_char *pkt_data=NULL; //网络中收到的字节流数据
u_char *ppkt_data;
Cmcf6Dlg *pthis =this; //些代码改造自lixsinff_CapThread,为节约工作量,故保留pthis指针
pcap_t *fp;
//首先处理一下路径,利用pcap_open_offline打开文件时,
//路径需要用char *类型,不能用CString强制转换后的char *
int len = path.GetLength()+1; /////////////////////////////////注意这一个细节,必须要加1,否则会出错
char* charpath = (char *)malloc(len);
memset(charpath,0,len);
if(NULL==charpath)
return -1;
for(i=0;i= 0)
{
struct datapkt *data = (struct datapkt*)malloc(sizeof(struct datapkt));
memset(data,0,sizeof(struct datapkt));
if(NULL == data)
{
MessageBox(_T("空间已满,无法接收新的数据包"));
return -1;
}
//分析出错或所接收数据包不在处理范围内
if(analyze_frame(pkt_data,data,&(pthis->npacket))<0)
continue;
//更新各类数据包计数
pthis->lixsniff_updateNPacket();
//将本地化后的数据装入一个链表中,以便后来使用
ppkt_data = (u_char*)malloc(header->len);
memcpy(ppkt_data,pkt_data,header->len);
pthis->m_localDataList.AddTail(data);
pthis->m_netDataList.AddTail(ppkt_data);
/*预处理,获得时间、长度*/
data->len = header->len; //链路中收到的数据长度
local_tv_sec = header->ts.tv_sec;
ltime = localtime(&local_tv_sec);
data->time[0] = ltime->tm_year+1900;
data->time[1] = ltime->tm_mon+1;
data->time[2] = ltime->tm_mday;
data->time[3] = ltime->tm_hour;
data->time[4] = ltime->tm_min;
data->time[5] = ltime->tm_sec;
/*为新接收到的数据包在listControl中新建一个item*/
buf.Format(_T("%d"),pthis->npkt);
nItem = pthis->m_listCtrl.InsertItem(pthis->npkt,buf);
/*显示时间戳*/
timestr.Format(_T("%d/%d/%d %d:%d:%d"),data->time[0],
data->time[1],data->time[2],data->time[3],data->time[4],data->time[5]);
pthis->m_listCtrl.SetItemText(nItem,1,timestr);
/*显示长度*/
buf.Empty();
buf.Format(_T("%d"),data->len);
pthis->m_listCtrl.SetItemText(nItem,2,buf);
/*显示源MAC*/
buf.Empty();
buf.Format(_T("%02X-%02X-%02X-%02X-%02X-%02X"),data->ethh->src[0],data->ethh->src[1],
data->ethh->src[2],data->ethh->src[3],data->ethh->src[4],data->ethh->src[5]);
pthis->m_listCtrl.SetItemText(nItem,3,buf);
/*显示目的MAC*/
buf.Empty();
buf.Format(_T("%02X-%02X-%02X-%02X-%02X-%02X"),data->ethh->dest[0],data->ethh->dest[1],
data->ethh->dest[2],data->ethh->dest[3],data->ethh->dest[4],data->ethh->dest[5]);
pthis->m_listCtrl.SetItemText(nItem,4,buf);
/*获得协议*/
pthis->m_listCtrl.SetItemText(nItem,5,CString(data->pktType));
/*获得源IP*/
buf.Empty();
if(0x0806== data->ethh->type)
{
buf.Format(_T("%d.%d.%d.%d"),data->arph->ar_srcip[0],
data->arph->ar_srcip[1],data->arph->ar_srcip[2],data->arph->ar_srcip[3]);
}else if(0x0800 == data->ethh->type){
struct in_addr in;
in.S_un.S_addr = data->iph->saddr;
buf = CString(inet_ntoa(in));
}else if(0x86dd == data->ethh->type){
int i;
for(i=0;i<8;i++)
{
if(i<=6)
buf.AppendFormat(_T("%02x-"),data->iph6->saddr[i]);
else
buf.AppendFormat(_T("%02x"),data->iph6->saddr[i]);
}
}
pthis->m_listCtrl.SetItemText(nItem,6,buf);
/*获得目的IP*/
buf.Empty();
if(0x0806 == data->ethh->type)
{
buf.Format(_T("%d.%d.%d.%d"),data->arph->ar_destip[0],
data->arph->ar_destip[1],data->arph->ar_destip[2],data->arph->ar_destip[3]);
}else if(0x0800 == data->ethh->type) {
struct in_addr in;
in.S_un.S_addr = data->iph->daddr;
buf = CString(inet_ntoa(in));
}else if(0x86dd == data->ethh->type){
int i;
for(i=0;i<8;i++)
{
if(i<=6)
buf.AppendFormat(_T("%02x-"),data->iph6->daddr[i]);
else
buf.AppendFormat(_T("%02x"),data->iph6->daddr[i]);
}
}
pthis->m_listCtrl.SetItemText(nItem,7,buf);
/*对包计数*/
pthis->npkt++;
}
pcap_close(fp);
return 1;
}