zxDlg.cpp
上传用户:aaagroup07
上传日期:2022-03-30
资源大小:1526k
文件大小:16k
源码类别:

网络截获/分析

开发平台:

C/C++

  1. // zxDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "zx.h"
  5. #include "zxDlg.h"
  6. #include "pcap.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. #pragma pack(1) //进入字节对齐方式
  13. typedef struct FrameHeader_t  { //帧首部
  14.     BYTE DesMAC[6]; // 目的地址
  15.     BYTE  SrcMAC[6]; // 源地址
  16.     WORD FrameType; // 帧类型
  17. } FrameHeader_t;
  18. typedef struct IPHeader_t { //IP首部
  19. BYTE Ver_HLen;
  20. BYTE TOS;
  21. WORD TotalLen;
  22. WORD ID;
  23. WORD Flag_Segment;
  24. BYTE TTL;
  25. BYTE Protocol;
  26. WORD Checksum;
  27. ULONG SrcIP;
  28. ULONG DstIP;
  29. } IPHeader_t;
  30. typedef struct Data_t { //包含帧首部和IP首部的数据包
  31. FrameHeader_t FrameHeader;
  32. IPHeader_t IPHeader;
  33. } Data_t;
  34. #pragma pack() //恢复缺省对齐方式
  35. pcap_t* thread_pNet;
  36. CListBox* thread_list_out;
  37. bool thread_can;
  38. CSliderCtrl *thread_pSlidCtrl;
  39. int TIME_ERR;
  40. int TIME_CANNOT;
  41. int PCAP_OPEN_FLAGS;
  42. int REC_MAX;
  43. int TIME_OUT;
  44. pcap_if_t* now_dev;
  45. CRITICAL_SECTION can_mutex; //串口读取 临界区变量
  46. /////////////////////////////////////////////////////////////////////////////
  47. // CAboutDlg dialog used for App About
  48. class CAboutDlg : public CDialog
  49. {
  50. public:
  51. CAboutDlg();
  52. // Dialog Data
  53. //{{AFX_DATA(CAboutDlg)
  54. enum { IDD = IDD_ABOUTBOX };
  55. CEdit m_edit_out;
  56. //}}AFX_DATA
  57. // ClassWizard generated virtual function overrides
  58. //{{AFX_VIRTUAL(CAboutDlg)
  59. protected:
  60. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  61. //}}AFX_VIRTUAL
  62. // Implementation
  63. protected:
  64. //{{AFX_MSG(CAboutDlg)
  65. virtual BOOL OnInitDialog();
  66. //}}AFX_MSG
  67. DECLARE_MESSAGE_MAP()
  68. };
  69. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  70. {
  71. //{{AFX_DATA_INIT(CAboutDlg)
  72. //}}AFX_DATA_INIT
  73. }
  74. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  75. {
  76. CDialog::DoDataExchange(pDX);
  77. //{{AFX_DATA_MAP(CAboutDlg)
  78. DDX_Control(pDX, IDC_EDIT_OUT, m_edit_out);
  79. //}}AFX_DATA_MAP
  80. }
  81. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  82. //{{AFX_MSG_MAP(CAboutDlg)
  83. //}}AFX_MSG_MAP
  84. END_MESSAGE_MAP()
  85. /////////////////////////////////////////////////////////////////////////////
  86. // CZxDlg dialog
  87. CZxDlg::CZxDlg(CWnd* pParent /*=NULL*/)
  88. : CDialog(CZxDlg::IDD, pParent)
  89. {
  90. //{{AFX_DATA_INIT(CZxDlg)
  91. //}}AFX_DATA_INIT
  92. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  93. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  94. }
  95. void CZxDlg::DoDataExchange(CDataExchange* pDX)
  96. {
  97. CDialog::DoDataExchange(pDX);
  98. //{{AFX_DATA_MAP(CZxDlg)
  99. DDX_Control(pDX, IDC_LIST_OUT, m_list_out);
  100. DDX_Control(pDX, IDC_LIST_DEV, m_list_dev);
  101. DDX_Control(pDX, IDC_COMBO_DEV, m_com_dev);
  102. //}}AFX_DATA_MAP
  103. }
  104. BEGIN_MESSAGE_MAP(CZxDlg, CDialog)
  105. //{{AFX_MSG_MAP(CZxDlg)
  106. ON_WM_SYSCOMMAND()
  107. ON_WM_PAINT()
  108. ON_WM_QUERYDRAGICON()
  109. ON_CBN_SELCHANGE(IDC_COMBO_DEV, OnSelchangeComboDev)
  110. ON_WM_DESTROY()
  111. ON_BN_CLICKED(IDCLEAR, OnClear)
  112. ON_BN_CLICKED(IDC_BUTTON_SET, OnButtonSet)
  113. ON_BN_CLICKED(IDC_BUTTON_HELP, OnButtonHelp)
  114. //}}AFX_MSG_MAP
  115. END_MESSAGE_MAP()
  116. /////////////////////////////////////////////////////////////////////////////
  117. // CZxDlg message handlers
  118. BOOL CZxDlg::OnInitDialog()
  119. {
  120. CDialog::OnInitDialog();
  121. // Add "About..." menu item to system menu.
  122. // IDM_ABOUTBOX must be in the system command range.
  123. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  124. ASSERT(IDM_ABOUTBOX < 0xF000);
  125. CMenu* pSysMenu = GetSystemMenu(FALSE);
  126. if (pSysMenu != NULL)
  127. {
  128. CString strAboutMenu;
  129. strAboutMenu.LoadString(IDS_ABOUTBOX);
  130. if (!strAboutMenu.IsEmpty())
  131. {
  132. pSysMenu->AppendMenu(MF_SEPARATOR);
  133. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  134. }
  135. }
  136. // Set the icon for this dialog.  The framework does this automatically
  137. //  when the application's main window is not a dialog
  138. SetIcon(m_hIcon, TRUE); // Set big icon
  139. SetIcon(m_hIcon, FALSE); // Set small icon
  140. // TODO: Add extra initialization here
  141. InitializeCriticalSection(&can_mutex);
  142. pcap_if_t *d; 
  143. //获得本机的设备列表
  144. if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING,  //获取本机的接口设备
  145. NULL, //无需认证
  146. &alldevs, //指向设备列表首部
  147. errbuf //出错信息保存缓存区
  148. ) == -1)
  149. {
  150. AfxMessageBox("获得本机的设备列表失败!");
  151. return FALSE; //错误处理
  152. }
  153. m_list_out.AddString("获得本机的设备列表成功");
  154. //显示接口列表
  155. for(d= alldevs; d != NULL; d= d->next)
  156. {
  157. m_com_dev.AddString(d->name); //利用d->name获取该网络接口设备的名字
  158. }
  159. pNet=NULL;
  160. thread_list_out=&m_list_out;
  161. thread_can=false;
  162. now_dev=NULL;
  163. m_list_out.AddString("读取配置文件");
  164. ReadProfile();
  165. CSliderCtrl *pSlidCtrl=(CSliderCtrl*)GetDlgItem(IDC_SLIDER);
  166. pSlidCtrl->SetRange(0,10,TRUE);//设置滑动条范围
  167. pSlidCtrl->SetPos(5);//设置滑动条位置
  168. thread_pSlidCtrl=pSlidCtrl;
  169. HANDLE Capturer_Thread=CreateThread(NULL,0,Capturer,0,CREATE_SUSPENDED,NULL);
  170. if( Capturer_Thread==NULL )
  171. {
  172. AfxMessageBox("Capturer线程创建线程失败!");
  173. return FALSE;
  174. }
  175. else
  176. {
  177. ResumeThread(Capturer_Thread); // 恢复线程运行
  178. m_list_out.AddString("创建捕获线程成功");
  179. }
  180. return TRUE;  // return TRUE  unless you set the focus to a control
  181. }
  182. void CZxDlg::OnSysCommand(UINT nID, LPARAM lParam)
  183. {
  184. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  185. {
  186. CAboutDlg dlgAbout;
  187. dlgAbout.DoModal();
  188. }
  189. else
  190. {
  191. CDialog::OnSysCommand(nID, lParam);
  192. }
  193. }
  194. // If you add a minimize button to your dialog, you will need the code below
  195. //  to draw the icon.  For MFC applications using the document/view model,
  196. //  this is automatically done for you by the framework.
  197. void CZxDlg::OnPaint() 
  198. {
  199. if (IsIconic())
  200. {
  201. CPaintDC dc(this); // device context for painting
  202. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  203. // Center icon in client rectangle
  204. int cxIcon = GetSystemMetrics(SM_CXICON);
  205. int cyIcon = GetSystemMetrics(SM_CYICON);
  206. CRect rect;
  207. GetClientRect(&rect);
  208. int x = (rect.Width() - cxIcon + 1) / 2;
  209. int y = (rect.Height() - cyIcon + 1) / 2;
  210. // Draw the icon
  211. dc.DrawIcon(x, y, m_hIcon);
  212. }
  213. else
  214. {
  215. CDialog::OnPaint();
  216. }
  217. }
  218. // The system calls this to obtain the cursor to display while the user drags
  219. //  the minimized window.
  220. HCURSOR CZxDlg::OnQueryDragIcon()
  221. {
  222. return (HCURSOR) m_hIcon;
  223. }
  224. void CZxDlg::OnSelchangeComboDev() 
  225. {
  226. // TODO: Add your control notification handler code here
  227. while(m_list_dev.GetCount()>0)
  228. {
  229. m_list_dev.DeleteString(0);
  230. }
  231. pcap_addr_t *a; 
  232. pcap_if_t *d;
  233. d=alldevs;
  234. int com_num=m_com_dev.GetCurSel();
  235. int i=0;
  236. while(i<com_num) 
  237. {
  238. d=d->next;
  239. i++;
  240. }
  241. now_dev=d;
  242. //获取该网络接口设备的描述字符串
  243. m_list_dev.AddString(d->description);
  244. //打开该网络接口
  245. pNet=pcap_open(d->name,REC_MAX,PCAP_OPEN_FLAGS,TIME_OUT,NULL,errbuf);//PCAP_OPENFLAG_PROMISCUOUS
  246. if(pNet==NULL)
  247. {
  248. AfxMessageBox("打开该网络接口失败!");
  249. }
  250. thread_pNet=pNet;
  251. ////////////////
  252. //获取该网络接口设备的IP地址信息
  253. a=d->addresses;
  254. if(a!=NULL)
  255. {
  256. for(; a!=NULL; a=a->next)
  257. {
  258. if (a->addr->sa_family==AF_INET) //判断该地址是否IP地址
  259. {
  260. CString out;
  261. //利用a->addr获取IP地址
  262. if(a->addr!=NULL) 
  263. {
  264. out.Format("IP地址:   %d.%d.%d.%d ",(int)a->addr->sa_data[2]&255,
  265. (int)a->addr->sa_data[3]&255,(int)a->addr->sa_data[4]&255,
  266. (int)a->addr->sa_data[5]&255);
  267. }
  268. else
  269. {
  270. out="IP地址:   空";
  271. }
  272. m_list_dev.AddString(out);
  273. //利用a->netmask获取网络掩码
  274. if(a->netmask!=NULL) 
  275. {
  276. out.Format("网络掩码:   %d.%d.%d.%d ",(int)a->netmask->sa_data[2]&255,
  277. (int)a->netmask->sa_data[3]&255,(int)a->netmask->sa_data[4]&255,
  278. (int)a->netmask->sa_data[5]&255);
  279. }
  280. else
  281. {
  282. out="网络掩码:   空";
  283. }
  284. m_list_dev.AddString(out);
  285. //利用a->broadaddr获取广播地址
  286. if(a->broadaddr!=NULL) 
  287. {
  288. out.Format("广播地址:   %d.%d.%d.%d ",(int)a->broadaddr->sa_data[2]&255,
  289. (int)a->broadaddr->sa_data[3]&255,(int)a->broadaddr->sa_data[4]&255,
  290. (int)a->broadaddr->sa_data[5]&255);
  291. }
  292. else
  293. {
  294. out="广播地址:   空";
  295. }
  296. m_list_dev.AddString(out);
  297. //利用a->dstaddr)获取目的地址
  298. if(a->dstaddr!=NULL) 
  299. {
  300. out.Format("目的地址:   %d.%d.%d.%d ",(int)a->dstaddr->sa_data[2]&255,
  301. (int)a->dstaddr->sa_data[3]&255,(int)a->dstaddr->sa_data[4]&255,
  302. (int)a->dstaddr->sa_data[5]&255);
  303. }
  304. else
  305. {
  306. out="目的地址:   空";
  307. }
  308. m_list_dev.AddString(out);
  309. }
  310. }
  311. }
  312. else
  313. {
  314. m_list_dev.AddString("该网卡无地址");
  315. }
  316. }
  317. void CZxDlg::OnDestroy() 
  318. {
  319. CDialog::OnDestroy();
  320. // TODO: Add your message handler code here
  321. //释放设备列表
  322. pcap_freealldevs(alldevs);
  323. }
  324. void CZxDlg::OnOK() 
  325. {
  326. // TODO: Add extra validation here
  327. if(thread_can==true)
  328. {
  329. thread_can=false;
  330. }
  331. else
  332. {
  333. thread_can=true;
  334. }
  335. }
  336. void CZxDlg::OnClear()
  337. {
  338. // TODO: Add your control notification handler code here
  339. EnterCriticalSection(&can_mutex); //进入临界区
  340. bool last_can=thread_can;
  341. thread_can=false;
  342. while(m_list_out.GetCount()>0)
  343. {
  344. m_list_out.DeleteString(0);
  345. }
  346. thread_can=last_can;
  347. LeaveCriticalSection(&can_mutex); //离开临界区
  348. }
  349. DWORD WINAPI CZxDlg::Capturer(PVOID pvoid)
  350. {
  351. while(true)
  352. {
  353. if(thread_pNet!=NULL && thread_can==true)
  354. {
  355. pcap_pkthdr* pkt_header,kt_header;
  356. pkt_header=&kt_header;
  357. const u_char* pkt_data;
  358. EnterCriticalSection(&can_mutex); //进入临界区
  359. if(pcap_next_ex(thread_pNet,&pkt_header,&pkt_data)==1)
  360. {
  361. LeaveCriticalSection(&can_mutex); //离开临界区
  362. /////////////////////////
  363. thread_list_out->AddString("------------------------------------------------------------");
  364. //////////////////////////
  365. CString cout_time,cout_len;
  366. struct timeval ts; /* time stamp */
  367. bpf_u_int32 len; /* length this packet (off wire) */
  368. len=pkt_header->len;
  369. ts=pkt_header->ts;
  370. cout_len.Format("数据包长度:   %d",len);
  371. COleDateTime   DataTime   =   ts.tv_sec;  
  372. int   nYear   =   DataTime.GetYear();  
  373. int   nMonth   =   DataTime.GetMonth();  
  374. int   nDay   =   DataTime.GetDay();  
  375. int   nHour   =   DataTime.GetHour();  
  376. int   nMin   =   DataTime.GetMinute();  
  377. int   nSec   =   DataTime.GetSecond();
  378. cout_time.Format("时间:   %d年%d月%d号%d时%d分%d秒",nYear,nMonth,nDay,nHour,nMin,nSec);
  379. //////////////////////////
  380. Data_t * IPPacket;
  381. ULONG SourceIP,DestinationIP;
  382. IPPacket = (Data_t *) pkt_data;
  383. SourceIP = (IPPacket->IPHeader.SrcIP);
  384. DestinationIP = (IPPacket->IPHeader.DstIP);
  385. BYTE DesMAC[6]; // 目的地址
  386. BYTE  SrcMAC[6]; // 源地址
  387. WORD FrameType; // 帧类型
  388. FrameType=ntohs(IPPacket->FrameHeader.FrameType);
  389. memcpy(DesMAC, IPPacket->FrameHeader.DesMAC, 6);
  390. memcpy(SrcMAC, IPPacket->FrameHeader.SrcMAC, 6);
  391. CString cout_DesMAC,cout_SrcMAC,cout_FrameType;
  392. cout_DesMAC.Format("目的地址:   %d-%d-%d-%d-%d-%d ",(int)DesMAC[0]&255,
  393. (int)DesMAC[1]&255,(int)DesMAC[2]&255,(int)DesMAC[3]&255,
  394. (int)DesMAC[4]&255,(int)DesMAC[5]&255);
  395. cout_SrcMAC.Format("源地址:   %d-%d-%d-%d-%d-%d ",(int)SrcMAC[0]&255,
  396. (int)SrcMAC[1]&255,(int)SrcMAC[2]&255,(int)SrcMAC[3]&255,
  397. (int)SrcMAC[4]&255,(int)SrcMAC[5]&255);
  398. if(FrameType>=2048)
  399. {
  400. cout_FrameType.Format("帧类型:   %d ",FrameType);
  401. }
  402. else
  403. {
  404. cout_FrameType.Format("帧长度:   %d ",FrameType);
  405. }
  406. /////////////////////////
  407. thread_list_out->AddString(cout_len+"       "+cout_time);
  408. thread_list_out->AddString(cout_DesMAC+"  "+cout_SrcMAC+"  "+cout_FrameType);
  409. /////////////////////////
  410. if(FrameType==0x0800)
  411. {
  412. in_addr SourceIP_addr,DestinationIP_addr;
  413. CString cout_SourceIP,cout_DestinationIP;
  414. memcpy(&SourceIP_addr, &SourceIP, 4);
  415. memcpy(&DestinationIP_addr, &DestinationIP, 4);
  416. cout_SourceIP.Format("源IP地址:   %s",inet_ntoa(SourceIP_addr));
  417. cout_DestinationIP.Format("目的IP地址:   %s",inet_ntoa(DestinationIP_addr));
  418. thread_list_out->AddString(cout_DestinationIP+"  "+cout_SourceIP);
  419. }
  420. /////////////////////////
  421. int sleep_time=thread_pSlidCtrl->GetPos()*100;
  422. Sleep(sleep_time);
  423. else
  424. {
  425. LeaveCriticalSection(&can_mutex); //离开临界区
  426. thread_list_out->AddString("************************************************************");
  427. thread_list_out->AddString("捕获数据超时或失败!");
  428. Sleep(TIME_ERR);
  429. }
  430. }
  431. else
  432. {
  433. Sleep(TIME_CANNOT);
  434. }
  435. }
  436. return 0;
  437. }
  438. void CZxDlg::ReadProfile()
  439. {
  440. if((TIME_ERR=(GetPrivateProfileInt("捕获数据包参数", "捕获出错后睡眠时间", -1, "MyWinPcap.ini")))==-1) 
  441.     {
  442. WritePrivateProfileString ("捕获数据包参数", "捕获出错后睡眠时间", "1000", "MyWinPcap.ini");  
  443. TIME_ERR=1000;                                        
  444.     }
  445. if((TIME_CANNOT=(GetPrivateProfileInt("捕获数据包参数", "不能捕获时睡眠时间", -1, "MyWinPcap.ini")))==-1) 
  446.     {
  447. WritePrivateProfileString ("捕获数据包参数", "不能捕获时睡眠时间", "1000", "MyWinPcap.ini");  
  448. TIME_CANNOT=1000;                                        
  449.     }
  450. if((PCAP_OPEN_FLAGS=(GetPrivateProfileInt("捕获数据包参数", "捕获方式", -1, "MyWinPcap.ini")))==-1) 
  451.     {
  452. WritePrivateProfileString ("捕获数据包参数", "捕获方式", "1", "MyWinPcap.ini");  
  453. PCAP_OPEN_FLAGS=1;                                        
  454.     }
  455. if((REC_MAX=(GetPrivateProfileInt("捕获数据包参数", "获取数据包最大长度", 0, "MyWinPcap.ini")))==0) 
  456.     {
  457. WritePrivateProfileString ("捕获数据包参数", "获取数据包最大长度", "1024", "MyWinPcap.ini");  
  458. REC_MAX=1024;                                        
  459.     }
  460. if((TIME_OUT=(GetPrivateProfileInt("捕获数据包参数", "获取数据包超时时间", 0, "MyWinPcap.ini")))==0) 
  461.     {
  462. WritePrivateProfileString ("捕获数据包参数", "获取数据包超时时间", "1000", "MyWinPcap.ini");  
  463. TIME_OUT=1000;                                        
  464.     }
  465. CString out;
  466. out.Format("捕获出错后睡眠时间:   %d",TIME_ERR);
  467. m_list_out.AddString(out);
  468. out.Format("不能捕获时睡眠时间:   %d",TIME_CANNOT);
  469. m_list_out.AddString(out);
  470. out.Format("捕获方式:   %d",PCAP_OPEN_FLAGS);
  471. m_list_out.AddString(out);
  472. out.Format("获取数据包最大长度:   %d",REC_MAX);
  473. m_list_out.AddString(out);
  474. out.Format("获取数据包超时时间:   %d",TIME_OUT);
  475. m_list_out.AddString(out);
  476. }
  477. void CZxDlg::OnButtonSet() 
  478. {
  479. // TODO: Add your control notification handler code here
  480. EnterCriticalSection(&can_mutex); //进入临界区
  481. bool last_can=thread_can;
  482. thread_can=false;
  483. //////////////////////////////// 
  484. if(now_dev!=NULL)
  485. {
  486. //char filter[100] = "arp"; 
  487. char filter[100];
  488. CEdit *pedit_in=(CEdit*)GetDlgItem(IDC_EDIT_IN);
  489. pedit_in->GetLine(0,filter,100);
  490. struct bpf_program fcode;
  491. bpf_u_int32 localnet;
  492. bpf_u_int32 netmask;
  493. char thread_errbuf[PCAP_ERRBUF_SIZE];
  494. if(pcap_lookupnet(now_dev->name,&localnet,&netmask,thread_errbuf)  < 0)
  495. {
  496. AfxMessageBox("查找子网掩码失败!");
  497. return;
  498. }
  499. //compile the filter
  500. if(pcap_compile(thread_pNet, &fcode, filter, 0, netmask)  < 0)
  501. {
  502. AfxMessageBox("编译过滤字符串失败!");
  503. return;
  504. }
  505. //set the filter
  506. if(pcap_setfilter(thread_pNet, &fcode) <0)
  507. {
  508. AfxMessageBox("设置过滤字符串失败!");
  509. return;
  510. }
  511. ///////////////
  512. }
  513. else
  514. {
  515. thread_list_out->AddString("设备为空,无法过滤");
  516. }
  517. ///////////////////////////////////
  518. thread_can=last_can;
  519. LeaveCriticalSection(&can_mutex); //离开临界区
  520. }
  521. void CZxDlg::OnButtonHelp() 
  522. {
  523. // TODO: Add your control notification handler code here
  524. CAboutDlg help_dlg;
  525. help_dlg.DoModal();
  526. }
  527. BOOL CAboutDlg::OnInitDialog() 
  528. {
  529. CDialog::OnInitDialog();
  530. // TODO: Add extra initialization here
  531. CString out;
  532. out.LoadString(IDS_STRING_HELP);
  533. m_edit_out.SetWindowText(out);
  534. return TRUE;  // return TRUE unless you set the focus to a control
  535.               // EXCEPTION: OCX Property Pages should return FALSE
  536. }