网卡混杂模式
2016-04-10 10:58
561 查看
前言
使用原始套接字, 练习网卡混杂模式, 封装了一个UI.取到IP数据, 用IP头, TCP头, UDP头,ICMP头按照定义进行了读取和显示.
可以分别监听TCP,UDP,ICMP数据
数据得到后,不能显示的太猛了,否则UI挂掉。
让UI定时检测显示数据,而不是来了数据就立即显示。
从混杂模式取数据的速度快于显示速度,如果用UpdateAllViews来调用OnUpdate, UI挂掉了.
工程下载点
编译环境: win7x64 + vc6sp6 + PSDK补丁srcNetDataViewer_2016_0412_0031.zip
代码预览
// MainDoc.h : interface of the CMainDoc class // ///////////////////////////////////////////////////////////////////////////// #if !defined(AFX_MAINDOC_H__E5B7BA53_5BC1_42BF_85B1_F0022F06D5E9__INCLUDED_) #define AFX_MAINDOC_H__E5B7BA53_5BC1_42BF_85B1_F0022F06D5E9__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "LsCriticalSection.h" #include "MyThread.h" #include "ListRowData.h" #include "net_data_header.h" #include <list> using namespace std; #define WM_MY_UPDATE_VIEW WM_APP + 1000 class CMainDoc : public CDocument { protected: // create from serialization only CMainDoc(); DECLARE_DYNCREATE(CMainDoc) // Attributes public: // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMainDoc) public: virtual BOOL OnNewDocument(); virtual void Serialize(CArchive& ar); //}}AFX_VIRTUAL // Implementation public: virtual ~CMainDoc(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif protected: // Generated message map functions protected: //{{AFX_MSG(CMainDoc) afx_msg void OnListenBegin(); afx_msg void OnListenEnd(); afx_msg void OnUpdateListenBegin(CCmdUI* pCmdUI); afx_msg void OnUpdateListenEnd(CCmdUI* pCmdUI); afx_msg void OnListenTcp(); afx_msg void OnUpdateListenTcp(CCmdUI* pCmdUI); afx_msg void OnListenUdp(); afx_msg void OnUpdateListenUdp(CCmdUI* pCmdUI); afx_msg void OnListenIcmp(); afx_msg void OnUpdateListenIcmp(CCmdUI* pCmdUI); //}}AFX_MSG DECLARE_MESSAGE_MAP() public: void ShowErrMsg(int iErrSn); void ShowSocketErrMsg(); void ShowErrMsg(); void ShowThreadMsg(TCHAR* pMsg, eImageIndex ImageIndex); void ShowThreadMsgRowData(CListRowData* pRowData); void ClearThreadMsg(); void LockMsg(); void UnLockMsg(); list<CListRowData>& GetListRowData(); BOOL IsThreadRunning(); void StartListenThread(); void StopListenThread(); static unsigned __stdcall ThreadProcNetDataListen(void* pParam); unsigned ThreadProcNetDataListen(); BOOL fnNetworkProtocolAnalysis(BYTE* pBuf, int iLenRecv); ///< 网络协议分析 BOOL fnNetworkProtocolAnalysis_TCP(int iLenRecv, CListRowData* pRowData, IPHDR* pIpHeader, BYTE* pBuf, int iLenBuf); ///< 网络协议分析-TCP BOOL fnNetworkProtocolAnalysis_UDP(int iLenRecv, CListRowData* pRowData, IPHDR* pIpHeader, BYTE* pBuf, int iLenBuf); ///< 网络协议分析-UDP BOOL fnNetworkProtocolAnalysis_ICMP(int iLenRecv, CListRowData* pRowData, IPHDR* pIpHeader, BYTE* pBuf, int iLenBuf); ///< 网络协议分析-ICMP BOOL fnNetworkProtocolAnalysis_AddData(int iLenRecv, CListRowData* pRowData, BYTE* pBuf, int iLenBuf); ///< 网络协议分析-加入现实数据 void SetListenOptTCP(BOOL bParam); BOOL GetListenOptTCP(); void SetListenOptUDP(BOOL bParam); BOOL GetListenOptUDP(); void SetListenOptICMP(BOOL bParam); BOOL GetListenOptICMP(); private: void DataInit(); void DataUnInit(); unsigned fnThreadProcNetDataListen(CMyThread& Thread); private: list<CListRowData> m_ListRowData; CLsCriticalSection g_csDispMsg; CMyThread m_ThreadNetDataListen; ///< 监听网络数据的线程 BOOL m_bListernTCP; ///< 是否监听TCP BOOL m_bListernUDP; ///< 是否监听UDP BOOL m_bListernICMP; ///< 是否监听ICMP }; ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_MAINDOC_H__E5B7BA53_5BC1_42BF_85B1_F0022F06D5E9__INCLUDED_)
// MainDoc.cpp : implementation of the CMainDoc class // #include "stdafx.h" #include <MSTcpIP.h> ///< for SIO_RCVALL #include "NetDataViewer.h" #include "net_data_header.h" #include "MainDoc.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CMainDoc IMPLEMENT_DYNCREATE(CMainDoc, CDocument) BEGIN_MESSAGE_MAP(CMainDoc, CDocument) //{{AFX_MSG_MAP(CMainDoc) ON_COMMAND(IDM_LISTEN_BEGIN, OnListenBegin) ON_COMMAND(IDM_LISTEN_END, OnListenEnd) ON_UPDATE_COMMAND_UI(IDM_LISTEN_BEGIN, OnUpdateListenBegin) ON_UPDATE_COMMAND_UI(IDM_LISTEN_END, OnUpdateListenEnd) ON_COMMAND(IDM_LISTEN_TCP, OnListenTcp) ON_UPDATE_COMMAND_UI(IDM_LISTEN_TCP, OnUpdateListenTcp) ON_COMMAND(IDM_LISTEN_UDP, OnListenUdp) ON_UPDATE_COMMAND_UI(IDM_LISTEN_UDP, OnUpdateListenUdp) ON_COMMAND(IDM_LISTEN_ICMP, OnListenIcmp) ON_UPDATE_COMMAND_UI(IDM_LISTEN_ICMP, OnUpdateListenIcmp) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMainDoc construction/destruction CMainDoc::CMainDoc() { // TODO: add one-time construction code here DataInit(); } CMainDoc::~CMainDoc() { DataUnInit(); } BOOL CMainDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; // TODO: add reinitialization code here // (SDI documents will reuse this document) return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CMainDoc serialization void CMainDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // TODO: add storing code here } else { // TODO: add loading code here } } ///////////////////////////////////////////////////////////////////////////// // CMainDoc diagnostics #ifdef _DEBUG void CMainDoc::AssertValid() const { CDocument::AssertValid(); } void CMainDoc::Dump(CDumpContext& dc) const { CDocument::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CMainDoc commands void CMainDoc::DataInit() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(2, 2); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ return; } /* Confirm that the WinSock DLL supports 2.2.*/ /* Note that if the DLL supports versions greater */ /* than 2.2 in addition to 2.2, it will still return */ /* 2.2 in wVersion since that is the version we */ /* requested. */ if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ WSACleanup(); return; } SetListenOptTCP(TRUE); SetListenOptUDP(TRUE); SetListenOptICMP(TRUE); } void CMainDoc::DataUnInit() { WSACleanup(); } void CMainDoc::ShowErrMsg(int iErrSn) { LPVOID lpMsgBuf = NULL; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, iErrSn, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL); if (NULL != lpMsgBuf) { ShowThreadMsg((LPTSTR)lpMsgBuf, eImageIndex_error); } LocalFree(lpMsgBuf); } void CMainDoc::LockMsg() { g_csDispMsg.Lock(); } void CMainDoc::UnLockMsg() { g_csDispMsg.UnLock(); } list<CListRowData>& CMainDoc::GetListRowData() { return m_ListRowData; } void CMainDoc::ShowThreadMsg(TCHAR* pMsg, eImageIndex ImageIndex) { CListRowData RowData; if (NULL != pMsg) { RowData.m_ImageIndex = ImageIndex; RowData.m_strDesc = pMsg; ShowThreadMsgRowData(&RowData); } } void CMainDoc::ShowThreadMsgRowData(CListRowData* pRowData) { CWnd* pMainWnd = NULL; if (NULL != pRowData) { LockMsg(); GetListRowData().push_back(*pRowData); UnLockMsg(); pMainWnd = AfxGetMainWnd(); if (NULL != pMainWnd) { pMainWnd->PostMessage(WM_MY_UPDATE_VIEW, 0, 0); } } } void CMainDoc::ShowSocketErrMsg() { int iErrSn = WSAGetLastError(); ShowErrMsg(iErrSn); } void CMainDoc::ShowErrMsg() { int iErrSn = GetLastError(); ShowErrMsg(iErrSn); } void CMainDoc::OnListenBegin() { StartListenThread(); } void CMainDoc::OnListenEnd() { StopListenThread(); } void CMainDoc::StartListenThread() { if (!IsThreadRunning()) { m_ThreadNetDataListen.SetParam( &CMainDoc::ThreadProcNetDataListen, NULL, NULL, this); m_ThreadNetDataListen.Start(); } } void CMainDoc::StopListenThread() { if (IsThreadRunning()) { m_ThreadNetDataListen.Stop(); } } void CMainDoc::OnUpdateListenBegin(CCmdUI* pCmdUI) { BOOL bThreadIsRunning = IsThreadRunning(); pCmdUI->Enable(!bThreadIsRunning); pCmdUI->SetCheck(bThreadIsRunning); } void CMainDoc::OnUpdateListenEnd(CCmdUI* pCmdUI) { BOOL bThreadIsRunning = IsThreadRunning(); pCmdUI->Enable(bThreadIsRunning); pCmdUI->SetCheck(!bThreadIsRunning); } BOOL CMainDoc::IsThreadRunning() { return m_ThreadNetDataListen.IsRunning(); } unsigned __stdcall CMainDoc::ThreadProcNetDataListen(void* pParam) { if (NULL == pParam) { return S_FALSE; } return ((CMainDoc*)pParam)->ThreadProcNetDataListen(); } unsigned CMainDoc::ThreadProcNetDataListen() { UINT uRc = S_FALSE; ShowThreadMsg(_T(">> 网络数据监听线程开始运行"), eImageIndex_information); uRc = fnThreadProcNetDataListen(m_ThreadNetDataListen); ShowThreadMsg(_T("<< 网络数据监听线程结束运行"), eImageIndex_information); return uRc; } unsigned CMainDoc::fnThreadProcNetDataListen(CMyThread& Thread) { SOCKET s = INVALID_SOCKET; sockaddr_in addr; int iRc = SOCKET_ERROR; ULONG ul = 0; char cBuf[MAXBYTE] = {'\0'}; struct hostent* pHost = NULL; BYTE cRecvBuf[0x2000] = {'\0'}; do { init_data_net_data_header(); s = socket(AF_INET, SOCK_RAW, IPPROTO_IP); if (INVALID_SOCKET == s) { ShowSocketErrMsg(); break; } iRc = gethostname(cBuf, sizeof(cBuf)); if (SOCKET_ERROR == iRc) { ShowSocketErrMsg(); break; } pHost = gethostbyname(cBuf); if (NULL == pHost) { ShowSocketErrMsg(); break; } addr.sin_family = AF_INET; addr.sin_port = htons(0); addr.sin_addr.s_addr = *((ULONG*)pHost->h_addr_list[0]); iRc = bind(s, (struct sockaddr*)&addr, sizeof(addr)); if (SOCKET_ERROR == iRc) { ShowSocketErrMsg(); break; } ul = 1; iRc = ioctlsocket(s, SIO_RCVALL, &ul); if (SOCKET_ERROR == iRc) { ShowSocketErrMsg(); break; } do { if (!Thread.cbIsCanContinue()) { continue; } if (Thread.cbIsNeedQuit()) { break; } iRc = recv(s, (char*)cRecvBuf, sizeof(cRecvBuf), 0); if (SOCKET_ERROR == iRc) { continue; } /// 分析 fnNetworkProtocolAnalysis(cRecvBuf, iRc); } while (1); } while (0); if (INVALID_SOCKET != s) { closesocket(s); } return S_OK; } BOOL CMainDoc::fnNetworkProtocolAnalysis(BYTE* pBuf, int iLenRecv) { int iLenIpHeader = 0; IPHDR* pIpHeader = NULL; BYTE* pBufNow = NULL; TAG_PROTOCOL_NAME protocolName; CListRowData RowData; if (NULL == pBuf) { return FALSE; } if (iLenRecv < sizeof(IPHDR)) { return FALSE; } pIpHeader = (IPHDR*)pBuf; /// IP头是变长的, 有可能不是20Bytes, 要根据pIpHeader->hlen去算 iLenIpHeader = sizeof(IPHDR); if (pIpHeader->h_len > 0) { iLenIpHeader = pIpHeader->h_len * 4; } if (iLenRecv < iLenIpHeader) { return FALSE; } pBufNow = (BYTE*)(pIpHeader) + iLenIpHeader; GetProtocolName(pIpHeader->Protocol, protocolName); RowData.m_strProtocol = protocolName.cName; RowData.m_strSrcIp = inet_ntoa(pIpHeader->iaSrc); RowData.m_strDstIp = inet_ntoa(pIpHeader->iaDst); RowData.m_strDataLen.Format("%u", ntohs(pIpHeader->TotLen)); switch (pIpHeader->Protocol) { case eProtocalIndex_TCP: if (GetListenOptTCP()) { fnNetworkProtocolAnalysis_TCP(iLenRecv, &RowData, pIpHeader, pBufNow, iLenRecv - iLenIpHeader); } break; case eProtocalIndex_UDP: if (GetListenOptUDP()) { fnNetworkProtocolAnalysis_UDP(iLenRecv, &RowData, pIpHeader, pBufNow, iLenRecv - iLenIpHeader); } break; case eProtocalIndex_ICMP: if (GetListenOptICMP()) { fnNetworkProtocolAnalysis_ICMP(iLenRecv, &RowData, pIpHeader, pBufNow, iLenRecv - iLenIpHeader); } break; default: break; } return TRUE; } BOOL CMainDoc::fnNetworkProtocolAnalysis_TCP(int iLenRecv, CListRowData* pRowData, IPHDR* pIpHeader, BYTE* pBuf, int iLenBuf) { TCP_HEADER* pTcpHeader = NULL; int iLenIpHeader = sizeof(IPHDR); int iLenTcpHeader = sizeof(TCP_HEADER); BYTE* pData = NULL; int iLenDat = 0; if ((NULL == pRowData) || (NULL == pIpHeader) || (NULL == pBuf) || (iLenBuf < iLenTcpHeader)) { return FALSE; } if (pIpHeader->h_len > 0) { iLenIpHeader = pIpHeader->h_len * 4; } pTcpHeader = (TCP_HEADER*)pBuf; if (pTcpHeader->nHLenAndFlag > 0) { iLenTcpHeader = ntohs(pTcpHeader->nHLenAndFlag); iLenTcpHeader = (iLenTcpHeader >> 12) & 0x0f; iLenTcpHeader *= 4; } pData = (BYTE*)pTcpHeader + iLenTcpHeader; iLenDat = iLenBuf - iLenTcpHeader; pRowData->m_strDataLen.Format("%d", iLenDat); pRowData->m_strSrcIp.Format("%s:%d", inet_ntoa(pIpHeader->iaSrc), pTcpHeader->nSourPort); pRowData->m_strDstIp.Format("%s:%d", inet_ntoa(pIpHeader->iaDst), pTcpHeader->nDestPort); if (pIpHeader->h_len > 0) { iLenIpHeader = pIpHeader->h_len * 4; } pRowData->m_strDesc.Format("[Recv:%u]" " - IP[TotLen:%u][Len:%u][IpV%d][ID:0x%X][TTL:%d][Checksum:0x%X]" " - TCP[Len:%u][seq:0x%X][ack:0x%X][窗口大小:0x%X][CheckSum:0x%X]", iLenRecv, ntohs(pIpHeader->TotLen), iLenIpHeader, pIpHeader->version, ntohs(pIpHeader->ID), pIpHeader->TTL, ntohs(pIpHeader->Checksum), iLenTcpHeader, ntohl(pTcpHeader->nSequNum), ntohl(pTcpHeader->nAcknowledgeNum), ntohs(pTcpHeader->nWindowSize), ntohs(pTcpHeader->nCheckSum)); fnNetworkProtocolAnalysis_AddData(iLenRecv, pRowData, pData, iLenDat); return TRUE; } BOOL CMainDoc::fnNetworkProtocolAnalysis_UDP(int iLenRecv, CListRowData* pRowData, IPHDR* pIpHeader, BYTE* pBuf, int iLenBuf) { UDP_HEADER* pUdpHeader = NULL; int iLenIpHeader = sizeof(IPHDR); int iLenUdpHeader = sizeof(UDP_HEADER); BYTE* pData = NULL; int iLenDat = 0; if ((NULL == pRowData) || (NULL == pIpHeader) || (NULL == pBuf) || (iLenBuf < iLenUdpHeader)) { return FALSE; } pUdpHeader = (UDP_HEADER*)pBuf; pData = (BYTE*)(pUdpHeader + 1); iLenDat = iLenBuf - iLenUdpHeader; pRowData->m_strDataLen.Format("%d", iLenDat); pRowData->m_strSrcIp.Format("%s:%d", inet_ntoa(pIpHeader->iaSrc), pUdpHeader->nSourPort); pRowData->m_strDstIp.Format("%s:%d", inet_ntoa(pIpHeader->iaDst), pUdpHeader->nDestPort); if (pIpHeader->h_len > 0) { iLenIpHeader = pIpHeader->h_len * 4; } pRowData->m_strDesc.Format("[Recv:%u]" " - IP[TotLen:%u][Len:%u][IpV%d][ID:0x%X][TTL:%d][Checksum:0x%X]" " - UDP[TotLen:%u][Len:%u][CheckSum:0x%X]", iLenRecv, ntohs(pIpHeader->TotLen), iLenIpHeader, pIpHeader->version, ntohs(pIpHeader->ID), pIpHeader->TTL, ntohs(pIpHeader->Checksum), ntohs(pUdpHeader->nLength), iLenUdpHeader, ntohs(pUdpHeader->nCheckSum)); fnNetworkProtocolAnalysis_AddData(iLenRecv, pRowData, pData, iLenDat); return TRUE; } BOOL CMainDoc::fnNetworkProtocolAnalysis_ICMP(int iLenRecv, CListRowData* pRowData, IPHDR* pIpHeader, BYTE* pBuf, int iLenBuf) { ICMPHDR* pIcmpHeader = NULL; int iLenIpHeader = sizeof(IPHDR); int iLenIcmpHeader = sizeof(ICMPHDR) - 1; ///< 不算柔性数组的开始字节 BYTE* pData = NULL; int iLenDat = 0; if ((NULL == pRowData) || (NULL == pIpHeader) || (NULL == pBuf) || (iLenBuf < iLenIcmpHeader)) { return FALSE; } pIcmpHeader = (ICMPHDR*)pBuf; pData = (BYTE*)(pIcmpHeader + 1) - 1; ///< 不算柔性数组的开始字节 iLenDat = iLenBuf - iLenIcmpHeader; pRowData->m_strDataLen.Format("%d", iLenDat); if (pIpHeader->h_len > 0) { iLenIpHeader = pIpHeader->h_len * 4; } pRowData->m_strDesc.Format("[Recv:%u]" " - IP[TotLen:%u][Len:%u][IpV%d][ID:0x%X][TTL:%d][Checksum:0x%X]" " - ICMP[Len:%u][Type:%u][Code:%u][CheckSum:0x%X]", iLenRecv, ntohs(pIpHeader->TotLen), iLenIpHeader, pIpHeader->version, ntohs(pIpHeader->ID), pIpHeader->TTL, ntohs(pIpHeader->Checksum), iLenIcmpHeader, pIcmpHeader->Type, pIcmpHeader->Code, ntohs(pIcmpHeader->Checksum)); fnNetworkProtocolAnalysis_AddData(iLenRecv, pRowData, pData, iLenDat); return TRUE; } BOOL CMainDoc::fnNetworkProtocolAnalysis_AddData(int iLenRecv, CListRowData* pRowData, BYTE* pBuf, int iLenBuf) { BOOL bFirstAddMsg = TRUE; int i = 0; /// ListView中的ListCtrl, 一列现实不了那么多, 就(80~90)*3那么多Ascii字符 const int iMaxShowBytes = 16; int iProcessCnt = 0; CString str; if ((NULL == pRowData) || (NULL == pBuf) || (iLenBuf < 0)) { return FALSE; } pRowData->m_strDataContent.Empty(); for (i = 0; i < iLenBuf; i++) { str.Format(_T("%02X "), pBuf[i]); pRowData->m_strDataContent += (LPTSTR)(LPCTSTR)str; if (iProcessCnt < (iMaxShowBytes - 1)) { iProcessCnt++; } else { if (bFirstAddMsg) { bFirstAddMsg = FALSE; pRowData->m_ImageIndex = eImageIndex_information; } else { pRowData->m_ImageIndex = eImageIndex_null; } ShowThreadMsgRowData(pRowData); pRowData->Clear(); iProcessCnt = 0; } } if (iProcessCnt > 0) { if (bFirstAddMsg) { bFirstAddMsg = FALSE; pRowData->m_ImageIndex = eImageIndex_information; } else { pRowData->m_ImageIndex = eImageIndex_null; } ShowThreadMsgRowData(pRowData); pRowData->Clear(); } return TRUE; } void CMainDoc::OnListenTcp() { SetListenOptTCP(!GetListenOptTCP()); } void CMainDoc::OnUpdateListenTcp(CCmdUI* pCmdUI) { pCmdUI->SetCheck(GetListenOptTCP()); } void CMainDoc::OnListenUdp() { SetListenOptUDP(!GetListenOptUDP()); } void CMainDoc::OnUpdateListenUdp(CCmdUI* pCmdUI) { pCmdUI->SetCheck(GetListenOptUDP()); } void CMainDoc::OnListenIcmp() { SetListenOptICMP(!GetListenOptICMP()); } void CMainDoc::OnUpdateListenIcmp(CCmdUI* pCmdUI) { pCmdUI->SetCheck(GetListenOptICMP()); } void CMainDoc::SetListenOptTCP(BOOL bParam) { m_bListernTCP = bParam; } BOOL CMainDoc::GetListenOptTCP() { return m_bListernTCP; } void CMainDoc::SetListenOptUDP(BOOL bParam) { m_bListernUDP = bParam; } BOOL CMainDoc::GetListenOptUDP() { return m_bListernUDP; } void CMainDoc::SetListenOptICMP(BOOL bParam) { m_bListernICMP = bParam; } BOOL CMainDoc::GetListenOptICMP() { return m_bListernICMP; }
// MainView.h : interface of the CMainView class // ///////////////////////////////////////////////////////////////////////////// #if !defined(AFX_MAINVIEW_H__A45AF28F_5CC6_43A0_912C_90AF75F7CA75__INCLUDED_) #define AFX_MAINVIEW_H__A45AF28F_5CC6_43A0_912C_90AF75F7CA75__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "ListRowData.h" class CMainView : public CListView { protected: // create from serialization only CMainView(); DECLARE_DYNCREATE(CMainView) // Attributes public: CMainDoc* GetDocument(); // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMainView) public: virtual void OnDraw(CDC* pDC); // overridden to draw this view virtual BOOL PreCreateWindow(CREATESTRUCT& cs); protected: virtual void OnInitialUpdate(); // called first time after construct virtual BOOL OnPreparePrinting(CPrintInfo* pInfo); virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo); virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo); virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint); //}}AFX_VIRTUAL // Implementation public: virtual ~CMainView(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif protected: // Generated message map functions protected: //{{AFX_MSG(CMainView) afx_msg void OnRclick(NMHDR* pNMHDR, LRESULT* pResult); afx_msg void OnRButtonDown(UINT nFlags, CPoint point); afx_msg void OnListenContentClear(); afx_msg void OnTimer(UINT nIDEvent); afx_msg void OnDestroy(); //}}AFX_MSG DECLARE_MESSAGE_MAP() public: void ShowUiMsg(TCHAR* pcMsg); void ShowUiMsg(CListRowData* pRowData); private: void AddRowToUI(CListRowData* pListRowData); void AdjustColWidth(); void MyUpdateUI(); private: CImageList m_ImageList; ///< 图像列表, 用于调整行高 BOOL m_bListViewInitOk; ///< 视图是否已经初始化过? }; #ifndef _DEBUG // debug version in MainView.cpp inline CMainDoc* CMainView::GetDocument() { return (CMainDoc*)m_pDocument; } #endif ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_MAINVIEW_H__A45AF28F_5CC6_43A0_912C_90AF75F7CA75__INCLUDED_)
// MainView.cpp : implementation of the CMainView class // #include "stdafx.h" #include "NetDataViewer.h" #include "MainDoc.h" #include "MainView.h" #include "ListRowData.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define TIMER_EVENT_SN_ON_UPDATE 1 #define TIMER_DELAY_ON_UPDATE 500 ///////////////////////////////////////////////////////////////////////////// // CMainView IMPLEMENT_DYNCREATE(CMainView, CListView) BEGIN_MESSAGE_MAP(CMainView, CListView) //{{AFX_MSG_MAP(CMainView) ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick) ON_WM_RBUTTONDOWN() ON_COMMAND(IDM_LISTEN_CONTENT_CLEAR, OnListenContentClear) ON_WM_TIMER() ON_WM_DESTROY() //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CListView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CListView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CListView::OnFilePrintPreview) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMainView construction/destruction CMainView::CMainView() { m_bListViewInitOk = FALSE; } CMainView::~CMainView() { } BOOL CMainView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs return CListView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CMainView drawing void CMainView::OnDraw(CDC* pDC) { CMainDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here } void CMainView::AdjustColWidth() { int i = 0; int iArySize = sizeof(g_ListColumnName) / sizeof(g_ListColumnName[0]); CListCtrl& theCtrl = GetListCtrl(); for (i = 0; i < iArySize; i++) { theCtrl.SetColumnWidth(i, LVSCW_AUTOSIZE_USEHEADER); } } void CMainView::OnInitialUpdate() { DWORD dwStyleEx = LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES /*| LVS_EX_FLATSB*/; int i = 0; int iArySize = sizeof(g_ListColumnName) / sizeof(g_ListColumnName[0]); LVCOLUMN col; CListView::OnInitialUpdate(); CListCtrl& theCtrl = GetListCtrl(); m_ImageList.Create(16, 16, ILC_MASK | ILC_COLOR32, 0, 1); ///< 可以依靠图像size来调整行高 m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_IMAGE_NULL)); m_ImageList.Add(::LoadIcon(NULL, IDI_INFORMATION)); m_ImageList.Add(::LoadIcon(NULL, IDI_WARNING)); m_ImageList.Add(::LoadIcon(NULL, IDI_ERROR)); ASSERT(theCtrl.GetImageList(LVSIL_SMALL) == NULL); theCtrl.SetImageList(&m_ImageList, LVSIL_SMALL); ASSERT(theCtrl.GetImageList(LVSIL_SMALL) == &m_ImageList); // TODO: You may populate your ListView with items by directly accessing // its list control through a call to GetListCtrl(). // this code only works for a report-mode list view ModifyStyle(0, LVS_REPORT, 0); ASSERT(GetStyle() & LVS_REPORT); CListView::OnInitialUpdate(); // Gain a reference to the list control itself theCtrl.SetExtendedStyle (theCtrl.GetExtendedStyle() | dwStyleEx); for (i = 0; i < iArySize; i++) { col.mask = LVCF_FMT | LVCF_TEXT; col.pszText = (char*)g_ListColumnName[i]; col.fmt = LVCFMT_LEFT; theCtrl.InsertColumn(i, &col); theCtrl.SetColumnWidth(i, LVSCW_AUTOSIZE_USEHEADER); } /// 设置题头的自动列宽,要在列插入完成后,再设置 AdjustColWidth(); m_bListViewInitOk = TRUE; GetDocument()->ShowThreadMsg(_T("请执行网络包的检测[可以选择主菜单, 工具条, 右键菜单]"), eImageIndex_information); SetTimer(TIMER_EVENT_SN_ON_UPDATE, TIMER_DELAY_ON_UPDATE, NULL); } ///////////////////////////////////////////////////////////////////////////// // CMainView printing BOOL CMainView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CMainView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CMainView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } ///////////////////////////////////////////////////////////////////////////// // CMainView diagnostics #ifdef _DEBUG void CMainView::AssertValid() const { CListView::AssertValid(); } void CMainView::Dump(CDumpContext& dc) const { CListView::Dump(dc); } CMainDoc* CMainView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMainDoc))); return (CMainDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CMainView message handlers void CMainView::ShowUiMsg(TCHAR* pcMsg) { int iRc = 0; CListRowData RowData; if (NULL != pcMsg) { RowData.m_strDesc = pcMsg; AddRowToUI(&RowData); } } void CMainView::ShowUiMsg(CListRowData* pRowData) { if (NULL != pRowData) { AddRowToUI(pRowData); } } void CMainView::AddRowToUI(CListRowData* pListRowData) { int i = 0; int iArySize = sizeof(g_ListColumnName) / sizeof(g_ListColumnName[0]); CListCtrl& theCtrl = GetListCtrl(); int iRowCnt = theCtrl.GetItemCount(); LVITEM lvitem; int iColIndex = 0; if (NULL != pListRowData) { lvitem.mask = LVIF_TEXT | LVIF_IMAGE; lvitem.iImage = pListRowData->m_ImageIndex; lvitem.iItem = iRowCnt; lvitem.iSubItem = iColIndex++; lvitem.pszText = _T(""); theCtrl.InsertItem(&lvitem); theCtrl.SetItemText(iRowCnt, iColIndex++, (LPTSTR)(LPCTSTR)pListRowData->m_strProtocol); theCtrl.SetItemText(iRowCnt, iColIndex++, (LPTSTR)(LPCTSTR)pListRowData->m_strSrcIp); theCtrl.SetItemText(iRowCnt, iColIndex++, (LPTSTR)(LPCTSTR)pListRowData->m_strDstIp); theCtrl.SetItemText(iRowCnt, iColIndex++, (LPTSTR)(LPCTSTR)pListRowData->m_strDesc); theCtrl.SetItemText(iRowCnt, iColIndex++, (LPTSTR)(LPCTSTR)pListRowData->m_strDataLen); theCtrl.SetItemText(iRowCnt, iColIndex++, (LPTSTR)(LPCTSTR)pListRowData->m_strDataContent); } } void CMainView::OnListenContentClear() { CListCtrl& theCtrl = GetListCtrl(); GetDocument()->LockMsg(); theCtrl.DeleteAllItems(); if (!GetDocument()->GetListRowData().empty()) { GetDocument()->GetListRowData().clear(); } GetDocument()->UnLockMsg(); } void CMainView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { MyUpdateUI(); } void CMainView::MyUpdateUI() { CString str; CListRowData RowData; BOOL bHaveData = FALSE; /// 防止UI显示数据太猛挂掉 int iCntWasDisplay = 0; ///< 在这个更新显示中,已经显示了多少条数据 const int iCntWasDisplayMax = 60; ///< 最多显示多少条就跳出,等待下一次来显示 if (m_bListViewInitOk) { do { bHaveData = FALSE; /// 不能阻塞那么长时间, 只拿一条数据,就让出临界区 GetDocument()->LockMsg(); if (!GetDocument()->GetListRowData().empty()) { bHaveData = TRUE; RowData = GetDocument()->GetListRowData().front(); GetDocument()->GetListRowData().pop_front(); } GetDocument()->UnLockMsg(); if (bHaveData) { ShowUiMsg(&RowData); iCntWasDisplay++; } } while (bHaveData && (iCntWasDisplay < iCntWasDisplayMax)); /// 将所有数据都取光,再一次性调整列宽为自动, 防止数据多了,UI挂掉 AdjustColWidth(); } } void CMainView::OnRclick(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here *pResult = 0; } void CMainView::OnRButtonDown(UINT nFlags, CPoint point) { CMenu menu; CMenu* pSubMenu = NULL; BOOL bThreadIsRunning = GetDocument()->IsThreadRunning(); CListView::OnRButtonDown(nFlags, point); ClientToScreen(&point); menu.LoadMenu(MAKEINTRESOURCE(IDR_MENU_LIST_VIEW)); pSubMenu = menu.GetSubMenu(0); pSubMenu->CheckMenuItem(IDM_LISTEN_BEGIN, bThreadIsRunning ? MF_CHECKED : MF_UNCHECKED); pSubMenu->EnableMenuItem(IDM_LISTEN_BEGIN, bThreadIsRunning ? (MF_DISABLED | MF_GRAYED) : MF_ENABLED); pSubMenu->CheckMenuItem(IDM_LISTEN_END, !bThreadIsRunning ? MF_CHECKED : MF_UNCHECKED); pSubMenu->EnableMenuItem(IDM_LISTEN_END, !bThreadIsRunning ? (MF_DISABLED | MF_GRAYED) : MF_ENABLED); pSubMenu->CheckMenuItem(IDM_LISTEN_TCP, GetDocument()->GetListenOptTCP() ? MF_CHECKED : MF_UNCHECKED); pSubMenu->CheckMenuItem(IDM_LISTEN_UDP, GetDocument()->GetListenOptUDP() ? MF_CHECKED : MF_UNCHECKED); pSubMenu->CheckMenuItem(IDM_LISTEN_ICMP, GetDocument()->GetListenOptICMP() ? MF_CHECKED : MF_UNCHECKED); pSubMenu->TrackPopupMenu( TPM_LEFTALIGN |TPM_RIGHTBUTTON, point.x, point.y, this); } void CMainView::OnTimer(UINT nIDEvent) { CListView::OnTimer(nIDEvent); if (TIMER_EVENT_SN_ON_UPDATE == nIDEvent) { /// 靠pDoc->UpdateAllViews来刷UI太猛了,UI挂掉了 /// 为啥只来一次? KillTimer(TIMER_EVENT_SN_ON_UPDATE); MyUpdateUI(); SetTimer(TIMER_EVENT_SN_ON_UPDATE, TIMER_DELAY_ON_UPDATE, NULL); } } void CMainView::OnDestroy() { CListView::OnDestroy(); // TODO: Add your message handler code here KillTimer(TIMER_EVENT_SN_ON_UPDATE); }
网络包头结构定义
/// @file net_data_header.h /// @brief 网络通讯的包头数据结构的定义 /// http://blog.csdn.net/ithomer/article/details/5662383 这个资料有全面网络包结构定义 #ifndef __NET_DATA_HEADER_H_2016_0409__ #define __NET_DATA_HEADER_H_2016_0409__ #pragma pack(push) #pragma pack(1) #define ICMP_ECHOREPLY 0 #define ICMP_HOST_NOTEXIST 3 ///< 主机不存在 #define ICMP_ECHOREQ 8 // https://en.wikipedia.org/wiki/List_of_IP_protocol_numbers enum eProtocalIndex { eProtocalIndex_Reserved = 0xff, eProtocalIndex_ICMP = 1, eProtocalIndex_TCP = 6, eProtocalIndex_UDP = 17, }; // IP Header -- RFC 791 // https://en.wikipedia.org/wiki/List_of_IP_protocol_numbers typedef struct _tag_Protocol_name { BYTE ucProtocol; char cName[MAX_PATH]; }TAG_PROTOCOL_NAME; void init_data_net_data_header(); BOOL GetProtocolName(IN BYTE cProtocol, OUT TAG_PROTOCOL_NAME& info); typedef struct tagIPHDR { // u_char VIHL; // Version and IHL u_char h_len:4; // length of header u_char version:4; // Version of IP u_char TOS; // Type Of Service short TotLen; // Total Length short ID; // Identification short FlagOff; // Flags and Fragment Offset u_char TTL; // Time To Live u_char Protocol; // Protocol(tcp, udp, etc.) u_short Checksum; // Checksum struct in_addr iaSrc; // Internet Address - Source struct in_addr iaDst; // Internet Address - Destination }IPHDR, *PIPHDR; typedef struct _UDP_HEADER { USHORT nSourPort ; // 源端口号16bit USHORT nDestPort ; // 目的端口号16bit USHORT nLength ; // 数据包长度16bit USHORT nCheckSum ; // 校验和16bit }UDP_HEADER, *PUDP_HEADER; typedef struct _TCP_HEADER { USHORT nSourPort; // 源端口号16bit USHORT nDestPort; // 目的端口号16bit UINT nSequNum; // 序列号32bit UINT nAcknowledgeNum; // 确认号32bit USHORT nHLenAndFlag; // (前4位:TCP头长度;中6位:保留;后6位:标志位)共16bit /** 这样将位域分开也不行, 还是得对nHLenAndFlag移位 BYTE nTcpFlag1:4; BYTE nTcpFlag2:2; BYTE nTcpUnused1:2; BYTE nTcpUnused2:4; BYTE nTcpLen:4; */ USHORT nWindowSize; // 窗口大小16bit USHORT nCheckSum; // 检验和16bit USHORT nrgentPointer; // 紧急数据偏移量16bit }TCP_HEADER, *PTCP_HEADER; // ICMP Header - RFC 792 typedef struct tagICMPHDR { u_char Type; // Type u_char Code; // Code u_short Checksum; // Checksum /// http://network.51cto.com/art/201007/211240_all.htm BYTE icmp_data[1]; }ICMPHDR, *PICMPHDR; #define REQ_DATASIZE 32 // Echo Request Data size // ICMP Echo Request typedef struct tagECHOREQUEST { ICMPHDR icmpHdr; // DWORD dwTime; char cData[REQ_DATASIZE]; }ECHOREQUEST, *PECHOREQUEST; // ICMP Echo Reply typedef struct tagECHOREPLY { IPHDR ipHdr; ECHOREQUEST echoRequest; char cFiller[256]; }ECHOREPLY, *PECHOREPLY; #pragma pack(pop) #endif // #ifndef __NET_DATA_HEADER_H_2016_0409__
相关文章推荐
- php输出echo、print、print_r、printf、sprintf、var_dump比较
- MaterialDesign之NavigationView和DrawerLayout实现侧滑菜单栏
- 递归和闭包的理解
- opencl:C++11下使用别名(x,y,z,hi,lo...)访问vector类型(cl_int2,cl_long16...)的元素
- 响应式布局设计指南和教程(1)--响应式时代的设计历程
- countif
- Distinct powers
- 190. Reverse Bits
- Qt编写信息管理系统(2)
- Java集合框架之Map--Hashtable源码分析
- pycharm快捷键及一些常用设置
- 【推荐】可查找下载和上传动漫外挂字幕网站
- HDU 4611 Balls Rearrangement 数学
- 选项卡切换
- Codeforces--658A--Bear and Reverse Radewoosh(模拟)
- shell 之 for 循环
- iOS Md5编码
- 怎样加入cocostudio生成的UI到项目
- Java学习系列——HTTP协议
- 指针与数组