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.

599 lines
12 KiB

  1. /*++
  2. Copyright (c) 1996-2000 Microsoft Corporation
  3. Module Name:
  4. table.c
  5. Abstract:
  6. Domain Name System (DNS) Library
  7. Routines to handle general table lookup.
  8. Author:
  9. Jim Gilroy (jamesg) December 1996
  10. Revision History:
  11. --*/
  12. #include "local.h"
  13. #include "time.h"
  14. //
  15. // Comparison function
  16. //
  17. typedef INT (__cdecl * COMPARISON_FUNCTION)(
  18. const CHAR *,
  19. const CHAR *,
  20. size_t );
  21. //
  22. // Table lookup.
  23. //
  24. // Many DNS Records have human readable mnemonics for given data values.
  25. // These are used for data file formats, and display in nslookup or debug
  26. // output or cmdline tools.
  27. //
  28. // To simplify this process, have a single mapping functionality that
  29. // supports DWORD \ LPSTR mapping tables. Tables for indivual types
  30. // may then be layered on top of this.
  31. //
  32. // Support two table types.
  33. // VALUE_TABLE_ENTRY is simple value-string mapping
  34. // FLAG_TABLE_ENTRY is designed for bit field flag mappings where
  35. // several flag strings might be contained in flag; this table
  36. // contains additional mask field to allow multi-bit fields
  37. // within the flag
  38. //
  39. #if 0
  40. //
  41. // Defined in local.h here only for reference
  42. //
  43. typedef struct
  44. {
  45. DWORD dwValue; // flag value
  46. PCHAR pszString; // string representation of value
  47. }
  48. DNS_VALUE_TABLE_ENTRY;
  49. typedef struct
  50. {
  51. DWORD dwFlag; // flag value
  52. DWORD dwMask; // flag value mask
  53. PCHAR pszString; // string representation of value
  54. }
  55. DNS_FLAG_TABLE_ENTRY;
  56. // Error return on unmatched string
  57. #define DNS_TABLE_LOOKUP_ERROR (-1)
  58. #endif
  59. DWORD
  60. Dns_ValueForString(
  61. IN DNS_VALUE_TABLE_ENTRY * Table,
  62. IN BOOL fIgnoreCase,
  63. IN PCHAR pchName,
  64. IN INT cchNameLength
  65. )
  66. /*++
  67. Routine Description:
  68. Retrieve value for given string.
  69. Arguments:
  70. Table - table with value\string mapping
  71. fIgnoreCase - TRUE if case-insensitive string lookup
  72. pchName - ptr to string
  73. cchNameLength - length of string
  74. Return Value:
  75. Flag value corresponding to string, if found.
  76. DNS_TABLE_LOOKUP_ERROR otherwise.
  77. --*/
  78. {
  79. INT i = 0;
  80. // INT (* pcompareFunction)( const char *, const char *, size_t );
  81. COMPARISON_FUNCTION pcompareFunction;
  82. //
  83. // if not given get string length
  84. //
  85. if ( !cchNameLength )
  86. {
  87. cchNameLength = strlen( pchName );
  88. }
  89. //
  90. // determine comparison routine
  91. //
  92. if ( fIgnoreCase )
  93. {
  94. pcompareFunction = _strnicmp;
  95. }
  96. else
  97. {
  98. pcompareFunction = strncmp;
  99. }
  100. //
  101. // find value matching name
  102. //
  103. while( Table[i].pszString != NULL )
  104. {
  105. if ( pcompareFunction( pchName, Table[i].pszString, cchNameLength ) == 0 )
  106. {
  107. return( Table[i].dwValue );
  108. }
  109. i++;
  110. }
  111. return( (DWORD)DNS_TABLE_LOOKUP_ERROR );
  112. }
  113. PCHAR
  114. Dns_GetStringForValue(
  115. IN DNS_VALUE_TABLE_ENTRY * Table,
  116. IN DWORD dwValue
  117. )
  118. /*++
  119. Routine Description:
  120. Retrieve string representation of given value.
  121. Arguments:
  122. Table - table with value\string mapping
  123. dwValue - value to map to strings
  124. Return Value:
  125. Ptr to mapping mneumonic string.
  126. NULL if unknown mapping type.
  127. --*/
  128. {
  129. INT i = 0;
  130. //
  131. // check all supported values for match
  132. //
  133. while( Table[i].pszString != NULL )
  134. {
  135. if ( dwValue == Table[i].dwValue )
  136. {
  137. return( Table[i].pszString );
  138. }
  139. i++;
  140. }
  141. return( NULL );
  142. }
  143. DWORD
  144. Dns_FlagForString(
  145. IN DNS_FLAG_TABLE_ENTRY * Table,
  146. IN BOOL fIgnoreCase,
  147. IN PCHAR pchName,
  148. IN INT cchNameLength
  149. )
  150. /*++
  151. Routine Description:
  152. Retrieve flag value for given string.
  153. This may be called repeatedly with additional strings and OR the result
  154. together to build flag with independent bit settings.
  155. Arguments:
  156. Table - table with value\string mapping
  157. fIgnoreCase - TRUE if case-insensitive string lookup
  158. pchName - ptr to string
  159. cchNameLength - length of string
  160. Return Value:
  161. Flag value corresponding to string, if found.
  162. DNS_TABLE_LOOKUP_ERROR otherwise.
  163. --*/
  164. {
  165. INT i = 0;
  166. //
  167. // if not given get string length
  168. //
  169. if ( !cchNameLength )
  170. {
  171. cchNameLength = strlen( pchName );
  172. }
  173. //
  174. // check all supported values for name match
  175. //
  176. if ( fIgnoreCase )
  177. {
  178. while( Table[i].pszString != NULL )
  179. {
  180. if ( cchNameLength == (INT)strlen( Table[i].pszString )
  181. &&
  182. ! _strnicmp( pchName, Table[i].pszString, cchNameLength ) )
  183. {
  184. return( Table[i].dwFlag );
  185. }
  186. i++;
  187. }
  188. }
  189. else
  190. {
  191. while( Table[i].pszString != NULL )
  192. {
  193. if ( cchNameLength == (INT)strlen( Table[i].pszString )
  194. &&
  195. ! strncmp( pchName, Table[i].pszString, cchNameLength ) )
  196. {
  197. return( Table[i].dwFlag );
  198. }
  199. i++;
  200. }
  201. }
  202. return( (DWORD) DNS_TABLE_LOOKUP_ERROR );
  203. }
  204. VOID
  205. DnsPrint_ValueTable(
  206. IN PRINT_ROUTINE PrintRoutine,
  207. IN PPRINT_CONTEXT pPrintContext,
  208. IN LPSTR pszHeader,
  209. IN PDNS_VALUE_TABLE Table
  210. )
  211. /*++
  212. Routine Description:
  213. Print value table.
  214. Arguments:
  215. PrintRoutine - routine to print with
  216. pPrintContext - print context
  217. pszHeader - header to print
  218. Table - value table to print
  219. Return Value:
  220. None
  221. --*/
  222. {
  223. DWORD i = 0;
  224. if ( !pszHeader )
  225. {
  226. pszHeader = "Table";
  227. }
  228. if ( ! pszHeader )
  229. {
  230. PrintRoutine(
  231. pPrintContext,
  232. "%s NULL value table to print",
  233. pszHeader );
  234. }
  235. //
  236. // print each value in table
  237. //
  238. DnsPrint_Lock();
  239. PrintRoutine(
  240. pPrintContext,
  241. "%s\n",
  242. pszHeader );
  243. while( Table[i].pszString != NULL )
  244. {
  245. PrintRoutine(
  246. pPrintContext,
  247. "\t%40s\t\t%08x\n",
  248. Table[i].pszString,
  249. Table[i].dwValue );
  250. i++;
  251. }
  252. DnsPrint_Unlock();
  253. }
  254. PCHAR
  255. Dns_WriteStringsForFlag(
  256. IN DNS_FLAG_TABLE_ENTRY * Table,
  257. IN DWORD dwFlag,
  258. IN OUT PCHAR pchFlag
  259. )
  260. /*++
  261. Routine Description:
  262. Retrieve flag string(s) corresponding to a given flag value.
  263. This function is specifically for mapping a flag value into the
  264. corresponding flag mnemonics.
  265. No attempt is made to insure that every bit of dwValue is mapped,
  266. nor are bits eliminated as they are mapped. Every value in table
  267. that exactly matches bits in the table is returned.
  268. Arguments:
  269. Table - table with value\string mapping
  270. dwFlag - flag value to map to strings
  271. pchFlag - buffer to write flag to
  272. Return Value:
  273. Ptr to next location in pchFlag buffer.
  274. If this is same as input, then no strings were written.
  275. --*/
  276. {
  277. INT i = 0;
  278. // init buffer for no-match
  279. DNS_ASSERT( pchFlag != NULL );
  280. *pchFlag = 0;
  281. //
  282. // check all supported flags types for name match
  283. // - note comparing flag within mask to allow match of multi-bit
  284. // flags
  285. //
  286. while( Table[i].pszString != NULL )
  287. {
  288. if ( (dwFlag & Table[i].dwMask) == Table[i].dwFlag )
  289. {
  290. pchFlag += sprintf( pchFlag, "%s ", Table[i].pszString );
  291. }
  292. i++;
  293. }
  294. return( pchFlag );
  295. }
  296. //
  297. // Specific simple tables
  298. //
  299. //
  300. // RnR Flag mappings
  301. //
  302. DNS_VALUE_TABLE_ENTRY RnrLupFlagTable[] =
  303. {
  304. LUP_DEEP , "LUP_DEEP" ,
  305. LUP_CONTAINERS , "LUP_CONTAINERS" ,
  306. LUP_NOCONTAINERS , "LUP_NOCONTAINERS" ,
  307. LUP_RETURN_NAME , "LUP_RETURN_NAME" ,
  308. LUP_RETURN_TYPE , "LUP_RETURN_TYPE" ,
  309. LUP_RETURN_VERSION , "LUP_RETURN_VERSION" ,
  310. LUP_RETURN_COMMENT , "LUP_RETURN_COMMENT" ,
  311. LUP_RETURN_ADDR , "LUP_RETURN_ADDR" ,
  312. LUP_RETURN_BLOB , "LUP_RETURN_BLOB" ,
  313. LUP_RETURN_ALIASES , "LUP_RETURN_ALIASES" ,
  314. LUP_RETURN_QUERY_STRING , "LUP_RETURN_QUERY_STRING" ,
  315. LUP_RETURN_ALL , "LUP_RETURN_ALL" ,
  316. LUP_RES_SERVICE , "LUP_RES_SERVICE" ,
  317. LUP_FLUSHCACHE , "LUP_FLUSHCACHE" ,
  318. LUP_FLUSHPREVIOUS , "LUP_FLUSHPREVIOUS" ,
  319. 0, NULL,
  320. };
  321. DWORD
  322. Dns_RnrLupFlagForString(
  323. IN PCHAR pchName,
  324. IN INT cchNameLength
  325. )
  326. /*++
  327. Routine Description:
  328. Retrieve RnR LUP flag corresponding to string.
  329. Arguments:
  330. pchName - ptr to string
  331. cchNameLength - length of string
  332. Return Value:
  333. Flag corresponding to string, if found.
  334. Zero otherwise.
  335. --*/
  336. {
  337. return Dns_ValueForString(
  338. RnrLupFlagTable,
  339. FALSE, // always upper case
  340. pchName,
  341. cchNameLength );
  342. }
  343. PCHAR
  344. Dns_GetRnrLupFlagString(
  345. IN DWORD dwFlag
  346. )
  347. /*++
  348. Routine Description:
  349. Get string corresponding to a given RnR LUP flag.
  350. Arguments:
  351. dwFlag -- flag
  352. Return Value:
  353. Ptr to flag mneumonic string.
  354. NULL if unknown flag.
  355. --*/
  356. {
  357. return Dns_GetStringForValue(
  358. RnrLupFlagTable,
  359. dwFlag );
  360. }
  361. //
  362. // RnR Name Space ID mappings
  363. //
  364. DNS_VALUE_TABLE_ENTRY RnrNameSpaceMappingTable[] =
  365. {
  366. NS_ALL , "NS_ALL" ,
  367. //NS_DEFAULT , "NS_DEFAULT" ,
  368. NS_SAP , "NS_SAP" ,
  369. NS_NDS , "NS_NDS" ,
  370. NS_PEER_BROWSE , "NS_PEER_BROWSEE" ,
  371. NS_SLP , "NS_SLP" ,
  372. NS_DHCP , "NS_DHCP" ,
  373. NS_TCPIP_LOCAL , "NS_TCPIP_LOCAL" ,
  374. NS_TCPIP_HOSTS , "NS_TCPIP_HOSTS" ,
  375. NS_DNS , "NS_DNS" ,
  376. NS_NETBT , "NS_NETBT" ,
  377. NS_WINS , "NS_WINS" ,
  378. NS_NLA , "NS_NLA" ,
  379. NS_NBP , "NS_NBP" ,
  380. NS_MS , "NS_MS" ,
  381. NS_STDA , "NS_STDA" ,
  382. NS_NTDS , "NS_NTDS" ,
  383. NS_X500 , "NS_X500" ,
  384. NS_NIS , "NS_NIS" ,
  385. NS_NISPLUS , "NS_NISPLUS" ,
  386. NS_WRQ , "NS_WRQ" ,
  387. NS_NETDES , "NS_NETDES" ,
  388. 0, NULL,
  389. };
  390. DWORD
  391. Dns_RnrNameSpaceIdForString(
  392. IN PCHAR pchName,
  393. IN INT cchNameLength
  394. )
  395. /*++
  396. Routine Description:
  397. Retrieve RnR Name Space Id corresponding to string.
  398. Arguments:
  399. pchName - ptr to string
  400. cchNameLength - length of string
  401. Return Value:
  402. Name space ID corresponding to string, if found.
  403. Zero otherwise.
  404. --*/
  405. {
  406. return Dns_ValueForString(
  407. RnrNameSpaceMappingTable,
  408. FALSE, // always upper case
  409. pchName,
  410. cchNameLength );
  411. }
  412. PCHAR
  413. Dns_GetRnrNameSpaceIdString(
  414. IN DWORD dwFlag
  415. )
  416. /*++
  417. Routine Description:
  418. Get string corresponding to a given RnR name space id.
  419. Arguments:
  420. dwFlag -- flag
  421. Return Value:
  422. Ptr to name space mneumonic string.
  423. NULL if unknown flag.
  424. --*/
  425. {
  426. return Dns_GetStringForValue(
  427. RnrNameSpaceMappingTable,
  428. dwFlag );
  429. }
  430. //
  431. // End table.c
  432. //