SnifferDlg.cpp
上传用户:benyan892
上传日期:2010-01-28
资源大小:158k
文件大小:17k
源码类别:

网络截获/分析

开发平台:

Visual C++

  1. // SnifferDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "Sniffer.h"
  5. #include "SnifferDlg.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #endif
  9. inline CString GetNiceString(LPCTSTR pString)
  10. {
  11. const int numDots = 40 - _tcslen(pString);
  12. CString dotString(_T('.'),numDots);
  13. CString s = CString(pString) + dotString + CString(_T(" "));
  14. return s;
  15. }
  16. // CAboutDlg dialog used for App About
  17. class CAboutDlg : public CDialog
  18. {
  19. public:
  20. CAboutDlg();
  21. // Dialog Data
  22. enum { IDD = IDD_ABOUTBOX };
  23. protected:
  24. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  25. // Implementation
  26. protected:
  27. DECLARE_MESSAGE_MAP()
  28. };
  29. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  30. {
  31. }
  32. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  33. {
  34. CDialog::DoDataExchange(pDX);
  35. }
  36. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  37. END_MESSAGE_MAP()
  38. // CSnifferDlg dialog
  39. CSnifferDlg::CSnifferDlg(CWnd* pParent /*=NULL*/)
  40. : CDialog(CSnifferDlg::IDD, pParent)
  41. , m_SelInterface(_T(""))
  42. {
  43. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  44. Init();
  45. }
  46. void CSnifferDlg::DoDataExchange(CDataExchange* pDX)
  47. {
  48. CDialog::DoDataExchange(pDX);
  49. DDX_Control(pDX, IDC_CMB_INTERFACES, m_CmbInterfaces);
  50. DDX_Control(pDX, IDC_FRM_INTERFACES, m_FrmInterfaces);
  51. DDX_Control(pDX, IDC_STARTSNIFFING, m_BtnStartSniffing);
  52. DDX_Control(pDX, IDC_TV_PACKETS, m_TVPackets);
  53. }
  54. BEGIN_MESSAGE_MAP(CSnifferDlg, CDialog)
  55. ON_WM_SYSCOMMAND()
  56. ON_WM_PAINT()
  57. ON_WM_QUERYDRAGICON()
  58. //}}AFX_MSG_MAP
  59. ON_WM_SIZE()
  60. ON_BN_CLICKED(IDC_STARTSNIFFING, OnBnClickedStartsniffing)
  61. ON_WM_CLOSE()
  62. END_MESSAGE_MAP()
  63. // CSnifferDlg message handlers
  64. BOOL CSnifferDlg::OnInitDialog()
  65. {
  66. CDialog::OnInitDialog();
  67. // Add "About..." menu item to system menu.
  68. // IDM_ABOUTBOX must be in the system command range.
  69. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  70. ASSERT(IDM_ABOUTBOX < 0xF000);
  71. CMenu* pSysMenu = GetSystemMenu(FALSE);
  72. if (pSysMenu != NULL)
  73. {
  74. CString strAboutMenu;
  75. strAboutMenu.LoadString(IDS_ABOUTBOX);
  76. if (!strAboutMenu.IsEmpty())
  77. {
  78. pSysMenu->AppendMenu(MF_SEPARATOR);
  79. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  80. }
  81. }
  82. // Set the icon for this dialog.  The framework does this automatically
  83. //  when the application's main window is not a dialog
  84. SetIcon(m_hIcon, TRUE); // Set big icon
  85. SetIcon(m_hIcon, FALSE); // Set small icon
  86. // TODO: Add extra initialization here
  87. for ( int i = 0 ; i < m_Interfaces.GetSize(); i ++ )
  88. {
  89. m_CmbInterfaces.AddString( m_Interfaces.GetAt(i) );
  90. }
  91. m_CmbInterfaces.SetCurSel( 0 );
  92. m_IL.Create(16,16,ILC_COLOR32 | ILC_MASK, 0,1);
  93. m_IL.Add( LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_COMP2COMP ) ) );
  94. m_IL.Add( LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_IPHeader ) ) );
  95. m_IL.Add( LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_TCPHEADER ) ) );
  96. m_TVPackets.SetImageList( &m_IL,TVSIL_NORMAL );
  97. // ShowWindow( SW_SHOWMAXIMIZED );
  98. ResizeForm();
  99. LOGFONT logFont;
  100. CFont* pFont = new CFont();
  101. RtlZeroMemory( &logFont, sizeof(logFont) );
  102. _tcscpy(logFont.lfFaceName, _T("Lucida Console"));
  103. logFont.lfHeight = 12;
  104. pFont->CreateFontIndirect( &logFont );
  105. m_TVPackets.SetFont( pFont, TRUE );
  106. return TRUE;  // return TRUE  unless you set the focus to a control
  107. }
  108. void CSnifferDlg::OnSysCommand(UINT nID, LPARAM lParam)
  109. {
  110. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  111. {
  112. CAboutDlg dlgAbout;
  113. dlgAbout.DoModal();
  114. }
  115. else
  116. {
  117. CDialog::OnSysCommand(nID, lParam);
  118. }
  119. }
  120. // If you add a minimize button to your dialog, you will need the code below
  121. //  to draw the icon.  For MFC applications using the document/view model,
  122. //  this is automatically done for you by the framework.
  123. void CSnifferDlg::OnPaint() 
  124. {
  125. if (IsIconic())
  126. {
  127. CPaintDC dc(this); // device context for painting
  128. SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
  129. // Center icon in client rectangle
  130. int cxIcon = GetSystemMetrics(SM_CXICON);
  131. int cyIcon = GetSystemMetrics(SM_CYICON);
  132. CRect rect;
  133. GetClientRect(&rect);
  134. int x = (rect.Width() - cxIcon + 1) / 2;
  135. int y = (rect.Height() - cyIcon + 1) / 2;
  136. // Draw the icon
  137. dc.DrawIcon(x, y, m_hIcon);
  138. }
  139. else
  140. {
  141. CDialog::OnPaint();
  142. }
  143. }
  144. // The system calls this function to obtain the cursor to display while the user drags
  145. //  the minimized window.
  146. HCURSOR CSnifferDlg::OnQueryDragIcon()
  147. {
  148. return static_cast<HCURSOR>(m_hIcon);
  149. }
  150. // Starts the sniffing process
  151. bool CSnifferDlg::StartSniffing(void)
  152. {
  153. SOCKET        s = INVALID_SOCKET;
  154. WSABUF        wbuf = {0};
  155. DWORD         dwBytesRet = 0, dwFlags = 0;
  156. unsigned int  optval = 0;
  157. char         *rcvbuf=NULL;
  158. int           rc = 0, err;
  159. if ( m_ulFilterMask & (FILTER_MASK_SOURCE_ADDRESS | FILTER_MASK_SOURCE_PORT) )
  160. {
  161. printf("Source address filter     : ");
  162. //PrintAddress((SOCKADDR *)&m_saSourceAddress, sizeof(m_saSourceAddress));
  163. printf("n");
  164. }
  165. if ( m_ulFilterMask & (FILTER_MASK_DESTINATION_ADDRESS | FILTER_MASK_DESTINATION_PORT) )
  166. {
  167. printf("Destination address filter: ");
  168. //PrintAddress((SOCKADDR *)&g_saDestinationAddress, sizeof(g_saDestinationAddress));
  169. printf("n");
  170. }
  171. //
  172. // Create a raw socket for receiving IP datagrams
  173. //
  174. s = WSASocket(AF_INET, SOCK_RAW, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);
  175. if (s == INVALID_SOCKET)
  176. {
  177. printf("WSASocket() failed: %dn", WSAGetLastError());
  178. return false;
  179. }
  180. //
  181. // This socket MUST be bound before calling the ioctl
  182. //
  183. sockaddr_in sa;
  184. sa.sin_family = AF_INET;
  185. sa.sin_addr.s_addr = inet_addr(m_SelInterface);
  186. sa.sin_port = INADDR_ANY;//htons(7000);
  187. rc = bind(s, (SOCKADDR *)&sa, sizeof(sa));
  188. if (rc == SOCKET_ERROR)
  189. {
  190. printf("bind() failed: %dn", WSAGetLastError());
  191. if (INVALID_SOCKET != s)
  192. {
  193. closesocket(s);
  194. s = INVALID_SOCKET;
  195. }
  196. WSACleanup();
  197. return false;
  198. }
  199. printf("Binding to: ");
  200. //PrintAddress((SOCKADDR *)&g_saLocalInterface, sizeof(g_saLocalInterface));
  201. printf("n");
  202. //
  203. // Set the SIO_RCVALLxxx ioctl
  204. //
  205. optval = 1;
  206. rc = WSAIoctl(s, SIO_RCVALL, &optval, sizeof(optval),
  207. NULL, 0, &dwBytesRet, NULL, NULL);
  208. if (rc == SOCKET_ERROR)
  209. {
  210. printf("WSAIotcl(0x%x) failed: %dn", SIO_RCVALL,
  211. (err = WSAGetLastError()));
  212. if (err == WSAEINVAL)
  213. {
  214. printf("NOTE: IPv6 does not currently support the SIO_RCVALL* ioctlsn");
  215. }
  216. if (INVALID_SOCKET != s)
  217. {
  218. closesocket(s);
  219. s = INVALID_SOCKET;
  220. }
  221. WSACleanup();
  222. return false;
  223. }
  224. //
  225. // Allocate a buffer for receiving data
  226. //
  227. rcvbuf = (char *)HeapAlloc(GetProcessHeap(), 0, MAX_IP_SIZE);
  228. if (rcvbuf == NULL)
  229. {
  230. fprintf(stderr, "HeapAlloc failed: %dn", GetLastError());
  231. if (INVALID_SOCKET != s)
  232. {
  233. closesocket(s);
  234. s = INVALID_SOCKET;
  235. }
  236. WSACleanup();
  237. return false;
  238. }
  239. //
  240. // Start receiving IP datagrams until interrupted
  241. // 
  242. while ( !m_bExit )
  243. {
  244. wbuf.len = MAX_IP_SIZE;
  245. wbuf.buf = rcvbuf;
  246. dwFlags  = 0;
  247. rc = WSARecv(s, &wbuf, 1, &dwBytesRet, &dwFlags, NULL, NULL);
  248. if (rc == SOCKET_ERROR)
  249. {
  250. printf("WSARecv() failed: %dn", WSAGetLastError());
  251. break;
  252. }
  253. DecodePacket(rcvbuf , dwBytesRet );
  254. }
  255. //
  256. // Cleanup
  257. //
  258. if (rcvbuf) 
  259. HeapFree(GetProcessHeap(), 0, rcvbuf);
  260. if (INVALID_SOCKET != s)
  261. {
  262. closesocket(s);
  263. s = INVALID_SOCKET;
  264. }
  265. WSACleanup();
  266. return true;
  267. }
  268. bool CSnifferDlg::Init(void)
  269. {
  270. try
  271. {
  272. m_bExit = false;
  273. m_hThread = NULL;
  274. m_dwThreadID = 0;
  275. m_ulFilterMask = 0;
  276. m_Logger.Open( _T("Logger.txt"),CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone);
  277. int           rc = 0;
  278. WSADATA       wsd;
  279. //
  280. // Load Winsock
  281. //
  282. if ((rc = WSAStartup(MAKEWORD(2,2), &wsd)) != 0)
  283. {
  284. printf("WSAStartup() failed: %dn", rc);
  285. return false;
  286. }
  287. GetInterfaces( m_Interfaces );
  288. return true;
  289. }
  290. catch(...)
  291. {
  292. return false;
  293. }
  294. }
  295. // Decodes the packet
  296. bool CSnifferDlg::DecodePacket(char* pData, DWORD dwSize)
  297. {
  298. try
  299. {
  300. if (dwSize < sizeof(char))
  301. return false;
  302. // Check the IP version
  303. const int ip_version = HI_BYTE(*pData);
  304. CString source, destination;
  305. if ( ip_version == 4)
  306. {
  307. IPV4_HDR* pHeader;
  308. int headerLen = 0;
  309. // Verify the buffer is large enough
  310. if (dwSize  < sizeof(IPV4_HDR))
  311. return false;
  312. // Get length of IPv4 header to determine where next protocol header begins
  313. headerLen = LO_BYTE(*pData) * 4;
  314. pHeader = (IPV4_HDR *)pData;
  315. ConvertAddress( pHeader->ip_srcaddr, source );
  316. ConvertAddress( pHeader->ip_destaddr, destination);
  317. switch (pHeader->ip_protocol)
  318. {
  319. case IPPROTO_TCP:
  320. TCP_HDR* pTCPHeader;
  321. pTCPHeader = (TCP_HDR *) &pData[headerLen];
  322. ParseTCPPacket(source, destination, pTCPHeader, pData, dwSize - headerLen );
  323. break;
  324. default:
  325. //TRACE(_T("Not a TCP packet"));
  326. return false;
  327. }
  328. }
  329. else
  330. {
  331. //TRACE( _T("IP version 6") );
  332. return false;
  333. }
  334. /*
  335. struct in_addr sa4 = {0};
  336. char* pAddress = NULL;
  337. // sa4.S_un.sin_family = AF_INET;
  338. //    sa4.sin_port   = 0;
  339. sa4.S_un.S_addr = pIPHeader->ip_srcaddr;
  340. pAddress = inet_ntoa( sa4);
  341. */
  342. return true;
  343. }
  344. catch(...)
  345. {
  346. return false;
  347. }
  348. }
  349. bool CSnifferDlg::ParseTCPPacket(const CString& source, const CString& destination, TCP_HDR* pTCPHeader, char* pData, unsigned long len )
  350. {
  351. try
  352. {
  353. if ( len < sizeof(*pTCPHeader) )
  354. return false;
  355. len -= sizeof(*pTCPHeader);
  356. pData += sizeof(*pTCPHeader);
  357. unsigned int sourcePort, destPort;
  358. sourcePort = htons(pTCPHeader->src_portno);
  359. destPort = htons(pTCPHeader->dest_portno);
  360. // if ( sourcePort != 25 && destPort != 25 )
  361. // return false;
  362. Session* pSide = NULL;
  363. CString strError;
  364. INT_PTR arrayIndex = -1;
  365. for ( int i = 0 ; i < m_Array.GetSize(); i++ )
  366. {
  367. Session* pCur = m_Array.GetAt(i);
  368. if ( pCur->sourceIP == source && pCur->sourcePort == sourcePort 
  369. && pCur->destIP == destination && pCur->destPort == destPort)
  370. {
  371. pSide = pCur;
  372. arrayIndex = i; // Save the position in the array
  373. break;
  374. }
  375. }
  376. const bool sideExist = (pSide != NULL );
  377. const tcp_seq curSeq = ntohl(pTCPHeader->seq_num);
  378. // if the packet is a SYN packet then don't count the gap
  379. const USHORT flg = (ntohs(pTCPHeader->lenflags) & 0x3F);
  380. if ( !pSide )  // A new session
  381. {
  382. // Only if the packet is a SYN packet then
  383. if ( (flg & TH_SYN ) )
  384. {
  385. pSide = new Session();
  386. pSide->sourceIP = source;
  387. pSide->destIP = destination;
  388. pSide->sourcePort = sourcePort;
  389. pSide->destPort = destPort;
  390. pSide->len = len;
  391. pSide->ISN = curSeq;
  392. pSide->pOtherSide = NULL;
  393. arrayIndex = m_Array.Add( pSide );
  394. strError = _T(" /*New session*/ ");
  395. }
  396. }
  397. // Make sure the gap in sequences is less than 10 MB and is positive
  398. if ( sideExist )
  399. {
  400. const long gap = curSeq - pSide->ISN;
  401. pSide->len = len;
  402. if ( (flg & TH_SYN) != TH_SYN )
  403. {
  404. if ( (flg & TH_RST ) || ( flg & TH_FIN) )
  405. {
  406. m_Array.RemoveAt( arrayIndex );
  407. }
  408. else
  409. {
  410. // Only if the size is greater than 0 do the checking
  411. if ( len > 0 )
  412. {
  413. // ASSERT( gap >= 0 );
  414. if ( gap < 0 )
  415. strError += _T(" { Gap < 0 }");
  416. // ASSERT ( gap <= 10 * 1024 * 1000 );
  417. if ( gap >  10 * 1024 * 1000 )
  418. strError += _T(" { Gap > 10 MB }");
  419. }
  420. }
  421. }
  422. else
  423. pSide->ISN = curSeq;
  424. }
  425. // if ( sourcePort == 25 || destPort == 25 )
  426. PrintPacket( source, destination, pTCPHeader, len, strError);
  427. return true;
  428. }
  429. catch(...)
  430. {
  431. return false;
  432. }
  433. }
  434. void CSnifferDlg::ConvertAddress( unsigned int address, CString& strAddress )
  435. {
  436. IN_ADDR ad;
  437. ad.S_un.S_addr = address;
  438. strAddress = inet_ntoa( ad );
  439. }
  440. void CSnifferDlg::PrintSession( Session* pSession )
  441. {
  442. }
  443. void CSnifferDlg::PrintPacket( const CString& source, const CString& destination,TCP_HDR* pTCPHeader, DWORD dwSize, const CString& errors ) 
  444. {
  445. CString s, from, to, flags, sequence, ack ;
  446. from = source;
  447. to = destination;
  448. unsigned int sourcePort, destPort;
  449. sourcePort = htons(pTCPHeader->src_portno);
  450. destPort = htons(pTCPHeader->dest_portno);
  451. // if the packet is a SYN packet then don't count the gap
  452. const USHORT flg = (ntohs(pTCPHeader->lenflags) & 0x3F);
  453. if ( flg & TH_SYN ) 
  454. {
  455. if ( flags.GetLength() > 0 )
  456. flags += _T(",");
  457. flags += _T("SYN");
  458. }
  459. if ( flg & TH_RST ) 
  460. {
  461. if ( flags.GetLength() > 0 )
  462. flags += _T(",");
  463. flags += _T("RST");
  464. }
  465. if ( flg & TH_FIN ) 
  466. {
  467. if ( flags.GetLength() > 0 )
  468. flags += _T(",");
  469. flags += _T("FIN");
  470. }
  471. if ( flg & TH_ACK ) 
  472. {
  473. if ( flags.GetLength() > 0 )
  474. flags += _T(",");
  475. flags += _T("ACK");
  476. }
  477. if ( flg & TH_URG ) 
  478. {
  479. if ( flags.GetLength() > 0 )
  480. flags += _T(",");
  481. flags += _T("URG");
  482. }
  483. if ( flg & TH_PUSH ) 
  484. {
  485. if ( flags.GetLength() > 0 )
  486. flags += _T(",");
  487. flags += _T("PUSH");
  488. }
  489. if ( flg & TH_TAPI ) 
  490. {
  491. if ( flags.GetLength() > 0 )
  492. flags += _T(",");
  493. flags += _T("TAPI");
  494. }
  495. if ( flg & TH_NETDEV ) 
  496. {
  497. if ( flags.GetLength() > 0 )
  498. flags += _T(",");
  499. flags += _T("NETDEV");
  500. }
  501. sequence.Format(_T("%lu"),ntohl(pTCPHeader->seq_num));
  502. ack.Format(_T("%lu"),ntohl(pTCPHeader->ack_num) );
  503. 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);
  504. m_Logger.Write( (LPCTSTR)s, s.GetLength() * sizeof(TCHAR) );
  505. CString szSourcePort, szDestPort, szSize;
  506. szSourcePort.Format( _T("%ld"), sourcePort );
  507. szDestPort.Format( _T("%ld"), destPort );
  508. szSize.Format( _T("%ld"), dwSize );
  509. TVPacketItem packetItem(source, szSourcePort, destination, szDestPort, szSize, flags, sequence, ack);
  510. InsertPacketToTV( packetItem );
  511. }
  512. bool CSnifferDlg::GetInterfaces(CStringArray& interfaces)
  513. {
  514. try
  515. {
  516. char     Hostname[MAX_PATH];
  517. HOSTENT *pHostEnt;
  518. int      nAdapter = 0;
  519. struct sockaddr_in   address;
  520. gethostname( Hostname, sizeof( Hostname ));
  521. pHostEnt = gethostbyname( Hostname );
  522. while ( pHostEnt->h_addr_list[nAdapter] )
  523. {
  524. memcpy(&address.sin_addr,pHostEnt->h_addr_list[nAdapter], pHostEnt->h_length);
  525. interfaces.Add(inet_ntoa(address.sin_addr));
  526. nAdapter++;
  527. return true;
  528. }
  529. catch(...)
  530. {
  531. return false;
  532. }
  533. }
  534. void CSnifferDlg::OnSize(UINT nType, int cx, int cy)
  535. {
  536. CDialog::OnSize(nType, cx, cy);
  537. ResizeForm();
  538. }
  539. void CSnifferDlg::ResizeForm(void)
  540. {
  541. if ( !IsWindowVisible() || !m_CmbInterfaces.IsWindowVisible() ||  !m_FrmInterfaces.IsWindowVisible() || !m_TVPackets.IsWindowVisible())
  542. return;
  543. CRect rect, dlgRect;
  544. GetClientRect( &dlgRect );
  545. rect = dlgRect;
  546. rect.top = 100;
  547. m_TVPackets.MoveWindow( &rect );
  548. }
  549. void CSnifferDlg::OnBnClickedStartsniffing()
  550. {
  551. m_CmbInterfaces.GetLBText( m_CmbInterfaces.GetCurSel(), m_SelInterface );
  552. m_hThread = CreateThread(NULL, 0,SnifferThread,this,0,&m_dwThreadID);
  553. }
  554. ULONG WINAPI CSnifferDlg::SnifferThread(LPVOID pParam)
  555. {
  556. CSnifferDlg* pDlg = (CSnifferDlg*)pParam;
  557. pDlg->StartSniffing();
  558. return S_OK;
  559. }
  560. void CSnifferDlg::OnClose()
  561. {
  562. m_bExit = true;
  563. DWORD dwValue = WaitForSingleObject( m_hThread, 5000);
  564. if ( dwValue == WAIT_TIMEOUT )
  565. TerminateThread( m_hThread,0);
  566. CDialog::OnClose();
  567. }
  568. void CSnifferDlg::InsertPacketToTV(const TVPacketItem& packetItem)
  569. {
  570. const CString caption = packetItem.m_SourceIP + CString(_T(" - ")) + packetItem.m_DestIP;
  571. HTREEITEM hItem = m_TVPackets.InsertItem( caption,0,0 );
  572. m_TVPackets.SetItemData( hItem, DWORD_PTR(&packetItem) );
  573. HTREEITEM hIPHeader = m_TVPackets.InsertItem(_T("IP Header"),1,1,hItem);
  574. CString str;
  575. str = GetNiceString(_T("Source IP:")) + packetItem.m_SourceIP;
  576. m_TVPackets.InsertItem(str,2,2,hIPHeader);
  577. str = GetNiceString(_T("Destination IP:")) + packetItem.m_DestIP;
  578. m_TVPackets.InsertItem(str,2,2,hIPHeader);
  579. HTREEITEM hTCPHeader = m_TVPackets.InsertItem(_T("TCP Header"),1,1,hItem);
  580. str = GetNiceString(_T("Source Port:")) + packetItem.m_SourcePort;
  581. m_TVPackets.InsertItem(str,2,2,hTCPHeader);
  582. str = GetNiceString(_T("Destination Port:")) + packetItem.m_DestPort;
  583. m_TVPackets.InsertItem(str,2,2,hTCPHeader);
  584. str = GetNiceString(_T("Size:")) + packetItem.m_Size;
  585. m_TVPackets.InsertItem(str,2,2,hTCPHeader);
  586. str = GetNiceString(_T("Flags:")) + packetItem.m_Flags;
  587. m_TVPackets.InsertItem(str,2,2,hTCPHeader);
  588. str = GetNiceString(_T("Sequence:")) + packetItem.m_Sequence;
  589. m_TVPackets.InsertItem(str,2,2,hTCPHeader);
  590. str = GetNiceString(_T("Ack:")) + packetItem.m_Ack;
  591. m_TVPackets.InsertItem(str,2,2,hTCPHeader);
  592. }