SnifferDlg.cpp
资源名称:MSSniffer.zip [点击查看]
上传用户:benyan892
上传日期:2010-01-28
资源大小:158k
文件大小:17k
源码类别:
网络截获/分析
开发平台:
Visual C++
- // SnifferDlg.cpp : implementation file
- //
- #include "stdafx.h"
- #include "Sniffer.h"
- #include "SnifferDlg.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #endif
- inline CString GetNiceString(LPCTSTR pString)
- {
- const int numDots = 40 - _tcslen(pString);
- CString dotString(_T('.'),numDots);
- CString s = CString(pString) + dotString + CString(_T(" "));
- return s;
- }
- // CAboutDlg dialog used for App About
- class CAboutDlg : public CDialog
- {
- public:
- CAboutDlg();
- // Dialog Data
- enum { IDD = IDD_ABOUTBOX };
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- // Implementation
- protected:
- DECLARE_MESSAGE_MAP()
- };
- CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
- {
- }
- void CAboutDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- }
- BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
- END_MESSAGE_MAP()
- // CSnifferDlg dialog
- CSnifferDlg::CSnifferDlg(CWnd* pParent /*=NULL*/)
- : CDialog(CSnifferDlg::IDD, pParent)
- , m_SelInterface(_T(""))
- {
- m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
- Init();
- }
- void CSnifferDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- DDX_Control(pDX, IDC_CMB_INTERFACES, m_CmbInterfaces);
- DDX_Control(pDX, IDC_FRM_INTERFACES, m_FrmInterfaces);
- DDX_Control(pDX, IDC_STARTSNIFFING, m_BtnStartSniffing);
- DDX_Control(pDX, IDC_TV_PACKETS, m_TVPackets);
- }
- BEGIN_MESSAGE_MAP(CSnifferDlg, CDialog)
- ON_WM_SYSCOMMAND()
- ON_WM_PAINT()
- ON_WM_QUERYDRAGICON()
- //}}AFX_MSG_MAP
- ON_WM_SIZE()
- ON_BN_CLICKED(IDC_STARTSNIFFING, OnBnClickedStartsniffing)
- ON_WM_CLOSE()
- END_MESSAGE_MAP()
- // CSnifferDlg message handlers
- BOOL CSnifferDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- // Add "About..." menu item to system menu.
- // IDM_ABOUTBOX must be in the system command range.
- ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
- ASSERT(IDM_ABOUTBOX < 0xF000);
- CMenu* pSysMenu = GetSystemMenu(FALSE);
- if (pSysMenu != NULL)
- {
- CString strAboutMenu;
- strAboutMenu.LoadString(IDS_ABOUTBOX);
- if (!strAboutMenu.IsEmpty())
- {
- pSysMenu->AppendMenu(MF_SEPARATOR);
- pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
- }
- }
- // Set the icon for this dialog. The framework does this automatically
- // when the application's main window is not a dialog
- SetIcon(m_hIcon, TRUE); // Set big icon
- SetIcon(m_hIcon, FALSE); // Set small icon
- // TODO: Add extra initialization here
- for ( int i = 0 ; i < m_Interfaces.GetSize(); i ++ )
- {
- m_CmbInterfaces.AddString( m_Interfaces.GetAt(i) );
- }
- m_CmbInterfaces.SetCurSel( 0 );
- m_IL.Create(16,16,ILC_COLOR32 | ILC_MASK, 0,1);
- m_IL.Add( LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_COMP2COMP ) ) );
- m_IL.Add( LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_IPHeader ) ) );
- m_IL.Add( LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_TCPHEADER ) ) );
- m_TVPackets.SetImageList( &m_IL,TVSIL_NORMAL );
- // ShowWindow( SW_SHOWMAXIMIZED );
- ResizeForm();
- LOGFONT logFont;
- CFont* pFont = new CFont();
- RtlZeroMemory( &logFont, sizeof(logFont) );
- _tcscpy(logFont.lfFaceName, _T("Lucida Console"));
- logFont.lfHeight = 12;
- pFont->CreateFontIndirect( &logFont );
- m_TVPackets.SetFont( pFont, TRUE );
- return TRUE; // return TRUE unless you set the focus to a control
- }
- void CSnifferDlg::OnSysCommand(UINT nID, LPARAM lParam)
- {
- if ((nID & 0xFFF0) == IDM_ABOUTBOX)
- {
- CAboutDlg dlgAbout;
- dlgAbout.DoModal();
- }
- else
- {
- CDialog::OnSysCommand(nID, lParam);
- }
- }
- // If you add a minimize button to your dialog, you will need the code below
- // to draw the icon. For MFC applications using the document/view model,
- // this is automatically done for you by the framework.
- void CSnifferDlg::OnPaint()
- {
- if (IsIconic())
- {
- CPaintDC dc(this); // device context for painting
- SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
- // Center icon in client rectangle
- int cxIcon = GetSystemMetrics(SM_CXICON);
- int cyIcon = GetSystemMetrics(SM_CYICON);
- CRect rect;
- GetClientRect(&rect);
- int x = (rect.Width() - cxIcon + 1) / 2;
- int y = (rect.Height() - cyIcon + 1) / 2;
- // Draw the icon
- dc.DrawIcon(x, y, m_hIcon);
- }
- else
- {
- CDialog::OnPaint();
- }
- }
- // The system calls this function to obtain the cursor to display while the user drags
- // the minimized window.
- HCURSOR CSnifferDlg::OnQueryDragIcon()
- {
- return static_cast<HCURSOR>(m_hIcon);
- }
- // Starts the sniffing process
- bool CSnifferDlg::StartSniffing(void)
- {
- SOCKET s = INVALID_SOCKET;
- WSABUF wbuf = {0};
- DWORD dwBytesRet = 0, dwFlags = 0;
- unsigned int optval = 0;
- char *rcvbuf=NULL;
- int rc = 0, err;
- if ( m_ulFilterMask & (FILTER_MASK_SOURCE_ADDRESS | FILTER_MASK_SOURCE_PORT) )
- {
- printf("Source address filter : ");
- //PrintAddress((SOCKADDR *)&m_saSourceAddress, sizeof(m_saSourceAddress));
- printf("n");
- }
- if ( m_ulFilterMask & (FILTER_MASK_DESTINATION_ADDRESS | FILTER_MASK_DESTINATION_PORT) )
- {
- printf("Destination address filter: ");
- //PrintAddress((SOCKADDR *)&g_saDestinationAddress, sizeof(g_saDestinationAddress));
- printf("n");
- }
- //
- // Create a raw socket for receiving IP datagrams
- //
- s = WSASocket(AF_INET, SOCK_RAW, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);
- if (s == INVALID_SOCKET)
- {
- printf("WSASocket() failed: %dn", WSAGetLastError());
- return false;
- }
- //
- // This socket MUST be bound before calling the ioctl
- //
- sockaddr_in sa;
- sa.sin_family = AF_INET;
- sa.sin_addr.s_addr = inet_addr(m_SelInterface);
- sa.sin_port = INADDR_ANY;//htons(7000);
- rc = bind(s, (SOCKADDR *)&sa, sizeof(sa));
- if (rc == SOCKET_ERROR)
- {
- printf("bind() failed: %dn", WSAGetLastError());
- if (INVALID_SOCKET != s)
- {
- closesocket(s);
- s = INVALID_SOCKET;
- }
- WSACleanup();
- return false;
- }
- printf("Binding to: ");
- //PrintAddress((SOCKADDR *)&g_saLocalInterface, sizeof(g_saLocalInterface));
- printf("n");
- //
- // Set the SIO_RCVALLxxx ioctl
- //
- optval = 1;
- rc = WSAIoctl(s, SIO_RCVALL, &optval, sizeof(optval),
- NULL, 0, &dwBytesRet, NULL, NULL);
- if (rc == SOCKET_ERROR)
- {
- printf("WSAIotcl(0x%x) failed: %dn", SIO_RCVALL,
- (err = WSAGetLastError()));
- if (err == WSAEINVAL)
- {
- printf("NOTE: IPv6 does not currently support the SIO_RCVALL* ioctlsn");
- }
- if (INVALID_SOCKET != s)
- {
- closesocket(s);
- s = INVALID_SOCKET;
- }
- WSACleanup();
- return false;
- }
- //
- // Allocate a buffer for receiving data
- //
- rcvbuf = (char *)HeapAlloc(GetProcessHeap(), 0, MAX_IP_SIZE);
- if (rcvbuf == NULL)
- {
- fprintf(stderr, "HeapAlloc failed: %dn", GetLastError());
- if (INVALID_SOCKET != s)
- {
- closesocket(s);
- s = INVALID_SOCKET;
- }
- WSACleanup();
- return false;
- }
- //
- // Start receiving IP datagrams until interrupted
- //
- while ( !m_bExit )
- {
- wbuf.len = MAX_IP_SIZE;
- wbuf.buf = rcvbuf;
- dwFlags = 0;
- rc = WSARecv(s, &wbuf, 1, &dwBytesRet, &dwFlags, NULL, NULL);
- if (rc == SOCKET_ERROR)
- {
- printf("WSARecv() failed: %dn", WSAGetLastError());
- break;
- }
- DecodePacket(rcvbuf , dwBytesRet );
- }
- //
- // Cleanup
- //
- if (rcvbuf)
- HeapFree(GetProcessHeap(), 0, rcvbuf);
- if (INVALID_SOCKET != s)
- {
- closesocket(s);
- s = INVALID_SOCKET;
- }
- WSACleanup();
- return true;
- }
- bool CSnifferDlg::Init(void)
- {
- try
- {
- m_bExit = false;
- m_hThread = NULL;
- m_dwThreadID = 0;
- m_ulFilterMask = 0;
- m_Logger.Open( _T("Logger.txt"),CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone);
- int rc = 0;
- WSADATA wsd;
- //
- // Load Winsock
- //
- if ((rc = WSAStartup(MAKEWORD(2,2), &wsd)) != 0)
- {
- printf("WSAStartup() failed: %dn", rc);
- return false;
- }
- GetInterfaces( m_Interfaces );
- return true;
- }
- catch(...)
- {
- return false;
- }
- }
- // Decodes the packet
- bool CSnifferDlg::DecodePacket(char* pData, DWORD dwSize)
- {
- try
- {
- if (dwSize < sizeof(char))
- return false;
- // Check the IP version
- const int ip_version = HI_BYTE(*pData);
- CString source, destination;
- if ( ip_version == 4)
- {
- IPV4_HDR* pHeader;
- int headerLen = 0;
- // Verify the buffer is large enough
- if (dwSize < sizeof(IPV4_HDR))
- return false;
- // Get length of IPv4 header to determine where next protocol header begins
- headerLen = LO_BYTE(*pData) * 4;
- pHeader = (IPV4_HDR *)pData;
- ConvertAddress( pHeader->ip_srcaddr, source );
- ConvertAddress( pHeader->ip_destaddr, destination);
- switch (pHeader->ip_protocol)
- {
- case IPPROTO_TCP:
- TCP_HDR* pTCPHeader;
- pTCPHeader = (TCP_HDR *) &pData[headerLen];
- ParseTCPPacket(source, destination, pTCPHeader, pData, dwSize - headerLen );
- break;
- default:
- //TRACE(_T("Not a TCP packet"));
- return false;
- }
- }
- else
- {
- //TRACE( _T("IP version 6") );
- return false;
- }
- /*
- struct in_addr sa4 = {0};
- char* pAddress = NULL;
- // sa4.S_un.sin_family = AF_INET;
- // sa4.sin_port = 0;
- sa4.S_un.S_addr = pIPHeader->ip_srcaddr;
- pAddress = inet_ntoa( sa4);
- */
- return true;
- }
- catch(...)
- {
- return false;
- }
- }
- bool CSnifferDlg::ParseTCPPacket(const CString& source, const CString& destination, TCP_HDR* pTCPHeader, char* pData, unsigned long len )
- {
- try
- {
- if ( len < sizeof(*pTCPHeader) )
- return false;
- len -= sizeof(*pTCPHeader);
- pData += sizeof(*pTCPHeader);
- unsigned int sourcePort, destPort;
- sourcePort = htons(pTCPHeader->src_portno);
- destPort = htons(pTCPHeader->dest_portno);
- // if ( sourcePort != 25 && destPort != 25 )
- // return false;
- Session* pSide = NULL;
- CString strError;
- INT_PTR arrayIndex = -1;
- for ( int i = 0 ; i < m_Array.GetSize(); i++ )
- {
- Session* pCur = m_Array.GetAt(i);
- if ( pCur->sourceIP == source && pCur->sourcePort == sourcePort
- && pCur->destIP == destination && pCur->destPort == destPort)
- {
- pSide = pCur;
- arrayIndex = i; // Save the position in the array
- break;
- }
- }
- const bool sideExist = (pSide != NULL );
- const tcp_seq curSeq = ntohl(pTCPHeader->seq_num);
- // if the packet is a SYN packet then don't count the gap
- const USHORT flg = (ntohs(pTCPHeader->lenflags) & 0x3F);
- if ( !pSide ) // A new session
- {
- // Only if the packet is a SYN packet then
- if ( (flg & TH_SYN ) )
- {
- pSide = new Session();
- pSide->sourceIP = source;
- pSide->destIP = destination;
- pSide->sourcePort = sourcePort;
- pSide->destPort = destPort;
- pSide->len = len;
- pSide->ISN = curSeq;
- pSide->pOtherSide = NULL;
- arrayIndex = m_Array.Add( pSide );
- strError = _T(" /*New session*/ ");
- }
- }
- // Make sure the gap in sequences is less than 10 MB and is positive
- if ( sideExist )
- {
- const long gap = curSeq - pSide->ISN;
- pSide->len = len;
- if ( (flg & TH_SYN) != TH_SYN )
- {
- if ( (flg & TH_RST ) || ( flg & TH_FIN) )
- {
- m_Array.RemoveAt( arrayIndex );
- }
- else
- {
- // Only if the size is greater than 0 do the checking
- if ( len > 0 )
- {
- // ASSERT( gap >= 0 );
- if ( gap < 0 )
- strError += _T(" { Gap < 0 }");
- // ASSERT ( gap <= 10 * 1024 * 1000 );
- if ( gap > 10 * 1024 * 1000 )
- strError += _T(" { Gap > 10 MB }");
- }
- }
- }
- else
- pSide->ISN = curSeq;
- }
- // if ( sourcePort == 25 || destPort == 25 )
- PrintPacket( source, destination, pTCPHeader, len, strError);
- return true;
- }
- catch(...)
- {
- return false;
- }
- }
- void CSnifferDlg::ConvertAddress( unsigned int address, CString& strAddress )
- {
- IN_ADDR ad;
- ad.S_un.S_addr = address;
- strAddress = inet_ntoa( ad );
- }
- void CSnifferDlg::PrintSession( Session* pSession )
- {
- }
- void CSnifferDlg::PrintPacket( const CString& source, const CString& destination,TCP_HDR* pTCPHeader, DWORD dwSize, const CString& errors )
- {
- CString s, from, to, flags, sequence, ack ;
- from = source;
- to = destination;
- unsigned int sourcePort, destPort;
- sourcePort = htons(pTCPHeader->src_portno);
- destPort = htons(pTCPHeader->dest_portno);
- // if the packet is a SYN packet then don't count the gap
- const USHORT flg = (ntohs(pTCPHeader->lenflags) & 0x3F);
- if ( flg & TH_SYN )
- {
- if ( flags.GetLength() > 0 )
- flags += _T(",");
- flags += _T("SYN");
- }
- if ( flg & TH_RST )
- {
- if ( flags.GetLength() > 0 )
- flags += _T(",");
- flags += _T("RST");
- }
- if ( flg & TH_FIN )
- {
- if ( flags.GetLength() > 0 )
- flags += _T(",");
- flags += _T("FIN");
- }
- if ( flg & TH_ACK )
- {
- if ( flags.GetLength() > 0 )
- flags += _T(",");
- flags += _T("ACK");
- }
- if ( flg & TH_URG )
- {
- if ( flags.GetLength() > 0 )
- flags += _T(",");
- flags += _T("URG");
- }
- if ( flg & TH_PUSH )
- {
- if ( flags.GetLength() > 0 )
- flags += _T(",");
- flags += _T("PUSH");
- }
- if ( flg & TH_TAPI )
- {
- if ( flags.GetLength() > 0 )
- flags += _T(",");
- flags += _T("TAPI");
- }
- if ( flg & TH_NETDEV )
- {
- if ( flags.GetLength() > 0 )
- flags += _T(",");
- flags += _T("NETDEV");
- }
- sequence.Format(_T("%lu"),ntohl(pTCPHeader->seq_num));
- ack.Format(_T("%lu"),ntohl(pTCPHeader->ack_num) );
- s.Format(_T("%s - %s {%ld-%ld}, len: %ld, seq: %s,ack: %s, Flags: %s %srn"), from, to, sourcePort, destPort, dwSize, sequence,ack, flags, errors);
- m_Logger.Write( (LPCTSTR)s, s.GetLength() * sizeof(TCHAR) );
- CString szSourcePort, szDestPort, szSize;
- szSourcePort.Format( _T("%ld"), sourcePort );
- szDestPort.Format( _T("%ld"), destPort );
- szSize.Format( _T("%ld"), dwSize );
- TVPacketItem packetItem(source, szSourcePort, destination, szDestPort, szSize, flags, sequence, ack);
- InsertPacketToTV( packetItem );
- }
- bool CSnifferDlg::GetInterfaces(CStringArray& interfaces)
- {
- try
- {
- char Hostname[MAX_PATH];
- HOSTENT *pHostEnt;
- int nAdapter = 0;
- struct sockaddr_in address;
- gethostname( Hostname, sizeof( Hostname ));
- pHostEnt = gethostbyname( Hostname );
- while ( pHostEnt->h_addr_list[nAdapter] )
- {
- memcpy(&address.sin_addr,pHostEnt->h_addr_list[nAdapter], pHostEnt->h_length);
- interfaces.Add(inet_ntoa(address.sin_addr));
- nAdapter++;
- }
- return true;
- }
- catch(...)
- {
- return false;
- }
- }
- void CSnifferDlg::OnSize(UINT nType, int cx, int cy)
- {
- CDialog::OnSize(nType, cx, cy);
- ResizeForm();
- }
- void CSnifferDlg::ResizeForm(void)
- {
- if ( !IsWindowVisible() || !m_CmbInterfaces.IsWindowVisible() || !m_FrmInterfaces.IsWindowVisible() || !m_TVPackets.IsWindowVisible())
- return;
- CRect rect, dlgRect;
- GetClientRect( &dlgRect );
- rect = dlgRect;
- rect.top = 100;
- m_TVPackets.MoveWindow( &rect );
- }
- void CSnifferDlg::OnBnClickedStartsniffing()
- {
- m_CmbInterfaces.GetLBText( m_CmbInterfaces.GetCurSel(), m_SelInterface );
- m_hThread = CreateThread(NULL, 0,SnifferThread,this,0,&m_dwThreadID);
- }
- ULONG WINAPI CSnifferDlg::SnifferThread(LPVOID pParam)
- {
- CSnifferDlg* pDlg = (CSnifferDlg*)pParam;
- pDlg->StartSniffing();
- return S_OK;
- }
- void CSnifferDlg::OnClose()
- {
- m_bExit = true;
- DWORD dwValue = WaitForSingleObject( m_hThread, 5000);
- if ( dwValue == WAIT_TIMEOUT )
- TerminateThread( m_hThread,0);
- CDialog::OnClose();
- }
- void CSnifferDlg::InsertPacketToTV(const TVPacketItem& packetItem)
- {
- const CString caption = packetItem.m_SourceIP + CString(_T(" - ")) + packetItem.m_DestIP;
- HTREEITEM hItem = m_TVPackets.InsertItem( caption,0,0 );
- m_TVPackets.SetItemData( hItem, DWORD_PTR(&packetItem) );
- HTREEITEM hIPHeader = m_TVPackets.InsertItem(_T("IP Header"),1,1,hItem);
- CString str;
- str = GetNiceString(_T("Source IP:")) + packetItem.m_SourceIP;
- m_TVPackets.InsertItem(str,2,2,hIPHeader);
- str = GetNiceString(_T("Destination IP:")) + packetItem.m_DestIP;
- m_TVPackets.InsertItem(str,2,2,hIPHeader);
- HTREEITEM hTCPHeader = m_TVPackets.InsertItem(_T("TCP Header"),1,1,hItem);
- str = GetNiceString(_T("Source Port:")) + packetItem.m_SourcePort;
- m_TVPackets.InsertItem(str,2,2,hTCPHeader);
- str = GetNiceString(_T("Destination Port:")) + packetItem.m_DestPort;
- m_TVPackets.InsertItem(str,2,2,hTCPHeader);
- str = GetNiceString(_T("Size:")) + packetItem.m_Size;
- m_TVPackets.InsertItem(str,2,2,hTCPHeader);
- str = GetNiceString(_T("Flags:")) + packetItem.m_Flags;
- m_TVPackets.InsertItem(str,2,2,hTCPHeader);
- str = GetNiceString(_T("Sequence:")) + packetItem.m_Sequence;
- m_TVPackets.InsertItem(str,2,2,hTCPHeader);
- str = GetNiceString(_T("Ack:")) + packetItem.m_Ack;
- m_TVPackets.InsertItem(str,2,2,hTCPHeader);
- }