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 "DNSParser.h"
00038 
00039 #include "ErrorHandlerMacros.h"
00040 #include "Array_ptr.h"
00041 
00042 #ifdef _MEMORY_DEBUG 
00043     #define new    DEBUG_NEW  
00044     #define malloc DEBUG_MALLOC  
00045     static char THIS_FILE[] = __FILE__;  
00046 #endif
00047 
00048 namespace KomodiaDNS
00049 {
00050 
00051 #define CDNSParser_Class "CDNSParser"
00052 
00053 #define MAX_REPLY 2000
00054 #define MAX_DOMAIN_SIZE 1024
00055 
00056 CDNSParser::CDNSParser() : CErrorHandler()
00057 {
00058     try
00059     {
00060         
00061         SetName(CDNSParser_Class);
00062     }
00063     ERROR_HANDLER("CDNSParser")
00064 }
00065 
00066 CDNSParser::~CDNSParser()
00067 {
00068 }
00069 
00070 std::string CDNSParser::ParseName(const char* pBuffer,
00071                                   const char* pOriginalBuffer,
00072                                   unsigned short& rLength)
00073 {
00074     try
00075     {
00076         
00077         rLength=0;
00078 
00079         
00080         unsigned short usShort;
00081         usShort=*((unsigned short*)pBuffer);
00082         
00083         
00084         usShort=htons(usShort);
00085 
00086         
00087         if (usShort & 0xc000)
00088         {
00089             
00090             usShort=usShort & 0x3fff;
00091 
00092             
00093             unsigned short usLength;
00094             usLength=GetParsedDomainLength(pOriginalBuffer+usShort,
00095                                            pOriginalBuffer);
00096 
00097             
00098             if (!usLength)
00099             {
00100                 
00101                 ReportStaticError(CDNSParser_Class,"ParseName","Received zero length!");
00102 
00103                 
00104                 return "";
00105             }
00106             else
00107             {
00108                 
00109                 rLength=2;
00110 
00111                 
00112                 return ConvertParsedName(pOriginalBuffer+usShort,
00113                                          pOriginalBuffer);
00114             }
00115         }
00116         else
00117         {
00118             
00119             
00120             unsigned short usLength;
00121             usLength=GetParsedDomainLength(pBuffer,
00122                                            pOriginalBuffer);
00123 
00124             
00125             if (!usLength)
00126             {
00127                 
00128                 ReportStaticError(CDNSParser_Class,"ParseName","Received zero length!");
00129 
00130                 
00131                 return "";
00132             }
00133             else
00134             {
00135                 
00136                 rLength=usLength;
00137 
00138                 
00139                 return ConvertParsedName(pBuffer,
00140                                          pOriginalBuffer);
00141             }
00142         }
00143     }
00144     ERROR_HANDLER_STATIC_RETURN(CDNSParser_Class,"ParseName","")
00145 }
00146 
00147 unsigned short CDNSParser::GetParsedDomainLength(const char *pBuffer,
00148                                                  const char* pOriginalBuffer)
00149 {
00150     try
00151     {
00152         
00153         const unsigned char* pBackupBuffer=(const unsigned char*)pBuffer;
00154 
00155         
00156         unsigned short usCounter;
00157         usCounter=0;
00158 
00159         while (*pBackupBuffer && 
00160                usCounter<256)
00161         {
00162             if (pOriginalBuffer)
00163             {
00164                 
00165                 unsigned short usShort;
00166                 usShort=*((unsigned short*)pBackupBuffer);
00167             
00168                 
00169                 usShort=htons(usShort);
00170 
00171                 
00172                 if (usShort & 0xc000)
00173                 {
00174                     
00175                     usShort=usShort & 0x3fff;
00176 
00177                     
00178                     if (usShort>MAX_REPLY)
00179                     {
00180                         
00181                         ReportStaticError(CDNSParser_Class,"GetParsedDomainLength","Size too big!");
00182 
00183                         
00184                         return 0;
00185                     }
00186 
00187                     
00188                     unsigned short usLength;
00189                     usLength=GetParsedDomainLength(pOriginalBuffer+usShort,
00190                                                    pOriginalBuffer);
00191 
00192                     
00193                     if (!usLength)
00194                     {
00195                         
00196                         ReportStaticError(CDNSParser_Class,"GetParsedDomainLength","Received zero length!");
00197 
00198                         
00199                         return 0;
00200                     }
00201                     else
00202                     {
00203                         
00204                         usCounter+=usLength;
00205 
00206                         
00207                         return usCounter+1;
00208                     }
00209                 }
00210             }
00211             
00212             
00213             usCounter+=*pBackupBuffer+1;
00214             pBackupBuffer+=*pBackupBuffer+1;
00215         }
00216         
00217         
00218         if (usCounter>256)
00219         {
00220             
00221             ReportStaticError(CDNSParser_Class,"GetParsedDomainLength","Recieved length too high!");
00222 
00223             
00224             return 0;
00225         }
00226         else
00227             return usCounter+1;
00228     }
00229     ERROR_HANDLER_STATIC_RETURN(CDNSParser_Class,"GetParsedDomainLength",0)
00230 }
00231 
00232 std::string CDNSParser::ConvertParsedName(const char* pBuffer,
00233                                           const char* pOriginalBuffer)
00234 {
00235     try
00236     {
00237         
00238         std::string sParsedName;
00239 
00240         
00241         unsigned short usCounter;
00242         usCounter=0;
00243 
00244         while (*pBuffer && 
00245                usCounter<MAX_DOMAIN_SIZE)
00246         {
00247             if (pOriginalBuffer)
00248             {
00249                 
00250                 unsigned short usShort;
00251                 usShort=*((const unsigned short*)pBuffer);
00252             
00253                 
00254                 usShort=htons(usShort);
00255 
00256                 
00257                 if (usShort & 0xc000)
00258                 {
00259                     
00260                     usShort=usShort & 0x3fff;
00261 
00262                     
00263                     if (usShort>MAX_REPLY)
00264                     {
00265                         
00266                         ReportStaticError(CDNSParser_Class,"ConvertParsedName","Size too big!");
00267 
00268                         
00269                         return 0;
00270                     }
00271 
00272                     
00273                     unsigned short usLength;
00274                     usLength=GetParsedDomainLength(pOriginalBuffer+usShort,
00275                                                    pOriginalBuffer);
00276 
00277                     
00278                     if (!usLength)
00279                     {
00280                         
00281                         ReportStaticError(CDNSParser_Class,"ConvertParsedName","Recieved zero length!");
00282 
00283                         
00284                         return "";
00285                     }
00286                     else
00287                         
00288                         pBuffer=pOriginalBuffer+usShort;
00289                 }
00290             }
00291             
00292             
00293             unsigned short usLength;
00294             usLength=*pBuffer;
00295 
00296             
00297             ++pBuffer;
00298 
00299             
00300             CArray_ptr<char> pTmpData(new char[usLength+1]);
00301             memcpy(pTmpData.Get(),
00302                    pBuffer,
00303                    usLength);
00304 
00305             
00306             pTmpData.Get()[usLength]=0;
00307 
00308             
00309             sParsedName+=pTmpData.Get();
00310 
00311             
00312             pBuffer+=usLength;
00313 
00314             
00315             if (*pBuffer)
00316                 
00317                 sParsedName+='.';
00318         }
00319 
00320         
00321         if (usCounter>MAX_DOMAIN_SIZE)
00322         {
00323             
00324             ReportStaticError(CDNSParser_Class,"ConvertParsedName","Recieved size too large!");
00325 
00326             
00327             return "";
00328         }
00329         else
00330             
00331             return sParsedName;
00332     }
00333     ERROR_HANDLER_STATIC_RETURN(CDNSParser_Class,"ConvertParsedName","")
00334 }
00335 
00336 std::string CDNSParser::ConvertName(const std::string& rName)
00337 {
00338     try
00339     {
00340         
00341         unsigned short usLength;
00342 
00343         
00344         std::string sAnswer;
00345         sAnswer=ParseName(rName.c_str(),
00346                           rName.c_str(),
00347                           usLength);
00348 
00349         
00350         if (usLength)
00351             return sAnswer;
00352         else
00353             return "";
00354     }
00355     ERROR_HANDLER_STATIC_RETURN(CDNSParser_Class,"ConvertName","")
00356 }
00357 
00358 
00359 }