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.

739 lines
14 KiB

  1. /*++
  2. Copyright (c) 1997-2000 Microsoft Corporation
  3. Module Name:
  4. rrwrite.c
  5. Abstract:
  6. Domain Name System (DNS) Library
  7. Write resource record to packet routines.
  8. Author:
  9. Jim Gilroy (jamesg) January, 1997
  10. Revision History:
  11. --*/
  12. #include "local.h"
  13. PCHAR
  14. A_RecordWrite(
  15. IN OUT PDNS_RECORD pRR,
  16. IN PCHAR pch,
  17. IN PCHAR pchEnd
  18. )
  19. /*++
  20. Routine Description:
  21. Write A record data to packet.
  22. Arguments:
  23. pRR - ptr to record to write
  24. pch - ptr to position in buffer to write
  25. pchEnd - end of buffer position
  26. Return Value:
  27. Ptr to next byte in buffer to write.
  28. NULL on error. (Error code through GetLastError())
  29. --*/
  30. {
  31. if ( pch + sizeof(IP4_ADDRESS) > pchEnd )
  32. {
  33. SetLastError( ERROR_MORE_DATA );
  34. return( NULL );
  35. }
  36. *(UNALIGNED DWORD *) pch = pRR->Data.A.IpAddress;
  37. return ( pch + sizeof(IP4_ADDRESS) );
  38. }
  39. PCHAR
  40. Ptr_RecordWrite(
  41. IN OUT PDNS_RECORD pRR,
  42. IN PCHAR pch,
  43. IN PCHAR pchEnd
  44. )
  45. /*++
  46. Routine Description:
  47. Write PTR compatible record data to packet.
  48. Includes: PTR, CNAME, MB, MR, MG, MD, MF
  49. Arguments:
  50. pRR - ptr to record to write
  51. pch - ptr to position in buffer to write
  52. pchEnd - end of buffer position
  53. Return Value:
  54. Ptr to next byte in buffer to write.
  55. NULL on error. (Error code through GetLastError())
  56. --*/
  57. {
  58. //
  59. // write name to packet
  60. // - no compression in data
  61. //
  62. pch = Dns_WriteDottedNameToPacket(
  63. pch,
  64. pchEnd,
  65. pRR->Data.PTR.pNameHost,
  66. NULL,
  67. 0,
  68. IS_UNICODE_RECORD(pRR) );
  69. if ( !pch )
  70. {
  71. SetLastError( ERROR_MORE_DATA );
  72. }
  73. return( pch );
  74. }
  75. PCHAR
  76. Soa_RecordWrite(
  77. IN OUT PDNS_RECORD pRR,
  78. IN PCHAR pch,
  79. IN PCHAR pchEnd
  80. )
  81. /*++
  82. Routine Description:
  83. Write SOA compatible to wire.
  84. Arguments:
  85. pRR - ptr to record to write
  86. pch - ptr to position in buffer to write
  87. pchEnd - end of buffer position
  88. Return Value:
  89. Ptr to next byte in buffer to write.
  90. NULL on error. (Error code through GetLastError())
  91. --*/
  92. {
  93. PCHAR pchdone;
  94. PDWORD pdword;
  95. //
  96. // SOA names: primary server, responsible party
  97. //
  98. pch = Dns_WriteDottedNameToPacket(
  99. pch,
  100. pchEnd,
  101. pRR->Data.SOA.pNamePrimaryServer,
  102. NULL,
  103. 0,
  104. IS_UNICODE_RECORD(pRR) );
  105. if ( !pch )
  106. {
  107. SetLastError( ERROR_MORE_DATA );
  108. return( NULL );
  109. }
  110. pch = Dns_WriteDottedNameToPacket(
  111. pch,
  112. pchEnd,
  113. pRR->Data.SOA.pNameAdministrator,
  114. NULL,
  115. 0,
  116. IS_UNICODE_RECORD(pRR) );
  117. if ( !pch )
  118. {
  119. SetLastError( ERROR_MORE_DATA );
  120. return( NULL );
  121. }
  122. //
  123. // SOA integer fields
  124. //
  125. pchdone = pch + SIZEOF_SOA_FIXED_DATA;
  126. if ( pchdone > pchEnd )
  127. {
  128. SetLastError( ERROR_MORE_DATA );
  129. return( NULL );
  130. }
  131. pdword = &pRR->Data.SOA.dwSerialNo;
  132. while( pch < pchdone )
  133. {
  134. *(UNALIGNED DWORD *) pch = htonl( *pdword++ );
  135. pch += sizeof( DWORD );
  136. }
  137. return( pch );
  138. }
  139. PCHAR
  140. Mx_RecordWrite(
  141. IN OUT PDNS_RECORD pRR,
  142. IN PCHAR pch,
  143. IN PCHAR pchEnd
  144. )
  145. /*++
  146. Routine Description:
  147. Write MX compatible record to wire.
  148. Includes: MX, RT, AFSDB
  149. Arguments:
  150. pRR - ptr to record to write
  151. pch - ptr to position in buffer to write
  152. pchEnd - end of buffer position
  153. Return Value:
  154. Ptr to next byte in buffer to write.
  155. NULL on error. (Error code through GetLastError())
  156. --*/
  157. {
  158. //
  159. // MX preference value
  160. // RT preference
  161. // AFSDB subtype
  162. //
  163. if ( pch + sizeof(WORD) > pchEnd )
  164. {
  165. SetLastError( ERROR_MORE_DATA );
  166. return( NULL );
  167. }
  168. *(UNALIGNED WORD *) pch = htons( pRR->Data.MX.wPreference );
  169. pch += sizeof( WORD );
  170. //
  171. // MX exchange
  172. // RT exchange
  173. // AFSDB hostname
  174. //
  175. pch = Dns_WriteDottedNameToPacket(
  176. pch,
  177. pchEnd,
  178. pRR->Data.MX.pNameExchange,
  179. NULL,
  180. 0,
  181. IS_UNICODE_RECORD(pRR) );
  182. if ( !pch )
  183. {
  184. SetLastError( ERROR_MORE_DATA );
  185. }
  186. return( pch );
  187. }
  188. PCHAR
  189. Txt_RecordWrite(
  190. IN OUT PDNS_RECORD pRR,
  191. IN PCHAR pch,
  192. IN PCHAR pchEnd
  193. )
  194. /*++
  195. Routine Description:
  196. Write TXT compatible record to wire.
  197. Includes: TXT, HINFO, ISDN, X25 types.
  198. Arguments:
  199. pRR - ptr to record to write
  200. pch - ptr to position in buffer to write
  201. pchEnd - end of buffer position
  202. Return Value:
  203. Ptr to next byte in buffer to write.
  204. NULL on error. (Error code through GetLastError())
  205. --*/
  206. {
  207. WORD i;
  208. PCHAR * ppstring;
  209. //
  210. // write all available text strings
  211. //
  212. i = (WORD) pRR->Data.TXT.dwStringCount;
  213. if ( ! Dns_IsStringCountValidForTextType( pRR->wType, i ) )
  214. {
  215. SetLastError( ERROR_INVALID_DATA );
  216. return( NULL );
  217. }
  218. ppstring = pRR->Data.TXT.pStringArray;
  219. while ( i-- )
  220. {
  221. pch = Dns_WriteStringToPacket(
  222. pch,
  223. pchEnd,
  224. *ppstring,
  225. IS_UNICODE_RECORD(pRR) );
  226. if ( !pch )
  227. {
  228. SetLastError( ERROR_MORE_DATA );
  229. break;
  230. }
  231. ppstring++;
  232. }
  233. return( pch );
  234. }
  235. PCHAR
  236. Hinfo_RecordWrite(
  237. IN OUT PDNS_RECORD pRR,
  238. IN PCHAR pch,
  239. IN PCHAR pchEnd
  240. )
  241. /*++
  242. Routine Description:
  243. Write HINFO (string like) record to wire.
  244. Includes: HINFO, ISDN, X25 types.
  245. Arguments:
  246. pRR - ptr to record to write
  247. pch - ptr to position in buffer to write
  248. pchEnd - end of buffer position
  249. Return Value:
  250. Ptr to next byte in buffer to write.
  251. NULL on error. (Error code through GetLastError())
  252. --*/
  253. {
  254. WORD i;
  255. PCHAR * ppstring;
  256. //
  257. // write all available text strings
  258. //
  259. // DCR: ISDN HINFO write -- not sure works
  260. // not sure this works, because NULL may need to
  261. // be written for ISDN or even HINFO
  262. //
  263. i = 2;
  264. if ( pRR->wType == DNS_TYPE_X25 )
  265. {
  266. i=1;
  267. }
  268. ppstring = (PSTR *) & pRR->Data.TXT;
  269. while ( i-- )
  270. {
  271. if ( ! *ppstring )
  272. {
  273. break;
  274. }
  275. pch = Dns_WriteStringToPacket(
  276. pch,
  277. pchEnd,
  278. *ppstring,
  279. IS_UNICODE_RECORD(pRR) );
  280. if ( !pch )
  281. {
  282. SetLastError( ERROR_MORE_DATA );
  283. break;
  284. }
  285. ppstring++;
  286. }
  287. return( pch );
  288. }
  289. PCHAR
  290. Minfo_RecordWrite(
  291. IN OUT PDNS_RECORD pRR,
  292. IN PCHAR pch,
  293. IN PCHAR pchEnd
  294. )
  295. /*++
  296. Routine Description:
  297. Write MINFO compatible to wire.
  298. Includes MINFO and RP types.
  299. Arguments:
  300. pRR - ptr to record to write
  301. pch - ptr to position in buffer to write
  302. pchEnd - end of buffer position
  303. Return Value:
  304. Ptr to next byte in buffer to write.
  305. NULL on error. (Error code through GetLastError())
  306. --*/
  307. {
  308. //
  309. // MINFO responsible mailbox
  310. // RP responsible person mailbox
  311. pch = Dns_WriteDottedNameToPacket(
  312. pch,
  313. pchEnd,
  314. pRR->Data.MINFO.pNameMailbox,
  315. NULL,
  316. 0,
  317. IS_UNICODE_RECORD(pRR) );
  318. if ( !pch )
  319. {
  320. SetLastError( ERROR_MORE_DATA );
  321. return( NULL );
  322. }
  323. //
  324. // MINFO errors to mailbox
  325. // RP text RR location
  326. pch = Dns_WriteDottedNameToPacket(
  327. pch,
  328. pchEnd,
  329. pRR->Data.MINFO.pNameErrorsMailbox,
  330. NULL,
  331. 0,
  332. IS_UNICODE_RECORD(pRR) );
  333. if ( !pch )
  334. {
  335. SetLastError( ERROR_MORE_DATA );
  336. return( NULL );
  337. }
  338. return( pch );
  339. }
  340. PCHAR
  341. Flat_RecordWrite(
  342. IN OUT PDNS_RECORD pRR,
  343. IN PCHAR pch,
  344. IN PCHAR pchEnd
  345. )
  346. /*++
  347. Routine Description:
  348. Write flat record type data to packet.
  349. Flat types include:
  350. AAAA
  351. WINS
  352. Arguments:
  353. pRR - ptr to record to write
  354. pch - ptr to position in buffer to write
  355. pchEnd - end of buffer position
  356. Return Value:
  357. Ptr to next byte in buffer to write.
  358. NULL on error. (Error code through GetLastError())
  359. --*/
  360. {
  361. WORD length = pRR->wDataLength;
  362. if ( pch + length > pchEnd )
  363. {
  364. SetLastError( ERROR_MORE_DATA );
  365. return( NULL );
  366. }
  367. memcpy(
  368. pch,
  369. (PCHAR)&pRR->Data,
  370. length );
  371. pch += length;
  372. return( pch );
  373. }
  374. PCHAR
  375. Srv_RecordWrite(
  376. IN OUT PDNS_RECORD pRR,
  377. IN PCHAR pch,
  378. IN PCHAR pchEnd
  379. )
  380. /*++
  381. Routine Description:
  382. Write SRV record to wire.
  383. Arguments:
  384. pRR - ptr to record to write
  385. pch - ptr to position in buffer to write
  386. pchEnd - end of buffer position
  387. Return Value:
  388. Ptr to next byte in buffer to write.
  389. NULL on error. (Error code through GetLastError())
  390. --*/
  391. {
  392. PCHAR pchname;
  393. PWORD pword;
  394. //
  395. // SRV integer values
  396. //
  397. pchname = pch + SIZEOF_SRV_FIXED_DATA;
  398. if ( pchname > pchEnd )
  399. {
  400. SetLastError( ERROR_MORE_DATA );
  401. return( NULL );
  402. }
  403. pword = &pRR->Data.SRV.wPriority;
  404. while ( pch < pchname )
  405. {
  406. *(UNALIGNED WORD *) pch = htons( *pword++ );
  407. pch += sizeof(WORD);
  408. }
  409. //
  410. // SRV target host
  411. //
  412. pch = Dns_WriteDottedNameToPacket(
  413. pch,
  414. pchEnd,
  415. pRR->Data.SRV.pNameTarget,
  416. NULL,
  417. 0,
  418. IS_UNICODE_RECORD(pRR) );
  419. if ( !pch )
  420. {
  421. SetLastError( ERROR_MORE_DATA );
  422. }
  423. return( pch );
  424. }
  425. PCHAR
  426. Atma_RecordWrite(
  427. IN OUT PDNS_RECORD pRR,
  428. IN PCHAR pch,
  429. IN PCHAR pchEnd
  430. )
  431. /*++
  432. Routine Description:
  433. Write ATMA record to wire.
  434. Arguments:
  435. pRR - ptr to record to write
  436. pch - ptr to position in buffer to write
  437. pchEnd - end of buffer position
  438. Return Value:
  439. Ptr to next byte in buffer to write.
  440. NULL on error. (Error code through GetLastError())
  441. --*/
  442. {
  443. PBYTE pbyte;
  444. //
  445. // ATMA integer values
  446. //
  447. if ( ( pch + sizeof( DNS_ATMA_DATA ) + DNS_ATMA_MAX_ADDR_LENGTH ) >
  448. pchEnd )
  449. {
  450. SetLastError( ERROR_MORE_DATA );
  451. return( NULL );
  452. }
  453. pbyte = &pRR->Data.ATMA.AddressType;
  454. *(BYTE *) pch = *pbyte;
  455. pch += sizeof( BYTE );
  456. //
  457. // write ATMA address
  458. //
  459. memcpy( pch,
  460. (PCHAR)&pRR->Data.ATMA.Address,
  461. pRR->wDataLength );
  462. pch += pRR->wDataLength;
  463. return( pch );
  464. }
  465. //
  466. // stubs until read to go
  467. //
  468. PCHAR
  469. Tkey_RecordWrite(
  470. IN OUT PDNS_RECORD pRR,
  471. IN PCHAR pch,
  472. IN PCHAR pchEnd
  473. )
  474. {
  475. return( NULL );
  476. }
  477. PCHAR
  478. Tsig_RecordWrite(
  479. IN OUT PDNS_RECORD pRR,
  480. IN PCHAR pch,
  481. IN PCHAR pchEnd
  482. )
  483. {
  484. return( NULL );
  485. }
  486. //
  487. // RR write to packet jump table
  488. //
  489. RR_WRITE_FUNCTION RR_WriteTable[] =
  490. {
  491. NULL, // ZERO
  492. A_RecordWrite, // A
  493. Ptr_RecordWrite, // NS
  494. Ptr_RecordWrite, // MD
  495. Ptr_RecordWrite, // MF
  496. Ptr_RecordWrite, // CNAME
  497. Soa_RecordWrite, // SOA
  498. Ptr_RecordWrite, // MB
  499. Ptr_RecordWrite, // MG
  500. Ptr_RecordWrite, // MR
  501. NULL, // NULL
  502. NULL, //Wks_RecordWrite, // WKS
  503. Ptr_RecordWrite, // PTR
  504. Txt_RecordWrite, // HINFO
  505. Minfo_RecordWrite, // MINFO
  506. Mx_RecordWrite, // MX
  507. Txt_RecordWrite, // TXT
  508. Minfo_RecordWrite, // RP
  509. Mx_RecordWrite, // AFSDB
  510. Txt_RecordWrite, // X25
  511. Txt_RecordWrite, // ISDN
  512. Mx_RecordWrite, // RT
  513. NULL, // NSAP
  514. NULL, // NSAPPTR
  515. NULL, // SIG
  516. NULL, // KEY
  517. NULL, // PX
  518. NULL, // GPOS
  519. Flat_RecordWrite, // AAAA
  520. NULL, // LOC
  521. NULL, // NXT
  522. NULL, // EID
  523. NULL, // NIMLOC
  524. Srv_RecordWrite, // SRV
  525. Atma_RecordWrite, // ATMA
  526. NULL, // NAPTR
  527. NULL, // KX
  528. NULL, // CERT
  529. NULL, // A6
  530. NULL, // DNAME
  531. NULL, // SINK
  532. NULL, // OPT
  533. NULL, // 42
  534. NULL, // 43
  535. NULL, // 44
  536. NULL, // 45
  537. NULL, // 46
  538. NULL, // 47
  539. NULL, // 48
  540. //
  541. // NOTE: last type indexed by type ID MUST be set
  542. // as MAX_SELF_INDEXED_TYPE #define in record.h
  543. // (see note above in record info table)
  544. //
  545. // Pseudo record types
  546. //
  547. Tkey_RecordWrite, // TKEY
  548. Tsig_RecordWrite, // TSIG
  549. //
  550. // MS only types
  551. //
  552. Flat_RecordWrite, // WINS
  553. NULL, // WINSR
  554. };
  555. //
  556. // End rrwire.c
  557. //