Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

709 lines
22 KiB

  1. /*++
  2. Copyright (c) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. dnsutil.c
  5. Abstract:
  6. Domain Name System (DNS) Library
  7. General DNS utilities.
  8. Author:
  9. Jim Gilroy (jamesg) Decemeber 1996
  10. Revision History:
  11. --*/
  12. #include "local.h"
  13. IP_ADDRESS
  14. Dns_GetNetworkMask(
  15. IN IP_ADDRESS ipAddress
  16. )
  17. /*++
  18. Routine Description:
  19. Gets network mask for IP address.
  20. Note, this is standard IP network mask for address type,
  21. obviously subnetting is unknown.
  22. Arguments:
  23. ipAddress -- IP to get mask for
  24. Return Value:
  25. Network mask in network byte order.
  26. --*/
  27. {
  28. // note addresses and masks are in netbyte order
  29. // which we are treating as byte flipped and hence
  30. // test the high bits in the low byte
  31. // class A?
  32. if ( ! (0x80 & ipAddress) )
  33. {
  34. return( 0x000000ff );
  35. }
  36. // class B?
  37. if ( ! (0x40 & ipAddress) )
  38. {
  39. return( 0x0000ffff );
  40. }
  41. // then class C
  42. // yes, there's some multicast BS out there, I don't
  43. // believe it requires any special handling
  44. return( 0x00ffffff );
  45. }
  46. //
  47. // DNS status\error mappings
  48. //
  49. // DCR: investigate tossing error mappings
  50. // and have all errors in Win32 system
  51. //
  52. typedef struct _DnsStatusStringMap
  53. {
  54. DNS_STATUS Status;
  55. PCHAR String;
  56. }
  57. DNS_STATUS_STRING_MAP;
  58. #define DNS_MAP_END ((DWORD)(-1))
  59. #define DNS_MAP_ENTRY( _ErrorCode ) _ErrorCode, #_ErrorCode
  60. DNS_STATUS_STRING_MAP DnsStatusStringMappings[] =
  61. {
  62. //
  63. // Response codes
  64. //
  65. DNS_ERROR_RCODE_NO_ERROR ,"ERROR_SUCCESS",
  66. DNS_ERROR_RCODE_FORMAT_ERROR ,"RCODE_FORMAT_ERROR",
  67. DNS_ERROR_RCODE_SERVER_FAILURE ,"RCODE_SERVER_FAILURE",
  68. DNS_ERROR_RCODE_NAME_ERROR ,"RCODE_NAME_ERROR",
  69. DNS_ERROR_RCODE_NOT_IMPLEMENTED ,"RCODE_NOT_IMPLEMENTED",
  70. DNS_ERROR_RCODE_REFUSED ,"RCODE_REFUSED",
  71. DNS_ERROR_RCODE_YXDOMAIN ,"RCODE_YXDOMAIN",
  72. DNS_ERROR_RCODE_YXRRSET ,"RCODE_YXRRSET",
  73. DNS_ERROR_RCODE_NXRRSET ,"RCODE_NXRRSET",
  74. DNS_ERROR_RCODE_NOTAUTH ,"RCODE_NOTAUTH",
  75. DNS_ERROR_RCODE_NOTZONE ,"RCODE_NOTZONE",
  76. DNS_ERROR_RCODE_BADSIG ,"RCODE_BADSIG",
  77. DNS_ERROR_RCODE_BADKEY ,"RCODE_BADKEY",
  78. DNS_ERROR_RCODE_BADTIME ,"RCODE_BADTIME",
  79. //
  80. // Packet format
  81. //
  82. DNS_INFO_NO_RECORDS ,"DNS_INFO_NO_RECORDS",
  83. DNS_ERROR_BAD_PACKET ,"DNS_ERROR_BAD_PACKET",
  84. DNS_ERROR_NO_PACKET ,"DNS_ERROR_NO_PACKET",
  85. DNS_ERROR_RCODE ,"DNS_ERROR_RCODE",
  86. DNS_ERROR_UNSECURE_PACKET ,"DNS_ERROR_UNSECURE_PACKET",
  87. //
  88. // General API errors
  89. //
  90. DNS_ERROR_INVALID_NAME ,"ERROR_INVALID_NAME",
  91. DNS_ERROR_INVALID_DATA ,"ERROR_INVALID_DATA",
  92. DNS_ERROR_INVALID_TYPE ,"ERROR_INVALID_TYPE",
  93. DNS_ERROR_INVALID_IP_ADDRESS ,"DNS_ERROR_INVALID_IP_ADDRESS",
  94. DNS_ERROR_INVALID_PROPERTY ,"DNS_ERROR_INVALID_PROPERTY",
  95. DNS_ERROR_TRY_AGAIN_LATER ,"DNS_ERROR_TRY_AGAIN_LATER",
  96. DNS_ERROR_NOT_UNIQUE ,"DNS_ERROR_NOT_UNIQUE",
  97. DNS_ERROR_NON_RFC_NAME ,"DNS_ERROR_NON_RFC_NAME",
  98. DNS_STATUS_FQDN ,"DNS_STATUS_FQDN",
  99. DNS_STATUS_DOTTED_NAME ,"DNS_STATUS_DOTTED_NAME",
  100. DNS_STATUS_SINGLE_PART_NAME ,"DNS_STATUS_SINGLE_PART_NAME",
  101. DNS_ERROR_INVALID_NAME_CHAR ,"DNS_ERROR_INVALID_NAME_CHAR",
  102. DNS_ERROR_NUMERIC_NAME ,"DNS_ERROR_NUMERIC_NAME",
  103. //
  104. // Server errors
  105. //
  106. DNS_MAP_ENTRY( DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER ),
  107. //
  108. // Zone errors
  109. //
  110. DNS_ERROR_ZONE_DOES_NOT_EXIST ,"DNS_ERROR_ZONE_DOES_NOT_EXIST",
  111. DNS_ERROR_NO_ZONE_INFO ,"DNS_ERROR_NO_ZONE_INFO",
  112. DNS_ERROR_INVALID_ZONE_OPERATION ,"DNS_ERROR_INVALID_ZONE_OPERATION",
  113. DNS_ERROR_ZONE_CONFIGURATION_ERROR ,"DNS_ERROR_ZONE_CONFIGURATION_ERROR",
  114. DNS_ERROR_ZONE_HAS_NO_SOA_RECORD ,"DNS_ERROR_ZONE_HAS_NO_SOA_RECORD",
  115. DNS_ERROR_ZONE_HAS_NO_NS_RECORDS ,"DNS_ERROR_ZONE_HAS_NO_NS_RECORDS",
  116. DNS_ERROR_ZONE_LOCKED ,"DNS_ERROR_ZONE_LOCKED",
  117. DNS_ERROR_ZONE_CREATION_FAILED ,"DNS_ERROR_ZONE_CREATION_FAILED",
  118. DNS_ERROR_ZONE_ALREADY_EXISTS ,"DNS_ERROR_ZONE_ALREADY_EXISTS",
  119. DNS_ERROR_AUTOZONE_ALREADY_EXISTS ,"DNS_ERROR_AUTOZONE_ALREADY_EXISTS",
  120. DNS_ERROR_INVALID_ZONE_TYPE ,"DNS_ERROR_INVALID_ZONE_TYPE",
  121. DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP ,"DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP",
  122. DNS_MAP_ENTRY( DNS_ERROR_ZONE_REQUIRES_MASTER_IP ),
  123. DNS_MAP_ENTRY( DNS_ERROR_ZONE_IS_SHUTDOWN ),
  124. DNS_ERROR_ZONE_NOT_SECONDARY ,"DNS_ERROR_ZONE_NOT_SECONDARY",
  125. DNS_ERROR_NEED_SECONDARY_ADDRESSES ,"DNS_ERROR_NEED_SECONDARY_ADDRESSES",
  126. DNS_ERROR_WINS_INIT_FAILED ,"DNS_ERROR_WINS_INIT_FAILED",
  127. DNS_ERROR_NEED_WINS_SERVERS ,"DNS_ERROR_NEED_WINS_SERVERS",
  128. DNS_ERROR_NBSTAT_INIT_FAILED ,"DNS_ERROR_NBSTAT_INIT_FAILED",
  129. DNS_ERROR_SOA_DELETE_INVALID ,"DNS_ERROR_SOA_DELETE_INVALID",
  130. DNS_MAP_ENTRY( DNS_ERROR_FORWARDER_ALREADY_EXISTS ),
  131. //
  132. // Datafile errors
  133. //
  134. DNS_ERROR_PRIMARY_REQUIRES_DATAFILE ,"DNS_ERROR_PRIMARY_REQUIRES_DATAFILE",
  135. DNS_ERROR_INVALID_DATAFILE_NAME ,"DNS_ERROR_INVALID_DATAFILE_NAME",
  136. DNS_ERROR_DATAFILE_OPEN_FAILURE ,"DNS_ERROR_DATAFILE_OPEN_FAILURE",
  137. DNS_ERROR_FILE_WRITEBACK_FAILED ,"DNS_ERROR_FILE_WRITEBACK_FAILED",
  138. DNS_ERROR_DATAFILE_PARSING ,"DNS_ERROR_DATAFILE_PARSING",
  139. //
  140. // Database errors
  141. //
  142. DNS_ERROR_RECORD_DOES_NOT_EXIST ,"DNS_ERROR_RECORD_DOES_NOT_EXIST",
  143. DNS_ERROR_RECORD_FORMAT ,"DNS_ERROR_RECORD_FORMAT",
  144. DNS_ERROR_NODE_CREATION_FAILED ,"DNS_ERROR_NODE_CREATION_FAILED",
  145. DNS_ERROR_UNKNOWN_RECORD_TYPE ,"DNS_ERROR_UNKNOWN_RECORD_TYPE",
  146. DNS_ERROR_RECORD_TIMED_OUT ,"DNS_ERROR_RECORD_TIMED_OUT",
  147. DNS_ERROR_NAME_NOT_IN_ZONE ,"DNS_ERROR_NAME_NOT_IN_ZONE",
  148. DNS_ERROR_CNAME_LOOP ,"DNS_ERROR_CNAME_LOOP",
  149. DNS_ERROR_NODE_IS_CNAME ,"DNS_ERROR_NODE_IS_CNAME",
  150. DNS_ERROR_CNAME_COLLISION ,"DNS_ERROR_CNAME_COLLISION",
  151. DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT ,"DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT",
  152. DNS_ERROR_RECORD_ALREADY_EXISTS ,"DNS_ERROR_RECORD_ALREADY_EXISTS",
  153. DNS_ERROR_SECONDARY_DATA ,"DNS_ERROR_SECONDARY_DATA",
  154. DNS_ERROR_NO_CREATE_CACHE_DATA ,"DNS_ERROR_NO_CREATE_CACHE_DATA",
  155. DNS_ERROR_NAME_DOES_NOT_EXIST ,"DNS_ERROR_NAME_DOES_NOT_EXIST",
  156. DNS_WARNING_PTR_CREATE_FAILED ,"DNS_WARNING_PTR_CREATE_FAILED",
  157. DNS_WARNING_DOMAIN_UNDELETED ,"DNS_WARNING_DOMAIN_UNDELETED",
  158. DNS_ERROR_DS_UNAVAILABLE ,"DNS_ERROR_DS_UNAVAILABLE",
  159. DNS_ERROR_DS_ZONE_ALREADY_EXISTS ,"DNS_ERROR_DS_ZONE_ALREADY_EXISTS",
  160. //
  161. // Operation errors
  162. //
  163. DNS_INFO_AXFR_COMPLETE ,"DNS_INFO_AXFR_COMPLETE",
  164. DNS_ERROR_AXFR ,"DNS_ERROR_AXFR",
  165. DNS_INFO_ADDED_LOCAL_WINS ,"DNS_INFO_ADDED_LOCAL_WINS",
  166. //
  167. // Secure update
  168. //
  169. DNS_STATUS_CONTINUE_NEEDED ,"DNS_STATUS_CONTINUE_NEEDED",
  170. //
  171. // Client setup errors
  172. //
  173. DNS_ERROR_NO_TCPIP ,"DNS_ERROR_NO_TCPIP",
  174. DNS_ERROR_NO_DNS_SERVERS ,"DNS_ERROR_NO_DNS_SERVERS",
  175. //
  176. // Directory partition errors
  177. //
  178. DNS_MAP_ENTRY( DNS_ERROR_DP_DOES_NOT_EXIST ),
  179. DNS_MAP_ENTRY( DNS_ERROR_DP_ALREADY_EXISTS ),
  180. DNS_MAP_ENTRY( DNS_ERROR_DP_NOT_ENLISTED ),
  181. DNS_MAP_ENTRY( DNS_ERROR_DP_ALREADY_ENLISTED ),
  182. //
  183. // Throw in common Win32 errors
  184. //
  185. ERROR_FILE_NOT_FOUND ,"ERROR_FILE_NOT_FOUND",
  186. ERROR_ACCESS_DENIED ,"ERROR_ACCESS_DENIED",
  187. ERROR_NOT_ENOUGH_MEMORY ,"ERROR_NOT_ENOUGH_MEMORY",
  188. ERROR_BAD_FORMAT ,"ERROR_BAD_FORMAT",
  189. ERROR_INVALID_DATA ,"ERROR_INVALID_DATA",
  190. ERROR_OUTOFMEMORY ,"ERROR_OUTOFMEMORY",
  191. ERROR_SHARING_VIOLATION ,"ERROR_SHARING_VIOLATION",
  192. ERROR_NOT_SUPPORTED ,"ERROR_NOT_SUPPORTED",
  193. ERROR_INVALID_PARAMETER ,"ERROR_INVALID_PARAMETER",
  194. ERROR_INVALID_NAME ,"ERROR_INVALID_NAME",
  195. ERROR_BAD_ARGUMENTS ,"ERROR_BAD_ARGUMENTS",
  196. ERROR_BUSY ,"ERROR_BUSY",
  197. ERROR_ALREADY_EXISTS ,"ERROR_ALREADY_EXISTS",
  198. ERROR_LOCKED ,"ERROR_LOCKED",
  199. ERROR_MORE_DATA ,"ERROR_MORE_DATA",
  200. ERROR_INVALID_FLAGS ,"ERROR_INVALID_FLAGS",
  201. ERROR_FILE_INVALID ,"ERROR_FILE_INVALID",
  202. ERROR_TIMEOUT ,"ERROR_TIMEOUT",
  203. //
  204. // RPC error:
  205. //
  206. RPC_S_SERVER_UNAVAILABLE ,"RPC_S_SERVER_UNAVAILABLE",
  207. RPC_S_INVALID_NET_ADDR ,"RPC_S_INVALID_NET_ADDR",
  208. //
  209. // others:
  210. //
  211. ERROR_PATH_NOT_FOUND ,"ERROR_PATH_NOT_FOUND",
  212. ERROR_INVALID_ACCESS ,"ERROR_INVALID_ACCESS",
  213. ERROR_INVALID_DRIVE ,"ERROR_INVALID_DRIVE",
  214. ERROR_WRITE_PROTECT ,"ERROR_WRITE_PROTECT",
  215. ERROR_SHARING_VIOLATION ,"ERROR_SHARING_VIOLATION",
  216. ERROR_HANDLE_DISK_FULL ,"ERROR_HANDLE_DISK_FULL",
  217. ERROR_NOT_SUPPORTED ,"ERROR_NOT_SUPPORTED",
  218. ERROR_REM_NOT_LIST ,"ERROR_REM_NOT_LIST",
  219. ERROR_DUP_NAME ,"ERROR_DUP_NAME",
  220. ERROR_NETNAME_DELETED ,"ERROR_NETNAME_DELETED",
  221. ERROR_FILE_EXISTS ,"ERROR_FILE_EXISTS",
  222. ERROR_NET_WRITE_FAULT ,"ERROR_NET_WRITE_FAULT",
  223. //
  224. // winsock
  225. //
  226. WSAEINTR ,"WSAEINTR ",
  227. WSAEBADF ,"WSAEBADF ",
  228. WSAEACCES ,"WSAEACCES ",
  229. WSAEFAULT ,"WSAEFAULT ",
  230. WSAEINVAL ,"WSAEINVAL ",
  231. WSAEMFILE ,"WSAEMFILE ",
  232. WSAEWOULDBLOCK ,"WSAEWOULDBLOCK ",
  233. WSAEINPROGRESS ,"WSAEINPROGRESS ",
  234. WSAEALREADY ,"WSAEALREADY ",
  235. WSAENOTSOCK ,"WSAENOTSOCK ",
  236. WSAEDESTADDRREQ ,"WSAEDESTADDRREQ ",
  237. WSAEMSGSIZE ,"WSAEMSGSIZE ",
  238. WSAEPROTOTYPE ,"WSAEPROTOTYPE ",
  239. WSAENOPROTOOPT ,"WSAENOPROTOOPT ",
  240. WSAEPROTONOSUPPORT ,"WSAEPROTONOSUPPORT ",
  241. WSAESOCKTNOSUPPORT ,"WSAESOCKTNOSUPPORT ",
  242. WSAEOPNOTSUPP ,"WSAEOPNOTSUPP ",
  243. WSAEPFNOSUPPORT ,"WSAEPFNOSUPPORT ",
  244. WSAEAFNOSUPPORT ,"WSAEAFNOSUPPORT ",
  245. WSAEADDRINUSE ,"WSAEADDRINUSE ",
  246. WSAEADDRNOTAVAIL ,"WSAEADDRNOTAVAIL ",
  247. WSAENETDOWN ,"WSAENETDOWN ",
  248. WSAENETUNREACH ,"WSAENETUNREACH ",
  249. WSAENETRESET ,"WSAENETRESET ",
  250. WSAECONNABORTED ,"WSAECONNABORTED ",
  251. WSAECONNRESET ,"WSAECONNRESET ",
  252. WSAENOBUFS ,"WSAENOBUFS ",
  253. WSAEISCONN ,"WSAEISCONN ",
  254. WSAENOTCONN ,"WSAENOTCONN ",
  255. WSAESHUTDOWN ,"WSAESHUTDOWN ",
  256. WSAETOOMANYREFS ,"WSAETOOMANYREFS ",
  257. WSAETIMEDOUT ,"WSAETIMEDOUT ",
  258. WSAECONNREFUSED ,"WSAECONNREFUSED ",
  259. WSAELOOP ,"WSAELOOP ",
  260. WSAENAMETOOLONG ,"WSAENAMETOOLONG ",
  261. WSAEHOSTDOWN ,"WSAEHOSTDOWN ",
  262. WSAEHOSTUNREACH ,"WSAEHOSTUNREACH ",
  263. WSAENOTEMPTY ,"WSAENOTEMPTY ",
  264. WSAEPROCLIM ,"WSAEPROCLIM ",
  265. WSAEUSERS ,"WSAEUSERS ",
  266. WSAEDQUOT ,"WSAEDQUOT ",
  267. WSAESTALE ,"WSAESTALE ",
  268. WSAEREMOTE ,"WSAEREMOTE ",
  269. WSASYSNOTREADY ,"WSASYSNOTREADY ",
  270. WSAVERNOTSUPPORTED ,"WSAVERNOTSUPPORTED ",
  271. WSANOTINITIALISED ,"WSANOTINITIALISED ",
  272. WSAEDISCON ,"WSAEDISCON ",
  273. WSAENOMORE ,"WSAENOMORE ",
  274. WSAECANCELLED ,"WSAECANCELLED ",
  275. WSAEINVALIDPROCTABLE ,"WSAEINVALIDPROCTABLE ",
  276. WSAEINVALIDPROVIDER ,"WSAEINVALIDPROVIDER ",
  277. WSAEPROVIDERFAILEDINIT ,"WSAEPROVIDERFAILEDINIT ",
  278. WSASYSCALLFAILURE ,"WSASYSCALLFAILURE ",
  279. WSASERVICE_NOT_FOUND ,"WSASERVICE_NOT_FOUND ",
  280. WSATYPE_NOT_FOUND ,"WSATYPE_NOT_FOUND ",
  281. WSA_E_NO_MORE ,"WSA_E_NO_MORE ",
  282. WSA_E_CANCELLED ,"WSA_E_CANCELLED ",
  283. WSAEREFUSED ,"WSAEREFUSED ",
  284. WSAHOST_NOT_FOUND ,"WSAHOST_NOT_FOUND ",
  285. WSATRY_AGAIN ,"WSATRY_AGAIN ",
  286. WSANO_RECOVERY ,"WSANO_RECOVERY ",
  287. WSANO_DATA ,"WSANO_DATA ",
  288. WSA_QOS_RECEIVERS ,"WSA_QOS_RECEIVERS ",
  289. WSA_QOS_SENDERS ,"WSA_QOS_SENDERS ",
  290. WSA_QOS_NO_SENDERS ,"WSA_QOS_NO_SENDERS ",
  291. WSA_QOS_NO_RECEIVERS ,"WSA_QOS_NO_RECEIVERS ",
  292. WSA_QOS_REQUEST_CONFIRMED ,"WSA_QOS_REQUEST_CONFIRMED ",
  293. WSA_QOS_ADMISSION_FAILURE ,"WSA_QOS_ADMISSION_FAILURE ",
  294. WSA_QOS_POLICY_FAILURE ,"WSA_QOS_POLICY_FAILURE ",
  295. WSA_QOS_BAD_STYLE ,"WSA_QOS_BAD_STYLE ",
  296. WSA_QOS_BAD_OBJECT ,"WSA_QOS_BAD_OBJECT ",
  297. WSA_QOS_TRAFFIC_CTRL_ERROR ,"WSA_QOS_TRAFFIC_CTRL_ERROR ",
  298. WSA_QOS_GENERIC_ERROR ,"WSA_QOS_GENERIC_ERROR ",
  299. WSA_QOS_ESERVICETYPE ,"WSA_QOS_ESERVICETYPE ",
  300. WSA_QOS_EFLOWSPEC ,"WSA_QOS_EFLOWSPEC ",
  301. WSA_QOS_EPROVSPECBUF ,"WSA_QOS_EPROVSPECBUF ",
  302. WSA_QOS_EFILTERSTYLE ,"WSA_QOS_EFILTERSTYLE ",
  303. WSA_QOS_EFILTERTYPE ,"WSA_QOS_EFILTERTYPE ",
  304. WSA_QOS_EFILTERCOUNT ,"WSA_QOS_EFILTERCOUNT ",
  305. WSA_QOS_EOBJLENGTH ,"WSA_QOS_EOBJLENGTH ",
  306. WSA_QOS_EFLOWCOUNT ,"WSA_QOS_EFLOWCOUNT ",
  307. WSA_QOS_EUNKOWNPSOBJ ,"WSA_QOS_EUNKOWNPSOBJ ",
  308. WSA_QOS_EPOLICYOBJ ,"WSA_QOS_EPOLICYOBJ ",
  309. WSA_QOS_EFLOWDESC ,"WSA_QOS_EFLOWDESC ",
  310. WSA_QOS_EPSFLOWSPEC ,"WSA_QOS_EPSFLOWSPEC ",
  311. WSA_QOS_EPSFILTERSPEC ,"WSA_QOS_EPSFILTERSPEC ",
  312. WSA_QOS_ESDMODEOBJ ,"WSA_QOS_ESDMODEOBJ ",
  313. WSA_QOS_ESHAPERATEOBJ ,"WSA_QOS_ESHAPERATEOBJ ",
  314. WSA_QOS_RESERVED_PETYPE ,"WSA_QOS_RESERVED_PETYPE ",
  315. DNS_MAP_END ,"UNKNOWN",
  316. };
  317. PCHAR
  318. _fastcall
  319. Dns_StatusString(
  320. IN DNS_STATUS Status
  321. )
  322. /*++
  323. Routine Description:
  324. Map DNS error code to status string.
  325. Arguments:
  326. Status -- status code to check
  327. Return Value:
  328. DNS error string for error code.
  329. --*/
  330. {
  331. INT i = 0;
  332. DNS_STATUS mappedStatus;
  333. while ( 1 )
  334. {
  335. mappedStatus = DnsStatusStringMappings[i].Status;
  336. if ( mappedStatus == Status || mappedStatus == DNS_MAP_END )
  337. {
  338. return( DnsStatusStringMappings[i].String );
  339. }
  340. i++;
  341. }
  342. DNS_ASSERT( FALSE );
  343. return( NULL ); // make compiler happy
  344. }
  345. DNS_STATUS
  346. _fastcall
  347. Dns_MapRcodeToStatus(
  348. IN BYTE ResponseCode
  349. )
  350. /*++
  351. Routine Description:
  352. Map response code to DNS error code.
  353. Arguments:
  354. ResponseCode - response code to get error for
  355. Return Value:
  356. DNS error code for response code.
  357. --*/
  358. {
  359. if ( !ResponseCode )
  360. {
  361. return( ERROR_SUCCESS );
  362. }
  363. else
  364. {
  365. return( DNS_ERROR_MASK + ((DWORD) ResponseCode) );
  366. }
  367. }
  368. BYTE
  369. _fastcall
  370. Dns_IsStatusRcode(
  371. IN DNS_STATUS Status
  372. )
  373. /*++
  374. Routine Description:
  375. Determine if status is RCODE and if so return it.
  376. Arguments:
  377. Status -- status code to check
  378. Return Value:
  379. Response code corresponding to status, if found.
  380. Zero otherwise.
  381. --*/
  382. {
  383. if ( Status >= DNS_ERROR_RCODE_FORMAT_ERROR &&
  384. Status <= DNS_ERROR_RCODE_LAST )
  385. {
  386. return( (BYTE) (DNS_ERROR_MASK ^ Status) );
  387. }
  388. else
  389. {
  390. return( 0 );
  391. }
  392. }
  393. DWORD
  394. Dns_TokenizeString(
  395. IN OUT PSTR pBuffer,
  396. OUT PCHAR * Argv,
  397. IN DWORD MaxArgs
  398. )
  399. /*++
  400. Routine Description:
  401. Tokenize buffer Argv/Argc form.
  402. Arguments:
  403. pBuffer -- string buffer to tokenize
  404. Argv -- argv array
  405. MaxArgs -- max size of Argv array
  406. Return Value:
  407. Response code corresponding to status, if found.
  408. Zero otherwise.
  409. --*/
  410. {
  411. DWORD count = 0;
  412. PCHAR pstring = pBuffer;
  413. //
  414. // tokenize string
  415. // - note that after the first call strtok
  416. // takes NULL ptr to continue tokening same string
  417. //
  418. while ( count < MaxArgs )
  419. {
  420. PCHAR pch;
  421. pch = strtok( pstring, " \t\r\n" );
  422. if ( !pch )
  423. {
  424. break;
  425. }
  426. Argv[ count++ ] = pch;
  427. pstring = NULL;
  428. }
  429. return count;
  430. }
  431. DNS_STATUS
  432. Dns_CreateTypeArrayFromMultiTypeString(
  433. IN LPSTR pchMultiTypeString,
  434. OUT INT * piTypeCount,
  435. OUT PWORD * ppwTypeArray
  436. )
  437. /*++
  438. Routine Description:
  439. Allocates an array of types from a string containing DNS types
  440. in numeric and/or string format separated by whitespace.
  441. Arguments:
  442. pBuffer -- string buffer with list of numeric or alpha types
  443. piTypeCount -- number of types parsed written here
  444. ppwTypeArray -- ptr to allocated array of types written here
  445. this ptr must be freed even if the number of types returned
  446. is zero
  447. Return Value:
  448. ERROR_SUCCESS
  449. --*/
  450. {
  451. PCHAR psz;
  452. DWORD argc;
  453. PCHAR argv[ 50 ];
  454. DWORD idx;
  455. ASSERT( pchMultiTypeString );
  456. ASSERT( piTypeCount );
  457. ASSERT( ppwTypeArray );
  458. *piTypeCount = 0;
  459. //
  460. // Allocate array: be cheap and assume max # of types in string
  461. // is twice the length of the string, e.g. "1 2 3 4 5".
  462. //
  463. *ppwTypeArray = ALLOCATE_HEAP(
  464. ( strlen( pchMultiTypeString ) / 2 + 2 ) * sizeof( WORD ) );
  465. if ( !*ppwTypeArray )
  466. {
  467. return DNS_ERROR_NO_MEMORY;
  468. }
  469. //
  470. // Parse the string.
  471. //
  472. argc = Dns_TokenizeString(
  473. pchMultiTypeString,
  474. argv,
  475. sizeof( argv ) / sizeof( PCHAR ) );
  476. for ( idx = 0; idx < argc; ++idx )
  477. {
  478. if ( isdigit( argv[ idx ][ 0 ] ) )
  479. {
  480. ( *ppwTypeArray )[ *piTypeCount ] =
  481. ( WORD ) strtol( argv[ idx ], NULL, 0 );
  482. }
  483. else
  484. {
  485. ( *ppwTypeArray )[ *piTypeCount ] = Dns_RecordTypeForName(
  486. argv[ idx ],
  487. 0 ); // string length
  488. }
  489. if ( ( *ppwTypeArray )[ *piTypeCount ] != 0 )
  490. {
  491. ++*piTypeCount;
  492. }
  493. }
  494. return ERROR_SUCCESS;
  495. } // Dns_CreateTypeArrayFromMultiTypeString
  496. LPSTR
  497. Dns_CreateMultiTypeStringFromTypeArray(
  498. IN INT iTypeCount,
  499. IN PWORD ppwTypeArray,
  500. IN CHAR chSeparator OPTIONAL
  501. )
  502. /*++
  503. Routine Description:
  504. Allocate a string and write the types in the array in string format
  505. separated by the specified separator or by a space char.
  506. Arguments:
  507. iTypeCount -- number of types in the array
  508. ppwTypeArray -- ptr to array of types
  509. chSeparator -- string separator or zero for the default separator
  510. Return Value:
  511. ERROR_SUCCESS
  512. --*/
  513. {
  514. LPSTR pszTypes;
  515. INT idx;
  516. LPSTR psz;
  517. ASSERT( ppwTypeArray );
  518. //
  519. // Allocate array: be cheap and assume 10 chars per element.
  520. //
  521. psz = pszTypes = ALLOCATE_HEAP( iTypeCount * 10 * sizeof( CHAR ) );
  522. if ( !psz )
  523. {
  524. return NULL;
  525. }
  526. //
  527. // Output type strings.
  528. //
  529. for ( idx = 0; idx < iTypeCount; ++idx )
  530. {
  531. PCHAR pszThisType;
  532. pszThisType = Dns_RecordStringForType( ppwTypeArray[ idx ] );
  533. if ( !pszThisType )
  534. {
  535. continue;
  536. }
  537. strcpy( psz, pszThisType );
  538. psz += strlen( pszThisType );
  539. *psz++ = chSeparator ? chSeparator : ' ';
  540. }
  541. *psz = '\0'; // NULL terminate the string
  542. return pszTypes;
  543. } // Dns_CreateMultiTypeStringFromTypeArray
  544. //
  545. // End dnsutil.c
  546. //