Leaked source code of windows server 2003
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.

2637 lines
50 KiB

  1. /*++
  2. Copyright (c) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. rrbuild.c
  5. Abstract:
  6. Domain Name System (DNS) Library
  7. Build resource record routines.
  8. Author:
  9. Jim Gilroy (jamesg) January, 1997
  10. Revision History:
  11. Jing Chen (t-jingc) June, 1998
  12. --*/
  13. #include "local.h"
  14. //
  15. // Type specific record build routines
  16. //
  17. PDNS_RECORD
  18. A_RecordBuild(
  19. IN DWORD Argc,
  20. IN PCHAR * Argv
  21. )
  22. /*++
  23. Routine Description:
  24. Build A record from string data.
  25. Arguments:
  26. Argc -- count of data arguments
  27. Argv -- argv array of data string pointers
  28. Return Value:
  29. Ptr to new record if successful.
  30. NULL on failure.
  31. --*/
  32. {
  33. PDNS_RECORD precord;
  34. if ( Argc != 1 )
  35. {
  36. SetLastError( ERROR_INVALID_DATA );
  37. return( NULL );
  38. }
  39. precord = Dns_AllocateRecord( sizeof(DNS_A_DATA) );
  40. if ( !precord )
  41. {
  42. return( NULL );
  43. }
  44. if ( ! Dns_Ip4StringToAddress_A(
  45. &precord->Data.A.IpAddress,
  46. Argv[0] ) )
  47. {
  48. Dns_RecordFree( precord );
  49. SetLastError( ERROR_INVALID_DATA );
  50. return NULL;
  51. }
  52. return( precord );
  53. }
  54. PDNS_RECORD
  55. A_RecordBuildW(
  56. IN DWORD Argc,
  57. IN PWCHAR * Argv
  58. )
  59. /*++
  60. Routine Description:
  61. Build A record from string data.
  62. Arguments:
  63. Argc -- count of data arguments
  64. Argv -- argv array of data string pointers
  65. Return Value:
  66. Ptr to new record if successful.
  67. NULL on failure.
  68. --*/
  69. {
  70. PDNS_RECORD precord;
  71. if ( Argc != 1 )
  72. {
  73. SetLastError( ERROR_INVALID_DATA );
  74. return( NULL );
  75. }
  76. precord = Dns_AllocateRecord( sizeof(DNS_A_DATA) );
  77. if ( !precord )
  78. {
  79. return( NULL );
  80. }
  81. if ( ! Dns_Ip4StringToAddress_W(
  82. &precord->Data.A.IpAddress,
  83. Argv[0] ) )
  84. {
  85. Dns_RecordFree( precord );
  86. SetLastError( ERROR_INVALID_DATA );
  87. return NULL;
  88. }
  89. return( precord );
  90. }
  91. PDNS_RECORD
  92. Ptr_RecordBuild(
  93. IN DWORD Argc,
  94. IN PCHAR * Argv
  95. )
  96. /*++
  97. Routine Description:
  98. Build PTR compatible record from string data.
  99. Includes: NS, PTR, CNAME, MB, MR, MG, MD, MF
  100. Arguments:
  101. Argc -- count of data arguments
  102. Argv -- argv array of data string pointers
  103. Return Value:
  104. Ptr to new record if successful.
  105. NULL on failure.
  106. --*/
  107. {
  108. PDNS_RECORD precord;
  109. if ( Argc != 1 )
  110. {
  111. SetLastError( ERROR_INVALID_DATA );
  112. return( NULL );
  113. }
  114. precord = Dns_AllocateRecord( sizeof(DNS_PTR_DATA) );
  115. if ( !precord )
  116. {
  117. return( NULL );
  118. }
  119. precord->Data.PTR.pNameHost = Argv[0];
  120. return( precord );
  121. }
  122. PDNS_RECORD
  123. Ptr_RecordBuildW(
  124. IN DWORD Argc,
  125. IN PWCHAR * Argv
  126. )
  127. /*++
  128. Routine Description:
  129. Build PTR compatible record from string data.
  130. Includes: NS, PTR, CNAME, MB, MR, MG, MD, MF
  131. Arguments:
  132. Argc -- count of data arguments
  133. Argv -- argv array of data string pointers
  134. Return Value:
  135. Ptr to new record if successful.
  136. NULL on failure.
  137. --*/
  138. {
  139. PDNS_RECORD precord;
  140. if ( Argc != 1 )
  141. {
  142. SetLastError( ERROR_INVALID_DATA );
  143. return( NULL );
  144. }
  145. precord = Dns_AllocateRecord( sizeof(DNS_PTR_DATA) );
  146. if ( !precord )
  147. {
  148. return( NULL );
  149. }
  150. precord->Data.PTR.pNameHost = (PDNS_NAME) Argv[0];
  151. return( precord );
  152. }
  153. PDNS_RECORD
  154. Mx_RecordBuild(
  155. IN DWORD Argc,
  156. IN PCHAR * Argv
  157. )
  158. /*++
  159. Routine Description:
  160. Build MX compatible record from string data.
  161. Includes: MX, RT, AFSDB
  162. Arguments:
  163. Argc -- count of data arguments
  164. Argv -- argv array of data string pointers
  165. Return Value:
  166. Ptr to new record if successful.
  167. NULL on failure.
  168. --*/
  169. {
  170. PDNS_RECORD precord;
  171. DWORD temp;
  172. if ( Argc != 2 )
  173. {
  174. SetLastError( ERROR_INVALID_DATA );
  175. return( NULL );
  176. }
  177. precord = Dns_AllocateRecord( sizeof(DNS_MX_DATA) );
  178. if ( !precord )
  179. {
  180. return( NULL );
  181. }
  182. //
  183. // MX preference value
  184. // RT preference
  185. // AFSDB subtype
  186. //
  187. temp = strtoul( Argv[0], NULL, 10 );
  188. if ( temp > MAXWORD )
  189. {
  190. temp = MAXWORD;
  191. }
  192. precord->Data.MX.wPreference = (USHORT) temp;
  193. //
  194. // MX exchange
  195. // RT exchange
  196. // AFSDB hostname
  197. //
  198. precord->Data.MX.pNameExchange = Argv[1];
  199. return( precord );
  200. }
  201. PDNS_RECORD
  202. Mx_RecordBuildW(
  203. IN DWORD Argc,
  204. IN PWCHAR * Argv
  205. )
  206. /*++
  207. Routine Description:
  208. Build MX compatible record from string data.
  209. Includes: MX, RT, AFSDB
  210. Arguments:
  211. Argc -- count of data arguments
  212. Argv -- argv array of data string pointers
  213. Return Value:
  214. Ptr to new record if successful.
  215. NULL on failure.
  216. --*/
  217. {
  218. PDNS_RECORD precord;
  219. DWORD temp;
  220. if ( Argc != 2 )
  221. {
  222. SetLastError( ERROR_INVALID_DATA );
  223. return( NULL );
  224. }
  225. precord = Dns_AllocateRecord( sizeof(DNS_MX_DATA) );
  226. if ( !precord )
  227. {
  228. return( NULL );
  229. }
  230. //
  231. // MX preference value
  232. // RT preference
  233. // AFSDB subtype
  234. //
  235. temp = wcstoul( Argv[0], NULL, 10 );
  236. if ( temp > MAXWORD )
  237. {
  238. temp = MAXWORD;
  239. }
  240. precord->Data.MX.wPreference = (USHORT) temp;
  241. //
  242. // MX exchange
  243. // RT exchange
  244. // AFSDB hostname
  245. //
  246. precord->Data.MX.pNameExchange = (PDNS_NAME) Argv[1];
  247. return( precord );
  248. }
  249. PDNS_RECORD
  250. Soa_RecordBuild(
  251. IN DWORD Argc,
  252. IN PCHAR * Argv
  253. )
  254. /*++
  255. Routine Description:
  256. Build SOA record from string data.
  257. Arguments:
  258. Argc -- count of data arguments
  259. Argv -- argv array of data string pointers
  260. Return Value:
  261. Ptr to new record if successful.
  262. NULL on failure.
  263. --*/
  264. {
  265. PDNS_RECORD precord;
  266. PDWORD pdword;
  267. if ( Argc != 7 )
  268. {
  269. SetLastError( ERROR_INVALID_DATA );
  270. return( NULL );
  271. }
  272. precord = Dns_AllocateRecord( sizeof(DNS_SOA_DATA) );
  273. if ( !precord )
  274. {
  275. return( NULL );
  276. }
  277. //
  278. // read primary server and responsible party
  279. //
  280. precord->Data.SOA.pNamePrimaryServer = Argv[0];
  281. Argc--;
  282. Argv++;
  283. precord->Data.SOA.pNameAdministrator = Argv[0];
  284. Argc--;
  285. Argv++;
  286. //
  287. // read integer data
  288. //
  289. pdword = &precord->Data.SOA.dwSerialNo;
  290. while( Argc-- )
  291. {
  292. *pdword = strtoul( Argv[0], NULL, 10 );
  293. pdword++;
  294. Argv++;
  295. }
  296. return( precord );
  297. }
  298. PDNS_RECORD
  299. Soa_RecordBuildW(
  300. IN DWORD Argc,
  301. IN PWCHAR * Argv
  302. )
  303. /*++
  304. Routine Description:
  305. Build SOA record from string data.
  306. Arguments:
  307. Argc -- count of data arguments
  308. Argv -- argv array of data string pointers
  309. Return Value:
  310. Ptr to new record if successful.
  311. NULL on failure.
  312. --*/
  313. {
  314. PDNS_RECORD precord;
  315. PDWORD pdword;
  316. if ( Argc != 7 )
  317. {
  318. SetLastError( ERROR_INVALID_DATA );
  319. return( NULL );
  320. }
  321. precord = Dns_AllocateRecord( sizeof(DNS_SOA_DATA) );
  322. if ( !precord )
  323. {
  324. return( NULL );
  325. }
  326. //
  327. // read primary server and responsible party
  328. //
  329. precord->Data.SOA.pNamePrimaryServer = (PDNS_NAME) Argv[0];
  330. Argc--;
  331. Argv++;
  332. precord->Data.SOA.pNameAdministrator = (PDNS_NAME) Argv[0];
  333. Argc--;
  334. Argv++;
  335. //
  336. // read integer data
  337. //
  338. pdword = &precord->Data.SOA.dwSerialNo;
  339. while( Argc-- )
  340. {
  341. *pdword = wcstoul( Argv[0], NULL, 10 );
  342. pdword++;
  343. Argv++;
  344. }
  345. return( precord );
  346. }
  347. PDNS_RECORD
  348. Minfo_RecordBuild(
  349. IN DWORD Argc,
  350. IN PCHAR * Argv
  351. )
  352. /*++
  353. Routine Description:
  354. Build MINFO and RP records from string data.
  355. Arguments:
  356. Argc -- count of data Arguments
  357. Argv -- argv array of data string pointers
  358. Return Value:
  359. Ptr to new record if successful.
  360. NULL on failure.
  361. --*/
  362. {
  363. PDNS_RECORD precord;
  364. if ( Argc != 2 )
  365. {
  366. SetLastError( ERROR_INVALID_DATA );
  367. return( NULL );
  368. }
  369. precord = Dns_AllocateRecord( sizeof(DNS_MINFO_DATA) );
  370. if ( !precord )
  371. {
  372. return( NULL );
  373. }
  374. //
  375. // MINFO responsible mailbox
  376. // RP responsible person mailbox
  377. precord->Data.MINFO.pNameMailbox = Argv[0];
  378. Argc--;
  379. Argv++;
  380. //
  381. // MINFO errors to mailbox
  382. // RP text RR location
  383. precord->Data.MINFO.pNameErrorsMailbox = Argv[0];
  384. Argc--;
  385. Argv++;
  386. return( precord );
  387. }
  388. PDNS_RECORD
  389. Minfo_RecordBuildW(
  390. IN DWORD Argc,
  391. IN PWCHAR * Argv
  392. )
  393. /*++
  394. Routine Description:
  395. Build MINFO and RP records from string data.
  396. Arguments:
  397. Argc -- count of data Arguments
  398. Argv -- argv array of data string pointers
  399. Return Value:
  400. Ptr to new record if successful.
  401. NULL on failure.
  402. --*/
  403. {
  404. PDNS_RECORD precord;
  405. if ( Argc != 2 )
  406. {
  407. SetLastError( ERROR_INVALID_DATA );
  408. return( NULL );
  409. }
  410. precord = Dns_AllocateRecord( sizeof(DNS_MINFO_DATA) );
  411. if ( !precord )
  412. {
  413. return( NULL );
  414. }
  415. //
  416. // MINFO responsible mailbox
  417. // RP responsible person mailbox
  418. precord->Data.MINFO.pNameMailbox = (PDNS_NAME) Argv[0];
  419. Argc--;
  420. Argv++;
  421. //
  422. // MINFO errors to mailbox
  423. // RP text RR location
  424. precord->Data.MINFO.pNameErrorsMailbox = (PDNS_NAME) Argv[0];
  425. Argc--;
  426. Argv++;
  427. return( precord );
  428. }
  429. PDNS_RECORD
  430. Txt_RecordBuild(
  431. IN DWORD Argc,
  432. IN PCHAR * Argv
  433. )
  434. /*++
  435. Routine Description:
  436. Build TXT compatible records from string data.
  437. Includes: TXT, X25, HINFO, ISDN
  438. Arguments:
  439. Argc -- count of data Arguments
  440. Argv -- argv array of data string pointers
  441. Return Value:
  442. Ptr to new record if successful.
  443. NULL on failure.
  444. --*/
  445. {
  446. PDNS_RECORD precord;
  447. WORD dataLength;
  448. PCHAR * pstringPtr;
  449. if ( Argc < 1 )
  450. {
  451. SetLastError( ERROR_INVALID_DATA );
  452. return( NULL );
  453. }
  454. //
  455. // allocate space for a pointer for each data string
  456. //
  457. precord = Dns_AllocateRecord( (WORD)DNS_TEXT_RECORD_LENGTH(Argc) );
  458. if ( !precord )
  459. {
  460. return( NULL );
  461. }
  462. precord->Data.TXT.dwStringCount = Argc;
  463. //
  464. // read as many strings as we have
  465. //
  466. // DCR_FIX: no checking for string limits
  467. // - string count limits on HINFO, X25, ISDN
  468. // - 256 length on strings
  469. // - 64K on overall size
  470. //
  471. pstringPtr = (PCHAR *) precord->Data.TXT.pStringArray;
  472. while ( Argc-- )
  473. {
  474. *pstringPtr = Argv[0];
  475. pstringPtr++;
  476. Argv++;
  477. }
  478. return( precord );
  479. }
  480. PDNS_RECORD
  481. Txt_RecordBuildW(
  482. IN DWORD Argc,
  483. IN PWCHAR * Argv
  484. )
  485. /*++
  486. Routine Description:
  487. Build TXT compatible records from string data.
  488. Includes: TXT, X25, HINFO, ISDN
  489. Arguments:
  490. Argc -- count of data Arguments
  491. Argv -- argv array of data string pointers
  492. Return Value:
  493. Ptr to new record if successful.
  494. NULL on failure.
  495. --*/
  496. {
  497. PDNS_RECORD precord;
  498. WORD dataLength;
  499. LPWSTR * pstringPtr;
  500. if ( Argc < 1 )
  501. {
  502. SetLastError( ERROR_INVALID_DATA );
  503. return( NULL );
  504. }
  505. //
  506. // allocate space for a pointer for each data string
  507. //
  508. precord = Dns_AllocateRecord( (WORD)DNS_TEXT_RECORD_LENGTH(Argc) );
  509. if ( !precord )
  510. {
  511. return( NULL );
  512. }
  513. precord->Data.TXT.dwStringCount = Argc;
  514. //
  515. // read as many strings as we have
  516. //
  517. // DCR_FIX: no checking for string limits
  518. // - string count limits on HINFO, X25, ISDN
  519. // - 256 length on strings
  520. // - 64K on overall size
  521. //
  522. pstringPtr = (LPWSTR *) precord->Data.TXT.pStringArray;
  523. while ( Argc-- )
  524. {
  525. *pstringPtr = Argv[0];
  526. pstringPtr++;
  527. Argv++;
  528. }
  529. return( precord );
  530. }
  531. PDNS_RECORD
  532. Aaaa_RecordBuild(
  533. IN DWORD Argc,
  534. IN PCHAR * Argv
  535. )
  536. /*++
  537. Routine Description:
  538. Build AAAA record from string data.
  539. Arguments:
  540. Argc -- count of data Arguments
  541. Argv -- argv array of data string pointers
  542. Return Value:
  543. Ptr to new record if successful.
  544. NULL on failure.
  545. --*/
  546. {
  547. PDNS_RECORD precord;
  548. if ( Argc != 1 )
  549. {
  550. SetLastError( ERROR_INVALID_DATA );
  551. return( NULL );
  552. }
  553. precord = Dns_AllocateRecord( sizeof(DNS_AAAA_DATA) );
  554. if ( !precord )
  555. {
  556. return( NULL );
  557. }
  558. //
  559. // read IP6 address
  560. //
  561. if ( ! Dns_Ip6StringToAddress_A(
  562. (PIP6_ADDRESS) &precord->Data.AAAA.Ip6Address,
  563. Argv[0] ) )
  564. {
  565. Dns_RecordFree( precord );
  566. SetLastError( ERROR_INVALID_DATA );
  567. return NULL;
  568. }
  569. return( precord );
  570. }
  571. PDNS_RECORD
  572. Aaaa_RecordBuildW(
  573. IN DWORD Argc,
  574. IN PWCHAR * Argv
  575. )
  576. /*++
  577. Routine Description:
  578. Build AAAA record from string data.
  579. Arguments:
  580. Argc -- count of data Arguments
  581. Argv -- argv array of data string pointers
  582. Return Value:
  583. Ptr to new record if successful.
  584. NULL on failure.
  585. --*/
  586. {
  587. PDNS_RECORD precord;
  588. if ( Argc != 1 )
  589. {
  590. SetLastError( ERROR_INVALID_DATA );
  591. return( NULL );
  592. }
  593. precord = Dns_AllocateRecord( sizeof(DNS_AAAA_DATA) );
  594. if ( !precord )
  595. {
  596. return( NULL );
  597. }
  598. //
  599. // convert IPv6 string to address
  600. //
  601. if ( ! Dns_Ip6StringToAddress_W(
  602. &precord->Data.AAAA.Ip6Address,
  603. Argv[0]
  604. ) )
  605. {
  606. SetLastError( ERROR_INVALID_DATA );
  607. Dns_RecordFree( precord );
  608. return NULL;
  609. }
  610. return( precord );
  611. }
  612. PDNS_RECORD
  613. Srv_RecordBuild(
  614. IN DWORD Argc,
  615. IN PCHAR * Argv
  616. )
  617. /*++
  618. Routine Description:
  619. Build SRV record from string data.
  620. Arguments:
  621. Argc -- count of data Arguments
  622. Argv -- argv array of data string pointers
  623. Return Value:
  624. Ptr to new record if successful.
  625. NULL on failure.
  626. --*/
  627. {
  628. PDNS_RECORD precord;
  629. PWORD pword;
  630. if ( Argc != 4 )
  631. {
  632. SetLastError( ERROR_INVALID_DATA );
  633. return( NULL );
  634. }
  635. precord = Dns_AllocateRecord( sizeof(DNS_SRV_DATA) );
  636. if ( !precord )
  637. {
  638. return( NULL );
  639. }
  640. //
  641. // read integer data
  642. //
  643. pword = &precord->Data.SRV.wPriority;
  644. while( Argc-- > 1 )
  645. {
  646. DWORD temp;
  647. temp = strtoul( Argv[0], NULL, 10 );
  648. if ( temp > MAXWORD )
  649. {
  650. temp = MAXWORD;
  651. }
  652. *pword++ = (WORD) temp;
  653. Argv++;
  654. }
  655. //
  656. // target host
  657. //
  658. precord->Data.SRV.pNameTarget = Argv[0];
  659. return( precord );
  660. }
  661. PDNS_RECORD
  662. Srv_RecordBuildW(
  663. IN DWORD Argc,
  664. IN PWCHAR * Argv
  665. )
  666. /*++
  667. Routine Description:
  668. Build SRV record from string data.
  669. Arguments:
  670. Argc -- count of data Arguments
  671. Argv -- argv array of data string pointers
  672. Return Value:
  673. Ptr to new record if successful.
  674. NULL on failure.
  675. --*/
  676. {
  677. PDNS_RECORD precord;
  678. PWORD pword;
  679. if ( Argc != 4 )
  680. {
  681. SetLastError( ERROR_INVALID_DATA );
  682. return( NULL );
  683. }
  684. precord = Dns_AllocateRecord( sizeof(DNS_SRV_DATA) );
  685. if ( !precord )
  686. {
  687. return( NULL );
  688. }
  689. //
  690. // read integer data
  691. //
  692. pword = &precord->Data.SRV.wPriority;
  693. while( Argc-- > 1 )
  694. {
  695. DWORD temp;
  696. temp = wcstoul( Argv[0], NULL, 10 );
  697. if ( temp > MAXWORD )
  698. {
  699. temp = MAXWORD;
  700. }
  701. *pword++ = (WORD) temp;
  702. Argv++;
  703. }
  704. //
  705. // target host
  706. //
  707. precord->Data.SRV.pNameTarget = (PDNS_NAME) Argv[0];
  708. return( precord );
  709. }
  710. PDNS_RECORD
  711. Atma_RecordBuild(
  712. IN DWORD Argc,
  713. IN PCHAR * Argv
  714. )
  715. /*++
  716. Routine Description:
  717. Build ATMA record from string data.
  718. Arguments:
  719. Argc -- count of data Arguments
  720. Argv -- argv array of data string pointers
  721. Return Value:
  722. Ptr to new record if successful.
  723. NULL on failure.
  724. --*/
  725. {
  726. PDNS_RECORD precord;
  727. PBYTE pbyte;
  728. if ( Argc != 2 )
  729. {
  730. SetLastError( ERROR_INVALID_DATA );
  731. return( NULL );
  732. }
  733. precord = Dns_AllocateRecord( sizeof(DNS_ATMA_DATA) +
  734. DNS_ATMA_MAX_ADDR_LENGTH );
  735. if ( !precord )
  736. {
  737. return( NULL );
  738. }
  739. //
  740. // read integer data
  741. //
  742. pbyte = &precord->Data.ATMA.AddressType;
  743. *pbyte = (BYTE) strtoul( Argv[0], NULL, 10 );
  744. pbyte++;
  745. Argv++;
  746. if ( precord->Data.ATMA.AddressType == DNS_ATMA_FORMAT_E164 )
  747. {
  748. UINT length = strlen( Argv[0] );
  749. UINT iter;
  750. if ( length > DNS_ATMA_MAX_ADDR_LENGTH )
  751. {
  752. length = DNS_ATMA_MAX_ADDR_LENGTH;
  753. }
  754. for ( iter = 0; iter < length; iter++ )
  755. {
  756. precord->Data.ATMA.Address[iter] = Argv[0][iter];
  757. }
  758. precord->wDataLength = (WORD) length;
  759. }
  760. else
  761. {
  762. UINT length = strlen( Argv[0] );
  763. UINT iter;
  764. length /= 2;
  765. if ( length != DNS_ATMA_MAX_ADDR_LENGTH )
  766. {
  767. Dns_RecordListFree( precord );
  768. return NULL;
  769. }
  770. for ( iter = 0; iter < length; iter++ )
  771. {
  772. char temp[3];
  773. temp[0] = Argv[0][(2*iter)];
  774. temp[1] = Argv[0][(2*iter) + 1];
  775. temp[2] = 0;
  776. precord->Data.ATMA.Address[iter] = (char) strtoul( temp, NULL, 16 );
  777. }
  778. precord->wDataLength = (WORD) length;
  779. }
  780. return( precord );
  781. }
  782. PDNS_RECORD
  783. Atma_RecordBuildW(
  784. IN DWORD Argc,
  785. IN PWCHAR * Argv
  786. )
  787. /*++
  788. Routine Description:
  789. Build ATMA record from string data.
  790. Arguments:
  791. Argc -- count of data Arguments
  792. Argv -- argv array of data string pointers
  793. Return Value:
  794. Ptr to new record if successful.
  795. NULL on failure.
  796. --*/
  797. {
  798. PDNS_RECORD precord;
  799. PBYTE pbyte;
  800. CHAR addrBuffer[256];
  801. DWORD bufLength;
  802. if ( Argc != 2 )
  803. {
  804. SetLastError( ERROR_INVALID_DATA );
  805. return( NULL );
  806. }
  807. precord = Dns_AllocateRecord( sizeof(DNS_ATMA_DATA) +
  808. DNS_ATMA_MAX_ADDR_LENGTH );
  809. if ( !precord )
  810. {
  811. return( NULL );
  812. }
  813. //
  814. // read integer data
  815. //
  816. pbyte = &precord->Data.ATMA.AddressType;
  817. *pbyte = (BYTE) wcstoul( Argv[0], NULL, 10 );
  818. pbyte++;
  819. Argv++;
  820. //
  821. // copy ATMA address string to wire
  822. //
  823. bufLength = DNS_ATMA_MAX_ADDR_LENGTH+1;
  824. if ( ! Dns_StringCopy(
  825. addrBuffer,
  826. & bufLength,
  827. (PCHAR) Argv[0],
  828. 0, // length unknown
  829. DnsCharSetUnicode,
  830. DnsCharSetWire
  831. ) )
  832. {
  833. Dns_RecordListFree( precord );
  834. SetLastError( ERROR_INVALID_DATA );
  835. return NULL;
  836. }
  837. //
  838. // read address into record buffer
  839. //
  840. // DCR_CLEANUP: this is duplicate code with above function,
  841. // functionalize and fix; also remove this loop
  842. // and do a memcopy
  843. //
  844. if ( precord->Data.ATMA.AddressType == DNS_ATMA_FORMAT_E164 )
  845. {
  846. UINT length = strlen( addrBuffer );
  847. UINT iter;
  848. if ( length > DNS_ATMA_MAX_ADDR_LENGTH )
  849. {
  850. length = DNS_ATMA_MAX_ADDR_LENGTH;
  851. }
  852. for ( iter = 0; iter < length; iter++ )
  853. {
  854. precord->Data.ATMA.Address[iter] = addrBuffer[iter];
  855. }
  856. precord->wDataLength = (WORD) length;
  857. }
  858. else
  859. {
  860. UINT length = strlen( addrBuffer );
  861. UINT iter;
  862. length /= 2;
  863. if ( length != DNS_ATMA_MAX_ADDR_LENGTH )
  864. {
  865. Dns_RecordListFree( precord );
  866. return NULL;
  867. }
  868. for ( iter = 0; iter < length; iter++ )
  869. {
  870. char temp[3];
  871. temp[0] = addrBuffer[(2*iter)];
  872. temp[1] = addrBuffer[(2*iter) + 1];
  873. temp[2] = 0;
  874. precord->Data.ATMA.Address[iter] = (char) strtoul( temp, NULL, 16 );
  875. }
  876. precord->wDataLength = (WORD) length;
  877. }
  878. return( precord );
  879. }
  880. PDNS_RECORD
  881. Wins_RecordBuild(
  882. IN DWORD Argc,
  883. IN PCHAR * Argv
  884. )
  885. /*++
  886. Routine Description:
  887. Build WINS record from string data.
  888. Arguments:
  889. Argc -- count of data Arguments
  890. Argv -- argv array of data string pointers
  891. Return Value:
  892. Ptr to new record if successful.
  893. NULL on failure.
  894. --*/
  895. {
  896. PDNS_RECORD precord;
  897. DWORD ipCount = Argc - 3;
  898. PDWORD pdword;
  899. PIP4_ADDRESS pip;
  900. if ( Argc < 4 )
  901. {
  902. SetLastError( ERROR_INVALID_DATA );
  903. return( NULL );
  904. }
  905. precord = Dns_AllocateRecord( (WORD) DNS_WINS_RECORD_LENGTH((WORD) ipCount) );
  906. if ( !precord )
  907. {
  908. return( NULL );
  909. }
  910. //
  911. // read integer data
  912. //
  913. // DCR_ENHANCE: could check for non-conversion in strtoul
  914. //
  915. pdword = &precord->Data.WINS.dwMappingFlag;
  916. while ( Argc > ipCount )
  917. {
  918. *pdword = (DWORD) strtoul( Argv[0], NULL, 10 );
  919. pdword++;
  920. Argv++;
  921. Argc--;
  922. }
  923. *pdword = ipCount;
  924. //
  925. // convert IP addresses
  926. //
  927. pip = precord->Data.WINS.WinsServers;
  928. while ( Argc-- )
  929. {
  930. if ( ! Dns_Ip4StringToAddress_A(
  931. pip,
  932. Argv[0] ) )
  933. {
  934. Dns_RecordFree( precord );
  935. SetLastError( ERROR_INVALID_DATA );
  936. return NULL;
  937. }
  938. pip++;
  939. Argv++;
  940. }
  941. return( precord );
  942. }
  943. PDNS_RECORD
  944. Wins_RecordBuildW(
  945. IN DWORD Argc,
  946. IN PWCHAR * Argv
  947. )
  948. /*++
  949. Routine Description:
  950. Build WINS record from string data.
  951. Arguments:
  952. Argc -- count of data Arguments
  953. Argv -- argv array of data string pointers
  954. Return Value:
  955. Ptr to new record if successful.
  956. NULL on failure.
  957. --*/
  958. {
  959. PDNS_RECORD precord;
  960. DWORD ipCount = Argc - 3;
  961. PDWORD pdword;
  962. PIP4_ADDRESS pip;
  963. char szAddr[256];
  964. if ( Argc < 4 )
  965. {
  966. SetLastError( ERROR_INVALID_DATA );
  967. return( NULL );
  968. }
  969. precord = Dns_AllocateRecord( (WORD) DNS_WINS_RECORD_LENGTH((WORD) ipCount) );
  970. if ( !precord )
  971. {
  972. return( NULL );
  973. }
  974. //
  975. // read integer data
  976. //
  977. // DCR_ENHANCE: could check for non-conversion in strtoul
  978. //
  979. pdword = &precord->Data.WINS.dwMappingFlag;
  980. while ( Argc-- > 1 )
  981. {
  982. *pdword = (DWORD) wcstoul( Argv[0], NULL, 10 );
  983. pdword++;
  984. Argv++;
  985. }
  986. *pdword = ipCount;
  987. //
  988. // convert IP addresses
  989. //
  990. pip = precord->Data.WINS.WinsServers;
  991. while ( Argc-- )
  992. {
  993. if ( ! Dns_Ip4StringToAddress_W(
  994. pip,
  995. Argv[0] ) )
  996. {
  997. Dns_RecordFree( precord );
  998. SetLastError( ERROR_INVALID_DATA );
  999. return NULL;
  1000. }
  1001. pip++;
  1002. Argv++;
  1003. }
  1004. return( precord );
  1005. }
  1006. PDNS_RECORD
  1007. Winsr_RecordBuild(
  1008. IN DWORD Argc,
  1009. IN PCHAR * Argv
  1010. )
  1011. /*++
  1012. Routine Description:
  1013. Build WINSR record from string data.
  1014. Arguments:
  1015. Argc -- count of data Arguments
  1016. Argv -- argv array of data string pointers
  1017. Return Value:
  1018. Ptr to new record if successful.
  1019. NULL on failure.
  1020. --*/
  1021. {
  1022. PDNS_RECORD precord;
  1023. PDWORD pdword;
  1024. if ( Argc != 4 )
  1025. {
  1026. SetLastError( ERROR_INVALID_DATA );
  1027. return( NULL );
  1028. }
  1029. precord = Dns_AllocateRecord( sizeof(DNS_WINSR_DATA) );
  1030. if ( !precord )
  1031. {
  1032. return( NULL );
  1033. }
  1034. //
  1035. // read integer data
  1036. //
  1037. // DCR_ENHANCE: could check for non-conversion in strtoul
  1038. //
  1039. pdword = &precord->Data.WINSR.dwMappingFlag;
  1040. while( Argc-- > 1 )
  1041. {
  1042. *pdword = (WORD) strtoul( Argv[0], NULL, 10 );
  1043. pdword++;
  1044. Argv++;
  1045. }
  1046. //
  1047. // result domain
  1048. //
  1049. precord->Data.WINSR.pNameResultDomain = Argv[0];
  1050. return( precord );
  1051. }
  1052. PDNS_RECORD
  1053. Winsr_RecordBuildW(
  1054. IN DWORD Argc,
  1055. IN PWCHAR * Argv
  1056. )
  1057. /*++
  1058. Routine Description:
  1059. Build WINSR record from string data.
  1060. Arguments:
  1061. Argc -- count of data Arguments
  1062. Argv -- argv array of data string pointers
  1063. Return Value:
  1064. Ptr to new record if successful.
  1065. NULL on failure.
  1066. --*/
  1067. {
  1068. PDNS_RECORD precord;
  1069. PDWORD pdword;
  1070. if ( Argc != 4 )
  1071. {
  1072. SetLastError( ERROR_INVALID_DATA );
  1073. return( NULL );
  1074. }
  1075. precord = Dns_AllocateRecord( sizeof(DNS_WINSR_DATA) );
  1076. if ( !precord )
  1077. {
  1078. return( NULL );
  1079. }
  1080. //
  1081. // read integer data
  1082. //
  1083. // DCR_ENHANCE: could check for non-conversion in strtoul
  1084. //
  1085. pdword = &precord->Data.WINSR.dwMappingFlag;
  1086. while( Argc-- > 1 )
  1087. {
  1088. *pdword = (WORD) wcstoul( Argv[0], NULL, 10 );
  1089. pdword++;
  1090. Argv++;
  1091. }
  1092. //
  1093. // result domain
  1094. //
  1095. precord->Data.WINSR.pNameResultDomain = (PDNS_NAME) Argv[0];
  1096. return( precord );
  1097. }
  1098. PDNS_RECORD
  1099. Wks_RecordBuild(
  1100. IN DWORD Argc,
  1101. IN PCHAR * Argv
  1102. )
  1103. /*++
  1104. Routine Description:
  1105. Build WKS record from string data.
  1106. Arguments:
  1107. Argc -- count of data Arguments
  1108. Argv -- argv array of data string pointers
  1109. Return Value:
  1110. Ptr to new record if successful.
  1111. NULL on failure.
  1112. --*/
  1113. {
  1114. PDNS_RECORD precord;
  1115. DWORD byteCount = 0;
  1116. DWORD i;
  1117. PCHAR pch;
  1118. WSADATA wsaData;
  1119. DNS_STATUS status;
  1120. struct protoent * pProtoent;
  1121. if ( Argc < 3 )
  1122. {
  1123. SetLastError( ERROR_INVALID_DATA );
  1124. return( NULL );
  1125. }
  1126. i = 2;
  1127. while ( i < Argc)
  1128. {
  1129. byteCount += strlen( Argv[i] ) + 1;
  1130. i++;
  1131. }
  1132. byteCount++; //bBitMasks[0] : string length
  1133. //
  1134. // allocate space for WKS
  1135. //
  1136. precord = Dns_AllocateRecord( (WORD)DNS_WKS_RECORD_LENGTH(byteCount) );
  1137. if ( !precord )
  1138. {
  1139. return( NULL );
  1140. }
  1141. //
  1142. // get protocol number:
  1143. //
  1144. // start winsock:
  1145. //
  1146. // DCR: this is busted, winsock should be started by now
  1147. status = WSAStartup( DNS_WINSOCK_VERSION, &wsaData );
  1148. if ( status == SOCKET_ERROR )
  1149. {
  1150. Dns_RecordFree( precord );
  1151. status = WSAGetLastError();
  1152. SetLastError( status );
  1153. return( NULL );
  1154. }
  1155. pProtoent = getprotobyname( Argv[0] );
  1156. if ( ! pProtoent || pProtoent->p_proto >= MAXUCHAR )
  1157. {
  1158. Dns_RecordFree( precord );
  1159. status = WSAGetLastError();
  1160. SetLastError( status );
  1161. return( NULL );
  1162. }
  1163. precord->Data.WKS.chProtocol = (UCHAR) pProtoent->p_proto;
  1164. //
  1165. // get ipAddresss:
  1166. //
  1167. precord->Data.WKS.IpAddress = inet_addr( Argv[1] );
  1168. //
  1169. // get the services, put all in one string
  1170. //
  1171. pch = precord->Data.WKS.BitMask;
  1172. (UCHAR) *pch = (UCHAR) byteCount-1; //string length
  1173. pch++;
  1174. i = 2;
  1175. strcpy( pch, Argv[i] );
  1176. while ( ++i < Argc )
  1177. {
  1178. strcat( pch, " " );
  1179. strcat( pch, Argv[i] );
  1180. }
  1181. return( precord );
  1182. }
  1183. PDNS_RECORD
  1184. Wks_RecordBuildW(
  1185. IN DWORD Argc,
  1186. IN PWCHAR * Argv
  1187. )
  1188. /*++
  1189. Routine Description:
  1190. Build WKS record from string data.
  1191. Arguments:
  1192. Argc -- count of data Arguments
  1193. Argv -- argv array of data string pointers
  1194. Return Value:
  1195. Ptr to new record if successful.
  1196. NULL on failure.
  1197. --*/
  1198. {
  1199. PDNS_RECORD precord;
  1200. DWORD byteCount = 0;
  1201. DWORD i;
  1202. PWCHAR pch;
  1203. WSADATA wsaData;
  1204. DNS_STATUS status;
  1205. struct protoent * pProtoent;
  1206. char szAddr[256];
  1207. WCHAR tcpStr[4], udpStr[4], space[2];
  1208. if ( Argc < 3 )
  1209. {
  1210. SetLastError( ERROR_INVALID_DATA );
  1211. return( NULL );
  1212. }
  1213. i = 2;
  1214. while ( i < Argc)
  1215. {
  1216. byteCount += wcslen( Argv[i] ) + 1;
  1217. i++;
  1218. }
  1219. byteCount++; //bBitMasks[0] : string length
  1220. //
  1221. // allocate space for WKS
  1222. //
  1223. precord = Dns_AllocateRecord( (WORD)DNS_WKS_RECORD_LENGTH(byteCount) );
  1224. if ( !precord )
  1225. {
  1226. return( NULL );
  1227. }
  1228. //
  1229. // get protocol number
  1230. //
  1231. status = WSAStartup( DNS_WINSOCK_VERSION, &wsaData );
  1232. if ( status == SOCKET_ERROR )
  1233. {
  1234. Dns_RecordFree( precord );
  1235. status = WSAGetLastError();
  1236. SetLastError( status );
  1237. return( NULL );
  1238. }
  1239. #if 0
  1240. //
  1241. // DCR_FIX: WKS build
  1242. //
  1243. if ( ! Dns_CopyStringEx( szAddr, 0, (PCHAR) Argv[0], 0, TRUE, FALSE ) )
  1244. {
  1245. Dns_RecordListFree( precord );
  1246. return NULL;
  1247. }
  1248. pProtoent = getprotobyname( szAddr );
  1249. if ( ! pProtoent || pProtoent->p_proto >= MAXUCHAR )
  1250. {
  1251. Dns_RecordFree( precord );
  1252. status = WSAGetLastError();
  1253. SetLastError( status );
  1254. return( NULL );
  1255. }
  1256. precord->Data.WKS.chProtocol = (UCHAR) pProtoent->p_proto;
  1257. //
  1258. // IP Address
  1259. //
  1260. if ( ! Dns_CopyStringEx( szAddr, 0, (PCHAR) Argv[0], 0, TRUE, FALSE ) )
  1261. {
  1262. Dns_RecordListFree( precord );
  1263. return NULL;
  1264. }
  1265. precord->Data.WKS.IpAddress = inet_addr( szAddr );
  1266. //
  1267. // get the services, put all in one string
  1268. //
  1269. pch = (PWCHAR) precord->Data.WKS.bBitMask;
  1270. (UCHAR) *pch = (UCHAR) byteCount-1;
  1271. pch++;
  1272. i = 2;
  1273. if ( ! Dns_NameCopy(
  1274. (PBYTE) space,
  1275. 0,
  1276. " ",
  1277. 0,
  1278. DnsCharSetUnicode,
  1279. DnsCharSetWire ) )
  1280. {
  1281. Dns_RecordListFree( precord );
  1282. return NULL;
  1283. }
  1284. wcscpy( pch, Argv[i] );
  1285. while ( ++i < Argc )
  1286. {
  1287. wcscat( pch, space );
  1288. wcscat( pch, Argv[i] );
  1289. }
  1290. #endif
  1291. return( precord );
  1292. }
  1293. PDNS_RECORD
  1294. Key_RecordBuild(
  1295. IN DWORD Argc,
  1296. IN PCHAR * Argv
  1297. )
  1298. /*++
  1299. Routine Description:
  1300. Build KEY record from string data.
  1301. Arguments:
  1302. Argc -- count of data Arguments
  1303. Argv -- argv array of data string pointers
  1304. Return Value:
  1305. Ptr to new record if successful.
  1306. NULL on failure.
  1307. --*/
  1308. {
  1309. PDNS_RECORD prec;
  1310. int keyStringLength;
  1311. DWORD keyLength = 0;
  1312. if ( Argc != 4 )
  1313. {
  1314. SetLastError( ERROR_INVALID_DATA );
  1315. return NULL;
  1316. }
  1317. keyStringLength = strlen( Argv[ 3 ] );
  1318. prec = Dns_AllocateRecord( (WORD)
  1319. sizeof( DNS_KEY_DATA ) + keyStringLength );
  1320. if ( !prec )
  1321. {
  1322. return NULL;
  1323. }
  1324. prec->Data.KEY.wFlags = (WORD) strtoul( *( Argv++ ), NULL, 0 );
  1325. prec->Data.KEY.chProtocol = (BYTE) strtoul( *( Argv++ ), NULL, 10 );
  1326. prec->Data.KEY.chAlgorithm = (BYTE) strtoul( *( Argv++ ), NULL, 10 );
  1327. Argc -= 3;
  1328. Dns_SecurityBase64StringToKey(
  1329. prec->Data.KEY.Key,
  1330. &keyLength,
  1331. *Argv,
  1332. keyStringLength );
  1333. Argc--;
  1334. Argv++;
  1335. prec->wDataLength = (WORD) ( SIZEOF_KEY_FIXED_DATA + keyLength );
  1336. return prec;
  1337. } // Key_RecordBuild
  1338. PDNS_RECORD
  1339. Key_RecordBuildW(
  1340. IN DWORD Argc,
  1341. IN PWCHAR * Argv
  1342. )
  1343. /*++
  1344. Routine Description:
  1345. Build KEY record from string data.
  1346. Arguments:
  1347. Argc -- count of data Arguments
  1348. Argv -- argv array of data string pointers
  1349. Return Value:
  1350. Ptr to new record if successful.
  1351. NULL on failure.
  1352. --*/
  1353. {
  1354. PDNS_RECORD prec;
  1355. int keyStringLength;
  1356. DWORD keyLength = 0;
  1357. if ( Argc != 4 )
  1358. {
  1359. SetLastError( ERROR_INVALID_DATA );
  1360. return NULL;
  1361. }
  1362. keyStringLength = wcslen( Argv[ 3 ] );
  1363. prec = Dns_AllocateRecord( (WORD)
  1364. sizeof( DNS_KEY_DATA ) + keyStringLength / 2 );
  1365. if ( !prec )
  1366. {
  1367. return NULL;
  1368. }
  1369. prec->Data.KEY.wFlags = (WORD) wcstoul( *( Argv++ ), NULL, 0 );
  1370. prec->Data.KEY.chProtocol = (BYTE) wcstoul( *( Argv++ ), NULL, 10 );
  1371. prec->Data.KEY.chAlgorithm = (BYTE) wcstoul( *( Argv++ ), NULL, 10 );
  1372. Argc -= 3;
  1373. #if 0
  1374. // JJW: MUST COPY BUFFER???
  1375. Dns_SecurityBase64StringToKey(
  1376. prec->Data.KEY.Key,
  1377. &keyLength,
  1378. *Argv,
  1379. keyStringLength );
  1380. #endif
  1381. Argc--;
  1382. Argv++;
  1383. prec->wDataLength = (WORD) ( SIZEOF_KEY_FIXED_DATA + keyLength );
  1384. return prec;
  1385. } // Key_RecordBuildW
  1386. PDNS_RECORD
  1387. Sig_RecordBuild(
  1388. IN DWORD Argc,
  1389. IN PCHAR * Argv
  1390. )
  1391. /*++
  1392. Routine Description:
  1393. Build SIG record from string data.
  1394. Arguments:
  1395. Argc -- count of data Arguments
  1396. Argv -- argv array of data string pointers
  1397. Return Value:
  1398. Ptr to new record if successful.
  1399. NULL on failure.
  1400. --*/
  1401. {
  1402. PDNS_RECORD prec;
  1403. int sigStringLength;
  1404. DWORD sigLength = 0;
  1405. if ( Argc != 9 )
  1406. {
  1407. SetLastError( ERROR_INVALID_DATA );
  1408. return NULL;
  1409. }
  1410. sigStringLength = strlen( Argv[8] );
  1411. prec = Dns_AllocateRecord( (WORD)
  1412. ( sizeof(DNS_SIG_DATA) + sigStringLength ) );
  1413. if ( !prec )
  1414. {
  1415. return NULL;
  1416. }
  1417. prec->Data.SIG.wTypeCovered = Dns_RecordTypeForName( *( Argv++ ), 0 );
  1418. prec->Data.SIG.chAlgorithm = (BYTE) strtoul( *( Argv++ ), NULL, 10 );
  1419. prec->Data.Sig.chLabelCount = (BYTE) strtoul( *( Argv++ ), NULL, 10 );
  1420. prec->Data.SIG.dwOriginalTtl = ( DWORD ) strtoul( *( Argv++ ), NULL, 10 );
  1421. prec->Data.SIG.dwExpiration = Dns_ParseSigTime( *( Argv++ ), 0 );
  1422. prec->Data.SIG.dwTimeSigned = Dns_ParseSigTime( *( Argv++ ), 0 );
  1423. prec->Data.SIG.wKeyTag = (WORD) strtoul( *( Argv++ ), NULL, 10 );
  1424. prec->Data.SIG.pNameSigner = *( Argv++ );
  1425. Argc -= 8;
  1426. //
  1427. // Validate signature times.
  1428. //
  1429. if ( prec->Data.SIG.dwExpiration == 0 ||
  1430. prec->Data.SIG.dwTimeSigned == 0 ||
  1431. prec->Data.SIG.dwTimeSigned >= prec->Data.SIG.dwExpiration )
  1432. {
  1433. Dns_RecordFree( prec );
  1434. SetLastError( ERROR_INVALID_DATA );
  1435. return NULL;
  1436. }
  1437. //
  1438. // Parse signature.
  1439. //
  1440. if ( Dns_SecurityBase64StringToKey(
  1441. prec->Data.SIG.Signature,
  1442. &sigLength,
  1443. *Argv,
  1444. sigStringLength ) != ERROR_SUCCESS )
  1445. {
  1446. Dns_RecordFree( prec );
  1447. SetLastError( ERROR_INVALID_DATA );
  1448. return NULL;
  1449. }
  1450. Argc--;
  1451. Argv++;
  1452. prec->wDataLength = (WORD) ( sizeof( DNS_SIG_DATA ) - 4 + sigLength );
  1453. return prec;
  1454. } // Sig_RecordBuild
  1455. PDNS_RECORD
  1456. Sig_RecordBuildW(
  1457. IN DWORD Argc,
  1458. IN PWCHAR * Argv
  1459. )
  1460. /*++
  1461. Routine Description:
  1462. Build SIG record from string data.
  1463. Arguments:
  1464. Argc -- count of data Arguments
  1465. Argv -- argv array of data string pointers
  1466. Return Value:
  1467. Ptr to new record if successful.
  1468. NULL on failure.
  1469. --*/
  1470. {
  1471. PDNS_RECORD prec;
  1472. int sigStringLength;
  1473. DWORD sigLength = 0;
  1474. PCHAR pch;
  1475. if ( Argc != 8 )
  1476. {
  1477. SetLastError( ERROR_INVALID_DATA );
  1478. return NULL;
  1479. }
  1480. sigStringLength = wcslen( Argv[ 7 ] );
  1481. prec = Dns_AllocateRecord( (WORD)
  1482. ( sizeof( DNS_SIG_DATA ) + sigStringLength ) );
  1483. if ( !prec )
  1484. {
  1485. return NULL;
  1486. }
  1487. #if 0
  1488. // JJW: how to convert all args here???
  1489. prec->Data.SIG.wTypeCovered = Dns_RecordTypeForName( *( Argv++ ), 0 );
  1490. prec->Data.SIG.chAlgorithm = (BYTE) strtoul( *( Argv++ ), NULL, 10 );
  1491. prec->Data.Sig.chLabelCount = (BYTE) strtoul( *( Argv++ ), NULL, 10 );
  1492. prec->Data.SIG.dwOriginalTtl = ( DWORD ) strtoul( *( Argv++ ), NULL, 10 );
  1493. prec->Data.SIG.dwExpiration = Dns_ParseSigTime( *( Argv++ ), 0 );
  1494. prec->Data.SIG.dwTimeSigned = Dns_ParseSigTime( *( Argv++ ), 0 );
  1495. prec->Data.SIG.wKeyTag = (WORD) strtoul( *( Argv++ ), NULL, 10 );
  1496. prec->Data.SIG.pNameSigner = *( Argv++ );
  1497. Argc -= 8;
  1498. Dns_SecurityBase64StringToKey(
  1499. prec->Data.SIG.Signature,
  1500. &sigLength,
  1501. *Argv,
  1502. sigStringLength );
  1503. #endif
  1504. Argc--;
  1505. Argv++;
  1506. prec->wDataLength = (WORD) ( sizeof( DNS_SIG_DATA ) - 4 + sigLength );
  1507. return prec;
  1508. } // Sig_RecordBuildW
  1509. PDNS_RECORD
  1510. Nxt_RecordBuild(
  1511. IN DWORD Argc,
  1512. IN PCHAR * Argv
  1513. )
  1514. /*++
  1515. Routine Description:
  1516. Build NXT record from string data.
  1517. First arg is next name, followed by list of record types at that name.
  1518. Arguments:
  1519. Argc -- count of data Arguments
  1520. Argv -- argv array of data string pointers
  1521. Return Value:
  1522. Ptr to new record if successful.
  1523. NULL on failure.
  1524. --*/
  1525. {
  1526. PDNS_RECORD prec;
  1527. int typeIdx = 0;
  1528. if ( Argc < 2 )
  1529. {
  1530. SetLastError( ERROR_INVALID_DATA );
  1531. return NULL;
  1532. }
  1533. prec = Dns_AllocateRecord( (WORD) (
  1534. sizeof( LPTSTR ) + sizeof(WORD) * Argc ) );
  1535. if ( !prec )
  1536. {
  1537. return NULL;
  1538. }
  1539. prec->Data.NXT.pNameNext = *( Argv++ );
  1540. --Argc;
  1541. prec->Data.NXT.wNumTypes = 0;
  1542. while ( Argc-- )
  1543. {
  1544. ++prec->Data.NXT.wNumTypes;
  1545. prec->Data.NXT.wTypes[ typeIdx++ ] =
  1546. Dns_RecordTypeForName( *( Argv++ ), 0 );
  1547. }
  1548. return prec;
  1549. } // Nxt_RecordBuild
  1550. PDNS_RECORD
  1551. Nxt_RecordBuildW(
  1552. IN DWORD Argc,
  1553. IN PWCHAR * Argv
  1554. )
  1555. /*++
  1556. Routine Description:
  1557. Build NXT record from string data.
  1558. First arg is next name, followed by list of record types at that name.
  1559. Arguments:
  1560. Argc -- count of data Arguments
  1561. Argv -- argv array of data string pointers
  1562. Return Value:
  1563. Ptr to new record if successful.
  1564. NULL on failure.
  1565. --*/
  1566. {
  1567. PDNS_RECORD prec;
  1568. int typeIdx = 0;
  1569. if ( Argc < 2 )
  1570. {
  1571. SetLastError( ERROR_INVALID_DATA );
  1572. return NULL;
  1573. }
  1574. prec = Dns_AllocateRecord( (WORD) (
  1575. sizeof( LPTSTR ) + sizeof(WORD) * ( Argc - 1 ) ) );
  1576. if ( !prec )
  1577. {
  1578. return NULL;
  1579. }
  1580. prec->Data.NXT.pNameNext = ( PDNS_NAME ) ( *( Argv++ ) );
  1581. --Argc;
  1582. #if 0
  1583. // JJW: convert type string???
  1584. while ( Argc-- )
  1585. {
  1586. prec->Data.NXT.wTypes[ typeIdx++ ] =
  1587. Dns_RecordTypeForName( *( Argv++ ), 0 );
  1588. }
  1589. #endif
  1590. return prec;
  1591. } // Nxt_RecordBuildW
  1592. //
  1593. // RR build routines jump table
  1594. //
  1595. typedef PDNS_RECORD (* RR_BUILD_FUNCTION)(
  1596. DWORD,
  1597. PCHAR * );
  1598. //extern RR_BUILD_FUNCTION RRBuildTable[];
  1599. typedef PDNS_RECORD (* RR_BUILD_FUNCTION_W)(
  1600. DWORD,
  1601. PWCHAR * );
  1602. //extern RR_BUILD_FUNCTION_W RRBuildTableW[];
  1603. RR_BUILD_FUNCTION RRBuildTable[] =
  1604. {
  1605. NULL, // ZERO
  1606. A_RecordBuild, // A
  1607. Ptr_RecordBuild, // NS
  1608. Ptr_RecordBuild, // MD
  1609. Ptr_RecordBuild, // MF
  1610. Ptr_RecordBuild, // CNAME
  1611. Soa_RecordBuild, // SOA
  1612. Ptr_RecordBuild, // MB
  1613. Ptr_RecordBuild, // MG
  1614. Ptr_RecordBuild, // MR
  1615. NULL, // NULL
  1616. Wks_RecordBuild, // WKS
  1617. Ptr_RecordBuild, // PTR
  1618. Txt_RecordBuild, // HINFO
  1619. Minfo_RecordBuild, // MINFO
  1620. Mx_RecordBuild, // MX
  1621. Txt_RecordBuild, // TXT
  1622. Minfo_RecordBuild, // RP
  1623. Mx_RecordBuild, // AFSDB
  1624. Txt_RecordBuild, // X25
  1625. Txt_RecordBuild, // ISDN
  1626. Mx_RecordBuild, // RT
  1627. NULL, // NSAP
  1628. NULL, // NSAPPTR
  1629. Sig_RecordBuild, // SIG
  1630. Key_RecordBuild, // KEY
  1631. NULL, // PX
  1632. NULL, // GPOS
  1633. Aaaa_RecordBuild, // AAAA
  1634. NULL, // LOC
  1635. Nxt_RecordBuild, // NXT
  1636. NULL, // EID
  1637. NULL, // NIMLOC
  1638. Srv_RecordBuild, // SRV
  1639. Atma_RecordBuild, // ATMA
  1640. NULL, // NAPTR
  1641. NULL, // KX
  1642. NULL, // CERT
  1643. NULL, // A6
  1644. NULL, // DNAME
  1645. NULL, // SINK
  1646. NULL, // OPT
  1647. NULL, // 42
  1648. NULL, // 43
  1649. NULL, // 44
  1650. NULL, // 45
  1651. NULL, // 46
  1652. NULL, // 47
  1653. NULL, // 48
  1654. //
  1655. // NOTE: last type indexed by type ID MUST be set
  1656. // as MAX_SELF_INDEXED_TYPE #define in record.h
  1657. // (see note above in record info table)
  1658. //
  1659. // Pseudo record types
  1660. //
  1661. NULL, // TKEY
  1662. NULL, // TSIG
  1663. //
  1664. // MS only types
  1665. //
  1666. Wins_RecordBuild, // WINS
  1667. Winsr_RecordBuild, // WINSR
  1668. };
  1669. RR_BUILD_FUNCTION_W RRBuildTableW[] =
  1670. {
  1671. NULL, // ZERO
  1672. A_RecordBuildW, // A
  1673. Ptr_RecordBuildW, // NS
  1674. Ptr_RecordBuildW, // MD
  1675. Ptr_RecordBuildW, // MF
  1676. Ptr_RecordBuildW, // CNAME
  1677. Soa_RecordBuildW, // SOA
  1678. Ptr_RecordBuildW, // MB
  1679. Ptr_RecordBuildW, // MG
  1680. Ptr_RecordBuildW, // MR
  1681. NULL, // NULL
  1682. Wks_RecordBuildW, // WKS
  1683. Ptr_RecordBuildW, // PTR
  1684. Txt_RecordBuildW, // HINFO
  1685. Minfo_RecordBuildW, // MINFO
  1686. Mx_RecordBuildW, // MX
  1687. Txt_RecordBuildW, // TXT
  1688. Minfo_RecordBuildW, // RP
  1689. Mx_RecordBuildW, // AFSDB
  1690. Txt_RecordBuildW, // X25
  1691. Txt_RecordBuildW, // ISDN
  1692. Mx_RecordBuildW, // RT
  1693. NULL, // NSAP
  1694. NULL, // NSAPPTR
  1695. Sig_RecordBuildW, // SIG
  1696. Key_RecordBuildW, // KEY
  1697. NULL, // PX
  1698. NULL, // GPOS
  1699. Aaaa_RecordBuildW, // AAAA
  1700. NULL, // LOC
  1701. Nxt_RecordBuildW, // NXT
  1702. NULL, // EID
  1703. NULL, // NIMLOC
  1704. Srv_RecordBuildW, // SRV
  1705. Atma_RecordBuildW, // ATMA
  1706. NULL, // NAPTR
  1707. NULL, // KX
  1708. NULL, // CERT
  1709. NULL, // A6
  1710. NULL, // DNAME
  1711. NULL, // SINK
  1712. NULL, // OPT
  1713. NULL, // 42
  1714. NULL, // 43
  1715. NULL, // 44
  1716. NULL, // 45
  1717. NULL, // 46
  1718. NULL, // 47
  1719. NULL, // 48
  1720. //
  1721. // NOTE: last type indexed by type ID MUST be set
  1722. // as MAX_SELF_INDEXED_TYPE #define in record.h
  1723. // (see note above in record info table)
  1724. //
  1725. // Pseudo record types
  1726. //
  1727. NULL, // TKEY
  1728. NULL, // TSIG
  1729. //
  1730. // MS only types
  1731. //
  1732. Wins_RecordBuildW, // WINS
  1733. Winsr_RecordBuildW, // WINSR
  1734. };
  1735. //
  1736. // Public build routine
  1737. //
  1738. PDNS_RECORD
  1739. Dns_RecordBuild_A(
  1740. IN OUT PDNS_RRSET pRRSet,
  1741. IN LPSTR pszOwner,
  1742. IN WORD wType,
  1743. IN BOOL fAdd,
  1744. IN UCHAR Section,
  1745. IN INT Argc,
  1746. IN PCHAR * Argv
  1747. )
  1748. /*++
  1749. Routine Description:
  1750. Build record from data strings.
  1751. Arguments:
  1752. pRRSet -- ptr to RR set structure being built
  1753. pszOwner -- DNS name of RR owner
  1754. wType -- record type
  1755. fAdd -- add\delete, exist\no-exist flag
  1756. Section -- RR section for record
  1757. Argc -- count of data strings
  1758. Argv -- argv array of ptrs to data strings
  1759. Return Value:
  1760. Ptr to record built.
  1761. NULL on error.
  1762. --*/
  1763. {
  1764. PDNS_RECORD precord;
  1765. WORD index;
  1766. IF_DNSDBG( INIT )
  1767. {
  1768. DNS_PRINT((
  1769. "Dns_RecordBuild()\n"
  1770. "\trrset = %p\n"
  1771. "\towner = %s\n"
  1772. "\ttype = %d\n"
  1773. "\tfAdd = %d\n"
  1774. "\tsection = %d\n"
  1775. "\targc = %d\n",
  1776. pRRSet,
  1777. pszOwner,
  1778. wType,
  1779. fAdd,
  1780. Section,
  1781. Argc ));
  1782. }
  1783. //
  1784. // every record MUST have owner name
  1785. //
  1786. if ( !pszOwner )
  1787. {
  1788. SetLastError( ERROR_INVALID_DATA );
  1789. return( NULL );
  1790. }
  1791. //
  1792. // if no data, no dispatch required
  1793. //
  1794. if ( Argc == 0 )
  1795. {
  1796. precord = Dns_AllocateRecord( 0 );
  1797. if ( ! precord )
  1798. {
  1799. return( NULL );
  1800. }
  1801. }
  1802. // have data, dispatch to type specific build routine
  1803. else
  1804. {
  1805. index = INDEX_FOR_TYPE( wType );
  1806. DNS_ASSERT( index <= MAX_RECORD_TYPE_INDEX );
  1807. if ( !index || !RRBuildTable[ index ] )
  1808. {
  1809. // can NOT build unknown types
  1810. SetLastError( DNS_ERROR_INVALID_TYPE );
  1811. DNS_PRINT((
  1812. "ERROR: can not build record of type %d\n",
  1813. wType ));
  1814. return( NULL );
  1815. }
  1816. precord = RRBuildTable[ index ](
  1817. Argc,
  1818. Argv );
  1819. if ( ! precord )
  1820. {
  1821. DNS_PRINT((
  1822. "ERROR: Record build routine failure for record type %d.\n"
  1823. "\tstatus = %d\n\n",
  1824. wType,
  1825. GetLastError() ));
  1826. if ( !GetLastError() )
  1827. {
  1828. SetLastError( ERROR_INVALID_DATA );
  1829. }
  1830. return( NULL );
  1831. }
  1832. }
  1833. //
  1834. // fill out record structure
  1835. //
  1836. precord->pName = pszOwner;
  1837. precord->wType = wType;
  1838. precord->Flags.S.Section = Section;
  1839. precord->Flags.S.Delete = !fAdd;
  1840. precord->Flags.S.CharSet = DnsCharSetAnsi;
  1841. IF_DNSDBG( INIT )
  1842. {
  1843. DnsDbg_Record(
  1844. "New record built\n",
  1845. precord );
  1846. }
  1847. //
  1848. // link into existing RR set (if any)
  1849. //
  1850. if ( pRRSet )
  1851. {
  1852. DNS_RRSET_ADD( *pRRSet, precord );
  1853. }
  1854. return( precord );
  1855. }
  1856. PDNS_RECORD
  1857. Dns_RecordBuild_W(
  1858. IN OUT PDNS_RRSET pRRSet,
  1859. IN LPWSTR pszOwner,
  1860. IN WORD wType,
  1861. IN BOOL fAdd,
  1862. IN UCHAR Section,
  1863. IN INT Argc,
  1864. IN PWCHAR * Argv
  1865. )
  1866. /*++
  1867. Routine Description:
  1868. Build record from data strings.
  1869. Arguments:
  1870. pRRSet -- ptr to RR set structure being built
  1871. pszOwner -- DNS name of RR owner
  1872. wType -- record type
  1873. fAdd -- add\delete, exist\no-exist flag
  1874. Section -- RR section for record
  1875. Argc -- count of data strings
  1876. Argv -- argv array of ptrs to data strings
  1877. Return Value:
  1878. Ptr to record built.
  1879. NULL on error.
  1880. --*/
  1881. {
  1882. PDNS_RECORD precord;
  1883. WORD index;
  1884. DNSDBG( INIT, (
  1885. "Dns_RecordBuild()\n"
  1886. "\trrset = %p\n"
  1887. "\towner = %S\n"
  1888. "\ttype = %d\n"
  1889. "\tfAdd = %d\n"
  1890. "\tsection = %d\n"
  1891. "\targc = %d\n",
  1892. pRRSet,
  1893. pszOwner,
  1894. wType,
  1895. fAdd,
  1896. Section,
  1897. Argc ));
  1898. //
  1899. // every record MUST have owner name
  1900. //
  1901. if ( !pszOwner )
  1902. {
  1903. SetLastError( ERROR_INVALID_DATA );
  1904. return( NULL );
  1905. }
  1906. //
  1907. // if no data, no dispatch required
  1908. //
  1909. if ( Argc == 0 )
  1910. {
  1911. precord = Dns_AllocateRecord( 0 );
  1912. if ( ! precord )
  1913. {
  1914. return( NULL );
  1915. }
  1916. }
  1917. // have data, dispatch to type specific build routine
  1918. else
  1919. {
  1920. index = INDEX_FOR_TYPE( wType );
  1921. DNS_ASSERT( index <= MAX_RECORD_TYPE_INDEX );
  1922. if ( !index || !RRBuildTableW[ index ] )
  1923. {
  1924. // can NOT build unknown types
  1925. SetLastError( DNS_ERROR_INVALID_TYPE );
  1926. DNS_PRINT((
  1927. "ERROR: can not build record of type %d\n",
  1928. wType ));
  1929. return( NULL );
  1930. }
  1931. precord = RRBuildTableW[ index ](
  1932. Argc,
  1933. Argv );
  1934. if ( ! precord )
  1935. {
  1936. DNS_PRINT((
  1937. "ERROR: Record build routine failure for record type %d.\n"
  1938. "\tstatus = %d\n\n",
  1939. wType,
  1940. GetLastError() ));
  1941. if ( !GetLastError() )
  1942. {
  1943. SetLastError( ERROR_INVALID_DATA );
  1944. }
  1945. return( NULL );
  1946. }
  1947. }
  1948. //
  1949. // fill out record structure
  1950. //
  1951. precord->pName = (PDNS_NAME) pszOwner;
  1952. precord->wType = wType;
  1953. precord->Flags.S.Section = Section;
  1954. precord->Flags.S.Delete = !fAdd;
  1955. precord->Flags.S.CharSet = DnsCharSetUnicode;
  1956. IF_DNSDBG( INIT )
  1957. {
  1958. DnsDbg_Record(
  1959. "New record built\n",
  1960. precord );
  1961. }
  1962. //
  1963. // link into existing RR set (if any)
  1964. //
  1965. if ( pRRSet )
  1966. {
  1967. DNS_RRSET_ADD( *pRRSet, precord );
  1968. }
  1969. return( precord );
  1970. }
  1971. //
  1972. // End rrbuild.c
  1973. //