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 "TCPSocket.h"
00038
00039 #include "ErrorHandlerMacros.h"
00040 #include "Array_ptr.h"
00041
00042 #include <memory>
00043
00044 #ifdef _MEMORY_DEBUG
00045 #define new DEBUG_NEW
00046 #define malloc DEBUG_MALLOC
00047 static char THIS_FILE[] = __FILE__;
00048 #endif
00049
00050 KOMODIA_NAMESPACE_START
00051
00052
00053
00054 #define CTCPOptions_LOGNAME "CTCPOptions"
00055
00056 void CTCPOptions::Reset()
00057 {
00058 try
00059 {
00060 CIPOptions::Reset();
00061 }
00062 ERROR_HANDLER("Reset")
00063 }
00064
00065 void CTCPOptions::SetAutoPad(BOOL bAutoPAD)
00066 {
00067 try
00068 {
00069 CIPOptions::SetAutoPad(bAutoPAD);
00070 }
00071 ERROR_HANDLER("SetAutoPad")
00072 }
00073
00074 void CTCPOptions::AddOption_ENDLIST()
00075 {
00076 try
00077 {
00078
00079 OptionType aOptionType;
00080
00081
00082 aOptionType=TCPOptions_END;
00083
00084
00085 AddToBuffer((char*)&aOptionType,sizeof(aOptionType));
00086 }
00087 ERROR_HANDLER("AddOption_ENDLIST")
00088 }
00089
00090 int CTCPOptions::GetBufferLength()const
00091 {
00092 try
00093 {
00094 return CIPOptions::GetBufferLength();
00095 }
00096 ERROR_HANDLER_RETURN("GetBufferLength",0)
00097 }
00098
00099 const char* CTCPOptions::GetBuffer()const
00100 {
00101 try
00102 {
00103 return CIPOptions::GetBuffer();
00104 }
00105 ERROR_HANDLER_RETURN("GetBuffer",NULL)
00106 }
00107
00108 void CTCPOptions::AddOption_Nothing()
00109 {
00110 try
00111 {
00112
00113 OptionType aOptionType;
00114
00115
00116 aOptionType=TCPOptions_NO_OPERATION;
00117
00118
00119 AddToBuffer((char*)&aOptionType,sizeof(aOptionType));
00120 }
00121 ERROR_HANDLER("AddOption_Nothing")
00122 }
00123
00124 CTCPOptions::CTCPOptions() : CIPOptions()
00125 {
00126 try
00127 {
00128 SetName(CTCPOptions_LOGNAME);
00129 }
00130 ERROR_HANDLER("CTCPOptions")
00131 }
00132
00133 CTCPOptions::CTCPOptions(const CTCPOptions& rOptions) : CIPOptions(rOptions)
00134 {
00135 try
00136 {
00137 SetName(CTCPOptions_LOGNAME);
00138 }
00139 ERROR_HANDLER("CTCPOptions")
00140 }
00141
00142 CTCPOptions::~CTCPOptions()
00143 {
00144 }
00145
00146 void CTCPOptions::AddOption_SegmentSize(unsigned short usMax)
00147 {
00148 try
00149 {
00150
00151 OptionType aOptionType;
00152
00153
00154 aOptionType=TCPOptions_MAX_Segment;
00155
00156
00157 AddToBuffer((char*)&aOptionType,
00158 sizeof(aOptionType));
00159
00160
00161 aOptionType=TCPOptions_MAX_Segment_Length;
00162 AddToBuffer((char*)&aOptionType,
00163 sizeof(aOptionType));
00164
00165
00166 unsigned short usOT;
00167 usOT=htons(usMax);
00168
00169
00170 AddToBuffer((char*)&usOT,
00171 sizeof(usOT));
00172 }
00173 ERROR_HANDLER("AddOption_SegmentSize")
00174 }
00175
00176
00177
00178 #define CTCPSocket_LOGNAME "CTCPSocket"
00179
00180 unsigned int CTCPSocket::m_uiSequence=(unsigned int)GetCurrentProcessId();
00181
00182 CTCPSocket::CTCPSocket(BOOL bRawSocket) : CSpoofSocket(bRawSocket)
00183 {
00184 try
00185 {
00186
00187 SetName(CTCPSocket_LOGNAME);
00188
00189
00190 InitializeTCP();
00191 }
00192 ERROR_HANDLER("CTCPSocket")
00193 }
00194
00195 CTCPSocket::CTCPSocket(SOCKET aSocket) : CSpoofSocket(aSocket)
00196 {
00197 try
00198 {
00199
00200 SetName(CTCPSocket_LOGNAME);
00201
00202
00203 InitializeTCP();
00204 }
00205 ERROR_HANDLER("CTCPSocket")
00206 }
00207
00208 CTCPSocket::~CTCPSocket()
00209 {
00210 try
00211 {
00212
00213 SetTCPOptions(FALSE);
00214 }
00215 ERROR_HANDLER("~CTCPSocket")
00216 }
00217
00218 BOOL CTCPSocket::Create()
00219 {
00220 try
00221 {
00222
00223 InitializeTCP();
00224
00225
00226 SetProtocol(IPPROTO_TCP);
00227
00228
00229 if (IsRaw())
00230 return CSpoofSocket::Create(IPPROTO_IP);
00231 else
00232 return CSpoofSocket::Create(IPPROTO_TCP);
00233 }
00234 ERROR_HANDLER_RETURN("Create",FALSE)
00235 }
00236
00237 BOOL CTCPSocket::Connect(IP aDestinationAddress,
00238 unsigned short usDestinationPort)
00239 {
00240 try
00241 {
00242 return Connect(0,
00243 aDestinationAddress,
00244 usDestinationPort);
00245 }
00246 ERROR_HANDLER_RETURN("Connect",FALSE)
00247 }
00248
00249 BOOL CTCPSocket::Connect(const std::string& rDestinationAddress,
00250 unsigned short usDestinationPort)
00251 {
00252 try
00253 {
00254 return Connect(0,
00255 rDestinationAddress,
00256 usDestinationPort);
00257 }
00258 ERROR_HANDLER_RETURN("Connect",FALSE)
00259 }
00260
00261 BOOL CTCPSocket::Connect(unsigned short usSourcePort,
00262 IP aDestinationAddress,
00263 unsigned short usDestinationPort)
00264 {
00265 try
00266 {
00267
00268 if (!CheckSocketValid())
00269 return FALSE;
00270
00271
00272 if (IsRaw())
00273 return SendRaw(usSourcePort,
00274 aDestinationAddress,
00275 usDestinationPort,
00276 NULL,
00277 0,
00278 TCPFlag_SYN);
00279 else
00280 {
00281
00282 int iResult;
00283
00284
00285 sockaddr_in aSrc;
00286
00287
00288 memset(&aSrc,
00289 0,
00290 sizeof(aSrc));
00291 aSrc.sin_family=AF_INET;
00292 aSrc.sin_addr.s_addr=aDestinationAddress;
00293 aSrc.sin_port=htons(usDestinationPort);
00294
00295
00296 iResult=connect(GetHandle(),
00297 (sockaddr*)&aSrc,
00298 sizeof(aSrc));
00299
00300
00301 BOOL bBlocked;
00302 bBlocked=FALSE;
00303
00304
00305 if (iResult==GetErrorCode())
00306 {
00307
00308 if (WSAGetLastError()!=WSAEWOULDBLOCK)
00309 SetLastError("Connect");
00310 else
00311 {
00312
00313 bBlocked=TRUE;
00314 iResult=!GetErrorCode();
00315 }
00316 }
00317 else
00318
00319 SetLastError("Connect");
00320
00321 if (iResult!=GetErrorCode())
00322 {
00323
00324 if (!IsAsyncClass())
00325 SetConnectionStatus(TRUE);
00326
00327
00328 SetConnectedTo(aSrc);
00329 }
00330
00331
00332 if (!bBlocked)
00333 return iResult!=GetErrorCode();
00334 else
00335 return FALSE;
00336 }
00337 }
00338 ERROR_HANDLER_RETURN("Connect",FALSE)
00339 }
00340
00341 BOOL CTCPSocket::Connect(unsigned short usSourcePort,
00342 const std::string& rDestinationAddress,
00343 unsigned short usDestinationPort)
00344 {
00345 try
00346 {
00347
00348 if (!CheckSocketValid())
00349 return FALSE;
00350
00351
00352 return Connect(usSourcePort,
00353 StringToLong(rDestinationAddress),
00354 usDestinationPort);
00355 }
00356 ERROR_HANDLER_RETURN("Connect",FALSE)
00357 }
00358
00359 LPTCPHeader CTCPSocket::ConstructTCPHeader(unsigned short usSourcePort,
00360 unsigned short usDestinationPort,
00361 unsigned char ucHeaderLength)const
00362 {
00363 try
00364 {
00365
00366 LPTCPHeader lpHead=new _TCPHeader;
00367
00368
00369 lpHead->usSourcePort=htons(usSourcePort);
00370 lpHead->usDestinationPort=htons(usDestinationPort);
00371
00372
00373 lpHead->usChecksum=0;
00374
00375
00376 lpHead->usWindows=htons(512);
00377
00378
00379 lpHead->ulAcknowledgeNumber=0;
00380
00381
00382 lpHead->ulSequenceNumber=htonl(m_uiSequence++);
00383
00384
00385 lpHead->ucDataOffset=(ucHeaderLength >> 2) << 4;
00386
00387
00388 lpHead->ucFlags=0;
00389
00390
00391 lpHead->usUrgentPointer=0;
00392
00393
00394 return lpHead;
00395 }
00396 ERROR_HANDLER_RETURN("ConstructTCPHeader",NULL)
00397 }
00398
00399 void CTCPSocket::SetHeaderFlag(LPTCPHeader lpHead,unsigned char ucFlags)
00400 {
00401
00402 lpHead->ucFlags=ucFlags;
00403 }
00404
00405 void CTCPSocket::SetTCPOptions(BOOL bOptions)
00406 {
00407 try
00408 {
00409
00410 m_bOptions=bOptions;
00411
00412
00413 if (m_pTCPOptions)
00414 {
00415 delete m_pTCPOptions;
00416 m_pTCPOptions=NULL;
00417 }
00418
00419 if (bOptions)
00420 m_pTCPOptions=new CTCPOptions;
00421 }
00422 ERROR_HANDLER("SetTCPOptions")
00423 }
00424
00425 CTCPOptions* CTCPSocket::GetTCPOptions() const
00426 {
00427 return m_pTCPOptions;
00428 }
00429
00430 BOOL CTCPSocket::Listen(unsigned long ulBackLog)
00431 {
00432 try
00433 {
00434
00435 if (!CheckSocketValid())
00436 return FALSE;
00437
00438
00439 int iResult;
00440 iResult=listen(GetHandle(),
00441 ulBackLog);
00442
00443
00444 if (iResult)
00445 {
00446
00447 SetLastError("Listen");
00448
00449
00450 return FALSE;
00451 }
00452 else
00453 return TRUE;
00454 }
00455 ERROR_HANDLER_RETURN("Listen",FALSE)
00456 }
00457
00458 CTCPSocket* CTCPSocket::Accept()
00459 {
00460 try
00461 {
00462
00463 if (!CheckSocketValid())
00464 return FALSE;
00465
00466
00467 SOCKET aSocket;
00468
00469
00470 sockaddr_in aConnected;
00471
00472
00473 int iSize;
00474 iSize=sizeof(aConnected);
00475
00476
00477 aSocket=accept(GetHandle(),
00478 (sockaddr*)&aConnected,
00479 &iSize);
00480
00481
00482 if (aSocket!=INVALID_SOCKET)
00483 {
00484
00485 CTCPSocket* pSocket;
00486 pSocket=new CTCPSocket(aSocket);
00487
00488
00489 pSocket->SetConnectedTo(aConnected);
00490 pSocket->SetConnectionStatus(TRUE);
00491
00492
00493 return pSocket;
00494 }
00495 else
00496 {
00497
00498 SetLastError("Accept");
00499
00500
00501 return NULL;
00502 }
00503 }
00504 ERROR_HANDLER_RETURN("Accept",NULL)
00505 }
00506
00507 void CTCPSocket::InitializeTCP()
00508 {
00509 try
00510 {
00511
00512 m_bConnected=FALSE;
00513
00514
00515 m_pTCPOptions=NULL;
00516 SetTCPOptions(FALSE);
00517 }
00518 ERROR_HANDLER("InitializeTCP")
00519 }
00520
00521 BOOL CTCPSocket::Accept(CTCPSocket* pNewSocket)
00522 {
00523 try
00524 {
00525
00526 if (!CheckSocketValid())
00527 return FALSE;
00528
00529
00530 SOCKET aNewSocket;
00531
00532
00533 sockaddr_in aAddress;
00534
00535
00536 int iSize;
00537 iSize=sizeof(aAddress);
00538
00539
00540 aNewSocket=accept(GetHandle(),
00541 (sockaddr*)&aAddress,
00542 &iSize);
00543
00544
00545 if (aNewSocket!=INVALID_SOCKET)
00546 {
00547
00548 pNewSocket->BeforeAccept();
00549
00550
00551 pNewSocket->SetConnectedTo(aAddress);
00552 pNewSocket->AssignSocket(aNewSocket);
00553 pNewSocket->SetConnectionStatus(TRUE);
00554 pNewSocket->Accepted();
00555
00556
00557 return TRUE;
00558 }
00559 else
00560 {
00561
00562 SetLastError("Accept");
00563
00564
00565 return FALSE;
00566 }
00567 }
00568 ERROR_HANDLER_RETURN("Accept",FALSE)
00569 }
00570
00571 int CTCPSocket::Send(const char *pBuffer,
00572 unsigned long ulBufferLength)
00573 {
00574 try
00575 {
00576
00577 if (!CheckSocketValid())
00578 return FALSE;
00579
00580
00581 int iResult;
00582
00583
00584 iResult=send(GetHandle(),
00585 pBuffer,
00586 ulBufferLength,
00587 NULL);
00588
00589
00590 if (iResult==GetErrorCode())
00591
00592 SetLastError("Send");
00593
00594
00595 return iResult;
00596 }
00597 ERROR_HANDLER_RETURN("Send",FALSE)
00598 }
00599
00600 void CTCPSocket::Accepted()
00601 {
00602 }
00603
00604 void CTCPSocket::FinalTCPHeader(LPTCPHeader lpHead)const
00605 {
00606 }
00607
00608 int CTCPSocket::SendRaw(unsigned short usSourcePort,
00609 const std::string& rDestinationAddress,
00610 unsigned short usDestinationPort,
00611 const char* pBuffer,
00612 unsigned long ulBufferLength,
00613 unsigned char ucFlags)
00614 {
00615 try
00616 {
00617
00618 if (!CheckSocketValid())
00619 return FALSE;
00620
00621 return SendRaw(usSourcePort,
00622 StringToLong(rDestinationAddress),
00623 usDestinationPort,
00624 pBuffer,
00625 ulBufferLength,
00626 ucFlags);
00627 }
00628 ERROR_HANDLER_RETURN("SendRaw",GetErrorCode())
00629 }
00630
00631 int CTCPSocket::SendRaw(unsigned short usSourcePort,
00632 IP aDestinationAddress,
00633 unsigned short usDestinationPort,
00634 const char* pBuffer,
00635 unsigned long ulBufferLength,
00636 unsigned char ucFlags)
00637 {
00638 try
00639 {
00640
00641 if (!CheckSocketValid())
00642 return FALSE;
00643
00644 if (IsRaw())
00645 {
00646
00647 LPTCPHeader lpHead;
00648
00649
00650 int iHeaderLength;
00651 iHeaderLength=TCPHeaderLength;
00652
00653
00654 if (m_bOptions)
00655 iHeaderLength+=m_pTCPOptions->GetBufferLength();
00656
00657
00658 lpHead=ConstructTCPHeader(usSourcePort,
00659 usDestinationPort,
00660 iHeaderLength);
00661
00662
00663 std::auto_ptr<TCPHeader> pProtection(lpHead);
00664
00665
00666 if (ucFlags)
00667
00668 SetHeaderFlag(lpHead,ucFlags);
00669
00670
00671 int iResult;
00672
00673
00674 if (m_bOptions)
00675 {
00676
00677 char* pOptionBuffer;
00678 pOptionBuffer=new char[iHeaderLength+ulBufferLength];
00679
00680
00681 CArray_ptr<char> pBufferProtection(pOptionBuffer);
00682
00683
00684 memcpy(pOptionBuffer,
00685 lpHead,
00686 TCPHeaderLength);
00687
00688
00689 memcpy(pOptionBuffer+TCPHeaderLength,
00690 m_pTCPOptions->GetBuffer(),
00691 m_pTCPOptions->GetBufferLength());
00692
00693
00694 if (ulBufferLength)
00695
00696 memcpy(pOptionBuffer+
00697 TCPHeaderLength+
00698 m_pTCPOptions->GetBufferLength(),
00699 pBuffer,
00700 ulBufferLength);
00701
00702
00703 int iTotalLength;
00704 iTotalLength=iHeaderLength+ulBufferLength;
00705
00706
00707 lpHead->ucDataOffset=(iTotalLength >> 2) << 4;
00708
00709
00710 lpHead->usChecksum=CalculatePseudoChecksum(pOptionBuffer,
00711 iTotalLength,
00712 aDestinationAddress,
00713 iTotalLength);
00714
00715
00716 FinalTCPHeader(lpHead);
00717
00718
00719 memcpy(pOptionBuffer,
00720 lpHead,
00721 TCPHeaderLength);
00722
00723
00724 iResult=CSpoofSocket::Send(aDestinationAddress,
00725 pOptionBuffer,
00726 iHeaderLength,
00727 usDestinationPort);
00728 }
00729 else
00730 {
00731
00732 unsigned long ulTotalLength;
00733 ulTotalLength=iHeaderLength+ulBufferLength;
00734
00735
00736 char* pNewBuffer;
00737 pNewBuffer=new char[ulTotalLength];
00738
00739
00740 CArray_ptr<char> pBufferProtection(pNewBuffer);
00741
00742
00743 memcpy(pNewBuffer,
00744 lpHead,
00745 ulTotalLength);
00746
00747
00748 if (ulBufferLength)
00749
00750 memcpy(pNewBuffer+iHeaderLength,
00751 pBuffer,
00752 ulBufferLength);
00753
00754
00755 lpHead->usChecksum=CalculatePseudoChecksum(pNewBuffer,
00756 ulTotalLength,
00757 aDestinationAddress,
00758 ulTotalLength);
00759
00760
00761 FinalTCPHeader(lpHead);
00762
00763
00764 memcpy(pNewBuffer,
00765 lpHead,
00766 iHeaderLength);
00767
00768
00769 iResult=CSpoofSocket::Send(aDestinationAddress,
00770 pNewBuffer,
00771 ulTotalLength,
00772 usDestinationPort);
00773 }
00774
00775
00776 SetLastError("Connect");
00777
00778
00779 return iResult;
00780 }
00781 else
00782 {
00783
00784 ReportError("SendRaw","Packet not in raw mode!");
00785
00786
00787 return GetErrorCode();
00788 }
00789 }
00790 ERROR_HANDLER_RETURN("SendRaw",GetErrorCode())
00791 }
00792
00793 void CTCPSocket::SetConnectionStatus(BOOL bConnected)
00794 {
00795 m_bConnected=bConnected;
00796 }
00797
00798 BOOL CTCPSocket::IsConnected()const
00799 {
00800 return m_bConnected;
00801 }
00802
00803 BOOL CTCPSocket::IsAsyncClass()const
00804 {
00805 return FALSE;
00806 }
00807
00808 BOOL CTCPSocket::SetNagle(BOOL bNagle)
00809 {
00810 try
00811 {
00812
00813 if (!CheckSocketValid())
00814 return FALSE;
00815
00816
00817 if (bNagle)
00818 bNagle=FALSE;
00819 else
00820 bNagle=TRUE;
00821
00822
00823 if (setsockopt(GetHandle(),
00824 IPPROTO_TCP,
00825 TCP_NODELAY,
00826 (const char*)&bNagle,
00827 sizeof(bNagle))==GetErrorCode())
00828 {
00829
00830 ReportError("SetNagle","Failed to set nagle");
00831
00832
00833 SetLastError("SetNagle");
00834
00835
00836 return FALSE;
00837 }
00838
00839
00840 return TRUE;
00841 }
00842 ERROR_HANDLER_RETURN("SetNagle",FALSE)
00843 }
00844
00845 BOOL CTCPSocket::Close()
00846 {
00847 try
00848 {
00849
00850 if (!CheckSocketValid())
00851 return FALSE;
00852
00853
00854 if (CSpoofSocket::Close())
00855 {
00856
00857 SetConnectionStatus(FALSE);
00858
00859
00860 return TRUE;
00861 }
00862 else
00863 return FALSE;
00864 }
00865 ERROR_HANDLER_RETURN("Close",FALSE)
00866 }
00867
00868 void CTCPSocket::BeforeAccept()
00869 {
00870 }
00871
00872 KOMODIA_NAMESPACE_END
00873