zoukankan      html  css  js  c++  java
  • MFC+WinPcap编写一个嗅探器之六(分析模块)

    这一节是程序的核心,也是最复杂的地方

    首先需要明白的一点是,一般对于一个有界面的程序来说,往往需要多线程。本程序中除了界面线程外,抓包需要另外创建一个新的线程。在写抓包函数之前,首先要将前面两个模块的结果返回到主对话框界面对应的类实现中,在SnifferDlg.cpp中,修改之前增加的两个模块的触发函数如下:

    1 void CSnifferDlg::OnAdp()
    2 {
    3     // TODO: 在此添加命令处理程序代码
    4     CAdpDlg adpdlg;
    5     if(adpdlg.DoModal() == IDOK)
    6     {
    7         m_pDevice = adpdlg.returnd();
    8     }
    9 }
     1 void CSnifferDlg::OnFilter()
     2 {
     3     // TODO: 在此添加命令处理程序代码
     4     CFilterDlg filterdlg;
     5     if(filterdlg.DoModal() == IDOK)
     6     {
     7         int len =WideCharToMultiByte(CP_ACP,0,filterdlg.GetFilterName(),-1,NULL,0,NULL,NULL); 
     8         WideCharToMultiByte(CP_ACP,0,filterdlg.GetFilterName(),-1,m_filtername,len,NULL,NULL );
     9         
    10     }
    11 }

     前一个函数是在打开选择适配器窗口后,在用户选择完网卡后,将选择的网卡返回到主界面的类实现中;后一个函数是在打开设置过滤规则后,将过滤规则的字符串返回到主界面的类实现中。也许你对第二个函数中的两个函数不太明白,这是一个宽字符转换为多字符的函数,就只需了解其中两个参数即可,其它的复制粘贴,函数是这样使用的。获得了前两个模块的返回值,就可以来写抓包函数了,创建一个新线程,抓包函数代码如下:

     1 DWORD WINAPI CapturePacket(LPVOID lpParam)
     2 {
     3     CSnifferDlg *pDlg = (CSnifferDlg *)lpParam;
     4     pcap_t *pCap;
     5     char    strErrorBuf[PCAP_ERRBUF_SIZE];
     6     int res;
     7     struct pcap_pkthdr *pkt_header;
     8     const u_char *pkt_data;
     9     u_int netmask;
    10     struct bpf_program fcode;
    11 
    12     if((pCap=pcap_open_live(pDlg->m_pDevice->name,65536,PCAP_OPENFLAG_PROMISCUOUS,1000,strErrorBuf))==NULL)
    13     {        
    14         return -1;
    15     }
    16 
    17     if(pDlg->m_pDevice->addresses != NULL)
    18         /* 获得接口第一个地址的掩码 */
    19         netmask=((struct sockaddr_in *)(pDlg->m_pDevice->addresses->netmask))->sin_addr.S_un.S_addr;
    20     else
    21         /* 如果接口没有地址,那么我们假设一个C类的掩码 */
    22         netmask=0xffffff; 
    23         //编译过滤器
    24         if (pcap_compile(pCap, &fcode,pDlg->m_filtername, 1, netmask) <0 )
    25         {
    26             AfxMessageBox(_T("请设置过滤规则"));
    27             return -1;
    28         }
    29         //设置过滤器
    30         if (pcap_setfilter(pCap, &fcode)<0)
    31             return -1;
    32 
    33     while((res = pcap_next_ex( pCap, &pkt_header, &pkt_data)) >= 0)
    34     {
    35 
    36         if(res == 0)
    37             continue;
    38         if(!pDlg->m_bFlag)
    39             break;
    40         CSnifferDlg *pDlg = (CSnifferDlg *)AfxGetApp()->GetMainWnd(); 
    41         pDlg->ShowPacketList(pkt_header,pkt_data);
    42         pDlg = NULL;
    43     }
    44 
    45     pcap_close(pCap);
    46     pDlg = NULL;
    47     return 1;     
    48 }

     解释两个地方,一是怎样控制开始抓包和停止抓包,这里采用了一个bool变量m_bFlag,这个变量初值是FALSE,当点击菜单中的开始捕获变量为true,点击停止捕获变量又变为false。二是当抓完一个包后,又将指针指向主界面的句柄,之后将抓来的数据包的内容在主界面中显示。

    主界面中有三个需要显示抓包内容的地方,一是数据包的概略信息,用ShowPacketList函数来实现;二是数据包的详细信息用ShowPacketTree函数来实现;三是数据包的具体内容和统计信息。这三部分是大量相似的代码,主要涉及到对网络协议的分析,用到的主要是判断语句,放到下一节讲吧。

    下一节 MFC+WinPcap编写一个嗅探器之七(协议)

  • 相关阅读:
    【Salesfoece】Apex基础数据类型
    【Javascript】Redux ,Saga关系
    【CSS】选择器
    爬取取百度和Flickr图像
    hadoop系列之一问题锦集
    进行数据清洗_在进行大数据分析之前都需要进行数据清洗,如何进行数据清洗?...
    Hadoop中文编码乱码相关问题
    Can not find the tag library descriptor for "http://java.sun.com/jsp/jstl/
    解决:Multiple annotations found at this line:
    HttpServletRequest cannot be resolved to a type解决方案
  • 原文地址:https://www.cnblogs.com/raichen/p/4133599.html
Copyright © 2011-2022 走看看