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 "ICMPCrafter.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 #define CICMPCrafter_Class "CICMPCrafter"
00053 
00054 CICMPCrafter::CICMPCrafter() : CIPCrafter(),
00055                                CICMPSocket(TRUE)
00056 {
00057     try
00058     {
00059         
00060         SetName(CICMPCrafter_Class);
00061 
00062         
00063         SetProtocol(IPPROTO_ICMP);
00064 
00065         
00066         m_bDefaultChecksum=FALSE;
00067         m_usChecksum=0;
00068     }
00069     ERROR_HANDLER("CICMPCrafter")
00070 }   
00071 
00072 CICMPCrafter::~CICMPCrafter()
00073 {
00074 }
00075 
00076 LPIpHeader CICMPCrafter::ConstructIPHeader(unsigned char  ucProtocol,
00077                                            unsigned short usFragmentationFlags,
00078                                            unsigned char  ucTTL,
00079                                            unsigned short usIdentification,
00080                                            unsigned char  ucHeaderLength)const
00081 {
00082     return ConstructCraftedIPHeader(ucProtocol,
00083                                     usFragmentationFlags,
00084                                     ucTTL,
00085                                     usIdentification,
00086                                     ucHeaderLength);
00087 }
00088 
00089 void CICMPCrafter::FinalIPHeader(LPIpHeader lpHead)const
00090 {
00091     try
00092     {
00093         
00094         if (!m_DefaultChecksum)
00095             lpHead->usChecksum=htons(m_usChecksum);
00096     }
00097     ERROR_HANDLER("FinalIPHeader")
00098 }
00099 
00100 void CICMPCrafter::SetICMPUseDefaultChecksum(BOOL bDefault)
00101 {
00102     m_bDefaultChecksum=bDefault;
00103 }
00104 
00105 void CICMPCrafter::SetICMPChecksum(unsigned short usChecksum)
00106 {
00107     m_usChecksum=usChecksum;
00108 }
00109 
00110 void CICMPCrafter::FinalICMPHeader(LPICMPHeader lpHead)const
00111 {
00112     if (!m_bDefaultChecksum)
00113         lpHead->usICMPChecksum=htons(m_usChecksum);
00114 }
00115 
00116 void CICMPCrafter::SetDestinationAddress(IP aDestinationAddress)
00117 {
00118     m_aDestinationAddress=aDestinationAddress;
00119 }
00120 
00121 void CICMPCrafter::SetDestinationAddress(const std::string& rDestinationAddress)
00122 {
00123     
00124     if (rDestinationAddress.empty())
00125         m_aDestinationAddress=0;
00126     else
00127         m_aDestinationAddress=StringToLong(rDestinationAddress);
00128 }
00129 
00130 char* CICMPCrafter::GetTime(unsigned char cType,
00131                             unsigned short& usTotalSize)const
00132 {
00133     try
00134     {
00135         return CreateFinal(ICMP_Time,
00136                            cType,
00137                            usTotalSize);
00138     }
00139     ERROR_HANDLER_RETURN("GetTime",NULL)
00140 }
00141 
00142 char* CICMPCrafter::GetParameter(unsigned char cError,
00143                                  unsigned short& usTotalSize)const
00144 {
00145     try
00146     {
00147         
00148         LPICMPHeader lpHead;
00149         lpHead=ConstructICMP();
00150 
00151         if (!lpHead)
00152         {
00153             ReportError("GetParameter","Failed to construct ICMP header!");
00154             return FALSE;
00155         }
00156 
00157         
00158         std::auto_ptr<ICMPHeader> pProtection(lpHead);
00159 
00160         
00161         lpHead->ucICMPType=ICMP_Parameter;
00162         lpHead->ucICMPCode=ICMP_Parameter_ERROR;
00163         lpHead->sICMP.sUC.uc1=cError;
00164 
00165         
00166         lpHead->usICMPChecksum=CalculateChecksum((unsigned short*)lpHead,ICMPHeaderLength);
00167 
00168         
00169         return CreateFinal(lpHead,
00170                            usTotalSize);
00171     }
00172     ERROR_HANDLER_RETURN("GetParameter",NULL)
00173 }
00174 
00175 char* CICMPCrafter::GetQuench(unsigned short& usTotalSize)const
00176 {
00177     try
00178     {
00179         return CreateFinal(ICMP_Quench,
00180                            0,
00181                            usTotalSize);
00182     }
00183     ERROR_HANDLER_RETURN("GetQuench",NULL)
00184 }
00185 
00186 char* CICMPCrafter::GetRedirect(unsigned char cType, 
00187                                 IP aGatewayAddress,
00188                                 unsigned short& usTotalSize)const
00189 {
00190     try
00191     {
00192         
00193         LPICMPHeader lpHead;
00194         lpHead=ConstructICMP();
00195 
00196         if (!lpHead)
00197         {
00198             ReportError("GetRedirect","Failed to construct ICMP header!");
00199             return FALSE;
00200         }
00201 
00202         
00203         std::auto_ptr<ICMPHeader> pProtection(lpHead);
00204 
00205         
00206         lpHead->ucICMPType=ICMP_Redirect;
00207         lpHead->ucICMPCode=cType;
00208         lpHead->sICMP.sUL=aGatewayAddress;
00209 
00210         
00211         lpHead->usICMPChecksum=CalculateChecksum((unsigned short*)lpHead,ICMPHeaderLength);
00212 
00213         
00214         return CreateFinal(lpHead,
00215                            usTotalSize);
00216     }
00217     ERROR_HANDLER_RETURN("GetRedirect",NULL)
00218 }
00219 
00220 char* CICMPCrafter::GetEcho(BOOL bReply, 
00221                             unsigned short usIdentifier, 
00222                             unsigned short usSequence, 
00223                             unsigned long ulData,
00224                             unsigned short& usTotalSize)const
00225 {
00226     try
00227     {
00228         
00229         LPICMPHeader lpHead;
00230         lpHead=ConstructICMP();
00231         
00232         if (!lpHead)
00233         {
00234             ReportError("SendEcho","Failed to construct ICMP header!");
00235             return FALSE;
00236         }
00237 
00238         
00239         std::auto_ptr<ICMPHeader> pProtection(lpHead);
00240 
00241         
00242         if (bReply)
00243             lpHead->ucICMPType=ICMP_Echo_Reply;
00244         else
00245             lpHead->ucICMPType=ICMP_Echo;
00246 
00247         lpHead->ucICMPCode=0;
00248         lpHead->sICMP.sUS.us1=htons(usIdentifier);
00249         lpHead->sICMP.sUS.us2=htons(usSequence);
00250         lpHead->ulICMP_Originate_Timestamp=htonl(ulData);
00251 
00252         
00253         lpHead->usICMPChecksum=CalculateChecksum((unsigned short*)lpHead,ICMPHeaderLength);
00254 
00255         
00256         return CreateFinal(lpHead,
00257                            usTotalSize);
00258     }
00259     ERROR_HANDLER_RETURN("GetEcho",NULL)
00260 }
00261 
00262 char* CICMPCrafter::GetTimestamp(BOOL bReply, 
00263                                  unsigned short usIdentifier, 
00264                                  unsigned short usSequence, 
00265                                  unsigned long ulOriginateTimestamp, 
00266                                  unsigned long ulReceiveTimestamp, 
00267                                  unsigned long ulTransmitTimestamp,
00268                                  unsigned short& usTotalSize)const
00269 {
00270     try
00271     {
00272         
00273         LPICMPHeader lpHead;
00274         lpHead=ConstructICMP();
00275 
00276         if (!lpHead)
00277         {
00278             ReportError("GetTimestamp","Failed to construct ICMP header!");
00279             return FALSE;
00280         }
00281 
00282         
00283         std::auto_ptr<ICMPHeader> pProtection(lpHead);
00284 
00285         
00286         if (bReply)
00287             lpHead->ucICMPType=ICMP_Timestamp_Reply;
00288         else
00289             lpHead->ucICMPType=ICMP_Timestamp;
00290 
00291         lpHead->ucICMPCode=0;
00292         lpHead->sICMP.sUS.us1=htons(usIdentifier);
00293         lpHead->sICMP.sUS.us2=htons(usSequence);
00294         lpHead->ulICMP_Originate_Timestamp=htonl(ulOriginateTimestamp);
00295         lpHead->ulICMP_Receive_Timestamp=htonl(ulReceiveTimestamp);
00296         lpHead->ulICMP_Transmit_Timestamp=htonl(ulTransmitTimestamp);
00297 
00298         
00299         lpHead->usICMPChecksum=CalculateChecksum((unsigned short*)lpHead,ICMPHeaderLength);
00300 
00301         
00302         return CreateFinal(lpHead,
00303                            usTotalSize);
00304     }
00305     ERROR_HANDLER_RETURN("GetTimestamp",NULL)
00306 }
00307 
00308 char* CICMPCrafter::GetInformation(BOOL bReply, 
00309                                    unsigned short usIdentifier, 
00310                                    unsigned short usSequence,
00311                                    unsigned short& usTotalSize)const
00312 {
00313     try
00314     {
00315         
00316         LPICMPHeader lpHead;
00317         lpHead=ConstructICMP();
00318 
00319         if (!lpHead)
00320         {
00321             ReportError("GetInformation","Failed to construct ICMP header!");
00322             return FALSE;
00323         }
00324 
00325         
00326         std::auto_ptr<ICMPHeader> pProtection(lpHead);
00327 
00328         
00329         if (bReply)
00330             lpHead->ucICMPType=ICMP_Information_Reply;
00331         else
00332             lpHead->ucICMPType=ICMP_Information;
00333 
00334         lpHead->ucICMPCode=0;
00335         lpHead->sICMP.sUS.us1=htons(usIdentifier);
00336         lpHead->sICMP.sUS.us2=htons(usSequence);
00337         
00338         
00339         
00340         lpHead->usICMPChecksum=CalculateChecksum((unsigned short*)lpHead,ICMP_Information_SIZE);
00341 
00342         
00343         return CreateFinal(lpHead,
00344                            usTotalSize);
00345     }
00346     ERROR_HANDLER_RETURN("GetInformation",NULL)
00347 }
00348 
00349 char* CICMPCrafter::GetUnreachable(unsigned char cType,
00350                                    unsigned short& usTotalSize)const
00351 {
00352     try
00353     {
00354         return CreateFinal(ICMP_Unreachable,
00355                            cType,
00356                            usTotalSize);
00357     }
00358     ERROR_HANDLER_RETURN("GetUnreachable",FALSE)
00359 }
00360 
00361 char* CICMPCrafter::CreateFinal(unsigned char cICMP, 
00362                                 unsigned char cType,
00363                                 unsigned short& usTotalSize)const
00364 {
00365     try
00366     {
00367         
00368         LPICMPHeader lpHead;
00369         lpHead=ConstructICMP();
00370 
00371         if (!lpHead)
00372         {
00373             ReportError("CreateFinal","Failed to construct ICMP header!");
00374             return NULL;
00375         }
00376 
00377         
00378         std::auto_ptr<ICMPHeader> pProtection(lpHead);
00379 
00380         
00381         lpHead->ucICMPType=cICMP;
00382         lpHead->ucICMPCode=cType;
00383 
00384         
00385         lpHead->usICMPChecksum=CalculateChecksum((unsigned short*)lpHead,ICMPHeaderLength);
00386 
00387         
00388         FinalICMPHeader(lpHead);
00389 
00390         
00391         return CIPCrafter::GetCraftedPacket(this,
00392                                             m_aDestinationAddress,
00393                                             (char*)lpHead,
00394                                             ICMPHeaderLength,
00395                                             usTotalSize);
00396     }
00397     ERROR_HANDLER_RETURN("CreateFinal",NULL)
00398 }
00399 
00400 char* CICMPCrafter::CreateFinal(const LPICMPHeader pHeader,
00401                                 unsigned short& usTotalSize)const
00402 {
00403     try
00404     {
00405         
00406         if (GetSendBuffer())
00407         {
00408             
00409             unsigned long ulNewSize;
00410             ulNewSize=GetBufferSize()+ICMPHeaderLength;
00411 
00412             
00413             char* pBuffer;
00414             pBuffer=new char[ulNewSize];
00415 
00416             
00417             CArray_ptr<char> pProtection(pBuffer);
00418 
00419             
00420             memcpy(pBuffer,pHeader,ICMPHeaderLength);
00421             memcpy(pBuffer+ICMPHeaderLength,
00422                    GetSendBuffer(),
00423                    GetBufferSize());
00424 
00425             
00426             return CIPCrafter::GetCraftedPacket(this,
00427                                                 m_aDestinationAddress,
00428                                                 pBuffer,
00429                                                 ulNewSize,
00430                                                 usTotalSize);
00431         }
00432         else
00433             return CIPCrafter::GetCraftedPacket(this,
00434                                                 m_aDestinationAddress,
00435                                                 (char*)pHeader,
00436                                                 ICMPHeaderLength,
00437                                                 usTotalSize);
00438     }
00439     ERROR_HANDLER_RETURN("CreateFinal",NULL)
00440 }
00441 
00442 KOMODIA_NAMESPACE_END