00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "stdafx.h"
00037 #include "TCPPortScanner.h"
00038
00039 #include "ErrorHandlerMacros.h"
00040 #include "OSManager.h"
00041 #include "GenericCriticalSection.h"
00042 #include "ThreadPool.h"
00043 #include "GenericThread.h"
00044
00045 #ifdef _MEMORY_DEBUG
00046 #define new DEBUG_NEW
00047 #define malloc DEBUG_MALLOC
00048 static char THIS_FILE[] = __FILE__;
00049 #endif
00050
00051 KOMODIA_NAMESPACE_START
00052
00053
00054
00055 #define CTCPScanner_Class "CTCPScanner"
00056
00057 CTCPPortScanner::CTCPScanner::CTCPScanner(CTCPPortScanner* pFather,
00058 unsigned short usPort,
00059 int iDataSize,
00060 DWORD dwTimeout) : CTCPSocketAsync(FALSE),
00061 m_pFather(pFather),
00062 m_iDataSize(iDataSize),
00063 m_dwTimeout(dwTimeout),
00064 m_usPort(usPort)
00065 {
00066 try
00067 {
00068
00069 SetName(CTCPScanner_Class);
00070 }
00071 ERROR_HANDLER("CTCPScanner")
00072 }
00073
00074 CTCPPortScanner::CTCPScanner::~CTCPScanner()
00075 {
00076 }
00077
00078 BOOL CTCPPortScanner::CTCPScanner::OnSocketTimeout()
00079 {
00080 try
00081 {
00082
00083 KillTimer();
00084
00085
00086 m_pFather->SocketDone(m_usPort,TRUE);
00087
00088
00089 delete this;
00090
00091
00092 return FALSE;
00093 }
00094 ERROR_HANDLER_RETURN("OnSocketTimeout",FALSE)
00095 }
00096
00097 BOOL CTCPPortScanner::CTCPScanner::OnSocketConnect(int iErrorCode)
00098 {
00099 try
00100 {
00101
00102 if (iErrorCode ||
00103 !m_iDataSize)
00104 {
00105
00106 m_pFather->SocketDone(m_usPort,
00107 iErrorCode==0);
00108
00109
00110 DeleteSocketFromThread(7000);
00111
00112
00113 return TRUE;
00114 }
00115
00116
00117 if (!SetTimeout(m_dwTimeout))
00118 {
00119
00120 ReportError("OnSocketConnect","Failed to set timeout!");
00121
00122
00123 m_pFather->SocketDone(m_usPort,TRUE);
00124
00125
00126 DeleteSocketFromThread(7000);
00127 }
00128
00129
00130 return TRUE;
00131 }
00132 ERROR_HANDLER_RETURN("OnSocketConnect",TRUE)
00133 }
00134
00135 BOOL CTCPPortScanner::CTCPScanner::OnSocketClose(int iErrorCode)
00136 {
00137 try
00138 {
00139
00140 m_pFather->SocketDone(m_usPort,TRUE);
00141
00142
00143 DeleteSocketFromThread();
00144
00145
00146 return TRUE;
00147 }
00148 ERROR_HANDLER_RETURN("OnSocketClose",TRUE)
00149 }
00150
00151 BOOL CTCPPortScanner::CTCPScanner::OnSocketReceive(int iErrorCode)
00152 {
00153 try
00154 {
00155
00156 if (!m_iDataSize)
00157 return TRUE;
00158
00159
00160 KillTimer();
00161
00162
00163 char* pData;
00164 pData=new char[m_iDataSize];
00165
00166
00167 int iSize;
00168 iSize=Receive(pData,m_iDataSize-1);
00169
00170
00171 if (iSize==GetErrorCode())
00172 {
00173
00174 m_pFather->SocketDone(m_usPort,
00175 TRUE);
00176
00177
00178 delete [] pData;
00179 }
00180 else
00181 {
00182
00183 pData[iSize]=0;
00184
00185
00186 m_pFather->SocketDone(m_usPort,
00187 pData,
00188 iSize);
00189 }
00190
00191
00192 DeleteSocketFromThread(7000);
00193
00194
00195 return TRUE;
00196 }
00197 ERROR_HANDLER_RETURN("OnSocketReceive",TRUE)
00198 }
00199
00200
00201
00202 #define CTCPPortScanner_Class "CTCPPortScanner"
00203
00204 CTCPPortScanner::CTCPPortScanner() : CErrorHandler(),
00205 m_pCSection(NULL),
00206 m_bDone(TRUE),
00207 m_iReceiveData(0),
00208 m_iConnectionTimeout(0),
00209 m_iMaxSockets(50),
00210 m_bFinished(FALSE),
00211 m_pCSectionDone(NULL)
00212 {
00213 try
00214 {
00215
00216 SetName(CTCPPortScanner_Class);
00217
00218
00219 m_pCSection=COSManager::CreateCriticalSection();
00220 m_pCSectionDone=COSManager::CreateCriticalSection();
00221
00222
00223 m_aCurrentPair.usFromPort=0;
00224 m_aCurrentPair.usToPort=0;
00225 }
00226 ERROR_HANDLER("CTCPPortScanner")
00227 }
00228
00229 CTCPPortScanner::~CTCPPortScanner()
00230 {
00231 try
00232 {
00233
00234 delete m_pCSection;
00235 delete m_pCSectionDone;
00236
00237
00238 DeletePortsMap();
00239 }
00240 ERROR_HANDLER("~CTCPPortScanner")
00241 }
00242
00243 void CTCPPortScanner::AddPorts(unsigned short usFromPort,
00244 unsigned short usToPort)
00245 {
00246 try
00247 {
00248
00249 if (!(usFromPort &&
00250 usToPort &&
00251 usFromPort<=usToPort))
00252 return;
00253
00254
00255 ScanPair aData;
00256 aData.usFromPort=usFromPort;
00257 aData.usToPort=usToPort;
00258
00259
00260 CCriticalAutoRelease aRelease(m_pCSection,TRUE);
00261
00262 m_aPortsToScan.push_back(aData);
00263 }
00264 ERROR_HANDLER("AddPorts")
00265 }
00266
00267 BOOL CTCPPortScanner::IsDone()const
00268 {
00269 return m_bDone;
00270 }
00271
00272 void CTCPPortScanner::SetReceiveData(int iMaxDataSize,
00273 DWORD dwTimeout)
00274 {
00275 if (!m_bDone ||
00276 !m_bFinished)
00277 return;
00278
00279 try
00280 {
00281 m_iReceiveData=iMaxDataSize;
00282 m_dwTimeout=dwTimeout;
00283 }
00284 ERROR_HANDLER("SetReceiveData")
00285 }
00286
00287 DWORD CTCPPortScanner::GetReceiveDataTimeout()const
00288 {
00289 return m_dwTimeout;
00290 }
00291
00292 int CTCPPortScanner::GetReceiveDataSize()const
00293 {
00294 return m_iReceiveData;
00295 }
00296
00297 unsigned short CTCPPortScanner::GetNextPort()
00298 {
00299 try
00300 {
00301
00302 CCriticalAutoRelease aRelease(m_pCSection,TRUE);
00303
00304
00305 if (!m_aCurrentPair.usFromPort ||
00306 !m_aCurrentPair.usToPort ||
00307 m_aCurrentPair.usFromPort>m_aCurrentPair.usToPort)
00308
00309 if (m_aPortsToScan.begin()==m_aPortsToScan.end())
00310 return 0;
00311 else
00312 {
00313
00314 m_aCurrentPair=m_aPortsToScan.front();
00315 m_aPortsToScan.pop_front();
00316 }
00317
00318
00319 unsigned short usPort;
00320 usPort=m_aCurrentPair.usFromPort;
00321
00322
00323 ++m_aCurrentPair.usFromPort;
00324
00325
00326 return usPort;
00327 }
00328 ERROR_HANDLER_RETURN("GetNextPort",0)
00329 }
00330
00331 BOOL CTCPPortScanner::CanScan()
00332 {
00333 try
00334 {
00335
00336 CCriticalAutoRelease aRelease(m_pCSection,TRUE);
00337
00338
00339 if (!m_aCurrentPair.usFromPort ||
00340 !m_aCurrentPair.usToPort ||
00341 m_aCurrentPair.usFromPort>m_aCurrentPair.usToPort)
00342
00343 if (m_aPortsToScan.begin()==m_aPortsToScan.end())
00344 return FALSE;
00345 else
00346 {
00347
00348 m_aCurrentPair=m_aPortsToScan.front();
00349 m_aPortsToScan.pop_front();
00350 }
00351
00352 return TRUE;
00353 }
00354 ERROR_HANDLER_RETURN("CanScan",FALSE)
00355 }
00356
00357 BOOL CTCPPortScanner::IsError()const
00358 {
00359 return m_bError;
00360 }
00361
00362 void CTCPPortScanner::SocketDone(unsigned short usPort,
00363 BOOL bConnected)
00364 {
00365 try
00366 {
00367 if (m_bDone ||
00368 m_bFinished)
00369 return;
00370
00371
00372 if (bConnected)
00373 {
00374
00375 CCriticalAutoRelease aRelease(m_pCSection,TRUE);
00376
00377
00378 if (m_aPortAnswers.find(usPort)!=m_aPortAnswers.end())
00379 return;
00380
00381
00382 m_aPortList.insert(usPort);
00383
00384
00385 m_aPortAnswers.insert(usPort);
00386 }
00387
00388
00389 OnPort(usPort,
00390 bConnected);
00391
00392 long lCount;
00393 lCount=AdjustNumberOfSockets(-1);
00394
00395
00396 if (!CanScan() &&
00397 lCount<=0)
00398 ScanDone(FALSE);
00399 else
00400 {
00401
00402 BOOL bQuit;
00403 bQuit=FALSE;
00404
00405
00406 while (!bQuit)
00407 {
00408
00409 AdjustNumberOfSockets(1);
00410
00411
00412 if (!(bQuit=NewSocket()))
00413 ReportError("SocketDone","Error creating the socket!");
00414 }
00415 }
00416 }
00417 ERROR_HANDLER("SocketDone")
00418 }
00419
00420 void CTCPPortScanner::SocketDone(unsigned short usPort,
00421 char* pData,
00422 int iDataSize)
00423 {
00424 try
00425 {
00426 if (m_bDone ||
00427 m_bFinished)
00428 return;
00429
00430 {
00431
00432 CCriticalAutoRelease aRelease(m_pCSection,TRUE);
00433
00434
00435 if (m_aPortAnswers.find(usPort)!=m_aPortAnswers.end())
00436 return;
00437
00438
00439 m_aPortList.insert(usPort);
00440
00441
00442 m_aPortAnswers.insert(usPort);
00443
00444
00445 m_aPortsData.insert(DataMap::value_type(usPort,pData));
00446 }
00447
00448
00449 OnPortData(usPort,
00450 pData,
00451 iDataSize);
00452
00453 long lCount;
00454 lCount=AdjustNumberOfSockets(-1);
00455
00456
00457 if (!CanScan() &&
00458 lCount<=0)
00459 ScanDone(FALSE);
00460 else
00461 {
00462
00463 BOOL bQuit;
00464 bQuit=FALSE;
00465
00466
00467 while (!bQuit)
00468 {
00469
00470 AdjustNumberOfSockets(1);
00471
00472
00473 if (!(bQuit=NewSocket()))
00474 ReportError("SocketDone","Error creating the socket!");
00475 }
00476 }
00477 }
00478 ERROR_HANDLER("SocketDone")
00479 }
00480
00481 void CTCPPortScanner::DeletePortsMap()
00482 {
00483 try
00484 {
00485
00486 DataMap::iterator aIterator;
00487 aIterator=m_aPortsData.begin();
00488
00489
00490 while (aIterator!=m_aPortsData.end())
00491 {
00492
00493 DataMap::iterator aBackupIterator;
00494 aBackupIterator=aIterator;
00495
00496
00497 ++aIterator;
00498
00499
00500 delete [] aBackupIterator->second;
00501
00502
00503 m_aPortsData.erase(aBackupIterator);
00504 }
00505 }
00506 ERROR_HANDLER("DeletePortsMap")
00507 }
00508
00509 BOOL CTCPPortScanner::NewSocket()
00510 {
00511 try
00512 {
00513
00514 if (m_bDone ||
00515 m_bFinished)
00516 return TRUE;
00517
00518
00519 unsigned short usPort;
00520 usPort=GetNextPort();
00521
00522
00523 if (!usPort)
00524 {
00525
00526 if (AdjustNumberOfSockets(-1)<=0)
00527 ScanDone(FALSE);
00528
00529
00530 return TRUE;
00531 }
00532
00533
00534 CTCPSocketAsync* pSocket;
00535 pSocket=AllocateSocket(usPort);
00536
00537
00538 if (!pSocket)
00539 {
00540
00541 if (AdjustNumberOfSockets(-1)<=0 &&
00542 !CanScan())
00543 {
00544
00545 ScanDone(FALSE);
00546
00547
00548 return TRUE;
00549 }
00550 else
00551 return FALSE;
00552 }
00553
00554
00555 if (!pSocket->Connect(0,
00556 m_aTarget,
00557 usPort))
00558 {
00559
00560 DestroySocket(pSocket);
00561
00562
00563 if (AdjustNumberOfSockets(-1)<=0 &&
00564 !CanScan())
00565 {
00566
00567 ScanDone(FALSE);
00568
00569
00570 return TRUE;
00571 }
00572 else
00573 return FALSE;
00574 }
00575
00576
00577 PortScanned(usPort);
00578
00579
00580 return TRUE;
00581 }
00582 ERROR_HANDLER_RETURN("NewSocket",FALSE)
00583 }
00584
00585 int CTCPPortScanner::AdjustNumberOfSockets(int iIncrement)
00586 {
00587 try
00588 {
00589
00590 CCriticalAutoRelease aRelease(m_pCSection,TRUE);
00591
00592
00593 m_iActiveSockets+=iIncrement;
00594
00595
00596 return m_iActiveSockets;
00597 }
00598 ERROR_HANDLER_RETURN("AdjustNumberOfSockets",0)
00599 }
00600
00601 DWORD CTCPPortScanner::DoneThread(LPVOID lpData)
00602 {
00603 try
00604 {
00605
00606 std::auto_ptr<ThreadData> pData((ThreadData*)lpData);
00607
00608
00609 CTCPPortScanner* pClass;
00610 pClass=(CTCPPortScanner*)pData->pScanner;
00611
00612
00613 pClass->TCPScanDoneLib(pData->bError);
00614
00615
00616 pClass->m_bDone=TRUE;
00617 pClass->m_bError=pData->bError;
00618
00619
00620 pClass->TCPScanDone(pData->bError);
00621
00622
00623 return TRUE;
00624 }
00625 ERROR_HANDLER_STATIC_RETURN(CTCPPortScanner_Class,"DoneThread",FALSE)
00626 }
00627
00628 void CTCPPortScanner::ScanDone(BOOL bError,
00629 BOOL bSpawnThread)
00630 {
00631 try
00632 {
00633 {
00634
00635 CCriticalAutoRelease aRelease(m_pCSectionDone);
00636
00637
00638 if (m_bDone ||
00639 m_bFinished)
00640 return;
00641
00642
00643 m_bFinished=TRUE;
00644 }
00645
00646
00647 ThreadData* pData;
00648 pData=new ThreadData;
00649
00650
00651 pData->bError=bError;
00652 pData->pScanner=this;
00653
00654
00655 if (bSpawnThread)
00656 {
00657
00658 CGenericThread* pThread;
00659 pThread=COSManager::CreateThread(DoneThread);
00660
00661
00662 pThread->SetAutoDelete(TRUE);
00663
00664
00665 pThread->Start((LPVOID)pData);
00666 }
00667 else
00668 DoneThread((LPVOID)pData);
00669 }
00670 ERROR_HANDLER("ScanDone")
00671 }
00672
00673 const CTCPPortScanner::PortsList& CTCPPortScanner::GetPortList()const
00674 {
00675 return m_aPortList;
00676 }
00677
00678 void CTCPPortScanner::OnPort(unsigned short usPort,
00679 BOOL bConnected)
00680 {
00681 }
00682
00683 void CTCPPortScanner::OnPortData(unsigned short usPort,
00684 const char* pData,
00685 int iDataSize)
00686 {
00687 }
00688
00689 void CTCPPortScanner::TCPScanDone(BOOL bError)
00690 {
00691 }
00692
00693 const char* CTCPPortScanner::GetData(unsigned short usPort)const
00694 {
00695 try
00696 {
00697
00698 DataMap::const_iterator aIterator;
00699 aIterator=m_aPortsData.find(usPort);
00700
00701
00702 if (aIterator!=m_aPortsData.end())
00703 return aIterator->second;
00704 else
00705 return NULL;
00706 }
00707 ERROR_HANDLER_RETURN("GetData",NULL)
00708 }
00709
00710 char* CTCPPortScanner::GetDataForModify(unsigned short usPort)const
00711 {
00712 try
00713 {
00714
00715 DataMap::const_iterator aIterator;
00716 aIterator=m_aPortsData.find(usPort);
00717
00718
00719 if (aIterator!=m_aPortsData.end())
00720 return aIterator->second;
00721 else
00722 return NULL;
00723 }
00724 ERROR_HANDLER_RETURN("GetDataForModify",NULL)
00725 }
00726
00727 void CTCPPortScanner::SetConnectionTimeout(int iMS)
00728 {
00729 m_iConnectionTimeout=iMS;
00730 }
00731
00732 int CTCPPortScanner::GetConnectionTimeout()const
00733 {
00734 return m_iConnectionTimeout;
00735 }
00736
00737 void CTCPPortScanner::SetMaxSockets(int iMaxSockets)
00738 {
00739 m_iMaxSockets=iMaxSockets;
00740 }
00741
00742 int CTCPPortScanner::GetMaxSockets()const
00743 {
00744 return m_iMaxSockets;
00745 }
00746
00747 void CTCPPortScanner::SetError(BOOL bError)
00748 {
00749 m_bError=bError;
00750 }
00751
00752 void CTCPPortScanner::SetDone(BOOL bDone)
00753 {
00754 m_bDone=bDone;
00755
00756
00757 if (!bDone)
00758 m_bFinished=FALSE;
00759 }
00760
00761 void CTCPPortScanner::ResetSocketCount()
00762 {
00763 m_iActiveSockets=0;
00764 }
00765
00766 void CTCPPortScanner::SetTarget(IP aTarget)
00767 {
00768 m_aTarget=aTarget;
00769 }
00770
00771 IP CTCPPortScanner::GetTarget()const
00772 {
00773 return m_aTarget;
00774 }
00775
00776 void CTCPPortScanner::ResetPair()
00777 {
00778 m_aCurrentPair.usFromPort=0;
00779 m_aCurrentPair.usToPort=0;
00780 }
00781
00782 void CTCPPortScanner::ResetData()
00783 {
00784 try
00785 {
00786
00787 m_aPortAnswers.clear();
00788 m_aPortList.clear();
00789 }
00790 ERROR_HANDLER("ResetData")
00791 }
00792
00793 CTCPSocketAsync* CTCPPortScanner::AllocateSocket(unsigned short usPort)const
00794 {
00795 try
00796 {
00797 CTCPScanner* pSocket;
00798 pSocket=new CTCPScanner((CTCPPortScanner*)this,
00799 usPort,
00800 GetReceiveDataSize(),
00801 GetReceiveDataTimeout());
00802
00803
00804 if (!GetReceiveDataSize())
00805
00806 pSocket->DisableEvents(CAsyncSocket::aeReceive);
00807
00808 if (!pSocket->Create())
00809 {
00810
00811 delete pSocket;
00812
00813
00814 return NULL;
00815 }
00816 else
00817 {
00818
00819 if (GetConnectionTimeout())
00820 if (!pSocket->SetConnectionTimeout(GetConnectionTimeout()))
00821 {
00822
00823 delete pSocket;
00824
00825
00826 return NULL;
00827 }
00828
00829
00830 return pSocket;
00831 }
00832 }
00833 ERROR_HANDLER_RETURN("AllocateSocket",NULL)
00834 }
00835
00836 void CTCPPortScanner::DestroySocket(CTCPSocketAsync* pSocket)const
00837 {
00838 try
00839 {
00840 delete pSocket;
00841 }
00842 ERROR_HANDLER("DestroySocket")
00843 }
00844
00845 void CTCPPortScanner::TCPScanDoneLib(BOOL bError)
00846 {
00847 }
00848
00849 void CTCPPortScanner::PortScanned(unsigned short usPort)
00850 {
00851 }
00852
00853 BOOL CTCPPortScanner::IsFinished()const
00854 {
00855 return m_bFinished;
00856 }
00857
00858 BOOL CTCPPortScanner::StopScan()
00859 {
00860 try
00861 {
00862
00863 ScanDone(TRUE,
00864 FALSE);
00865
00866
00867 return TRUE;
00868 }
00869 ERROR_HANDLER_RETURN("StopScan",FALSE)
00870 }
00871
00872 KOMODIA_NAMESPACE_END