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 }