一步一步开发sniffer(Winpcap+MFC)(三)安得广厦千万间,先画蓝图再砌砖——搭建winpcap抓包框架

采用天朝流行的话,“由于种种原因”本人已接近一年半没有写博客了,最近回想起来,很多东西即便再小也得慢慢积累,更何况前两章之后就没有了,很多网友表示比较期待后面的文字,不能做一个太监了事,打算还是继续写完,给被吊了胃口这么久的朋友表示深深地歉意。

这一章要讲的是winpcap核心编程,首先来看一下sniffer程序的整体框架,程序主要由三个部分构成,其示意图如下:


其中,winpcap对数据的捕获主要在cmcf6Dlg.cpp中完成(偷了些懒,就没有把界面与这部分程序分开了,我得承认这不是一个好习惯),一些功能函数如解析数据包等程序在utilities.cpp中完成,协议包数据结构及类型定义在Protocol.h完成。

winpcap的主要流程如下:

1)        调用pcap_findalldevs()获得网卡接口信息,一台计算机上可能有很多个网卡接口,知道有哪些接口是非常有必要的。

[cpp]  view plain copy
  1. //初始化winpcap  
  2. int Cmcf6Dlg::lixsniff_initCap()  
  3. {  
  4.     devCount = 0;  
  5.     if(pcap_findalldevs(&alldev, errbuf) ==-1)  
  6.         return -1;  
  7.     for(dev=alldev;dev;dev=dev->next)  
  8.         devCount++;     //记录设备数  
  9.     return 0;  
  10. }  

 其中 alldev与dev声明如下,主要是用来记录查找到的网卡设备

   pcap_if_t *alldev;

   pcap_if_t *dev;

2)        在获取了网卡接口信息后,即可调用pcap_open_live()打开指定网卡接口,winpcap将在此接口上侦听数据

[cpp]  view plain copy
  1. <pre name="code" class="cpp">if ((adhandle= pcap_open_live(dev->name,    // 设备名  
  2.                              65536,     //捕获数据包长度  
  3.                              1, // 混杂模式 (非0意味着是混杂模式)  
  4.                              1000,     // 读超时设置  
  5.                              errbuf    // 错误信息  
  6.                              )) == NULL)  
  7.     {  
  8.         MessageBox(_T("无法打开接口:"+CString(dev->description)));   
  9.         pcap_freealldevs(alldev);  
  10.         return -1;  
  11.     } </pre><br>  
  12. <br>  
  13. <br>  
  14. <pre></pre>  
  15. <p>3)        调用pcap_datalink()、pcap_compile()、pcap_setfilter()分别检查是否是以太网,并对过滤器进行设置。网络中过来的数据有些可能不是以太网数据,这样的数据我们处理不了,所以首先要进行一个检查;而过滤器是什么呢,简单的说,网络中过来的数据是不同层次、不同协议的,过滤器的作用就是可以设定一些的规则来查看你想要的数据包,如指定只需要TCP包。</p>  
  16. <p></p>  
  17. <pre name="code" class="cpp">/*检查是否为以太网*/  
  18.     if(pcap_datalink(adhandle)!=DLT_EN10MB)  
  19.     {  
  20.         MessageBox(_T("这不适合于非以太网的网络!"));  
  21.         pcap_freealldevs(alldev);  
  22.         return -1;  
  23.     }  
  24.   
  25. /*编译过滤器*/  
  26.     if(0==filter_index)  
  27.     {  
  28.         char filter[] = "";  
  29.         if (pcap_compile(adhandle, &fcode, filter, 1, netmask) <0 )  
  30.         {  
  31.             MessageBox(_T("语法错误,无法编译过滤器"));  
  32.             pcap_freealldevs(alldev);  
  33.             return -1;  
  34.         }  
  35.     }else{  
  36.         CString str;  
  37.         char *filter;  
  38.         int len,x;  
  39.         this->m_comboBoxRule.GetLBText(filter_index,str);  
  40.         len = str.GetLength()+1;  
  41.         filter = (char*)malloc(len);  
  42.         for(x=0;x<len;x++)  
  43.         {  
  44.             filter[x] = str.GetAt(x);  
  45.         }  
  46.         if (pcap_compile(adhandle, &fcode, filter, 1, netmask) <0 )  
  47.         {  
  48.             MessageBox(_T("语法错误,无法编译过滤器"));  
  49.             pcap_freealldevs(alldev);  
  50.             return -1;  
  51.         }  
  52.     }  
  53.   
  54.   
  55.     /*设置过滤器*/  
  56.     if (pcap_setfilter(adhandle, &fcode)<0)  
  57.     {  
  58.         MessageBox(_T("设置过滤器错误"));  
  59.         pcap_freealldevs(alldev);  
  60.         return -1;  
  61.     }  
  62. </pre>  
  63. <p></p>  
  64. <p></p>  
  65. <p>4)        调用pcap_dump_open()先创建一个文件,捕获的数据将会存储到此文件中,后面捕获的数据包将会实时地写入一个临时文件,文件默认存储在工程中的SaveData文件中,文件名为存储时的时间,如在2010年10月10日14:15:16存储的,那么其文件名即为20101010141516,在捕获数据结束时,用户可以选择将此文件存储于指定路径。</p>  
  66. <p></p>  
  67. <pre name="code" class="cpp">   dumpfile = pcap_dump_open(adhandle, filepath);  
  68.    if(dumpfile==NULL)  
  69.    {  
  70.             MessageBox(_T("文件创建错误!"));  
  71.             return -1;  
  72.    }</pre>  
  73. <p></p>  
  74. <p>5)        完成以上设置后,即可开始捕获数据包了。调用CreateThread()创建一个新的线程,调用lixsinff_CapThread()函数在线程中完成数据包的捕获工作。为什么要新建一个线程来完成这项工作?那是因为我们的主进程是一个Dialog(对话框),它主要的任务是处理界面交互,而数据捕获是一项后台工作,将数据包的捕获与界面进程分离,可以提高程序效率,避免了二者的干扰。</p>  
  75. <p></p>  
  76. <pre name="code" class="cpp">   /*接收数据,新建线程处理*/  
  77.     LPDWORD threadCap=NULL;  
  78.     m_ThreadHandle=CreateThread(NULL,0,lixsinff_CapThread,this,0,threadCap);  
  79.     if(m_ThreadHandle==NULL)  
  80.     {  
  81.         int code=GetLastError();  
  82.         CString str;  
  83.         str.Format(_T("创建线程错误,代码为%d."),code);  
  84.         MessageBox(str);  
  85.         return -1;  
  86.     }  
  87. </pre>6)在lixsinff_CapThread()中调用pcap_next_ex()函数进行数据包捕获,每到达一个数据包,调用自定义的包处理函数analyze_frame()完成对捕获数据的解析<span style="color:rgb(51,204,255)">。注:对于analyze_frame()函数将在第五章专门介绍其工作流程。</span><br>  
  88. <pre name="code" class="cpp">while((res = pcap_next_ex( pthis->adhandle, &header, &pkt_data)) >= 0)  
  89.     {  
  90.         if(res == 0)                //超时  
  91.             continue;  
  92.           
  93.         struct datapkt *data = (struct datapkt*)malloc(sizeof(struct datapkt));       
  94.         memset(data,0,sizeof(struct datapkt));  
  95.   
  96.         if(NULL == data)  
  97.         {  
  98.             MessageBox(NULL,_T("空间已满,无法接收新的数据包"),_T("Error"),MB_OK);  
  99.             return -1;  
  100.         }  
  101.   
  102.         //分析出错或所接收数据包不在处理范围内  
  103.         if(analyze_frame(pkt_data,data,&(pthis->npacket))<0)  
  104.             continue;    
  105. …….(以下省略)  
  106. }  
  107. </pre>  
  108. <p></p>  
  109. <p>7)        经过analyze_frame()函数处理后将相关数据更新到GUI。<span style="color:rgb(51,204,255)">这一点第六章会讲到</span>。</p>  
  110. <p> 以下是cmcf6Dlg.h以及cmcf6Dlg.cpp的源代码,也就是我们的主程序代码,在代码中可以看到完整的实现过程,实际上对于如何将数据写到GUI上已经大体从这里可以看得出来了:)</p>  
  111. <p></p>  
  112. <p><strong><span style="color:#33ccff">下一章:要想从此过,留下协议头——各层网络协议头的实现</span></strong></p>  
  113. <p><strong>cmcf6Dlg.h:</strong></p>  
  114. <strong></strong>  
  115. <p></p>  
  116. <pre name="code" class="cpp">// mcf6Dlg.h : 头文件  
  117. //  
  118. #pragma once  
  119. #include "afxcmn.h"  
  120. #include "afxwin.h"  
  121. #include"pcap.h"  
  122. #include "Protocol.h"  
  123. #include "utilities.h"  
  124.   
  125. // Cmcf6Dlg 对话框  
  126. class Cmcf6Dlg : public CDialog  
  127. {  
  128. // 构造  
  129. public:  
  130.     Cmcf6Dlg(CWnd* pParent = NULL); // 标准构造函数  
  131.   
  132.     /[my fuction]//  
  133.     int lixsniff_initCap();  
  134.     int lixsniff_startCap();  
  135.     int lixsniff_updateTree(int index);  
  136.     int lixsniff_updateEdit(int index);  
  137.     int lixsniff_updateNPacket();  
  138.     int lixsniff_saveFile();  
  139.     int lixsniff_readFile(CString path);  
  140.       
  141.     //[my data]/  
  142.     int devCount;  
  143.     struct pktcount npacket;                //各类数据包计数  
  144.     char errbuf[PCAP_ERRBUF_SIZE];  
  145.     pcap_if_t *alldev;  
  146.     pcap_if_t *dev;  
  147.     pcap_t *adhandle;  
  148.     pcap_dumper_t *dumpfile;  
  149.     char filepath[512];                         //  文件保存路径  
  150.     char filename[64];                          //  文件名称                              
  151.   
  152.     HANDLE m_ThreadHandle;          //线程  
  153.   
  154.     CPtrList m_pktList;                         //捕获包所存放的链表  
  155.   
  156. // 对话框数据  
  157.     enum { IDD = IDD_MCF6_DIALOG };  
  158.   
  159.     protected:  
  160.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持  
  161.   
  162. // 实现  
  163. protected:  
  164.     HICON m_hIcon;  
  165.   
  166.     // 生成的消息映射函数  
  167.     virtual BOOL OnInitDialog();  
  168.     afx_msg void OnSysCommand(UINT nID, LPARAM lParam);  
  169.     afx_msg void OnPaint();  
  170.     afx_msg HCURSOR OnQueryDragIcon();  
  171.     DECLARE_MESSAGE_MAP()  
  172. public:  
  173.     CListCtrl m_listCtrl;  
  174.     CComboBox m_comboBox;  
  175.     CComboBox m_comboBoxRule;  
  176.     CTreeCtrl m_treeCtrl;  
  177.     CEdit m_edit;  
  178.     afx_msg void OnBnClickedButton1();  
  179.     afx_msg void OnBnClickedButton2();  
  180.     CButton m_buttonStart;  
  181.     CButton m_buttonStop;  
  182.     CPtrList m_localDataList;               //保存被本地化后的数据包  
  183.     CPtrList m_netDataList;                 //保存从网络中直接获取的数据包  
  184.     CBitmapButton m_bitButton   ;       //图片按钮  
  185.     int npkt;  
  186.     afx_msg void OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult);  
  187.     CEdit m_editNTcp;  
  188.     CEdit m_editNUdp;  
  189.     CEdit m_editNIcmp;  
  190.     CEdit m_editNIp;  
  191.     CEdit m_editNArp;  
  192.     CEdit m_editNHttp;  
  193.     CEdit m_editNOther;  
  194.     CEdit m_editNSum;  
  195.     afx_msg void OnNMCustomdrawList1(NMHDR *pNMHDR, LRESULT *pResult);  
  196.     afx_msg void OnBnClickedButton5();  
  197.     CButton m_buttonSave;  
  198.     CButton m_buttonRead;  
  199.     afx_msg void OnBnClickedButton4();  
  200.     CEdit m_editNIpv4;  
  201.     CEdit m_editIcmpv6;  
  202. };</pre>  
  203. <p></p>  
  204. <p><strong>cmcf6Dlg.cpp:</strong></p>  
  205. <pre name="code" class="cpp">// mcf6Dlg.cpp : 实现文件  
  206. //  
  207.   
  208. #include "stdafx.h"  
  209. #include "mcf6.h"  
  210. #include "mcf6Dlg.h"  
  211.   
  212. #ifdef _DEBUG  
  213. #define new DEBUG_NEW  
  214. #endif  
  215.   
  216.   
  217. // 用于应用程序“关于”菜单项的 CAboutDlg 对话框  
  218. DWORD WINAPI lixsinff_CapThread(LPVOID lpParameter);  
  219.   
  220. class CAboutDlg : public CDialog  
  221. {  
  222. public:  
  223.     CAboutDlg();  
  224.       
  225. // 对话框数据  
  226.     enum { IDD = IDD_ABOUTBOX };  
  227.   
  228.     protected:  
  229.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持  
  230.   
  231. // 实现  
  232. protected:  
  233.     DECLARE_MESSAGE_MAP()  
  234. };  
  235.   
  236. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)  
  237. {  
  238. }  
  239.   
  240. void CAboutDlg::DoDataExchange(CDataExchange* pDX)  
  241. {  
  242.     CDialog::DoDataExchange(pDX);  
  243. }  
  244.   
  245. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)  
  246. END_MESSAGE_MAP()  
  247.   
  248.   
  249. // Cmcf6Dlg 对话框  
  250.   
  251.   
  252.   
  253.   
  254. Cmcf6Dlg::Cmcf6Dlg(CWnd* pParent /*=NULL*/)  
  255.     : CDialog(Cmcf6Dlg::IDD, pParent)  
  256. {  
  257.     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);  
  258. }  
  259.   
  260. void Cmcf6Dlg::DoDataExchange(CDataExchange* pDX)  
  261. {  
  262.     CDialog::DoDataExchange(pDX);  
  263.     DDX_Control(pDX, IDC_LIST1, m_listCtrl);  
  264.     DDX_Control(pDX, IDC_COMBO1, m_comboBox);  
  265.     DDX_Control(pDX, IDC_COMBO2, m_comboBoxRule);  
  266.     DDX_Control(pDX, IDC_TREE1, m_treeCtrl);  
  267.     DDX_Control(pDX, IDC_EDIT1, m_edit);  
  268.     DDX_Control(pDX, IDC_BUTTON1, m_buttonStart);  
  269.     DDX_Control(pDX, IDC_BUTTON2, m_buttonStop);  
  270.     DDX_Control(pDX, IDC_EDIT2, m_editNTcp);  
  271.     DDX_Control(pDX, IDC_EDIT3, m_editNUdp);  
  272.     DDX_Control(pDX, IDC_EDIT4, m_editNIcmp);  
  273.     DDX_Control(pDX, IDC_EDIT5, m_editNIp);  
  274.     DDX_Control(pDX, IDC_EDIT6, m_editNArp);  
  275.     DDX_Control(pDX, IDC_EDIT7, m_editNHttp);  
  276.     DDX_Control(pDX, IDC_EDIT8, m_editNOther);  
  277.     DDX_Control(pDX, IDC_EDIT9, m_editNSum);  
  278.     DDX_Control(pDX, IDC_BUTTON5, m_buttonSave);  
  279.     DDX_Control(pDX, IDC_BUTTON4, m_buttonRead);  
  280.     DDX_Control(pDX, IDC_EDIT10, m_editNIpv4);  
  281.     DDX_Control(pDX, IDC_EDIT11, m_editIcmpv6);  
  282. }  
  283.   
  284. BEGIN_MESSAGE_MAP(Cmcf6Dlg, CDialog)  
  285.     ON_WM_SYSCOMMAND()  
  286.     ON_WM_PAINT()  
  287.     ON_WM_QUERYDRAGICON()  
  288.     //}}AFX_MSG_MAP  
  289.     ON_BN_CLICKED(IDC_BUTTON1, &Cmcf6Dlg::OnBnClickedButton1)  
  290.     ON_BN_CLICKED(IDC_BUTTON2, &Cmcf6Dlg::OnBnClickedButton2)  
  291.     ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &Cmcf6Dlg::OnLvnItemchangedList1)  
  292.     ON_NOTIFY(NM_CUSTOMDRAW, IDC_LIST1, &Cmcf6Dlg::OnNMCustomdrawList1)  
  293.     ON_BN_CLICKED(IDC_BUTTON5, &Cmcf6Dlg::OnBnClickedButton5)  
  294.     ON_BN_CLICKED(IDC_BUTTON4, &Cmcf6Dlg::OnBnClickedButton4)  
  295. END_MESSAGE_MAP()  
  296.   
  297.   
  298. // Cmcf6Dlg 消息处理程序  
  299.   
  300. BOOL Cmcf6Dlg::OnInitDialog()  
  301. {  
  302.     CDialog::OnInitDialog();  
  303.   
  304.     // 将“关于...”菜单项添加到系统菜单中。  
  305.   
  306.     // IDM_ABOUTBOX 必须在系统命令范围内。  
  307.     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);  
  308.     ASSERT(IDM_ABOUTBOX < 0xF000);  
  309.   
  310.     CMenu* pSysMenu = GetSystemMenu(FALSE);  
  311.     if (pSysMenu != NULL)  
  312.     {  
  313.         CString strAboutMenu;  
  314.         strAboutMenu.LoadString(IDS_ABOUTBOX);  
  315.         if (!strAboutMenu.IsEmpty())  
  316.         {  
  317.             pSysMenu->AppendMenu(MF_SEPARATOR);  
  318.             pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);  
  319.         }  
  320.     }  
  321.   
  322.     // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动  
  323.     //  执行此操作  
  324.     SetIcon(m_hIcon, TRUE);         // 设置大图标  
  325.     SetIcon(m_hIcon, FALSE);        // 设置小图标  
  326.   
  327.     ShowWindow(SW_MINIMIZE);  
  328.   
  329.     // TODO: 在此添加额外的初始化代码  
  330.     m_listCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);  
  331.   
  332.     m_listCtrl.InsertColumn(0,_T("编号"),3,30);                        //1表示右,2表示中,3表示左  
  333.     m_listCtrl.InsertColumn(1,_T("时间"),3,130);  
  334.     m_listCtrl.InsertColumn(2,_T("长度"),3,72);  
  335.     m_listCtrl.InsertColumn(3,_T("源MAC地址"),3,140);  
  336.     m_listCtrl.InsertColumn(4,_T("目的MAC地址"),3,140);  
  337.     m_listCtrl.InsertColumn(5,_T("协议"),3,70);  
  338.     m_listCtrl.InsertColumn(6,_T("源IP地址"),3,145);  
  339.     m_listCtrl.InsertColumn(7,_T("目的IP地址"),3,145);  
  340.   
  341.     m_comboBox.AddString(_T("请选择一个网卡接口(必选)"));  
  342.     m_comboBoxRule.AddString(_T("请选择过滤规则(可选)"));  
  343.       
  344.     if(lixsniff_initCap()<0)  
  345.         return FALSE;  
  346.   
  347.     /*初始化接口列表*/  
  348.     for(dev=alldev;dev;dev=dev->next)  
  349.     {  
  350.         if(dev->description)  
  351.             m_comboBox.AddString(CString(dev->description));  //Problem 1字符集问题  
  352.     }     
  353.   
  354.     /*初始化过滤规则列表*/  
  355.     m_comboBoxRule.AddString(_T("tcp"));  
  356.     m_comboBoxRule.AddString(_T("udp"));  
  357.     m_comboBoxRule.AddString(_T("ip"));  
  358.     m_comboBoxRule.AddString(_T("icmp"));  
  359.     m_comboBoxRule.AddString(_T("arp"));  
  360.   
  361.     m_comboBox.SetCurSel(0);  
  362.     m_comboBoxRule.SetCurSel(0);  
  363.   
  364.     m_buttonStop.EnableWindow(FALSE);  
  365.     m_buttonSave.EnableWindow(FALSE);  
  366.   
  367.     //m_bitButton.RedrawWindow();  
  368.   
  369.     /listControl用法  
  370.     //int nitem = m_listCtrl.InsertItem(0,_T("hello"));  
  371.     /*char buf[5]; 
  372.     itoa(nitem,buf,10); 
  373.     MessageBox(CString(buf));*/  
  374.     /*m_listCtrl.SetItemText(nitem,1,_T("jak")); 
  375.     m_listCtrl.SetItemText(nitem,2,_T("bub")); 
  376.     m_listCtrl.SetItemText(nitem,3,_T("coco")); 
  377.     m_listCtrl.SetItemText(nitem,4,_T("haha"));*/  
  378.     return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE  
  379. }  
  380.   
  381. void Cmcf6Dlg::OnSysCommand(UINT nID, LPARAM lParam)  
  382. {  
  383.     if ((nID & 0xFFF0) == IDM_ABOUTBOX)  
  384.     {  
  385.         CAboutDlg dlgAbout;  
  386.         dlgAbout.DoModal();  
  387.     }  
  388.     else  
  389.     {  
  390.         CDialog::OnSysCommand(nID, lParam);  
  391.     }  
  392. }  
  393.   
  394. // 如果向对话框添加最小化按钮,则需要下面的代码  
  395. //  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,  
  396. //  这将由框架自动完成。  
  397.   
  398. void Cmcf6Dlg::OnPaint()  
  399. {  
  400.     if (IsIconic())  
  401.     {  
  402.         CPaintDC dc(this); // 用于绘制的设备上下文  
  403.   
  404.         SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);  
  405.   
  406.         // 使图标在工作区矩形中居中  
  407.         int cxIcon = GetSystemMetrics(SM_CXICON);  
  408.         int cyIcon = GetSystemMetrics(SM_CYICON);  
  409.         CRect rect;  
  410.         GetClientRect(&rect);  
  411.         int x = (rect.Width() - cxIcon + 1) / 2;  
  412.         int y = (rect.Height() - cyIcon + 1) / 2;  
  413.   
  414.         // 绘制图标  
  415.         dc.DrawIcon(x, y, m_hIcon);  
  416.     }  
  417.     else  
  418.     {  
  419.         CDialog::OnPaint();  
  420.     }  
  421. }  
  422.   
  423. //当用户拖动最小化窗口时系统调用此函数取得光标  
  424. //显示。  
  425. HCURSOR Cmcf6Dlg::OnQueryDragIcon()  
  426. {  
  427.     return static_cast<HCURSOR>(m_hIcon);  
  428. }  
  429.   
  430. /[事件函数]///  
  431.   
  432. //开始按钮  
  433. void Cmcf6Dlg::OnBnClickedButton1()  
  434. {  
  435.     // TODO: 在此添加控件通知处理程序代码  
  436.     //如果已经有数据了,提示保存数据  
  437.     if(this->m_localDataList.IsEmpty() == FALSE)  
  438.     {  
  439.         if(MessageBox(_T("确认不保存数据?"),_T("警告"),MB_YESNO)==IDNO)  
  440.         {  
  441.             this->lixsniff_saveFile();  
  442.         }  
  443.     }  
  444.   
  445.     this->npkt =1;                                                   //重新计数  
  446.     this->m_localDataList.RemoveAll();               //每次一开始就将以前存的数据清空掉  
  447.     this->m_netDataList.RemoveAll();  
  448.     memset(&(this->npacket),0,sizeof(struct pktcount));  
  449.     this->lixsniff_updateNPacket();  
  450.   
  451.     if(this->lixsniff_startCap()<0)  
  452.         return;  
  453.     this->m_listCtrl.DeleteAllItems();  
  454.     this->m_treeCtrl.DeleteAllItems();  
  455.     this->m_edit.SetWindowTextW(_T(""));  
  456.     this->m_buttonStart.EnableWindow(FALSE);  
  457.     this->m_buttonStop.EnableWindow(TRUE);  
  458.     this->m_buttonSave.EnableWindow(FALSE);  
  459. }  
  460.   
  461. //结束按钮  
  462. void Cmcf6Dlg::OnBnClickedButton2()  
  463. {  
  464.     // TODO: 在此添加控件通知处理程序代码  
  465.     if(NULL == this->m_ThreadHandle )  
  466.         return;  
  467.     if(TerminateThread(this->m_ThreadHandle,-1)==0)  
  468.     {  
  469.         MessageBox(_T("关闭线程错误,请稍后重试"));  
  470.         return;  
  471.     }  
  472.     this->m_ThreadHandle = NULL;  
  473.     this->m_buttonStart.EnableWindow(TRUE);  
  474.     this->m_buttonStop.EnableWindow(FALSE);    
  475.     this->m_buttonSave.EnableWindow(TRUE);  
  476. }  
  477.   
  478. //列表  
  479. void Cmcf6Dlg::OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult)  
  480. {  
  481.     LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);  
  482.     // TODO: 在此添加控件通知处理程序代码  
  483.     int index;  
  484.     index = this->m_listCtrl.GetHotItem();  
  485.   
  486.     if(index>this->m_localDataList.GetCount()-1)  
  487.         return;  
  488.   
  489.     this->lixsniff_updateEdit(index);  
  490.     this->lixsniff_updateTree(index);  
  491.     *pResult = 0;  
  492. }  
  493.   
  494. //保存按钮  
  495. void Cmcf6Dlg::OnBnClickedButton5()  
  496. {  
  497.     // TODO: 在此添加控件通知处理程序代码  
  498.     if(this->lixsniff_saveFile()<0)  
  499.         return;  
  500. }  
  501.   
  502. //读取按钮  
  503. void Cmcf6Dlg::OnBnClickedButton4()  
  504. {  
  505.     // TODO: 在此添加控件通知处理程序代码  
  506.     //读取之前将ListCtrl清空  
  507.     this->m_listCtrl.DeleteAllItems();  
  508.     this->npkt =1;                                                   //列表重新计数  
  509.     this->m_localDataList.RemoveAll();               //每次一开始就将以前存的数据清空掉  
  510.     this->m_netDataList.RemoveAll();  
  511.     memset(&(this->npacket),0,sizeof(struct pktcount));//各类包计数清空  
  512.   
  513.     //打开文件对话框  
  514.      CFileDialog   FileDlg(TRUE ,_T(".lix"),NULL,OFN_HIDEREADONLY   |   OFN_OVERWRITEPROMPT);     
  515.      FileDlg.m_ofn.lpstrInitialDir=_T("c:\\");     
  516.      if(FileDlg.DoModal()==IDOK)     
  517.      {     
  518.          int ret = this->lixsniff_readFile(FileDlg.GetPathName());  
  519.          if(ret < 0)  
  520.                 return;        
  521.      }  
  522. }  
  523.   
  524. //改变ListCtrl每行颜色  
  525. void Cmcf6Dlg::OnNMCustomdrawList1(NMHDR *pNMHDR, LRESULT *pResult)  
  526. {  
  527.     //LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);  
  528.     LPNMLVCUSTOMDRAW pNMCD = (LPNMLVCUSTOMDRAW)pNMHDR;  
  529.     *pResult = 0;  
  530.     // TODO: 在此添加控件通知处理程序代码  
  531.     if(CDDS_PREPAINT==pNMCD->nmcd.dwDrawStage)  
  532.     {  
  533.         *pResult = CDRF_NOTIFYITEMDRAW;  
  534.     }else if(CDDS_ITEMPREPAINT ==pNMCD->nmcd.dwDrawStage){  
  535.         COLORREF crText;  
  536.         char buf[10];  
  537.         memset(buf,0,10);  
  538.         POSITION pos = this->m_localDataList.FindIndex(pNMCD->nmcd.dwItemSpec);  
  539.         struct datapkt * local_data = (struct datapkt *)this->m_localDataList.GetAt(pos);  
  540.         strcpy(buf,local_data->pktType);  
  541.   
  542.         if(strcmp(buf,"IPV6")==0)  
  543.             crText = RGB(111,224,254);  
  544.         else if(strcmp(buf,"UDP")==0)  
  545.             crText = RGB(194,195,252);                
  546.         else if(strcmp(buf,"TCP")==0)  
  547.                 crText = RGB(230,230,230);  
  548.         else if(strcmp(buf,"ARP")==0)  
  549.                 crText = RGB(226,238,227);  
  550.         else if(strcmp(buf,"ICMP")==0)  
  551.                 crText = RGB(49,164,238);  
  552.         else if(strcmp(buf,"HTTP")==0)  
  553.                 crText = RGB(238,232,180);  
  554.         else if(strcmp(buf,"ICMPv6")==0)  
  555.                 crText = RGB(189,254,76);  
  556.   
  557.         pNMCD->clrTextBk =crText;  
  558.         *pResult = CDRF_DODEFAULT;  
  559.     }  
  560. }  
  561. //[功能函数]///  
  562.   
  563. //初始化winpcap  
  564. int Cmcf6Dlg::lixsniff_initCap()  
  565. {  
  566.     devCount = 0;  
  567.     if(pcap_findalldevs(&alldev, errbuf) ==-1)  
  568.         return -1;  
  569.     for(dev=alldev;dev;dev=dev->next)  
  570.         devCount++;   
  571.     return 0;  
  572. }  
  573.   
  574. //开始捕获  
  575. int Cmcf6Dlg::lixsniff_startCap()  
  576. {     
  577.     int if_index,filter_index,count;  
  578.     u_int netmask;  
  579.     struct bpf_program fcode;  
  580.   
  581.     lixsniff_initCap();  
  582.   
  583.     //获得接口和过滤器索引  
  584.     if_index = this->m_comboBox.GetCurSel();  
  585.     filter_index = this->m_comboBoxRule.GetCurSel();  
  586.   
  587.     if(0==if_index || CB_ERR == if_index)  
  588.     {  
  589.         MessageBox(_T("请选择一个合适的网卡接口"));  
  590.         return -1;  
  591.     }  
  592.     if(CB_ERR == filter_index)  
  593.     {  
  594.         MessageBox(_T("过滤器选择错误"));    
  595.         return -1;  
  596.     }  
  597.   
  598.     /*获得选中的网卡接口*/  
  599.     dev=alldev;  
  600.     for(count=0;count<if_index-1;count++)  
  601.         dev=dev->next;  
  602.       
  603.     if ((adhandle= pcap_open_live(dev->name, // 设备名  
  604.                              65536,                                         //捕获数据包长度                                                                                     
  605.                              1,                                                 // 混杂模式 (非0意味着是混杂模式)  
  606.                              1000,                                              // 读超时设置  
  607.                              errbuf                                         // 错误信息  
  608.                              )) == NULL)  
  609.     {  
  610.         MessageBox(_T("无法打开接口:"+CString(dev->description)));   
  611.         pcap_freealldevs(alldev);  
  612.         return -1;  
  613.     }      
  614.   
  615.     /*检查是否为以太网*/  
  616.     if(pcap_datalink(adhandle)!=DLT_EN10MB)  
  617.     {  
  618.         MessageBox(_T("这不适合于非以太网的网络!"));  
  619.         pcap_freealldevs(alldev);  
  620.         return -1;  
  621.     }  
  622.   
  623.     if(dev->addresses!=NULL)   
  624.         netmask=((struct sockaddr_in *)(dev->addresses->netmask))->sin_addr.S_un.S_addr;  
  625.     else  
  626.         netmask=0xffffff;   
  627.   
  628.     //编译过滤器  
  629.     if(0==filter_index)  
  630.     {  
  631.         char filter[] = "";  
  632.         if (pcap_compile(adhandle, &fcode, filter, 1, netmask) <0 )  
  633.         {  
  634.             MessageBox(_T("语法错误,无法编译过滤器"));  
  635.             pcap_freealldevs(alldev);  
  636.             return -1;  
  637.         }  
  638.     }else{  
  639.         CString str;  
  640.         char *filter;  
  641.         int len,x;  
  642.         this->m_comboBoxRule.GetLBText(filter_index,str);  
  643.         len = str.GetLength()+1;  
  644.         filter = (char*)malloc(len);  
  645.         for(x=0;x<len;x++)  
  646.         {  
  647.             filter[x] = str.GetAt(x);  
  648.         }  
  649.         if (pcap_compile(adhandle, &fcode, filter, 1, netmask) <0 )  
  650.         {  
  651.             MessageBox(_T("语法错误,无法编译过滤器"));  
  652.             pcap_freealldevs(alldev);  
  653.             return -1;  
  654.         }  
  655.     }  
  656.   
  657.   
  658.     //设置过滤器  
  659.     if (pcap_setfilter(adhandle, &fcode)<0)  
  660.     {  
  661.         MessageBox(_T("设置过滤器错误"));  
  662.         pcap_freealldevs(alldev);  
  663.         return -1;  
  664.     }  
  665.   
  666.     /* 设置数据包存储路径*/  
  667.     CFileFind file;  
  668.     char thistime[30];  
  669.     struct tm *ltime;  
  670.     memset(filepath,0,512);  
  671.     memset(filename,0,64);  
  672.   
  673.     if(!file.FindFile(_T("SavedData")))  
  674.     {  
  675.         CreateDirectory(_T("SavedData"),NULL);  
  676.     }  
  677.   
  678.     time_t nowtime;  
  679.     time(&nowtime);  
  680.     ltime=localtime(&nowtime);  
  681.     strftime(thistime,sizeof(thistime),"%Y%m%d %H%M%S",ltime);    
  682.     strcpy(filepath,"SavedData\\");  
  683.     strcat(filename,thistime);  
  684.     strcat(filename,".lix");  
  685.   
  686.     strcat(filepath,filename);  
  687.     dumpfile = pcap_dump_open(adhandle, filepath);  
  688.     if(dumpfile==NULL)  
  689.     {  
  690.         MessageBox(_T("文件创建错误!"));  
  691.         return -1;   
  692.     }  
  693.   
  694.     pcap_freealldevs(alldev);     
  695.   
  696.     /*接收数据,新建线程处理*/  
  697.     LPDWORD threadCap=NULL;  
  698.     m_ThreadHandle=CreateThread(NULL,0,lixsinff_CapThread,this,0,threadCap);  
  699.     if(m_ThreadHandle==NULL)  
  700.     {  
  701.         int code=GetLastError();  
  702.         CString str;  
  703.         str.Format(_T("创建线程错误,代码为%d."),code);  
  704.         MessageBox(str);  
  705.         return -1;  
  706.     }  
  707.     return 1;  
  708. }  
  709.   
  710. DWORD WINAPI lixsinff_CapThread(LPVOID lpParameter)  
  711. {  
  712.     int res,nItem ;  
  713.     struct tm *ltime;  
  714.     CString timestr,buf,srcMac,destMac;  
  715.     time_t local_tv_sec;  
  716.     struct pcap_pkthdr *header;                                   //数据包头  
  717.     const u_char *pkt_data=NULL,*pData=NULL;     //网络中收到的字节流数据  
  718.     u_char *ppkt_data;  
  719.       
  720.     Cmcf6Dlg *pthis = (Cmcf6Dlg*) lpParameter;  
  721.     if(NULL == pthis->m_ThreadHandle)  
  722.     {  
  723.         MessageBox(NULL,_T("线程句柄错误"),_T("提示"),MB_OK);  
  724.         return -1;  
  725.     }  
  726.       
  727.     while((res = pcap_next_ex( pthis->adhandle, &header, &pkt_data)) >= 0)  
  728.     {  
  729.         if(res == 0)                //超时  
  730.             continue;  
  731.           
  732.         struct datapkt *data = (struct datapkt*)malloc(sizeof(struct datapkt));       
  733.         memset(data,0,sizeof(struct datapkt));  
  734.   
  735.         if(NULL == data)  
  736.         {  
  737.             MessageBox(NULL,_T("空间已满,无法接收新的数据包"),_T("Error"),MB_OK);  
  738.             return -1;  
  739.         }  
  740.   
  741.         //分析出错或所接收数据包不在处理范围内  
  742.         if(analyze_frame(pkt_data,data,&(pthis->npacket))<0)  
  743.             continue;    
  744.           
  745.         //将数据包保存到打开的文件中  
  746.         if(pthis->dumpfile!=NULL)  
  747.         {  
  748.             pcap_dump((unsigned char*)pthis->dumpfile,header,pkt_data);  
  749.         }  
  750.   
  751.         //更新各类数据包计数  
  752.         pthis->lixsniff_updateNPacket();  
  753.   
  754.         //将本地化后的数据装入一个链表中,以便后来使用          
  755.         ppkt_data = (u_char*)malloc(header->len);  
  756.         memcpy(ppkt_data,pkt_data,header->len);  
  757.   
  758.         pthis->m_localDataList.AddTail(data);  
  759.         pthis->m_netDataList.AddTail(ppkt_data);  
  760.       
  761.         /*预处理,获得时间、长度*/  
  762.         data->len = header->len;                              //链路中收到的数据长度  
  763.         local_tv_sec = header->ts.tv_sec;  
  764.         ltime = localtime(&local_tv_sec);  
  765.         data->time[0] = ltime->tm_year+1900;  
  766.         data->time[1] = ltime->tm_mon+1;  
  767.         data->time[2] = ltime->tm_mday;  
  768.         data->time[3] = ltime->tm_hour;  
  769.         data->time[4] = ltime->tm_min;  
  770.         data->time[5] = ltime->tm_sec;  
  771.   
  772.         /*为新接收到的数据包在listControl中新建一个item*/  
  773.         buf.Format(_T("%d"),pthis->npkt);  
  774.         nItem = pthis->m_listCtrl.InsertItem(pthis->npkt,buf);  
  775.   
  776.         /*显示时间戳*/  
  777.         timestr.Format(_T("%d/%d/%d  %d:%d:%d"),data->time[0],  
  778.             data->time[1],data->time[2],data->time[3],data->time[4],data->time[5]);  
  779.         pthis->m_listCtrl.SetItemText(nItem,1,timestr);  
  780.         //pthis->m_listCtrl.setitem  
  781.           
  782.         /*显示长度*/  
  783.         buf.Empty();  
  784.         buf.Format(_T("%d"),data->len);  
  785.         pthis->m_listCtrl.SetItemText(nItem,2,buf);  
  786.   
  787.         /*显示源MAC*/  
  788.         buf.Empty();  
  789.         buf.Format(_T("%02X-%02X-%02X-%02X-%02X-%02X"),data->ethh->src[0],data->ethh->src[1],  
  790.                             data->ethh->src[2],data->ethh->src[3],data->ethh->src[4],data->ethh->src[5]);  
  791.         pthis->m_listCtrl.SetItemText(nItem,3,buf);  
  792.   
  793.         /*显示目的MAC*/  
  794.         buf.Empty();  
  795.         buf.Format(_T("%02X-%02X-%02X-%02X-%02X-%02X"),data->ethh->dest[0],data->ethh->dest[1],  
  796.                             data->ethh->dest[2],data->ethh->dest[3],data->ethh->dest[4],data->ethh->dest[5]);  
  797.         pthis->m_listCtrl.SetItemText(nItem,4,buf);  
  798.   
  799.         /*获得协议*/  
  800.         pthis->m_listCtrl.SetItemText(nItem,5,CString(data->pktType));  
  801.   
  802.         /*获得源IP*/  
  803.         buf.Empty();  
  804.         if(0x0806== data->ethh->type)  
  805.         {  
  806.             buf.Format(_T("%d.%d.%d.%d"),data->arph->ar_srcip[0],  
  807.                 data->arph->ar_srcip[1],data->arph->ar_srcip[2],data->arph->ar_srcip[3]);           
  808.         }else if(0x0800 == data->ethh->type) {  
  809.             struct  in_addr in;  
  810.             in.S_un.S_addr = data->iph->saddr;  
  811.             buf = CString(inet_ntoa(in));  
  812.         }else if(0x86dd ==data->ethh->type ){  
  813.             int n;  
  814.             for(n=0;n<8;n++)  
  815.             {             
  816.                 if(n<=6)  
  817.                     buf.AppendFormat(_T("%02x:"),data->iph6->saddr[n]);         
  818.                 else  
  819.                     buf.AppendFormat(_T("%02x"),data->iph6->saddr[n]);          
  820.             }  
  821.         }  
  822.         pthis->m_listCtrl.SetItemText(nItem,6,buf);  
  823.   
  824.         /*获得目的IP*/  
  825.         buf.Empty();  
  826.         if(0x0806 == data->ethh->type)  
  827.         {  
  828.             buf.Format(_T("%d.%d.%d.%d"),data->arph->ar_destip[0],  
  829.                 data->arph->ar_destip[1],data->arph->ar_destip[2],data->arph->ar_destip[3]);            
  830.         }else if(0x0800 == data->ethh->type){  
  831.             struct  in_addr in;  
  832.             in.S_un.S_addr = data->iph->daddr;  
  833.             buf = CString(inet_ntoa(in));  
  834.         }else if(0x86dd ==data->ethh->type ){  
  835.             int n;  
  836.             for(n=0;n<8;n++)  
  837.             {             
  838.                 if(n<=6)  
  839.                     buf.AppendFormat(_T("%02x:"),data->iph6->daddr[n]);         
  840.                 else  
  841.                     buf.AppendFormat(_T("%02x"),data->iph6->daddr[n]);          
  842.             }  
  843.         }  
  844.         pthis->m_listCtrl.SetItemText(nItem,7,buf);  
  845.       
  846.         /*对包计数*/  
  847.         pthis->npkt++;  
  848.       
  849.     }  
  850.     return 1;  
  851. }  
  852.   
  853. //更新信息  
  854. int Cmcf6Dlg::lixsniff_updateEdit(int index)  
  855. {  
  856.     POSITION localpos,netpos;  
  857.     localpos = this->m_localDataList.FindIndex(index);  
  858.     netpos = this->m_netDataList.FindIndex(index);  
  859.   
  860.     struct datapkt* local_data = (struct datapkt*)(this->m_localDataList.GetAt(localpos));  
  861.     u_char * net_data = (u_char*)(this->m_netDataList.GetAt(netpos));  
  862.   
  863.     CString buf;  
  864.     print_packet_hex(net_data,local_data->len,&buf);  
  865.     //this-  
  866.     this->m_edit.SetWindowText(buf);  
  867.   
  868.     return 1;  
  869. }  
  870.   
  871. //更新统计数据  
  872. int Cmcf6Dlg::lixsniff_updateNPacket()  
  873. {  
  874.         CString str_num;          
  875.         str_num.Format(_T("%d"),this->npacket.n_arp);  
  876.         this->m_editNArp.SetWindowText(str_num);  
  877.   
  878.         str_num.Format(_T("%d"),this->npacket.n_http);  
  879.         this->m_editNHttp.SetWindowText(str_num);  
  880.   
  881.         str_num.Format(_T("%d"),this->npacket.n_icmp);  
  882.         this->m_editNIcmp.SetWindowText(str_num);  
  883.   
  884.         str_num.Format(_T("%d"),this->npacket.n_ip6);  
  885.         this->m_editNIp.SetWindowText(str_num);  
  886.   
  887.         str_num.Format(_T("%d"),this->npacket.n_other);  
  888.         this->m_editNOther.SetWindowText(str_num);  
  889.   
  890.         str_num.Format(_T("%d"),this->npacket.n_sum);  
  891.         this->m_editNSum.SetWindowText(str_num);  
  892.   
  893.         str_num.Format(_T("%d"),this->npacket.n_tcp);  
  894.         this->m_editNTcp.SetWindowText(str_num);  
  895.           
  896.         str_num.Format(_T("%d"),this->npacket.n_udp);  
  897.         this->m_editNUdp.SetWindowText(str_num);  
  898.       
  899.         str_num.Format(_T("%d"),this->npacket.n_ip);  
  900.         this->m_editNIpv4.SetWindowText(str_num);  
  901.   
  902.         str_num.Format(_T("%d"),this->npacket.n_icmp6);  
  903.         this->m_editIcmpv6.SetWindowText(str_num);  
  904.   
  905.         return 1;  
  906. }  
  907.   
  908. //更新树形控件  
  909. int Cmcf6Dlg::lixsniff_updateTree(int index)  
  910. {  
  911.     POSITION localpos;  
  912.     CString str;  
  913.     int i;  
  914.       
  915.     this->m_treeCtrl.DeleteAllItems();  
  916.   
  917.     localpos = this->m_localDataList.FindIndex(index);  
  918.     struct datapkt* local_data = (struct datapkt*)(this->m_localDataList.GetAt(localpos));  
  919.       
  920.     HTREEITEM root = this->m_treeCtrl.GetRootItem();  
  921.     str.Format(_T("接收到的第%d个数据包"),index+1);  
  922.     HTREEITEM data = this->m_treeCtrl.InsertItem(str,root);  
  923.   
  924.     /*处理帧数据*/  
  925.     HTREEITEM frame = this->m_treeCtrl.InsertItem(_T("链路层数据"),data);  
  926.     //源MAC  
  927.     str.Format(_T("源MAC:"));  
  928.     for(i=0;i<6;i++)  
  929.     {  
  930.         if(i<=4)  
  931.             str.AppendFormat(_T("%02x-"),local_data->ethh->src[i]);  
  932.         else  
  933.             str.AppendFormat(_T("%02x"),local_data->ethh->src[i]);  
  934.     }  
  935.     this->m_treeCtrl.InsertItem(str,frame);  
  936.     //目的MAC  
  937.     str.Format(_T("目的MAC:"));  
  938.     for(i=0;i<6;i++)  
  939.     {  
  940.         if(i<=4)  
  941.             str.AppendFormat(_T("%02x-"),local_data->ethh->dest[i]);  
  942.         else  
  943.             str.AppendFormat(_T("%02x"),local_data->ethh->dest[i]);  
  944.     }  
  945.     this->m_treeCtrl.InsertItem(str,frame);  
  946.     //类型  
  947.     str.Format(_T("类型:0x%02x"),local_data->ethh->type);  
  948.     this->m_treeCtrl.InsertItem(str,frame);  
  949.   
  950.     /*处理IP、ARP、IPv6数据包*/  
  951.     if(0x0806 == local_data->ethh->type)                          //ARP  
  952.     {  
  953.         HTREEITEM arp = this->m_treeCtrl.InsertItem(_T("ARP协议头"),data);  
  954.         str.Format(_T("硬件类型:%d"),local_data->arph->ar_hrd);  
  955.         this->m_treeCtrl.InsertItem(str,arp);  
  956.         str.Format(_T("协议类型:0x%02x"),local_data->arph->ar_pro);  
  957.         this->m_treeCtrl.InsertItem(str,arp);  
  958.         str.Format(_T("硬件地址长度:%d"),local_data->arph->ar_hln);  
  959.         this->m_treeCtrl.InsertItem(str,arp);  
  960.         str.Format(_T("协议地址长度:%d"),local_data->arph->ar_pln);  
  961.         this->m_treeCtrl.InsertItem(str,arp);  
  962.         str.Format(_T("操作码:%d"),local_data->arph->ar_op);  
  963.         this->m_treeCtrl.InsertItem(str,arp);  
  964.   
  965.         str.Format(_T("发送方MAC:"));  
  966.         for(i=0;i<6;i++)  
  967.         {  
  968.             if(i<=4)  
  969.                 str.AppendFormat(_T("%02x-"),local_data->arph->ar_srcmac[i]);  
  970.             else  
  971.                 str.AppendFormat(_T("%02x"),local_data->arph->ar_srcmac[i]);  
  972.         }  
  973.         this->m_treeCtrl.InsertItem(str,arp);  
  974.   
  975.         str.Format(_T("发送方IP:"),local_data->arph->ar_hln);  
  976.         for(i=0;i<4;i++)  
  977.         {  
  978.             if(i<=2)  
  979.                 str.AppendFormat(_T("%d."),local_data->arph->ar_srcip[i]);  
  980.             else  
  981.                 str.AppendFormat(_T("%d"),local_data->arph->ar_srcip[i]);  
  982.         }  
  983.         this->m_treeCtrl.InsertItem(str,arp);  
  984.   
  985.         str.Format(_T("接收方MAC:"),local_data->arph->ar_hln);  
  986.         for(i=0;i<6;i++)  
  987.         {  
  988.             if(i<=4)  
  989.                 str.AppendFormat(_T("%02x-"),local_data->arph->ar_destmac[i]);  
  990.             else  
  991.                 str.AppendFormat(_T("%02x"),local_data->arph->ar_destmac[i]);  
  992.         }  
  993.         this->m_treeCtrl.InsertItem(str,arp);  
  994.   
  995.         str.Format(_T("接收方IP:"),local_data->arph->ar_hln);  
  996.         for(i=0;i<4;i++)  
  997.         {  
  998.             if(i<=2)  
  999.                 str.AppendFormat(_T("%d."),local_data->arph->ar_destip[i]);  
  1000.             else  
  1001.                 str.AppendFormat(_T("%d"),local_data->arph->ar_destip[i]);  
  1002.         }  
  1003.         this->m_treeCtrl.InsertItem(str,arp);  
  1004.   
  1005.     }else if(0x0800 == local_data->ethh->type){                   //IP  
  1006.           
  1007.         HTREEITEM ip = this->m_treeCtrl.InsertItem(_T("IP协议头"),data);  
  1008.   
  1009.         str.Format(_T("版本:%d"),local_data->iph->version);  
  1010.         this->m_treeCtrl.InsertItem(str,ip);  
  1011.         str.Format(_T("IP头长:%d"),local_data->iph->ihl);  
  1012.         this->m_treeCtrl.InsertItem(str,ip);  
  1013.         str.Format(_T("服务类型:%d"),local_data->iph->tos);  
  1014.         this->m_treeCtrl.InsertItem(str,ip);  
  1015.         str.Format(_T("总长度:%d"),local_data->iph->tlen);  
  1016.         this->m_treeCtrl.InsertItem(str,ip);  
  1017.         str.Format(_T("标识:0x%02x"),local_data->iph->id);  
  1018.         this->m_treeCtrl.InsertItem(str,ip);  
  1019.         str.Format(_T("段偏移:%d"),local_data->iph->frag_off);  
  1020.         this->m_treeCtrl.InsertItem(str,ip);  
  1021.         str.Format(_T("生存期:%d"),local_data->iph->ttl);  
  1022.         this->m_treeCtrl.InsertItem(str,ip);  
  1023.         str.Format(_T("协议:%d"),local_data->iph->proto);  
  1024.         this->m_treeCtrl.InsertItem(str,ip);       
  1025.         str.Format(_T("头部校验和:0x%02x"),local_data->iph->check);  
  1026.         this->m_treeCtrl.InsertItem(str,ip);  
  1027.   
  1028.         str.Format(_T("源IP:"));  
  1029.         struct in_addr in;  
  1030.         in.S_un.S_addr = local_data->iph->saddr;        
  1031.         str.AppendFormat(CString(inet_ntoa(in)));  
  1032.         this->m_treeCtrl.InsertItem(str,ip);  
  1033.   
  1034.         str.Format(_T("目的IP:"));  
  1035.         in.S_un.S_addr = local_data->iph->daddr;        
  1036.         str.AppendFormat(CString(inet_ntoa(in)));  
  1037.         this->m_treeCtrl.InsertItem(str,ip);  
  1038.   
  1039.         /*处理传输层ICMP、UDP、TCP*/  
  1040.         if(1 == local_data->iph->proto )                          //ICMP  
  1041.         {  
  1042.             HTREEITEM icmp = this->m_treeCtrl.InsertItem(_T("ICMP协议头"),data);  
  1043.                   
  1044.             str.Format(_T("类型:%d"),local_data->icmph->type);  
  1045.             this->m_treeCtrl.InsertItem(str,icmp);  
  1046.             str.Format(_T("代码:%d"),local_data->icmph->code);  
  1047.             this->m_treeCtrl.InsertItem(str,icmp);  
  1048.             str.Format(_T("序号:%d"),local_data->icmph->seq);  
  1049.             this->m_treeCtrl.InsertItem(str,icmp);  
  1050.             str.Format(_T("校验和:%d"),local_data->icmph->chksum);  
  1051.             this->m_treeCtrl.InsertItem(str,icmp);  
  1052.   
  1053.         }else if(6 == local_data->iph->proto){                //TCP  
  1054.               
  1055.             HTREEITEM tcp = this->m_treeCtrl.InsertItem(_T("TCP协议头"),data);  
  1056.   
  1057.             str.Format(_T("  源端口:%d"),local_data->tcph->sport);  
  1058.             this->m_treeCtrl.InsertItem(str,tcp);  
  1059.             str.Format(_T("  目的端口:%d"),local_data->tcph->dport);  
  1060.             this->m_treeCtrl.InsertItem(str,tcp);  
  1061.             str.Format(_T("  序列号:0x%02x"),local_data->tcph->seq);  
  1062.             this->m_treeCtrl.InsertItem(str,tcp);  
  1063.             str.Format(_T("  确认号:%d"),local_data->tcph->ack_seq);  
  1064.             this->m_treeCtrl.InsertItem(str,tcp);  
  1065.             str.Format(_T("  头部长度:%d"),local_data->tcph->doff);  
  1066.   
  1067.             HTREEITEM flag = this->m_treeCtrl.InsertItem(_T(" +标志位"),tcp);  
  1068.       
  1069.             str.Format(_T("cwr %d"),local_data->tcph->cwr);  
  1070.             this->m_treeCtrl.InsertItem(str,flag);  
  1071.             str.Format(_T("ece %d"),local_data->tcph->ece);  
  1072.             this->m_treeCtrl.InsertItem(str,flag);  
  1073.             str.Format(_T("urg %d"),local_data->tcph->urg);  
  1074.             this->m_treeCtrl.InsertItem(str,flag);  
  1075.             str.Format(_T("ack %d"),local_data->tcph->ack);  
  1076.             this->m_treeCtrl.InsertItem(str,flag);  
  1077.             str.Format(_T("psh %d"),local_data->tcph->psh);  
  1078.             this->m_treeCtrl.InsertItem(str,flag);  
  1079.             str.Format(_T("rst %d"),local_data->tcph->rst);  
  1080.             this->m_treeCtrl.InsertItem(str,flag);  
  1081.             str.Format(_T("syn %d"),local_data->tcph->syn);  
  1082.             this->m_treeCtrl.InsertItem(str,flag);  
  1083.             str.Format(_T("fin %d"),local_data->tcph->fin);  
  1084.             this->m_treeCtrl.InsertItem(str,flag);  
  1085.   
  1086.             str.Format(_T("  紧急指针:%d"),local_data->tcph->urg_ptr);  
  1087.             this->m_treeCtrl.InsertItem(str,tcp);  
  1088.             str.Format(_T("  校验和:0x%02x"),local_data->tcph->check);  
  1089.             this->m_treeCtrl.InsertItem(str,tcp);  
  1090.             str.Format(_T("  选项:%d"),local_data->tcph->opt);  
  1091.             this->m_treeCtrl.InsertItem(str,tcp);  
  1092.         }else if(17 == local_data->iph->proto){               //UDP  
  1093.             HTREEITEM udp = this->m_treeCtrl.InsertItem(_T("UDP协议头"),data);  
  1094.                   
  1095.             str.Format(_T("源端口:%d"),local_data->udph->sport);  
  1096.             this->m_treeCtrl.InsertItem(str,udp);  
  1097.             str.Format(_T("目的端口:%d"),local_data->udph->dport);  
  1098.             this->m_treeCtrl.InsertItem(str,udp);  
  1099.             str.Format(_T("总长度:%d"),local_data->udph->len);  
  1100.             this->m_treeCtrl.InsertItem(str,udp);  
  1101.             str.Format(_T("校验和:0x%02x"),local_data->udph->check);  
  1102.             this->m_treeCtrl.InsertItem(str,udp);  
  1103.         }  
  1104.     }else if(0x86dd == local_data->ethh->type){       //IPv6  
  1105.         HTREEITEM ip6 = this->m_treeCtrl.InsertItem(_T("IPv6协议头"),data);  
  1106.           
  1107.         //  
  1108.         str.Format(_T("版本:%d"),local_data->iph6->flowtype);  
  1109.         this->m_treeCtrl.InsertItem(str,ip6);  
  1110.         str.Format(_T("流类型:%d"),local_data->iph6->version);  
  1111.         this->m_treeCtrl.InsertItem(str,ip6);  
  1112.         ///  
  1113.         str.Format(_T("流标签:%d"),local_data->iph6->flowid);  
  1114.         this->m_treeCtrl.InsertItem(str,ip6);  
  1115.         str.Format(_T("有效载荷长度:%d"),local_data->iph6->plen);  
  1116.         this->m_treeCtrl.InsertItem(str,ip6);  
  1117.         str.Format(_T("下一个首部:0x%02x"),local_data->iph6->nh);  
  1118.         this->m_treeCtrl.InsertItem(str,ip6);  
  1119.         str.Format(_T("跳限制:%d"),local_data->iph6->hlim);  
  1120.         this->m_treeCtrl.InsertItem(str,ip6);  
  1121.   
  1122.         str.Format(_T("源地址:"));  
  1123.         int n;  
  1124.         for(n=0;n<8;n++)  
  1125.         {             
  1126.             if(n<=6)  
  1127.                 str.AppendFormat(_T("%02x:"),local_data->iph6->saddr[n]);       
  1128.             else  
  1129.                 str.AppendFormat(_T("%02x"),local_data->iph6->saddr[n]);        
  1130.         }     
  1131.         this->m_treeCtrl.InsertItem(str,ip6);  
  1132.   
  1133.         str.Format(_T("目的地址:"));  
  1134.         for(n=0;n<8;n++)  
  1135.         {             
  1136.             if(n<=6)  
  1137.                 str.AppendFormat(_T("%02x:"),local_data->iph6->saddr[n]);       
  1138.             else  
  1139.                 str.AppendFormat(_T("%02x"),local_data->iph6->saddr[n]);        
  1140.         }     
  1141.         this->m_treeCtrl.InsertItem(str,ip6);  
  1142.   
  1143.         /*处理传输层ICMPv6、UDP、TCP*/  
  1144.         if(0x3a== local_data->iph6->nh )                          //ICMPv6  
  1145.         {  
  1146.             HTREEITEM icmp6 = this->m_treeCtrl.InsertItem(_T("ICMPv6协议头"),data);  
  1147.                   
  1148.             str.Format(_T("类型:%d"),local_data->icmph6->type);  
  1149.             this->m_treeCtrl.InsertItem(str,icmp6);  
  1150.             str.Format(_T("代码:%d"),local_data->icmph6->code);  
  1151.             this->m_treeCtrl.InsertItem(str,icmp6);  
  1152.             str.Format(_T("序号:%d"),local_data->icmph6->seq);  
  1153.             this->m_treeCtrl.InsertItem(str,icmp6);  
  1154.             str.Format(_T("校验和:%d"),local_data->icmph6->chksum);  
  1155.             this->m_treeCtrl.InsertItem(str,icmp6);  
  1156.             str.Format(_T("选项-类型:%d"),local_data->icmph6->op_type);  
  1157.             this->m_treeCtrl.InsertItem(str,icmp6);  
  1158.             str.Format(_T("选项-长度%d"),local_data->icmph6->op_len);  
  1159.             this->m_treeCtrl.InsertItem(str,icmp6);  
  1160.             str.Format(_T("选项-链路层地址:"));  
  1161.             int i;  
  1162.             for(i=0;i<6;i++)  
  1163.             {  
  1164.                 if(i<=4)               
  1165.                     str.AppendFormat(_T("%02x-"),local_data->icmph6->op_ethaddr[i]);  
  1166.                 else  
  1167.                     str.AppendFormat(_T("%02x"),local_data->icmph6->op_ethaddr[i]);  
  1168.             }  
  1169.             this->m_treeCtrl.InsertItem(str,icmp6);  
  1170.   
  1171.         }else if(0x06 == local_data->iph6->nh){               //TCP  
  1172.               
  1173.             HTREEITEM tcp = this->m_treeCtrl.InsertItem(_T("TCP协议头"),data);  
  1174.   
  1175.             str.Format(_T("  源端口:%d"),local_data->tcph->sport);  
  1176.             this->m_treeCtrl.InsertItem(str,tcp);  
  1177.             str.Format(_T("  目的端口:%d"),local_data->tcph->dport);  
  1178.             this->m_treeCtrl.InsertItem(str,tcp);  
  1179.             str.Format(_T("  序列号:0x%02x"),local_data->tcph->seq);  
  1180.             this->m_treeCtrl.InsertItem(str,tcp);  
  1181.             str.Format(_T("  确认号:%d"),local_data->tcph->ack_seq);  
  1182.             this->m_treeCtrl.InsertItem(str,tcp);  
  1183.             str.Format(_T("  头部长度:%d"),local_data->tcph->doff);  
  1184.   
  1185.             HTREEITEM flag = this->m_treeCtrl.InsertItem(_T("标志位"),tcp);  
  1186.       
  1187.             str.Format(_T("cwr %d"),local_data->tcph->cwr);  
  1188.             this->m_treeCtrl.InsertItem(str,flag);  
  1189.             str.Format(_T("ece %d"),local_data->tcph->ece);  
  1190.             this->m_treeCtrl.InsertItem(str,flag);  
  1191.             str.Format(_T("urg %d"),local_data->tcph->urg);  
  1192.             this->m_treeCtrl.InsertItem(str,flag);  
  1193.             str.Format(_T("ack %d"),local_data->tcph->ack);  
  1194.             this->m_treeCtrl.InsertItem(str,flag);  
  1195.             str.Format(_T("psh %d"),local_data->tcph->psh);  
  1196.             this->m_treeCtrl.InsertItem(str,flag);  
  1197.             str.Format(_T("rst %d"),local_data->tcph->rst);  
  1198.             this->m_treeCtrl.InsertItem(str,flag);  
  1199.             str.Format(_T("syn %d"),local_data->tcph->syn);  
  1200.             this->m_treeCtrl.InsertItem(str,flag);  
  1201.             str.Format(_T("fin %d"),local_data->tcph->fin);  
  1202.             this->m_treeCtrl.InsertItem(str,flag);  
  1203.   
  1204.             str.Format(_T("  紧急指针:%d"),local_data->tcph->urg_ptr);  
  1205.             this->m_treeCtrl.InsertItem(str,tcp);  
  1206.             str.Format(_T("  校验和:0x%02x"),local_data->tcph->check);  
  1207.             this->m_treeCtrl.InsertItem(str,tcp);  
  1208.             str.Format(_T("  选项:%d"),local_data->tcph->opt);  
  1209.             this->m_treeCtrl.InsertItem(str,tcp);  
  1210.         }else if(0x11== local_data->iph6->nh){                //UDP  
  1211.             HTREEITEM udp = this->m_treeCtrl.InsertItem(_T("UDP协议头"),data);  
  1212.   
  1213.             str.Format(_T("源端口:%d"),local_data->udph->sport);  
  1214.             this->m_treeCtrl.InsertItem(str,udp);  
  1215.             str.Format(_T("目的端口:%d"),local_data->udph->dport);  
  1216.             this->m_treeCtrl.InsertItem(str,udp);  
  1217.             str.Format(_T("总长度:%d"),local_data->udph->len);  
  1218.             this->m_treeCtrl.InsertItem(str,udp);  
  1219.             str.Format(_T("校验和:0x%02x"),local_data->udph->check);  
  1220.             this->m_treeCtrl.InsertItem(str,udp);  
  1221.         }  
  1222.     }  
  1223.   
  1224.     return 1;  
  1225. }  
  1226.   
  1227.   
  1228. int Cmcf6Dlg::lixsniff_saveFile()  
  1229. {  
  1230.     CFileFind find;  
  1231.     if(NULL==find.FindFile(CString(filepath)))  
  1232.     {  
  1233.         MessageBox(_T("保存文件遇到未知意外"));  
  1234.         return -1;  
  1235.     }  
  1236.   
  1237.     //打开文件对话框  
  1238.      CFileDialog   FileDlg(FALSE,_T(".lix"),NULL,OFN_HIDEREADONLY   |   OFN_OVERWRITEPROMPT);     
  1239.      FileDlg.m_ofn.lpstrInitialDir=_T("c:\\");     
  1240.      if(FileDlg.DoModal()==IDOK)     
  1241.      {     
  1242.             CopyFile(CString(filepath),FileDlg.GetPathName(),TRUE);  
  1243.      }  
  1244.     return 1;  
  1245. }  
  1246.   
  1247. int Cmcf6Dlg::lixsniff_readFile(CString path)  
  1248. {  
  1249.     int res,nItem,i ;  
  1250.     struct tm *ltime;  
  1251.     CString timestr,buf,srcMac,destMac;  
  1252.     time_t local_tv_sec;  
  1253.     struct pcap_pkthdr *header;                                   //数据包头  
  1254.     const u_char *pkt_data=NULL;     //网络中收到的字节流数据  
  1255.     u_char *ppkt_data;  
  1256.   
  1257.     Cmcf6Dlg *pthis =this;                      //些代码改造自lixsinff_CapThread,为节约工作量,故保留pthis指针  
  1258.     pcap_t *fp;  
  1259.       
  1260.     //首先处理一下路径,利用pcap_open_offline打开文件时,  
  1261.     //路径需要用char *类型,不能用CString强制转换后的char *  
  1262.     int len = path.GetLength()+1;                           /注意这一个细节,必须要加1,否则会出错  
  1263.     char* charpath = (char *)malloc(len);  
  1264.     memset(charpath,0,len);  
  1265.     if(NULL==charpath)  
  1266.         return -1;  
  1267.   
  1268.     for(i=0;i<len;i++)  
  1269.         charpath[i] = (char)path.GetAt(i);  
  1270.       
  1271.     //打开相关文件  
  1272.     if ((fp = pcap_open_offline( /*(char*)(LPCTSTR)path*/charpath, errbuf)) == NULL)  
  1273.     {  
  1274.         MessageBox(_T("打开文件错误")+CString(errbuf));  
  1275.         return -1;  
  1276.     }  
  1277.       
  1278.     while((res = pcap_next_ex(fp, &header, &pkt_data)) >= 0)  
  1279.     {  
  1280.         struct datapkt *data = (struct datapkt*)malloc(sizeof(struct datapkt));       
  1281.         memset(data,0,sizeof(struct datapkt));  
  1282.   
  1283.         if(NULL == data)  
  1284.         {  
  1285.             MessageBox(_T("空间已满,无法接收新的数据包"));  
  1286.             return  -1;  
  1287.         }  
  1288.   
  1289.         //分析出错或所接收数据包不在处理范围内  
  1290.         if(analyze_frame(pkt_data,data,&(pthis->npacket))<0)  
  1291.              continue;  
  1292.           
  1293.         //更新各类数据包计数  
  1294.         pthis->lixsniff_updateNPacket();  
  1295.   
  1296.         //将本地化后的数据装入一个链表中,以便后来使用          
  1297.         ppkt_data = (u_char*)malloc(header->len);  
  1298.         memcpy(ppkt_data,pkt_data,header->len);  
  1299.   
  1300.         pthis->m_localDataList.AddTail(data);  
  1301.         pthis->m_netDataList.AddTail(ppkt_data);  
  1302.       
  1303.         /*预处理,获得时间、长度*/  
  1304.         data->len = header->len;                              //链路中收到的数据长度  
  1305.         local_tv_sec = header->ts.tv_sec;  
  1306.         ltime = localtime(&local_tv_sec);  
  1307.         data->time[0] = ltime->tm_year+1900;  
  1308.         data->time[1] = ltime->tm_mon+1;  
  1309.         data->time[2] = ltime->tm_mday;  
  1310.         data->time[3] = ltime->tm_hour;  
  1311.         data->time[4] = ltime->tm_min;  
  1312.         data->time[5] = ltime->tm_sec;  
  1313.   
  1314.         /*为新接收到的数据包在listControl中新建一个item*/  
  1315.         buf.Format(_T("%d"),pthis->npkt);  
  1316.         nItem = pthis->m_listCtrl.InsertItem(pthis->npkt,buf);  
  1317.   
  1318.         /*显示时间戳*/  
  1319.         timestr.Format(_T("%d/%d/%d  %d:%d:%d"),data->time[0],  
  1320.             data->time[1],data->time[2],data->time[3],data->time[4],data->time[5]);  
  1321.         pthis->m_listCtrl.SetItemText(nItem,1,timestr);  
  1322.           
  1323.         /*显示长度*/  
  1324.         buf.Empty();  
  1325.         buf.Format(_T("%d"),data->len);  
  1326.         pthis->m_listCtrl.SetItemText(nItem,2,buf);  
  1327.   
  1328.         /*显示源MAC*/  
  1329.         buf.Empty();  
  1330.         buf.Format(_T("%02X-%02X-%02X-%02X-%02X-%02X"),data->ethh->src[0],data->ethh->src[1],  
  1331.                             data->ethh->src[2],data->ethh->src[3],data->ethh->src[4],data->ethh->src[5]);  
  1332.         pthis->m_listCtrl.SetItemText(nItem,3,buf);  
  1333.   
  1334.         /*显示目的MAC*/  
  1335.         buf.Empty();  
  1336.         buf.Format(_T("%02X-%02X-%02X-%02X-%02X-%02X"),data->ethh->dest[0],data->ethh->dest[1],  
  1337.                             data->ethh->dest[2],data->ethh->dest[3],data->ethh->dest[4],data->ethh->dest[5]);  
  1338.         pthis->m_listCtrl.SetItemText(nItem,4,buf);  
  1339.   
  1340.         /*获得协议*/  
  1341.         pthis->m_listCtrl.SetItemText(nItem,5,CString(data->pktType));  
  1342.   
  1343.         /*获得源IP*/  
  1344.         buf.Empty();  
  1345.         if(0x0806== data->ethh->type)  
  1346.         {  
  1347.             buf.Format(_T("%d.%d.%d.%d"),data->arph->ar_srcip[0],  
  1348.                 data->arph->ar_srcip[1],data->arph->ar_srcip[2],data->arph->ar_srcip[3]);           
  1349.         }else  if(0x0800 == data->ethh->type){  
  1350.             struct  in_addr in;  
  1351.             in.S_un.S_addr = data->iph->saddr;  
  1352.             buf = CString(inet_ntoa(in));  
  1353.         }else if(0x86dd == data->ethh->type){  
  1354.             int i;  
  1355.             for(i=0;i<8;i++)  
  1356.             {  
  1357.                 if(i<=6)  
  1358.                     buf.AppendFormat(_T("%02x-"),data->iph6->saddr[i]);  
  1359.                 else  
  1360.                     buf.AppendFormat(_T("%02x"),data->iph6->saddr[i]);  
  1361.             }  
  1362.         }  
  1363.         pthis->m_listCtrl.SetItemText(nItem,6,buf);  
  1364.   
  1365.         /*获得目的IP*/  
  1366.         buf.Empty();  
  1367.         if(0x0806 == data->ethh->type)  
  1368.         {  
  1369.             buf.Format(_T("%d.%d.%d.%d"),data->arph->ar_destip[0],  
  1370.                 data->arph->ar_destip[1],data->arph->ar_destip[2],data->arph->ar_destip[3]);            
  1371.         }else if(0x0800 == data->ethh->type) {  
  1372.             struct  in_addr in;  
  1373.             in.S_un.S_addr = data->iph->daddr;  
  1374.             buf = CString(inet_ntoa(in));  
  1375.         }else if(0x86dd == data->ethh->type){  
  1376.             int i;  
  1377.             for(i=0;i<8;i++)  
  1378.             {  
  1379.                 if(i<=6)  
  1380.   
  1381.                     buf.AppendFormat(_T("%02x-"),data->iph6->daddr[i]);  
  1382.                 else  
  1383.                     buf.AppendFormat(_T("%02x"),data->iph6->daddr[i]);  
  1384.             }  
  1385.         }  
  1386.         pthis->m_listCtrl.SetItemText(nItem,7,buf);  
  1387.       
  1388.         /*对包计数*/  
  1389.         pthis->npkt++;  
  1390.     }  
  1391.   
  1392.     pcap_close(fp);  
  1393.   
  1394.     return 1;  
  1395. }  
  1396. </pre><br>  
  1397. <br>  
  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值