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 "DNSAnswers.h"
00038 
00039 #include "ErrorHandlerMacros.h"
00040 #include "Array_ptr.h"
00041 
00042 #include "SpoofBase.h"
00043 
00044 #include "DNSParser.h"
00045 
00046 #ifdef _MEMORY_DEBUG 
00047     #define new    DEBUG_NEW  
00048     #define malloc DEBUG_MALLOC  
00049     static char THIS_FILE[] = __FILE__;  
00050 #endif
00051 
00052 namespace KomodiaDNS
00053 {
00054 
00055 #define CDNSAnswers_Class "CDNSAnswers"
00056 
00057 CDNSAnswers::CDNSAnswers() : CErrorHandler(),
00058                              m_pDNSQuery(NULL)
00059 {
00060     try
00061     {
00062         
00063         SetName(CDNSAnswers_Class);
00064     }
00065     ERROR_HANDLER("CDNSAnswers")
00066 }
00067 
00068 CDNSAnswers::CDNSAnswers(const CDNSAnswers& rAnswers) : CErrorHandler(),
00069                                                         m_pDNSQuery(NULL),
00070                                                         m_aAnswers(rAnswers.m_aAnswers)
00071 {
00072     try
00073     {
00074         
00075         SetName(CDNSAnswers_Class);
00076 
00077         
00078         if (rAnswers.m_pDNSQuery)
00079             
00080             m_pDNSQuery=new CDNSQuery(*rAnswers.m_pDNSQuery);
00081     }
00082     ERROR_HANDLER("CDNSAnswers")
00083 }
00084 
00085 CDNSAnswers::~CDNSAnswers()
00086 {
00087     try
00088     {
00089         
00090         delete m_pDNSQuery;
00091     }
00092     ERROR_HANDLER("~CDNSAnswers")
00093 }
00094 
00095 const CDNSAnswer& CDNSAnswers::GetAnswer(unsigned short usIndex)const
00096 {
00097     return m_aAnswers[usIndex];
00098 }
00099 
00100 int CDNSAnswers::Parse(const char *pBuffer,
00101                        int iLength)
00102 {
00103     try
00104     {
00105         
00106         UnInitialize();
00107 
00108         if (iLength<=DnsHeaderHeaderLength)
00109         {
00110             
00111             ReportError("Parse","Buffer size too small!");
00112 
00113             
00114             return 0;
00115         }
00116 
00117         
00118         const char* pBackupBuffer=pBuffer;
00119 
00120         
00121         memcpy(&m_aDNSHeader,
00122                pBackupBuffer,
00123                DnsHeaderHeaderLength);
00124 
00125         
00126         ReverseHeader();
00127 
00128         
00129         pBackupBuffer+=DnsHeaderHeaderLength;
00130 
00131         
00132         m_pDNSQuery=new CDNSQuery;
00133 
00134         
00135         unsigned short usParseLength;
00136 
00137         
00138         usParseLength=m_pDNSQuery->Parse(pBackupBuffer,
00139                                          m_aDNSHeader.usQDCount);
00140 
00141         
00142         if (!usParseLength)
00143         {
00144             
00145             ReportError("Parse","Received zero length!");
00146 
00147             
00148             return 0;
00149         }
00150 
00151         
00152         pBackupBuffer+=usParseLength;
00153 
00154         
00155         return ParseAnswers(pBackupBuffer,
00156                             pBuffer);
00157     }
00158     ERROR_HANDLER_RETURN("Parse",0)
00159 }
00160 
00161 void CDNSAnswers::UnInitialize()
00162 {
00163     try
00164     {
00165         
00166         delete m_pDNSQuery;
00167         m_pDNSQuery=NULL;
00168 
00169         
00170         m_aAnswers.clear();
00171     }
00172     ERROR_HANDLER("UnInitialize")
00173 }
00174 
00175 void CDNSAnswers::ReverseHeader()
00176 {
00177     try
00178     {
00179         
00180         m_aDNSHeader.usANCount=htons(m_aDNSHeader.usANCount);
00181         m_aDNSHeader.usARCount=htons(m_aDNSHeader.usARCount);
00182         m_aDNSHeader.usID=htons(m_aDNSHeader.usID);
00183         m_aDNSHeader.usNSCount=htons(m_aDNSHeader.usNSCount);
00184         m_aDNSHeader.usQDCount=htons(m_aDNSHeader.usQDCount);
00185     }
00186     ERROR_HANDLER("ReverseHeader")
00187 }
00188 
00189 unsigned short CDNSAnswers::ParseAnswers(const char *pBuffer,
00190                                          const char* pOriginalBuffer)
00191 {
00192     try
00193     {
00194         
00195         
00196         int iAnswers;
00197         iAnswers=m_aDNSHeader.usARCount+
00198                  m_aDNSHeader.usANCount+
00199                  m_aDNSHeader.usNSCount;
00200 
00201         for (int iCount=0;iCount<iAnswers;++iCount)
00202         {
00203             
00204             CDNSAnswer aAnswer;
00205 
00206             
00207             unsigned short usParseSize;
00208             usParseSize=aAnswer.ParseBuffer(pBuffer,
00209                                             pOriginalBuffer);
00210 
00211             if (!usParseSize)
00212             {
00213                 
00214                 ReportError("ParseAnswers","Failed to parse answer!");
00215 
00216                 
00217                 return 0;
00218             }
00219 
00220             
00221             CDNSAnswer::DnsHeaderType aAnswerType;
00222             if (iCount<m_aDNSHeader.usANCount)
00223                 aAnswerType=CDNSAnswer::dhAnswer;
00224             else if (iCount<m_aDNSHeader.usANCount+
00225                             m_aDNSHeader.usNSCount)
00226                 aAnswerType=CDNSAnswer::dhAuthoritive;
00227             else
00228                 aAnswerType=CDNSAnswer::dhAdditional;
00229 
00230             
00231             aAnswer.SetAnswerType(aAnswerType);
00232 
00233             
00234             m_aAnswers.push_back(aAnswer);
00235 
00236             
00237             pBuffer+=usParseSize;
00238         }
00239 
00240         
00241         return pBuffer-pOriginalBuffer;
00242     }
00243     ERROR_HANDLER_RETURN("ParseAnswers",0)
00244 }
00245 
00246 unsigned long CDNSAnswers::GetAddress(unsigned short usIndex)const
00247 {
00248     try
00249     {
00250         if (!m_aDNSHeader.usARCount || 
00251             !m_aDNSHeader.usANCount)
00252         {
00253             
00254             ReportError("GetAddress","No answers!");
00255 
00256             
00257             return 0;
00258         }
00259 
00260         
00261         unsigned short usPrior;
00262         usPrior=m_aDNSHeader.usANCount+
00263                 m_aDNSHeader.usNSCount;
00264 
00265         for (unsigned short usCounter=usIndex;
00266              usCounter<m_aDNSHeader.usARCount-usIndex;
00267              ++usCounter)
00268             if (m_aAnswers[usPrior+usCounter].GetResourceType()==CDNSQuery::A)
00269             {
00270                 
00271                 std::string sData;
00272                 sData=m_aAnswers[usPrior+usCounter].GetData();
00273 
00274                 
00275                 return atol(sData.c_str());
00276             }
00277 
00278         
00279         return 0;
00280     }
00281     ERROR_HANDLER_RETURN("GetAddress",0)
00282 }
00283 
00284 BOOL CDNSAnswers::IsResolved()const
00285 {
00286     return !(m_aDNSHeader.usOptions & DNS_SERVER_FAILURE);
00287 }
00288 
00289 unsigned short CDNSAnswers::GetDNSID() const
00290 {
00291     return m_aDNSHeader.usID;
00292 }
00293 
00294 unsigned long CDNSAnswers::GetAIPAnswer()const
00295 {
00296     try
00297     {
00298         
00299         if (!m_aDNSHeader.usANCount ||
00300             m_aAnswers.empty())
00301             return 0;
00302 
00303         
00304         const CDNSAnswer& rAnswer=m_aAnswers[0];
00305 
00306         
00307         if (rAnswer.GetResourceType()==CDNSQuery::A)
00308         {
00309             
00310             std::string sData;
00311             sData=rAnswer.GetData();
00312 
00313             
00314             return atol(sData.c_str());
00315         }
00316         else if (rAnswer.GetResourceType()==CDNSQuery::MX &&
00317                  m_aDNSHeader.usARCount)
00318         {
00319             
00320             int iPos;
00321             iPos=m_aDNSHeader.usANCount+
00322                  m_aDNSHeader.usNSCount;
00323 
00324             
00325             std::string sData;
00326             sData=rAnswer.GetData();
00327 
00328             
00329             for (int iCount=0;
00330                  iCount<m_aDNSHeader.usARCount;
00331                  iCount++)
00332             {
00333                 
00334                 const CDNSAnswer& rARAnswer=m_aAnswers[iCount+iPos];
00335 
00336                 
00337                 if (rARAnswer.GetResourceType()==CDNSQuery::A &&
00338                     rARAnswer.GetName()==sData)
00339                     
00340                     return atol(rARAnswer.GetData().c_str());
00341             }
00342 
00343             
00344             return 0;
00345         }
00346         else
00347             return 0;
00348     }
00349     ERROR_HANDLER_RETURN("GetAIPAnswer",0)
00350 }
00351 
00352 CDNSAnswers::IPAnswersVector CDNSAnswers::GetAIPAnswers()const
00353 {
00354     
00355     static IPAnswersVector aEmptyVector;
00356 
00357     try
00358     {
00359         
00360         IPAnswersVector aVector;
00361 
00362         
00363         if (!m_aDNSHeader.usANCount ||
00364             m_aAnswers.empty())
00365             return aVector;
00366 
00367         
00368         for (int iCount=0;
00369              iCount<m_aDNSHeader.usANCount;
00370              ++iCount)
00371         {
00372             
00373             const CDNSAnswer& rAnswer=m_aAnswers[iCount];
00374 
00375             
00376             if (rAnswer.GetResourceType()==CDNSQuery::A)
00377             {
00378                 
00379                 std::string sData;
00380                 sData=rAnswer.GetData();
00381 
00382                 
00383                 aVector.push_back(atol(sData.c_str()));
00384             }
00385             else if (rAnswer.GetResourceType()==CDNSQuery::MX &&
00386                      m_aDNSHeader.usARCount)
00387             {
00388                 
00389                 int iPos;
00390                 iPos=m_aDNSHeader.usANCount+
00391                      m_aDNSHeader.usNSCount;
00392 
00393                 
00394                 std::string sData;
00395                 sData=rAnswer.GetData();
00396 
00397                 
00398                 for (int iCount=0;
00399                      iCount<m_aDNSHeader.usARCount;
00400                      iCount++)
00401                 {
00402                     
00403                     const CDNSAnswer& rARAnswer=m_aAnswers[iCount+iPos];
00404 
00405                     
00406                     if (rARAnswer.GetResourceType()==CDNSQuery::A &&
00407                         rARAnswer.GetName()==sData)
00408                         
00409                         aVector.push_back(atol(rARAnswer.GetData().c_str()));
00410                 }
00411             }
00412         }
00413 
00414         
00415         return aVector;
00416     }
00417     ERROR_HANDLER_RETURN("GetAIPAnswers",aEmptyVector)
00418 }
00419 
00420 std::string CDNSAnswers::GetAnswer()const
00421 {
00422     try
00423     {
00424         
00425         if (!m_aDNSHeader.usANCount ||
00426             m_aAnswers.empty())
00427             return "";
00428 
00429         
00430         const CDNSAnswer& rAnswer=m_aAnswers[0];
00431 
00432         
00433         if (rAnswer.GetResourceType()==CDNSQuery::PTR ||
00434             rAnswer.GetResourceType()==CDNSQuery::MX)
00435         {
00436             
00437             std::string sData;
00438             sData=rAnswer.GetData();
00439 
00440             
00441             return sData;
00442         }
00443         else if (rAnswer.GetResourceType()==CDNSQuery::A)
00444         {
00445             
00446             std::string sData;
00447             sData=rAnswer.GetData();
00448 
00449             
00450             DWORD dwIP;
00451             dwIP=atof(sData.c_str());
00452 
00453             
00454             return CSpoofBase::LongToStdString(dwIP);
00455         }
00456         else
00457             return "";
00458     }
00459     ERROR_HANDLER_RETURN("GetAnswer","")
00460 }
00461 
00462 CDNSAnswers::StringAnswersVector CDNSAnswers::GetAnswers()const
00463 {
00464     
00465     static StringAnswersVector aEmptyVector;
00466 
00467     try
00468     {
00469         
00470         StringAnswersVector aVector;
00471 
00472         
00473         if (!m_aDNSHeader.usANCount ||
00474             m_aAnswers.empty())
00475             return aEmptyVector;
00476 
00477         
00478         for (int iCount=0;
00479              iCount<m_aDNSHeader.usANCount;
00480              ++iCount)
00481         {
00482             
00483             const CDNSAnswer& rAnswer=m_aAnswers[iCount];
00484 
00485             
00486             if (rAnswer.GetResourceType()==CDNSQuery::PTR ||
00487                 rAnswer.GetResourceType()==CDNSQuery::MX)
00488             {
00489                 
00490                 std::string sData;
00491                 sData=rAnswer.GetData();
00492 
00493                 
00494                 aVector.push_back(sData);
00495             }
00496             else if (rAnswer.GetResourceType()==CDNSQuery::A)
00497             {
00498                 
00499                 std::string sData;
00500                 sData=rAnswer.GetData();
00501 
00502                 
00503                 DWORD dwIP;
00504                 dwIP=atof(sData.c_str());
00505 
00506                 
00507                 
00508                 aVector.push_back(CSpoofBase::LongToStdString(dwIP));
00509             }
00510         }
00511 
00512         
00513         return aVector;
00514     }
00515     ERROR_HANDLER_RETURN("GetAnswers",aEmptyVector)
00516 }
00517 
00518 const CDNSQuery* CDNSAnswers::GetQuery()const
00519 {
00520     return m_pDNSQuery;
00521 }
00522 
00523 std::string CDNSAnswers::GetAnswerParsed(BOOL bWindowsLines,
00524                                          BOOL bBrief,
00525                                          BOOL bExtraLine)const
00526 {
00527     try
00528     {
00529         
00530         
00531         char aEndOfLine[3];
00532 
00533         
00534         if (bWindowsLines)
00535         {
00536             aEndOfLine[0]=13;
00537             aEndOfLine[1]=10;
00538             aEndOfLine[2]=0;
00539         }
00540         else
00541         {
00542             aEndOfLine[0]='\n';
00543             aEndOfLine[1]=0;
00544         }
00545 
00546         
00547         std::string sAnswer;
00548 
00549         
00550         for (int iCount=0;
00551              iCount<m_aAnswers.size();
00552              iCount++)
00553         {
00554             
00555             if (iCount<m_aDNSHeader.usANCount &&
00556                 !iCount)
00557             {
00558                 
00559                 sAnswer+="Non-authoritative answer:";
00560                 sAnswer+=aEndOfLine;
00561             }
00562             else if ((iCount<m_aDNSHeader.usANCount+
00563                              m_aDNSHeader.usNSCount) &&
00564                      iCount==m_aDNSHeader.usANCount)
00565             {
00566                 
00567                 sAnswer+=aEndOfLine;
00568                 sAnswer+="Authoritive servers:";
00569                 sAnswer+=aEndOfLine;
00570             }
00571             else if (iCount==m_aDNSHeader.usANCount+
00572                              m_aDNSHeader.usNSCount)
00573             {
00574                 
00575                 sAnswer+=aEndOfLine;
00576                 sAnswer+="Additional records:";
00577                 sAnswer+=aEndOfLine;
00578             }
00579 
00580             
00581             sAnswer+=m_aAnswers[iCount].GetAnswerParsed(bWindowsLines,
00582                                                         bBrief);
00583             sAnswer+=aEndOfLine;
00584         }
00585 
00586         
00587         if (bExtraLine)
00588             sAnswer+=aEndOfLine;
00589 
00590         
00591         return sAnswer;
00592     }
00593     ERROR_HANDLER_RETURN("GetAnswerParsed","")
00594 }
00595 
00596 BOOL CDNSAnswers::IsReverseAnswer()const
00597 {
00598     return IsResolved() &&
00599            m_pDNSQuery->GetFirstQueryType()==CDNSQuery::PTR;
00600 }
00601 
00602 
00603 }