Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenutility.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS nslookup utility 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: applications/network/nslookup/utility.c 00005 * PURPOSE: Support functions for nslookup.c 00006 * COPYRIGHT: Copyright 2009 Lucas Suggs <lucas.suggs@gmail.com> 00007 */ 00008 00009 #include "nslookup.h" 00010 00011 BOOL SendRequest( PCHAR pInBuffer, 00012 ULONG InBufferLength, 00013 PCHAR pOutBuffer, 00014 PULONG pOutBufferLength ) 00015 { 00016 int j; 00017 USHORT RequestID, ResponseID; 00018 BOOL bWait; 00019 SOCKET s; 00020 SOCKADDR_IN RecAddr, RecAddr2, SendAddr; 00021 int SendAddrLen = sizeof(SendAddr); 00022 00023 RtlZeroMemory( &RecAddr, sizeof(SOCKADDR_IN) ); 00024 RtlZeroMemory( &RecAddr2, sizeof(SOCKADDR_IN) ); 00025 RtlZeroMemory( &SendAddr, sizeof(SOCKADDR_IN) ); 00026 00027 /* Pull the request ID from the buffer. */ 00028 RequestID = ntohs( ((PSHORT)&pInBuffer[0])[0] ); 00029 00030 /* If D2 flags is enabled, then display D2 information. */ 00031 if( State.d2 ) PrintD2( pInBuffer, InBufferLength ); 00032 00033 /* Create the sockets for both send and receive. */ 00034 s = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); 00035 00036 /* Set up the structure to tell it where we are going. */ 00037 RecAddr.sin_family = AF_INET; 00038 RecAddr.sin_port = htons( State.port ); 00039 RecAddr.sin_addr.s_addr = inet_addr( State.DefaultServerAddress ); 00040 00041 /* Set up the structure to tell it what port to listen on. */ 00042 RecAddr2.sin_family = AF_INET; 00043 RecAddr2.sin_port = htons( State.port ); 00044 RecAddr2.sin_addr.s_addr = htonl( INADDR_ANY ); 00045 00046 /* Bind the receive socket. */ 00047 bind( s, (SOCKADDR*)&RecAddr2, sizeof(RecAddr2) ); 00048 00049 /* Send the datagram to the DNS server. */ 00050 j = sendto( s, 00051 pInBuffer, 00052 InBufferLength, 00053 0, 00054 (SOCKADDR*)&RecAddr, 00055 sizeof(RecAddr) ); 00056 if( j == SOCKET_ERROR ) 00057 { 00058 switch( WSAGetLastError() ) 00059 { 00060 case WSANOTINITIALISED: 00061 _tprintf( _T("sendto() failed with WSANOTINITIALIZED\n") ); 00062 break; 00063 case WSAENETDOWN: 00064 _tprintf( _T("sendto() failed with WSAENETDOWN\n") ); 00065 break; 00066 case WSAEACCES: 00067 _tprintf( _T("sendto() failed with WSAEACCES\n") ); 00068 break; 00069 case WSAEINVAL: 00070 _tprintf( _T("sendto() failed with WSAEINVAL\n") ); 00071 break; 00072 case WSAEINTR: 00073 _tprintf( _T("sendto() failed with WSAEINTR\n") ); 00074 break; 00075 case WSAEINPROGRESS: 00076 _tprintf( _T("sendto() failed with WSAEINPROGRESS\n") ); 00077 break; 00078 case WSAEFAULT: 00079 _tprintf( _T("sendto() failed with WSAEFAULT\n") ); 00080 break; 00081 case WSAENETRESET: 00082 _tprintf( _T("sendto() failed with WSAENETRESET\n") ); 00083 break; 00084 case WSAENOBUFS: 00085 _tprintf( _T("sendto() failed with WSAENOBUFS\n") ); 00086 break; 00087 case WSAENOTCONN: 00088 _tprintf( _T("sendto() failed with WSAENOTCONN\n") ); 00089 break; 00090 case WSAENOTSOCK: 00091 _tprintf( _T("sendto() failed with WSAENOTSOCK\n") ); 00092 break; 00093 case WSAEOPNOTSUPP: 00094 _tprintf( _T("sendto() failed with WSAEOPNOTSUPP\n") ); 00095 break; 00096 case WSAESHUTDOWN: 00097 _tprintf( _T("sendto() failed with WSAESHUTDOWN\n") ); 00098 break; 00099 case WSAEWOULDBLOCK: 00100 _tprintf( _T("sendto() failed with WSAEWOULDBLOCK\n") ); 00101 break; 00102 case WSAEMSGSIZE: 00103 _tprintf( _T("sendto() failed with WSAEMSGSIZE\n") ); 00104 break; 00105 case WSAEHOSTUNREACH: 00106 _tprintf( _T("sendto() failed with WSAEHOSTUNREACH\n") ); 00107 break; 00108 case WSAECONNABORTED: 00109 _tprintf( _T("sendto() failed with WSAECONNABORTED\n") ); 00110 break; 00111 case WSAECONNRESET: 00112 _tprintf( _T("sendto() failed with WSAECONNRESET\n") ); 00113 break; 00114 case WSAEADDRNOTAVAIL: 00115 _tprintf( _T("sendto() failed with WSAEADDRNOTAVAIL\n") ); 00116 break; 00117 case WSAEAFNOSUPPORT: 00118 _tprintf( _T("sendto() failed with WSAEAFNOSUPPORT\n") ); 00119 break; 00120 case WSAEDESTADDRREQ: 00121 _tprintf( _T("sendto() failed with WSAEDESTADDRREQ\n") ); 00122 break; 00123 case WSAENETUNREACH: 00124 _tprintf( _T("sendto() failed with WSAENETUNREACH\n") ); 00125 break; 00126 case WSAETIMEDOUT: 00127 _tprintf( _T("sendto() failed with WSAETIMEDOUT\n") ); 00128 break; 00129 default: 00130 _tprintf( _T("sendto() failed with unknown error\n") ); 00131 } 00132 00133 return FALSE; 00134 } 00135 00136 bWait = TRUE; 00137 00138 while( bWait ) 00139 { 00140 /* Wait for the DNS reply. */ 00141 j = recvfrom( s, 00142 pOutBuffer, 00143 *pOutBufferLength, 00144 0, 00145 (SOCKADDR*)&SendAddr, 00146 &SendAddrLen ); 00147 if( j == SOCKET_ERROR ) 00148 { 00149 switch( WSAGetLastError() ) 00150 { 00151 case WSANOTINITIALISED: 00152 _tprintf( _T("recvfrom() failed with WSANOTINITIALIZED\n") ); 00153 break; 00154 case WSAENETDOWN: 00155 _tprintf( _T("recvfrom() failed with WSAENETDOWN\n") ); 00156 break; 00157 case WSAEACCES: 00158 _tprintf( _T("recvfrom() failed with WSAEACCES\n") ); 00159 break; 00160 case WSAEINVAL: 00161 _tprintf( _T("recvfrom() failed with WSAEINVAL\n") ); 00162 break; 00163 case WSAEINTR: 00164 _tprintf( _T("recvfrom() failed with WSAEINTR\n") ); 00165 break; 00166 case WSAEINPROGRESS: 00167 _tprintf( _T("recvfrom() failed with WSAEINPROGRESS\n") ); 00168 break; 00169 case WSAEFAULT: 00170 _tprintf( _T("recvfrom() failed with WSAEFAULT\n") ); 00171 break; 00172 case WSAENETRESET: 00173 _tprintf( _T("recvfrom() failed with WSAENETRESET\n") ); 00174 break; 00175 case WSAENOBUFS: 00176 _tprintf( _T("recvfrom() failed with WSAENOBUFS\n") ); 00177 break; 00178 case WSAENOTCONN: 00179 _tprintf( _T("recvfrom() failed with WSAENOTCONN\n") ); 00180 break; 00181 case WSAENOTSOCK: 00182 _tprintf( _T("recvfrom() failed with WSAENOTSOCK\n") ); 00183 break; 00184 case WSAEOPNOTSUPP: 00185 _tprintf( _T("recvfrom() failed with WSAEOPNOTSUPP\n") ); 00186 break; 00187 case WSAESHUTDOWN: 00188 _tprintf( _T("recvfrom() failed with WSAESHUTDOWN\n") ); 00189 break; 00190 case WSAEWOULDBLOCK: 00191 _tprintf( _T("recvfrom() failed with WSAEWOULDBLOCK\n") ); 00192 break; 00193 case WSAEMSGSIZE: 00194 _tprintf( _T("recvfrom() failed with WSAEMSGSIZE\n") ); 00195 break; 00196 case WSAEHOSTUNREACH: 00197 _tprintf( _T("recvfrom() failed with WSAEHOSTUNREACH\n") ); 00198 break; 00199 case WSAECONNABORTED: 00200 _tprintf( _T("recvfrom() failed with WSAECONNABORTED\n") ); 00201 break; 00202 case WSAECONNRESET: 00203 _tprintf( _T("recvfrom() failed with WSAECONNRESET\n") ); 00204 break; 00205 case WSAEADDRNOTAVAIL: 00206 _tprintf( _T("recvfrom() failed with WSAEADDRNOTAVAIL\n") ); 00207 break; 00208 case WSAEAFNOSUPPORT: 00209 _tprintf( _T("recvfrom() failed with WSAEAFNOSUPPORT\n") ); 00210 break; 00211 case WSAEDESTADDRREQ: 00212 _tprintf( _T("recvfrom() failed with WSAEDESTADDRREQ\n") ); 00213 break; 00214 case WSAENETUNREACH: 00215 _tprintf( _T("recvfrom() failed with WSAENETUNREACH\n") ); 00216 break; 00217 case WSAETIMEDOUT: 00218 _tprintf( _T("recvfrom() failed with WSAETIMEDOUT\n") ); 00219 break; 00220 default: 00221 _tprintf( _T("recvfrom() failed with unknown error\n") ); 00222 } 00223 00224 return FALSE; 00225 } 00226 00227 ResponseID = ntohs( ((PSHORT)&pOutBuffer[0])[0] ); 00228 00229 if( ResponseID == RequestID ) bWait = FALSE; 00230 } 00231 00232 /* We don't need the sockets anymore. */ 00233 closesocket( s ); 00234 00235 /* If debug information then display debug information. */ 00236 if( State.debug ) PrintDebug( pOutBuffer, j ); 00237 00238 /* Return the real output buffer length. */ 00239 *pOutBufferLength = j; 00240 00241 return TRUE; 00242 } 00243 00244 void ReverseIP( PCHAR pIP, PCHAR pReturn ) 00245 { 00246 int i; 00247 int j; 00248 int k = 0; 00249 00250 j = strlen( pIP ) - 1; 00251 i = j; 00252 00253 /* We have A.B.C.D 00254 We will turn this into D.C.B.A and stick it in pReturn */ 00255 00256 /* A */ 00257 for( ; i > 0; i -= 1 ) if( '.' == pIP[i] ) break; 00258 00259 strncpy( &pReturn[k], &pIP[i + 1], (j - i) ); 00260 k += (j - i); 00261 00262 pReturn[k] = '.'; 00263 k += 1; 00264 00265 i -= 1; 00266 j = i; 00267 00268 /* B */ 00269 for( ; i > 0; i -= 1 ) if( '.' == pIP[i] ) break; 00270 00271 strncpy( &pReturn[k], &pIP[i + 1], (j - i) ); 00272 k += (j - i); 00273 00274 pReturn[k] = '.'; 00275 k += 1; 00276 00277 i -= 1; 00278 j = i; 00279 00280 /* C */ 00281 for( ; i > 0; i -= 1 ) if( '.' == pIP[i] ) break; 00282 00283 strncpy( &pReturn[k], &pIP[i + 1], (j - i) ); 00284 k += (j - i); 00285 00286 pReturn[k] = '.'; 00287 k += 1; 00288 00289 i -= 1; 00290 j = i; 00291 00292 /* D */ 00293 for( ; i > 0; i -= 1 ); 00294 00295 strncpy( &pReturn[k], &pIP[i], (j - i) + 1 ); 00296 k += (j - i) + 1; 00297 00298 pReturn[k] = '\0'; 00299 } 00300 00301 BOOL IsValidIP( PCHAR pInput ) 00302 { 00303 int i = 0, l = 0, b = 0, c = 1; 00304 00305 /* Max length of an IP, e.g. 255.255.255.255, is 15 characters. */ 00306 l = strlen( pInput ); 00307 if( l > 15 ) return FALSE; 00308 00309 /* 'b' is the count of the current segment. It gets reset after seeing a 00310 '.'. */ 00311 for( ; i < l; i += 1 ) 00312 { 00313 if( '.' == pInput[i] ) 00314 { 00315 if( !b ) return FALSE; 00316 if( b > 3 ) return FALSE; 00317 00318 b = 0; 00319 c += 1; 00320 } 00321 else 00322 { 00323 b += 1; 00324 00325 if( (pInput[i] < '0') || (pInput[i] > '9') ) return FALSE; 00326 } 00327 } 00328 00329 if( b > 3 ) return FALSE; 00330 00331 /* 'c' is the number of segments seen. If it's less than 4, then it's not 00332 a valid IP. */ 00333 if( c < 4 ) return FALSE; 00334 00335 return TRUE; 00336 } 00337 00338 int ExtractName( PCHAR pBuffer, PCHAR pOutput, USHORT Offset, UCHAR Limit ) 00339 { 00340 int c = 0, d = 0, i = 0, j = 0, k = 0, l = 0, m = 0; 00341 00342 i = Offset; 00343 00344 /* If Limit == 0, then we assume "no" limit. */ 00345 d = Limit; 00346 if( 0 == Limit ) d = 255; 00347 00348 while( d > 0 ) 00349 { 00350 l = pBuffer[i] & 0xFF; 00351 i += 1; 00352 if( !m ) c += 1; 00353 00354 if( 0xC0 == l ) 00355 { 00356 if( !m ) c += 1; 00357 m = 1; 00358 d += (255 - Limit); 00359 i = pBuffer[i]; 00360 } 00361 else 00362 { 00363 for( j = 0; j < l; j += 1 ) 00364 { 00365 pOutput[k] = pBuffer[i]; 00366 00367 i += 1; 00368 if( !m ) c += 1; 00369 k += 1; 00370 d -= 1; 00371 } 00372 00373 d -= 1; 00374 00375 if( !pBuffer[i] || (d < 1) ) break; 00376 00377 pOutput[k] = '.'; 00378 k += 1; 00379 } 00380 }; 00381 00382 if( !m ) 00383 { 00384 if( !Limit ) c += 1; 00385 } 00386 00387 pOutput[k] = '\0'; 00388 00389 return c; 00390 } 00391 00392 int ExtractIP( PCHAR pBuffer, PCHAR pOutput, USHORT Offset ) 00393 { 00394 int c = 0, l = 0, i = 0, v = 0; 00395 00396 i = Offset; 00397 00398 v = (UCHAR)pBuffer[i]; 00399 l += 1; 00400 i += 1; 00401 00402 sprintf( &pOutput[c], "%d.", v ); 00403 c += strlen( &pOutput[c] ); 00404 00405 v = (UCHAR)pBuffer[i]; 00406 l += 1; 00407 i += 1; 00408 00409 sprintf( &pOutput[c], "%d.", v ); 00410 c += strlen( &pOutput[c] ); 00411 00412 v = (UCHAR)pBuffer[i]; 00413 l += 1; 00414 i += 1; 00415 00416 sprintf( &pOutput[c], "%d.", v ); 00417 c += strlen( &pOutput[c] ); 00418 00419 v = (UCHAR)pBuffer[i]; 00420 l += 1; 00421 i += 1; 00422 00423 sprintf( &pOutput[c], "%d", v ); 00424 c += strlen( &pOutput[c] ); 00425 00426 pOutput[c] = '\0'; 00427 00428 return l; 00429 } 00430 00431 void PrintD2( PCHAR pBuffer, DWORD BufferLength ) 00432 { 00433 USHORT RequestID; 00434 UCHAR Header1, Header2; 00435 USHORT NumQuestions, NumAnswers, NumAuthority, NumAdditional; 00436 USHORT Type, Class; 00437 CHAR pName[255]; 00438 int i = 0, k = 0; 00439 00440 RequestID = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00441 i += 2; 00442 00443 Header1 = pBuffer[i]; 00444 i += 1; 00445 00446 Header2 = pBuffer[i]; 00447 i += 1; 00448 00449 NumQuestions = ntohs( ((PSHORT)&pBuffer[i])[0] ); 00450 i += 2; 00451 00452 NumAnswers = ntohs( ((PSHORT)&pBuffer[i])[0] ); 00453 i += 2; 00454 00455 NumAuthority = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00456 i += 2; 00457 00458 NumAdditional = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00459 i += 2; 00460 00461 _tprintf( _T("------------\n") ); 00462 _tprintf( _T("SendRequest(), len %d\n"), (int)BufferLength ); 00463 _tprintf( _T(" HEADER:\n") ); 00464 _tprintf( _T(" opcode = %s, id = %d, rcode = %s\n"), 00465 OpcodeIDtoOpcodeName( (Header1 & 0x78) >> 3 ), 00466 (int)RequestID, 00467 RCodeIDtoRCodeName( Header2 & 0x0F ) ); 00468 00469 _tprintf( _T(" header flags: query") ); 00470 if( Header1 & 0x01 ) _tprintf( _T(", want recursion") ); 00471 _tprintf( _T("\n") ); 00472 00473 _tprintf( _T(" questions = %d, answers = %d," 00474 " authority records = %d, additional = %d\n\n"), 00475 (int)NumQuestions, 00476 (int)NumAnswers, 00477 (int)NumAuthority, 00478 (int)NumAdditional ); 00479 00480 if( NumQuestions ) 00481 { 00482 _tprintf( _T(" QUESTIONS:\n") ); 00483 00484 for( k = 0; k < NumQuestions; k += 1 ) 00485 { 00486 i += ExtractName( pBuffer, pName, i, 0 ); 00487 00488 _tprintf( _T(" %s"), pName ); 00489 00490 Type = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00491 i += 2; 00492 00493 Class = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00494 i += 2; 00495 00496 _tprintf( _T(", type = %s, class = %s\n"), 00497 TypeIDtoTypeName( Type ), 00498 ClassIDtoClassName( Class ) ); 00499 } 00500 } 00501 00502 _tprintf( _T("\n------------\n") ); 00503 } 00504 00505 void PrintDebug( PCHAR pBuffer, DWORD BufferLength ) 00506 { 00507 USHORT ResponseID; 00508 UCHAR Header1, Header2; 00509 USHORT NumQuestions, NumAnswers, NumAuthority, NumAdditional; 00510 USHORT Type, Class; 00511 ULONG TTL; 00512 CHAR pName[255]; 00513 int d = 0, i = 0, k = 0; 00514 00515 ResponseID = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00516 i += 2; 00517 00518 Header1 = pBuffer[i]; 00519 i += 1; 00520 00521 Header2 = pBuffer[i]; 00522 i += 1; 00523 00524 NumQuestions = ntohs( ((PSHORT)&pBuffer[i])[0] ); 00525 i += 2; 00526 00527 NumAnswers = ntohs( ((PSHORT)&pBuffer[i])[0] ); 00528 i += 2; 00529 00530 NumAuthority = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00531 i += 2; 00532 00533 NumAdditional = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00534 i += 2; 00535 00536 _tprintf( _T("------------\n") ); 00537 _tprintf( _T("Got answer (%d bytes):\n"), (int)BufferLength ); 00538 _tprintf( _T(" HEADER:\n") ); 00539 _tprintf( _T(" opcode = %s, id = %d, rcode = %s\n"), 00540 OpcodeIDtoOpcodeName( (Header1 & 0x78) >> 3 ), 00541 (int)ResponseID, 00542 RCodeIDtoRCodeName( Header2 & 0x0F ) ); 00543 00544 _tprintf( _T(" header flags: response") ); 00545 if( Header1 & 0x01 ) _tprintf( _T(", want recursion") ); 00546 if( Header2 & 0x80 ) _tprintf( _T(", recursion avail.") ); 00547 _tprintf( _T("\n") ); 00548 00549 _tprintf( _T(" questions = %d, answers = %d, " 00550 "authority records = %d, additional = %d\n\n"), 00551 (int)NumQuestions, 00552 (int)NumAnswers, 00553 (int)NumAuthority, 00554 (int)NumAdditional ); 00555 00556 if( NumQuestions ) 00557 { 00558 _tprintf( _T(" QUESTIONS:\n") ); 00559 00560 for( k = 0; k < NumQuestions; k += 1 ) 00561 { 00562 i += ExtractName( pBuffer, pName, i, 0 ); 00563 00564 _tprintf( _T(" %s"), pName ); 00565 00566 Type = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00567 i += 2; 00568 00569 Class = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00570 i += 2; 00571 00572 _tprintf( _T(", type = %s, class = %s\n"), 00573 TypeIDtoTypeName( Type ), 00574 ClassIDtoClassName( Class ) ); 00575 } 00576 } 00577 00578 if( NumAnswers ) 00579 { 00580 _tprintf( _T(" ANSWERS:\n") ); 00581 00582 for( k = 0; k < NumAnswers; k += 1 ) 00583 { 00584 _tprintf( _T(" -> ") ); 00585 00586 /* Print out the name. */ 00587 i += ExtractName( pBuffer, pName, i, 0 ); 00588 00589 _tprintf( _T("%s\n"), pName ); 00590 00591 /* Print out the type, class and data length. */ 00592 Type = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00593 i += 2; 00594 00595 Class = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00596 i += 2; 00597 00598 TTL = ntohl( ((PULONG)&pBuffer[i])[0] ); 00599 i += 4; 00600 00601 d = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00602 i += 2; 00603 00604 _tprintf( _T(" type = %s, class = %s, dlen = %d\n"), 00605 TypeIDtoTypeName( Type ), 00606 ClassIDtoClassName( Class ), 00607 d ); 00608 00609 /* Print out the answer. */ 00610 if( TYPE_A == Type ) 00611 { 00612 i += ExtractIP( pBuffer, pName, i ); 00613 00614 _tprintf( _T(" internet address = %s\n"), pName ); 00615 } 00616 else 00617 { 00618 i += ExtractName( pBuffer, pName, i, d ); 00619 00620 _tprintf( _T(" name = %s\n"), pName ); 00621 } 00622 00623 _tprintf( _T(" ttl = %d ()\n"), (int)TTL ); 00624 } 00625 } 00626 00627 if( NumAuthority ) 00628 { 00629 _tprintf( _T(" AUTHORITY RECORDS:\n") ); 00630 00631 for( k = 0; k < NumAuthority; k += 1 ) 00632 { 00633 /* Print out the zone name. */ 00634 i += ExtractName( pBuffer, pName, i, 0 ); 00635 00636 _tprintf( _T(" -> %s\n"), pName ); 00637 00638 /* Print out the type, class, data length and TTL. */ 00639 Type = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00640 i += 2; 00641 00642 Class = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00643 i += 2; 00644 00645 TTL = ntohl( ((PULONG)&pBuffer[i])[0] ); 00646 i += 4; 00647 00648 d = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00649 i += 2; 00650 00651 _tprintf( _T(" type = %s, class = %s, dlen = %d\n"), 00652 TypeIDtoTypeName( Type ), 00653 ClassIDtoClassName( Class ), 00654 d ); 00655 00656 /* TODO: There might be more types? */ 00657 if( TYPE_NS == Type ) 00658 { 00659 /* Print out the NS. */ 00660 i += ExtractName( pBuffer, pName, i, d ); 00661 00662 _tprintf( _T(" nameserver = %s\n"), pName ); 00663 00664 _tprintf( _T(" ttl = %d ()\n"), (int)TTL ); 00665 } 00666 else if( TYPE_SOA == Type ) 00667 { 00668 _tprintf( _T(" ttl = %d ()\n"), (int)TTL ); 00669 00670 /* Print out the primary NS. */ 00671 i += ExtractName( pBuffer, pName, i, 0 ); 00672 00673 _tprintf( _T(" primary name server = %s\n"), pName ); 00674 00675 /* Print out the responsible mailbox. */ 00676 i += ExtractName( pBuffer, pName, i, 0 ); 00677 00678 _tprintf( _T(" responsible mail addr = %s\n"), pName ); 00679 00680 /* Print out the serial, refresh, retry, expire and default TTL. */ 00681 _tprintf( _T(" serial = ()\n") ); 00682 _tprintf( _T(" refresh = ()\n") ); 00683 _tprintf( _T(" retry = ()\n") ); 00684 _tprintf( _T(" expire = ()\n") ); 00685 _tprintf( _T(" default TTL = ()\n") ); 00686 i += 20; 00687 } 00688 } 00689 } 00690 00691 if( NumAdditional ) 00692 { 00693 _tprintf( _T(" ADDITIONAL:\n") ); 00694 00695 for( k = 0; k < NumAdditional; k += 1 ) 00696 { 00697 /* Print the name. */ 00698 i += ExtractName( pBuffer, pName, i, 0 ); 00699 00700 _tprintf( _T(" -> %s\n"), pName ); 00701 00702 /* Print out the type, class, data length and TTL. */ 00703 Type = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00704 i += 2; 00705 00706 Class = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00707 i += 2; 00708 00709 TTL = ntohl( ((PULONG)&pBuffer[i])[0] ); 00710 i += 4; 00711 00712 d = ntohs( ((PUSHORT)&pBuffer[i])[0] ); 00713 i += 2; 00714 00715 _tprintf( _T(" type = %s, class = %s, dlen = %d\n"), 00716 TypeIDtoTypeName( Type ), 00717 ClassIDtoClassName( Class ), 00718 d ); 00719 00720 /* TODO: There might be more types? */ 00721 if( TYPE_A == Type ) 00722 { 00723 /* Print out the NS. */ 00724 i += ExtractIP( pBuffer, pName, i ); 00725 00726 _tprintf( _T(" internet address = %s\n"), pName ); 00727 00728 _tprintf( _T(" ttl = %d ()\n"), (int)TTL ); 00729 } 00730 } 00731 } 00732 00733 _tprintf( _T("\n------------\n") ); 00734 } 00735 00736 PCHAR OpcodeIDtoOpcodeName( UCHAR Opcode ) 00737 { 00738 switch( Opcode & 0x0F ) 00739 { 00740 case OPCODE_QUERY: 00741 return OpcodeQuery; 00742 00743 case OPCODE_IQUERY: 00744 return OpcodeIQuery; 00745 00746 case OPCODE_STATUS: 00747 return OpcodeStatus; 00748 00749 default: 00750 return OpcodeReserved; 00751 } 00752 } 00753 00754 PCHAR RCodeIDtoRCodeName( UCHAR RCode ) 00755 { 00756 switch( RCode & 0x0F ) 00757 { 00758 case RCODE_NOERROR: 00759 return RCodeNOERROR; 00760 00761 case RCODE_FORMERR: 00762 return RCodeFORMERR; 00763 00764 case RCODE_FAILURE: 00765 return RCodeFAILURE; 00766 00767 case RCODE_NXDOMAIN: 00768 return RCodeNXDOMAIN; 00769 00770 case RCODE_NOTIMP: 00771 return RCodeNOTIMP; 00772 00773 case RCODE_REFUSED: 00774 return RCodeREFUSED; 00775 00776 default: 00777 return RCodeReserved; 00778 } 00779 } 00780 00781 PCHAR TypeIDtoTypeName( USHORT TypeID ) 00782 { 00783 switch( TypeID ) 00784 { 00785 case TYPE_A: 00786 return TypeA; 00787 00788 case TYPE_NS: 00789 return TypeNS; 00790 00791 case TYPE_CNAME: 00792 return TypeCNAME; 00793 00794 case TYPE_SOA: 00795 return TypeSOA; 00796 00797 case TYPE_WKS: 00798 return TypeSRV; 00799 00800 case TYPE_PTR: 00801 return TypePTR; 00802 00803 case TYPE_MX: 00804 return TypeMX; 00805 00806 case TYPE_ANY: 00807 return TypeAny; 00808 00809 default: 00810 return "Unknown"; 00811 } 00812 } 00813 00814 USHORT TypeNametoTypeID( PCHAR TypeName ) 00815 { 00816 if( !strncmp( TypeName, TypeA, strlen( TypeA ) ) ) return TYPE_A; 00817 if( !strncmp( TypeName, TypeNS, strlen( TypeNS ) ) ) return TYPE_NS; 00818 if( !strncmp( TypeName, TypeCNAME, strlen( TypeCNAME ) ) ) return TYPE_CNAME; 00819 if( !strncmp( TypeName, TypeSOA, strlen( TypeSOA ) ) ) return TYPE_SOA; 00820 if( !strncmp( TypeName, TypeSRV, strlen( TypeSRV ) ) ) return TYPE_WKS; 00821 if( !strncmp( TypeName, TypePTR, strlen( TypePTR ) ) ) return TYPE_PTR; 00822 if( !strncmp( TypeName, TypeMX, strlen( TypeMX ) ) ) return TYPE_MX; 00823 if( !strncmp( TypeName, TypeAny, strlen( TypeAny ) ) ) return TYPE_ANY; 00824 00825 return 0; 00826 } 00827 00828 PCHAR ClassIDtoClassName( USHORT ClassID ) 00829 { 00830 switch( ClassID ) 00831 { 00832 case CLASS_IN: 00833 return ClassIN; 00834 00835 case CLASS_ANY: 00836 return ClassAny; 00837 00838 default: 00839 return "Unknown"; 00840 } 00841 } 00842 00843 USHORT ClassNametoClassID( PCHAR ClassName ) 00844 { 00845 if( !strncmp( ClassName, ClassIN, strlen( ClassIN ) ) ) return CLASS_IN; 00846 if( !strncmp( ClassName, ClassAny, strlen( ClassAny ) ) ) return CLASS_ANY; 00847 00848 return 0; 00849 } Generated on Fri May 25 2012 04:15:32 for ReactOS by
1.7.6.1
|