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 }