MyCapView.cpp
上传用户:xakehao
上传日期:2013-08-28
资源大小:100k
文件大小:11k
- // MyCapView.cpp : implementation of the CMyCapView class
- #include "stdafx.h"
- #include "MyCap.h"
- #include "MyCapDoc.h"
- #include "MyCapView.h"
- #include <pcap.h>
- #include "InterfaceDlg.h"
- #include <vector>
- #include "packetfilter.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- using namespace std;
- typedef vector<const u_char *> v;
- v myvector;//定义了一个vector变量,用来放抓的包
- using namespace std;
- typedef vector<u_short> u;
- u mycount;//定义了一个vector变量,用来放所抓包的大小
- using namespace std;
- typedef vector<PACKET> c;
- c mypacket;//定义了一个vector变量,用来放所抓包的包头
- char *packet_filter = "";
- int m_flag = -1;
- HWND hWnd;
- #define WM_USER_THREAD_PACKET WM_USER+100
- IMPLEMENT_DYNCREATE(CMyCapView, CListView)
- BEGIN_MESSAGE_MAP(CMyCapView, CListView)
- ON_COMMAND(ID_FILE_START, OnFileStart)
- ON_COMMAND(ID_OPTION_CARD, OnOptionCard)
- ON_COMMAND(ID_FILE_STOP, OnFileStop)
- ON_NOTIFY_REFLECT(NM_CLICK, OnClick)
- ON_COMMAND(ID_FILE_SAVE, OnFileSave)
- ON_COMMAND(ID_OPTION_FILTER, OnOptionFilter)
- ON_COMMAND(ID_FILE_PRINT, CListView::OnFilePrint)
- ON_COMMAND(ID_FILE_PRINT_DIRECT, CListView::OnFilePrint)
- ON_COMMAND(ID_FILE_PRINT_PREVIEW, CListView::OnFilePrintPreview)
- ON_MESSAGE(WM_USER_THREAD_PACKET, OnGetPacket)
- END_MESSAGE_MAP()
- CMyCapView::CMyCapView()
- {
- strcpy(m_szName, "");//将m_szName初始化为空
- }
- CMyCapView::~CMyCapView()
- {
- }
- BOOL CMyCapView::PreCreateWindow(CREATESTRUCT& cs)
- {
- cs.style |= LVS_REPORT;
- return CListView::PreCreateWindow(cs);
- }
- void CMyCapView::OnDraw(CDC* pDC)
- {
- CMyCapDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- }
- void CMyCapView::OnInitialUpdate()
- {
- CListView::OnInitialUpdate();
- CListCtrl& theCtrl = GetListCtrl();
- theCtrl.SetExtendedStyle(theCtrl.GetExtendedStyle()|LVS_EX_FULLROWSELECT );
- theCtrl.InsertColumn(0, _T("时间"), LVCFMT_CENTER, 100);//给第一个CListView窗口添加各列
- theCtrl.InsertColumn(1, _T("长度"), LVCFMT_CENTER, 100);
- theCtrl.InsertColumn(2, _T("源IP"), LVCFMT_CENTER, 100);
- theCtrl.InsertColumn(3, _T("目的IP"), LVCFMT_CENTER, 100);
- theCtrl.InsertColumn(4, _T("源端口"), LVCFMT_CENTER, 100);
- theCtrl.InsertColumn(5, _T("目的端口"), LVCFMT_CENTER, 100);
- CString strSection = "global";
- CString strStringItem1 = "interface";
- CString strStringItem2 = "description";
- CString strStringItem3 = "netmask";
- CWinApp *pApp = AfxGetApp();
- strcpy(m_szName, pApp->GetProfileString(strSection, strStringItem1).GetBuffer(255));
- strcpy(m_szDescription, pApp->GetProfileString(strSection, strStringItem2).GetBuffer(255));
- strcpy(m_szNetmask, pApp->GetProfileString(strSection, strStringItem3).GetBuffer(16));
- }
- BOOL CMyCapView::OnPreparePrinting(CPrintInfo* pInfo)
- {
- return DoPreparePrinting(pInfo);
- }
- void CMyCapView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
- {
- }
- void CMyCapView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
- {
- }
- #ifdef _DEBUG
- void CMyCapView::AssertValid() const
- {
- CListView::AssertValid();
- }
- void CMyCapView::Dump(CDumpContext& dc) const
- {
- CListView::Dump(dc);
- }
- CMyCapDoc* CMyCapView::GetDocument()
- {
- ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyCapDoc)));
- return (CMyCapDoc*)m_pDocument;
- }
- #endif //_DEBUG
- void CMyCapView::OnFileStart()
- {
- CString strMsg;
- hWnd = GetSafeHwnd( ) ;
- if (strlen(m_szName) == 0 || strlen(m_szNetmask) == 0)
- {
- OnOptionCard(); //如果没有选择网卡就要求选择网卡
- }
- else
- {
- THREADPARMS *ptp = new THREADPARMS;
- strcpy(ptp->szName, m_szName);
- ptp->netmask = atoi(m_szNetmask);
- pThread = AfxBeginThread(ThreadFunc, ptp);
- char szStatus[255] = "";
- sprintf(szStatus,"listening on %s...", m_szDescription);
- CStatusBar* pStatus = (CStatusBar*)(AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR));
- pStatus->SetPaneText(0, szStatus, TRUE);
- } //打开网卡,如果成功,就开始抓包
- }
- void CMyCapView::OnFileStop()
- {
- ::TerminateThread(pThread->m_hThread, 0);//终止线程
- char szStatus[255] = "";
- sprintf(szStatus,"stop");
- CStatusBar* pStatus = (CStatusBar*)(AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR));
- pStatus->SetPaneText(0, szStatus, TRUE);
- }
- LONG CMyCapView::OnGetPacket(WPARAM wParam, LPARAM lParam)
- {
- PACKET pkt;
- memcpy(&pkt, (PACKET *)wParam, sizeof(PACKET));
- delete (PACKET *)wParam;
- mypacket.push_back(pkt);//将包头放到一个向量mypacket中
- CListCtrl& theCtrl = GetListCtrl();
- int nCount = theCtrl.GetItemCount();
- char srcIP[16] = "";
- char dstIP[16] = "";
- char srcPort[8] = "";
- char dstPort[8] = "";
- char szLen[8] = "";
- sprintf(srcIP, "%d.%d.%d.%d",
- pkt.IpHead.saddr.byte1,
- pkt.IpHead.saddr.byte2,
- pkt.IpHead.saddr.byte3,
- pkt.IpHead.saddr.byte4);
- sprintf(dstIP, "%d.%d.%d.%d",
- pkt.IpHead.daddr.byte1,
- pkt.IpHead.daddr.byte2,
- pkt.IpHead.daddr.byte3,
- pkt.IpHead.daddr.byte4);
- sprintf(szLen, "%d", ntohs(pkt.IpHead.tlen));
- if(int(pkt.IpHead.proto) == 17)
- {//如果IP包头的协议字段是17,即为UDP包时,在第一个CListView窗口中显示UDP包信息
- sprintf(srcPort, "%d", ntohs(pkt.UdpHead.sport));
- sprintf(dstPort, "%d", ntohs(pkt.UdpHead.dport));
- theCtrl.InsertItem(nCount, pkt.timestr, NULL);
- theCtrl.SetItemText(nCount, 1, szLen);
- theCtrl.SetItemText(nCount, 2, srcIP);
- theCtrl.SetItemText(nCount, 3, dstIP);
- theCtrl.SetItemText(nCount, 4, srcPort);
- theCtrl.SetItemText(nCount, 5, dstPort);
- }
- if(int(pkt.IpHead.proto == 6))
- {//如果IP包头的协议字段是6,即为TCP包时,在第一个CListView窗口中显示TCP包信息
- sprintf(srcPort, "%d", ntohs(pkt.TcpHead.tcpsport));
- sprintf(dstPort, "%d", ntohs(pkt.TcpHead.tcpdport));
- theCtrl.InsertItem(nCount, pkt.timestr, NULL);
- theCtrl.SetItemText(nCount, 1, szLen);
- theCtrl.SetItemText(nCount, 2, srcIP);
- theCtrl.SetItemText(nCount, 3, dstIP);
- theCtrl.SetItemText(nCount, 4, srcPort);
- theCtrl.SetItemText(nCount, 5, dstPort);
- }
- if(int(pkt.IpHead.proto == 1))
- {//如果IP包头的协议字段是1,即为ICMP包时,在第一个CListView窗口中显示ICMP包信息
- theCtrl.InsertItem(nCount, pkt.timestr, NULL);
- theCtrl.SetItemText(nCount, 1, szLen);
- theCtrl.SetItemText(nCount, 2, srcIP);
- theCtrl.SetItemText(nCount, 3, dstIP);
- }
-
- return 0;
- }
- void CMyCapView::OnOptionCard()
- {
- CString strSection = "global";
- CString strStringItem1 = "interface";
- CString strStringItem2 = "description";
- CString strStringItem3 = "netmask";
- CInterfaceDlg dlg;
- if (dlg.DoModal() == IDOK)
- {
- strcpy(m_szName, dlg.m_szName);
- strcpy(m_szDescription, dlg.m_szDescription);
- strcpy(m_szNetmask, dlg.m_szNetmask);
- CWinApp *pApp = AfxGetApp();
- pApp->WriteProfileString(strSection, strStringItem1, dlg.m_szName);
- pApp->WriteProfileString(strSection, strStringItem2, dlg.m_szDescription);
- pApp->WriteProfileString(strSection, strStringItem3, dlg.m_szNetmask);
- }
- else
- {
- MessageBox("请确保正确安装了winpcap!");
- return;
- }
- }
- UINT ThreadFunc(LPVOID pParam)
- {
- THREADPARMS *ptp = (THREADPARMS *) pParam;
- char szName[255];
- strcpy(szName, ptp->szName);
- u_int netmask = ptp->netmask;
- CString strMsg;
- delete ptp;
- pcap_t *adhandle;
- char errbuf[PCAP_ERRBUF_SIZE];
- if(packet_filter == "")
- packet_filter = "ip";
- struct bpf_program fcode;
- if ( (adhandle= pcap_open(szName,
- 65536,
- PCAP_OPENFLAG_PROMISCUOUS,
- 1000,
- NULL,
- errbuf
- ) ) == NULL)//将网卡设置成混杂模式
- {
- strMsg.Format("Unable to open the adapter. %s is not supported by WinPcapn", szName);
- AfxMessageBox(strMsg);
- return 0;
- }
- if(pcap_datalink(adhandle) != DLT_EN10MB)
- {
- AfxMessageBox("This program works only on Ethernet networks.");
- return 0;
- }
- if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0 )
- {
- AfxMessageBox("Unable to compile the packet filter. Check the syntax.");
- return 0;
- }
- if (pcap_setfilter(adhandle, &fcode)<0)//设置过滤器
- {
- AfxMessageBox("Error setting the filter.");
- return 0;
- }
- pcap_loop(adhandle, 0, packet_handler, NULL);
- return 0;
- }
- void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
- {
- struct tm *ltime;
- char timestr[16];
- ip_header *ih;
- udp_header *uh;
- tcp_header *th;
- icmp_header *ich;
- u_int ip_len;
- u_short totallen;
- myvector.push_back(pkt_data);//把收到的包放到一个向量myvector里面
- ltime=localtime(&header->ts.tv_sec);
- strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
- ih = (ip_header *) (pkt_data +14); //从包中解开IP头并将其赋给ih
- ip_len = (ih->ver_ihl & 0xf) * 4;
- totallen = ntohs(ih->tlen);
- totallen += 18;
- mycount.push_back(totallen);//将整个包的大小值放到一个向量mycount里面
- PACKET *pkt = new PACKET;
- strcpy(pkt->timestr, timestr);
- memcpy(&(pkt->IpHead), ih, sizeof(ip_header));
- if(int(ih->proto) == 17)
- {//如果是UDP包就从解开UDP头并将其赋给uh
- uh = (udp_header *) ((u_char*)ih + ip_len);
- memcpy(&(pkt->UdpHead), uh, sizeof(udp_header));
- }
- if(int(ih->proto) == 6)
- {//如果是TCP包就从解开TCP头并将其赋给th
- th = (tcp_header *)((u_char*)ih + ip_len);
- memcpy(&(pkt->TcpHead), th, sizeof(tcp_header));
- }
- if(int(ih->proto) == 1)
- {//如果是ICMP包就从解开ICMP头并将其赋给ich
- ich = (icmp_header *)((u_char*)ih + ip_len);
- memcpy(&(pkt->IcmpHead), ich, sizeof(icmp_header));
- }
- ::PostMessage(hWnd, WM_USER_THREAD_PACKET, (WPARAM) (pkt), 0);
- }
- void CMyCapView::OnClick(NMHDR* pNMHDR, LRESULT* pResult)
- {//如果选中CListView窗口中的某项,将这项的索引号赋给m_index
- CMyCapDoc* pDoc = GetDocument();
- DWORD dwPos = ::GetMessagePos();
- CPoint point((int) LOWORD(dwPos), (int) HIWORD(dwPos));
- GetListCtrl().ScreenToClient(&point);
- int m_index;
- if((m_index = GetListCtrl().HitTest(point)) !=-1)
- m_flag = m_index;
- pDoc->SetCount(m_index);
- *pResult = 0;
- }
- void CMyCapView::OnFileSave()
- {
- int num = 0;
- UINT count = 0;
- count = myvector.size();
- CFileDialog dlg(FALSE, "txt", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "*.txt");
- //实例化一个CFileDialog类对象
- if(dlg.DoModal() == IDOK)
- {
- CFile myfile;
- CString name = dlg.GetFileName();
- myfile.Open(name, CFile::modeCreate | CFile::modeReadWrite);//打开文件
- for (int i = 0; i < count; i++)
- {
- num = mycount[i];
- myfile.Write(myvector[i], num);//将包的内容写入文件
- }
- myfile.Close();
- }
- }
- void CMyCapView::OnOptionFilter()
- {
- packetfilter filterDlg;
- filterDlg.DoModal();
- if(filterDlg.m_tcp == FALSE && filterDlg.m_udp == TRUE)
- packet_filter = "ip and udp";//如果选择抓UDP包,将过滤器字段设置成“ip and udp”,即抓UDP包
- if(filterDlg.m_tcp == TRUE && filterDlg.m_udp == FALSE)
- packet_filter = "ip and tcp";
- if(filterDlg.m_tcp == TRUE && filterDlg.m_udp == TRUE)
- packet_filter = "ip";
- if(filterDlg.m_icmp == TRUE)
- packet_filter = "icmp";
- }