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.

1413 lines
36 KiB

  1. /****
  2. TODO
  3. Change name of this module to one that indicates the module to be
  4. platform dependent
  5. ****/
  6. /*++
  7. Copyright (c) 1990 Microsoft Corporation
  8. Module Name:
  9. rplmsgf.c
  10. Abstract:
  11. This module contains functions to format and unformat messages
  12. sent between the replicators on different WINS servers
  13. Functions:
  14. RplMsgfFrmAddVersMapReq--format send ip address - max version #
  15. records request
  16. RplMsgfFrmAddVersMapRsp--format response to send ip address - max
  17. version # request sent earlier
  18. RplMsgfFrmSndEntriesReq--format send data records request
  19. RplMsgfFrmSndEntriesRsp--format response to "send data records"
  20. request
  21. RplMsgfUfmAddVersMapRsp--unformat "send address - max version #"
  22. response
  23. RplMsgfUfmSndEntriesReq--unformat "send data records" request
  24. RplMsgfUfmSndEntriesRsp--unformat "send data records" response
  25. ....
  26. Portability:
  27. This module is non-portable across different address families (different
  28. transports) since it relies on the address being an IP address.
  29. Author:
  30. Pradeep Bahl (PradeepB) Jan-1993
  31. Revision History:
  32. Modification date Person Description of modification
  33. ----------------- ------- ----------------------------
  34. --*/
  35. /*
  36. * Includes
  37. */
  38. #include "wins.h"
  39. #ifdef DBGSVC
  40. #include "nms.h"
  41. #endif
  42. #include "comm.h"
  43. #include "nmsdb.h"
  44. #include "rpl.h"
  45. #include "rplmsgf.h"
  46. #include "winsevt.h"
  47. #include "winsmsc.h"
  48. /*
  49. * Local Macro Declarations
  50. */
  51. /*
  52. ENTRY_DELIM -- Delimiter between data records (name-address mapping records)
  53. in the message. The end of the message is marked by two of
  54. these.
  55. Since a data record starts with the length of the name
  56. (which will never by FFFFFFFF), this delimiter serves us
  57. fine.
  58. */
  59. #define ENTRY_DELIM 0xFFFFFFFF //-1
  60. /*
  61. * Local Typedef Declarations
  62. */
  63. /*
  64. * Global Variable Definitions
  65. */
  66. /*
  67. * Local Variable Definitions
  68. */
  69. /*
  70. * Local Function Prototype Declarations
  71. */
  72. /* prototypes for functions local to this module go here */
  73. FUTURES("Change to a macro")
  74. PERF("Change to a macro")
  75. VOID
  76. RplMsgfFrmAddVersMapReq(
  77. IN LPBYTE pBuff,
  78. OUT LPDWORD pMsgLen
  79. )
  80. /*++
  81. Routine Description:
  82. This function formats the message to request a remote WINS server's
  83. replicator to send the IP address - Max Version # mappings
  84. Arguments:
  85. Externals Used:
  86. None
  87. Return Value:
  88. None
  89. Error Handling:
  90. Called by:
  91. GetVersNo() in rplpull.c
  92. Side Effects:
  93. Comments:
  94. None
  95. --*/
  96. {
  97. RPLMSGF_SET_OPC_M(pBuff, RPLMSGF_E_ADDVERSNO_MAP_REQ);
  98. *pMsgLen = 4;
  99. return;
  100. }
  101. VOID
  102. RplMsgfFrmAddVersMapRsp(
  103. #if SUPPORT612WINS > 0
  104. IN BOOL fPnrIsBeta1Wins,
  105. #endif
  106. IN RPLMSGF_MSG_OPCODE_E Opcode_e,
  107. IN LPBYTE pBuff,
  108. IN DWORD BuffLen,
  109. IN PRPL_ADD_VERS_NO_T pOwnerAddVersNoMap,
  110. IN DWORD MaxNoOfOwners,
  111. IN DWORD InitiatorWinsIpAdd,
  112. OUT LPDWORD pMsgLen
  113. )
  114. /*++
  115. Routine Description:
  116. This function formats the following two messages
  117. 1)Response to the "send me IP address - version # map " request"
  118. 2)Push Notification message.
  119. Both messages are identical except for the opcode
  120. Arguments:
  121. Opcode_e - Opcode indicating the message to send
  122. pBuff - Buffer to populate
  123. BuffLen - Buffer length
  124. pOwnerAddVersNoMap - Array of address to version numbers mappings.
  125. The version number is the max version number
  126. for the owner RQ server
  127. MaxNoOfOwners - Max. No Of Owners in this WINS's db
  128. InitiatorWinsIpAdd - Address of WINS that initiated the push.
  129. pMsgLen - Actual length of buffer filled in
  130. Externals Used:
  131. None
  132. Return Value:
  133. None
  134. Error Handling:
  135. Called by:
  136. Push Handler (Push Thread)
  137. Side Effects:
  138. Comments:
  139. None
  140. --*/
  141. {
  142. LPLONG pTmpL = (LPLONG)pBuff;
  143. LPBYTE pTmpB = pBuff;
  144. DWORD i; //counter for looping over all records
  145. VERS_NO_T StartVersNo;
  146. WINS_UID_T Uid;
  147. //
  148. // Backward compatibility with pre-3.51 beta copies of WINS.
  149. //
  150. StartVersNo.QuadPart = 0;
  151. Uid = 1;
  152. RPLMSGF_SET_OPC_M(pTmpB, Opcode_e);
  153. pTmpL = (LPLONG)pTmpB;
  154. /*
  155. * Store number of records in the buffer
  156. */
  157. COMM_HOST_TO_NET_L_M( MaxNoOfOwners, *pTmpL );
  158. pTmpL += 1;
  159. //
  160. // To guard us (PUSH thread) against simultaneous updates to the
  161. // NmsDbOwnAddTbl array (by the PULL thread). This array is
  162. // accessed by RPL_FIND_ADD_BY_OWNER_ID_M macro
  163. //
  164. /*
  165. * Now, let us store all the records
  166. */
  167. for (i = 0; i < MaxNoOfOwners; i++)
  168. {
  169. /*
  170. * We will send the V part of the address since the other
  171. * end knows the T and L (more like XDR encoding where T is
  172. * not sent)
  173. */
  174. NONPORT("Do not rely on the address being a long here")
  175. /*
  176. * As an optmization here, we make use of the fact that
  177. * the address is an IP address and is therefore a long.
  178. * When we start working with more than one address family or
  179. * when the size of the IP address changes, we should change
  180. * the code here. For now, there is no harm in optimizing
  181. * it
  182. */
  183. COMM_HOST_TO_NET_L_M(
  184. (pOwnerAddVersNoMap + i)->OwnerWinsAdd.Add.IPAdd, *pTmpL
  185. );
  186. pTmpL++; //advance to next 4 bytes
  187. /*
  188. * Store the version number
  189. */
  190. WINS_PUT_VERS_NO_IN_STREAM_M(
  191. &((pOwnerAddVersNoMap + i)->VersNo),
  192. pTmpL
  193. );
  194. pTmpL = (LPLONG)((LPBYTE)(pTmpL) + WINS_VERS_NO_SIZE); //adv. the
  195. //pointer
  196. #if SUPPORT612WINS > 0
  197. if (fPnrIsBeta1Wins == FALSE)
  198. {
  199. #endif
  200. /*
  201. * Store the Start version number
  202. */
  203. WINS_PUT_VERS_NO_IN_STREAM_M( &StartVersNo, pTmpL );
  204. pTmpL = (LPLONG)((LPBYTE)(pTmpL) + WINS_VERS_NO_SIZE); //adv. the
  205. //pointer
  206. COMM_HOST_TO_NET_L_M( Uid, *pTmpL );
  207. pTmpL++;
  208. #if SUPPORT612WINS > 0
  209. }
  210. #endif
  211. }
  212. COMM_HOST_TO_NET_L_M( InitiatorWinsIpAdd, *pTmpL );
  213. pTmpL++;
  214. //
  215. // Let us tell our client the exact length of the response message
  216. //
  217. *pMsgLen = (ULONG) ( (LPBYTE)pTmpL - (LPBYTE)pBuff );
  218. return;
  219. } // RplMsgfFormatAddVersMapRsp()
  220. VOID
  221. RplMsgfFrmSndEntriesReq(
  222. #if SUPPORT612WINS > 0
  223. IN BOOL fPnrIsBeta1Wins,
  224. #endif
  225. IN LPBYTE pBuff,
  226. IN PCOMM_ADD_T pWinsAdd,
  227. IN VERS_NO_T MaxVersNo,
  228. IN VERS_NO_T MinVersNo,
  229. IN DWORD RplType, //for now
  230. OUT LPDWORD pMsgLen
  231. )
  232. /*++
  233. Routine Description:
  234. This function is called to format a "send data entries" request for
  235. getting records belonging to a particular WINS server.
  236. Arguments:
  237. pBuff - Buffer that will store the request message
  238. pWinsAdd - Address of the RQ server whose data records are being
  239. sought
  240. MaxVersNo - Max. Version Number in the range of records sought
  241. MinVersNo - Min. Version Number in the range of records sought.
  242. pMsgLen - Length of request message
  243. Externals Used:
  244. None
  245. Return Value:
  246. None
  247. Error Handling:
  248. Called by:
  249. PullEntries() in rplpull.c
  250. Side Effects:
  251. Comments:
  252. I might update this function to format a request for getting
  253. data records of more than one WINS server.
  254. For the sake of simplicity, I have chosen not to do so currently.
  255. --*/
  256. {
  257. LPBYTE pTmpB = pBuff;
  258. LPLONG pTmpL;
  259. RPLMSGF_SET_OPC_M(pTmpB, RPLMSGF_E_SNDENTRIES_REQ);
  260. pTmpL = (LPLONG)pTmpB;
  261. /*
  262. * We will send the V part of the address since the other
  263. * end knows the T and L (more like XDR encoding where T is
  264. * not sent)
  265. */
  266. NONPORT("Do not rely on the address being a long here")
  267. /*
  268. * As an optmization here, we make use of the fact that
  269. * the address is an IP address and is therefore a long.
  270. * When we start working with more than one address family or
  271. * when the size of the IP address changes, we should change
  272. * the code here. For now, there is no harm in optimizing
  273. * it
  274. */
  275. COMM_HOST_TO_NET_L_M(pWinsAdd->Add.IPAdd, *pTmpL);
  276. pTmpL++; //advance to next 4 bytes
  277. /*
  278. * Store the max version number
  279. */
  280. WINS_PUT_VERS_NO_IN_STREAM_M(&MaxVersNo, pTmpL);
  281. pTmpL = (LPLONG)((LPBYTE)(pTmpL) + WINS_VERS_NO_SIZE); //advance the
  282. //pointer
  283. /*
  284. * Store the min version number
  285. */
  286. WINS_PUT_VERS_NO_IN_STREAM_M(&MinVersNo, pTmpL);
  287. pTmpL = (LPLONG)((LPBYTE)(pTmpL) + WINS_VERS_NO_SIZE); //advance the
  288. //pointer
  289. #if SUPPORT612WINS > 0
  290. if (fPnrIsBeta1Wins == FALSE)
  291. {
  292. #endif
  293. COMM_HOST_TO_NET_L_M(RplType, *pTmpL);
  294. pTmpL++;
  295. #if SUPPORT612WINS > 0
  296. }
  297. #endif
  298. //
  299. // Let us tell the caller the exact length of the request message
  300. //
  301. *pMsgLen = (ULONG) ((LPBYTE)pTmpL - pBuff );
  302. return;
  303. }
  304. VOID
  305. RplMsgfFrmSndEntriesRsp (
  306. #if SUPPORT612WINS > 0
  307. IN BOOL fPnrIsBeta1Wins,
  308. #endif
  309. IN LPBYTE pBuff,
  310. IN DWORD NoOfRecs,
  311. IN LPBYTE pName,
  312. IN DWORD NameLen,
  313. IN BOOL fGrp,
  314. IN DWORD NoOfAdds,
  315. IN PCOMM_ADD_T pNodeAdd,
  316. IN DWORD Flag,
  317. IN VERS_NO_T VersNo,
  318. IN BOOL fFirstTime,
  319. OUT LPBYTE *ppNewPos
  320. )
  321. /*++
  322. Routine Description:
  323. This function is used to format a "send entries" response. The
  324. function is called once for each data entry record that needs to be
  325. sent.
  326. The first time, it is called (fFirstTime = TRUE), it puts the
  327. opcode and the first directory entry in the buffer. On subsequent
  328. calls the data entries passed are tacked on at the end of the
  329. buffer
  330. Arguments:
  331. ppBuff - ptr to address of location to start storing the info from.
  332. NoOfRecs - No of records that are being sent.
  333. pName - Name of unique entry or group
  334. NameLen - Length of name
  335. fGrp - Indicates whether the name is a unique name or a group name
  336. NoOfAdds - No of addresses (useful if entry is a group entry)
  337. pNodeAdd - Ptr to address of node (if unique entry) or to list of
  338. addresses if (entry group)
  339. Flag - The flag word of the entry
  340. VersNo - The version number of the entry
  341. fFirstTime - Indicates whether this is the first call in a sequence of
  342. calls to this function for formatting a send data entries
  343. response
  344. ppNewPos - contains the starting position for the next record
  345. Externals Used:
  346. None
  347. Return Value:
  348. None
  349. Error Handling:
  350. Called by:
  351. Side Effects:
  352. Comments:
  353. NOTE NOTE NOTE
  354. The set of calls to this function result in a message
  355. containing records pertaining to one owner. This is the owner
  356. whose records were requested by the PULL partner
  357. --*/
  358. {
  359. LPLONG pTmpL = (LPLONG)pBuff;
  360. LPBYTE pTmpB = pBuff;
  361. DWORD i; /*counter for looping over all records*/
  362. if (fFirstTime)
  363. {
  364. //
  365. // In the first invocation, we need to offset the
  366. // pointer by the header size used by COMM code for
  367. // its header
  368. //
  369. // Due to the above, this formatting function is slightly
  370. // inconsistent with the other formatting functions that
  371. // don't do any offsetting. Subsequent invocations do
  372. // not require any offseting.
  373. //
  374. RPLMSGF_SET_OPC_M(pTmpB, RPLMSGF_E_SNDENTRIES_RSP);
  375. pTmpL++; //advance to next 4 bytes
  376. COMM_HOST_TO_NET_L_M(NoOfRecs, *pTmpL);
  377. pTmpL++; //advance to next 4 bytes
  378. pTmpB = (LPBYTE)pTmpL;
  379. }
  380. /*
  381. * Store the length of the name
  382. */
  383. COMM_HOST_TO_NET_L_M(NameLen, *pTmpL);
  384. pTmpB += sizeof(LONG);
  385. /*
  386. *Store the name.
  387. */
  388. WINSMSC_COPY_MEMORY_M(pTmpB, pName, NameLen);
  389. /*
  390. * Adjust the pointer
  391. */
  392. pTmpB += NameLen;
  393. /*
  394. * let us align the next field at a long boundary
  395. */
  396. pTmpB += sizeof(LONG) - ((ULONG_PTR) pTmpB % sizeof(LONG));
  397. /*
  398. * Store the Flags field
  399. */
  400. #if SUPPORT612WINS > 0
  401. if (fPnrIsBeta1Wins == FALSE)
  402. {
  403. #endif
  404. pTmpL = (LPLONG)pTmpB;
  405. COMM_HOST_TO_NET_L_M(Flag, *pTmpL);
  406. pTmpB += sizeof(LONG);
  407. #if SUPPORT612WINS > 0
  408. }
  409. else
  410. {
  411. *pTmpB++ = (BYTE)Flag;
  412. }
  413. #endif
  414. /*
  415. * Store the group flag
  416. */
  417. *pTmpB++ = (UCHAR)fGrp;
  418. //align it on a long boundary
  419. pTmpB += sizeof(LONG) - ((ULONG_PTR)pTmpB % sizeof(LONG));
  420. pTmpL = (LPLONG)pTmpB;
  421. /*
  422. * Store the Version Number
  423. */
  424. WINS_PUT_VERS_NO_IN_STREAM_M(&VersNo, pTmpL);
  425. pTmpL = (LPLONG)((LPBYTE)pTmpL + WINS_VERS_NO_SIZE);
  426. if (NMSDB_ENTRY_TYPE_M(Flag) == NMSDB_UNIQUE_ENTRY)
  427. {
  428. /*
  429. * We will send the V part of the address since the other
  430. * and knows the T and L (more like XDR encoding where T is
  431. * not sent)
  432. */
  433. NONPORT("Do not rely on the address being a long here")
  434. /*
  435. * As an optmization here, we make use of the fact that
  436. * the address is an IP address and is therefore a long.
  437. * When we start working with more than one address family or
  438. * when the size of the IP address changes, we should change
  439. * the code here. For now, there is no harm in optimizing
  440. * it
  441. */
  442. COMM_HOST_TO_NET_L_M(pNodeAdd->Add.IPAdd, *pTmpL);
  443. pTmpL++;
  444. }
  445. else //it is a group or a multihomed entry
  446. {
  447. if (NMSDB_ENTRY_TYPE_M(Flag) != NMSDB_NORM_GRP_ENTRY)
  448. {
  449. //
  450. // we were passed a ptr to the address of the
  451. // first member in a ptr instead of a pptr.
  452. //
  453. PCOMM_ADD_T *ppNodeAdd = (PCOMM_ADD_T *)pNodeAdd;
  454. //
  455. // let us threfore initialize pNodeAdd to the address
  456. // of the first member
  457. //
  458. pNodeAdd = *ppNodeAdd;
  459. /*
  460. * It is a special group or a multihomed entry.
  461. * store the number of addresses first
  462. */
  463. pTmpB = (LPBYTE)pTmpL;
  464. FUTURES("If we start storing > 255 members in a group, then change the")
  465. FUTURES("following (i.e. use COMM_HOST_TO_NET_L_M)")
  466. *pTmpB++ = (BYTE)NoOfAdds;
  467. pTmpB += sizeof(LONG) - 1;
  468. DBGPRINT2(DET, "RplMsgfFrmSndEntriesRsp: NoOfAdds=(%d) in %s\n", NoOfAdds, NMSDB_ENTRY_TYPE_M(Flag) == NMSDB_SPEC_GRP_ENTRY ?
  469. "SPECIAL GROUP" : "MULTIHOMED");
  470. pTmpL = (LPLONG)pTmpB;
  471. /*
  472. * Store all the addresses
  473. * Note: The No of addresses is an even number
  474. * because we
  475. * are passing two addresses for each member in the
  476. * list (that is what this function gets). The first
  477. * address of the pair is the address of the member;
  478. * the second address of the pair is the address
  479. * of the WINS server that registered or refreshed the
  480. * member)
  481. */
  482. for (i = 0; i < NoOfAdds ; i++)
  483. {
  484. COMM_HOST_TO_NET_L_M(
  485. pNodeAdd->Add.IPAdd,
  486. *pTmpL
  487. );
  488. pNodeAdd++; //increment to point to
  489. //address of member
  490. pTmpL++;
  491. COMM_HOST_TO_NET_L_M(
  492. pNodeAdd->Add.IPAdd,
  493. *pTmpL
  494. );
  495. pNodeAdd++; //increment to point to
  496. //address of owner
  497. pTmpL++;
  498. }
  499. }
  500. else // it is a normal group
  501. {
  502. COMM_HOST_TO_NET_L_M(pNodeAdd->Add.IPAdd, *pTmpL);
  503. pTmpL++;
  504. }
  505. }
  506. /*
  507. * Store the end delimiter (2 row delimiters in sequence).
  508. */
  509. *pTmpL++ = ENTRY_DELIM;
  510. *pTmpL = ENTRY_DELIM;
  511. /*
  512. * Init ppBuff to point to last delimiter, so that next entry if
  513. * there starts from that location. If there is no other entry,
  514. * then two delimiters will be there to mark the end of the message
  515. */
  516. *ppNewPos = (LPBYTE)pTmpL;
  517. return;
  518. }
  519. VOID
  520. RplMsgfUfmAddVersMapRsp(
  521. #if SUPPORT612WINS > 0
  522. IN BOOL fIsPnrBeta1Wins,
  523. #endif
  524. IN LPBYTE pBuff,
  525. OUT LPDWORD pNoOfMaps,
  526. OUT LPDWORD pInitiatorWinsIpAdd,
  527. IN OUT PRPL_ADD_VERS_NO_T *ppAddVers
  528. )
  529. /*++
  530. Routine Description:
  531. This function unformats the request to the
  532. "give me address - version #" message
  533. Arguments:
  534. pBuff - Buffer that contains the response message
  535. pNoOfMaps - No of Address - Version # entries
  536. pAddVers - array of structures storing add-version # mappings
  537. Externals Used:
  538. None
  539. Return Value:
  540. None
  541. Error Handling:
  542. Called by:
  543. GetVersNo() in rplpull.c
  544. Side Effects:
  545. Comments:
  546. pBuff should be pointing to the location just past the opcode
  547. (i.e. 4 bytes from the start of the opcode in the message received
  548. --*/
  549. {
  550. DWORD i = 0;
  551. PRPL_ADD_VERS_NO_T pAddVers;
  552. VERS_NO_T StartVersNo;
  553. WINS_UID_T Uid;
  554. //
  555. // Get the No of Mappings
  556. //
  557. COMM_NET_TO_HOST_L_M(*((LPLONG)pBuff), *pNoOfMaps);
  558. ASSERT(*pNoOfMaps > 0);
  559. pBuff += sizeof(LONG);
  560. if (*pNoOfMaps > 0)
  561. {
  562. WinsMscAlloc(*pNoOfMaps * sizeof(RPL_ADD_VERS_NO_T), ppAddVers);
  563. pAddVers = *ppAddVers;
  564. //
  565. // get all the mappings
  566. //
  567. for(i=0; i < *pNoOfMaps ; i++, pAddVers++)
  568. {
  569. COMM_NET_TO_HOST_L_M(*((LPLONG)pBuff),
  570. pAddVers->OwnerWinsAdd.Add.IPAdd);
  571. pAddVers->OwnerWinsAdd.AddTyp_e = COMM_ADD_E_TCPUDPIP;
  572. pAddVers->OwnerWinsAdd.AddLen = sizeof(COMM_IP_ADD_T);
  573. pBuff += sizeof(LONG);
  574. WINS_GET_VERS_NO_FR_STREAM_M(pBuff, &pAddVers->VersNo);
  575. pBuff += WINS_VERS_NO_SIZE;
  576. #if SUPPORT612WINS > 0
  577. if (fIsPnrBeta1Wins == FALSE)
  578. {
  579. #endif
  580. WINS_GET_VERS_NO_FR_STREAM_M(pBuff, &StartVersNo);
  581. pBuff += WINS_VERS_NO_SIZE;
  582. COMM_NET_TO_HOST_L_M(*((LPLONG)pBuff), Uid);
  583. pBuff += sizeof(LONG);
  584. #if SUPPORT612WINS > 0
  585. }
  586. #endif
  587. }
  588. #if SUPPORT612WINS > 0
  589. if (fIsPnrBeta1Wins == FALSE)
  590. {
  591. #endif
  592. if (pInitiatorWinsIpAdd != NULL)
  593. {
  594. COMM_NET_TO_HOST_L_M(*((LPLONG)pBuff), *pInitiatorWinsIpAdd);
  595. }
  596. #if SUPPORT612WINS > 0
  597. }
  598. #endif
  599. } // if (NoOfMaps > 0)
  600. return;
  601. }
  602. VOID
  603. RplMsgfUfmSndEntriesReq(
  604. #if SUPPORT612WINS > 0
  605. IN BOOL fPnrIsBeta1Wins,
  606. #endif
  607. IN LPBYTE pBuff,
  608. OUT PCOMM_ADD_T pWinsAdd,
  609. OUT PVERS_NO_T pMaxVersNo,
  610. OUT PVERS_NO_T pMinVersNo,
  611. OUT LPDWORD pRplType
  612. )
  613. /*++
  614. Routine Description:
  615. This function unformats the "send entries request"
  616. Arguments:
  617. pBuff - buffer that holds the request
  618. pWinsAdd - memory that will hold the address of the
  619. WINS whose records are being requested
  620. pMaxVersNo - Max. Vers. No requested
  621. pMinVersNo - Min. Vers. No requested
  622. Externals Used:
  623. None
  624. Return Value:
  625. None
  626. Error Handling:
  627. Called by:
  628. HandleAddVersMapReq in rplpush.c
  629. Side Effects:
  630. Comments:
  631. pBuff should be pointing to the location just past the opcode
  632. (i.e. 4 bytes from the start of the opcode in the message received)
  633. --*/
  634. {
  635. LPLONG pTmpL = (LPLONG)pBuff;
  636. NONPORT("Port when we start supporting different address families")
  637. pWinsAdd->AddTyp_e = COMM_ADD_E_TCPUDPIP;
  638. COMM_NET_TO_HOST_L_M(*pTmpL, pWinsAdd->Add.IPAdd);
  639. pTmpL++;
  640. WINS_GET_VERS_NO_FR_STREAM_M(pTmpL, pMaxVersNo);
  641. pTmpL = (LPLONG)((LPBYTE)pTmpL + WINS_VERS_NO_SIZE);
  642. WINS_GET_VERS_NO_FR_STREAM_M(pTmpL, pMinVersNo);
  643. #if SUPPORT612WINS > 0
  644. if (fPnrIsBeta1Wins == FALSE)
  645. {
  646. #endif
  647. if (pRplType != NULL)
  648. {
  649. pTmpL = (LPLONG)((LPBYTE)pTmpL + WINS_VERS_NO_SIZE);
  650. //COMM_NET_TO_HOST_L_M(*pTmpL, *pRplType);
  651. *pRplType = WINSCNF_RPL_DEFAULT_TYPE;
  652. }
  653. #if SUPPORT612WINS > 0
  654. }
  655. else
  656. {
  657. *pRplType = WINSCNF_RPL_DEFAULT_TYPE;
  658. }
  659. #endif
  660. return;
  661. }
  662. //__inline
  663. VOID
  664. RplMsgfUfmSndEntriesRsp(
  665. #if SUPPORT612WINS > 0
  666. IN BOOL fPnrIsBeta1Wins,
  667. #endif
  668. IN OUT LPBYTE *ppBuff,
  669. OUT LPDWORD pNoOfRecs,
  670. OUT IN LPBYTE pName,
  671. OUT LPDWORD pNameLen,
  672. OUT LPBOOL pfGrp,
  673. OUT LPDWORD pNoOfAdds,
  674. OUT PCOMM_ADD_T pNodeAdd,
  675. OUT LPDWORD pFlag,
  676. OUT PVERS_NO_T pVersNo,
  677. IN BOOL fFirstTime
  678. )
  679. /*++
  680. Routine Description:
  681. This function unformats the "send entries response"
  682. When it is called the first time (fFirstTime = TRUE), it
  683. returns the value for the NoOfRecs OUTARG and the first
  684. record. The value of ppBuff is adjusted to point to just past
  685. the row delimiter.
  686. When called the second or subsequent times, the function returns with
  687. the next entry in the list, until all entries have been exhausted.
  688. The function finds out that it is at the end of the list when
  689. it encounters at ENTRY_DELIM in the first 'sizeof(LONG)' bytes in
  690. the buffer.
  691. When a group entry is returned, pNodeAdd is made to point to the
  692. start location in *ppBuff where the list of members are stored.
  693. The caller will have to use the COMM_NET_TO_HOST_L_M macro to
  694. convert each address to its host form.
  695. The above requires the caller to know the transport that is used
  696. (by the fact that it is extracting the IP address). For the sake
  697. of overall optimization, this is considered ok (If we didn't do this,
  698. this function would have to allocate a buffer to store all the
  699. addresses for a group and return that)
  700. Arguments:
  701. pNodeAdd -- This should point to an array of COMM_ADD_T structures.
  702. Since we have a maximum of 25 group members,
  703. the caller can use an auto array.
  704. Externals Used:
  705. None
  706. Return Value:
  707. NONE
  708. Error Handling:
  709. Called by:
  710. Side Effects:
  711. Comments:
  712. ppBuff should be pointing to the location just past the opcode
  713. (i.e. 4 bytes from the start of the opcode in the message received)
  714. when the function is called the first time. For subsequent calls,
  715. it would be at a row delimiter (ENTRY_DELIM)
  716. --*/
  717. {
  718. LPLONG pTmpL = (LPLONG)*ppBuff;
  719. LPBYTE pTmpB;
  720. if (fFirstTime)
  721. {
  722. COMM_NET_TO_HOST_L_M(*pTmpL, *pNoOfRecs);
  723. if (*pNoOfRecs == 0)
  724. {
  725. return;
  726. }
  727. pTmpL++;
  728. }
  729. else
  730. {
  731. //
  732. // If we are pointing to a delimiter, then we have
  733. // reached the end of the list of data records.
  734. //
  735. if (*pTmpL == ENTRY_DELIM)
  736. {
  737. DBGPRINT0(ERR, "RplMsgfUnfSndEntriesRsp:Weird. The function should not have been called\n");
  738. /*
  739. we have reached the end of the array, return
  740. success.
  741. Note: the caller should not have called us,
  742. since we gave him the No of Recs value before (
  743. the first time he called)
  744. */
  745. WINSEVT_LOG_M(
  746. WINS_FAILURE,
  747. WINS_EVT_SFT_ERR,
  748. );
  749. return;
  750. }
  751. }
  752. pTmpB = (LPBYTE)pTmpL;
  753. /*
  754. * Store the length of the name.
  755. */
  756. COMM_NET_TO_HOST_L_M(*pTmpL, *pNameLen);
  757. if(*pNameLen > 255) {
  758. *pNoOfRecs = 0;
  759. return;
  760. }
  761. pTmpB += sizeof(LONG);
  762. /*
  763. * Store the name.
  764. */
  765. WINSMSC_COPY_MEMORY_M(pName, pTmpB, *pNameLen);
  766. /*
  767. * Adjust the pointer
  768. */
  769. pTmpB += *pNameLen;
  770. /*
  771. * The next field is at a long boundary. So, let us adjust pTmpB
  772. */
  773. pTmpB += sizeof(LONG) - ((ULONG_PTR)pTmpB % sizeof(LONG));
  774. /*
  775. * Store the Flags field
  776. */
  777. #if SUPPORT612WINS > 0
  778. if (fPnrIsBeta1Wins == FALSE)
  779. {
  780. #endif
  781. pTmpL = (LPLONG)pTmpB;
  782. COMM_NET_TO_HOST_L_M(*pTmpL, *pFlag);
  783. pTmpB += sizeof(LONG);
  784. #if SUPPORT612WINS > 0
  785. }
  786. else
  787. {
  788. *pFlag = (DWORD)*pTmpB++;
  789. }
  790. #endif
  791. /*
  792. * Store the group field
  793. */
  794. *pfGrp = *pTmpB++;
  795. //align it at a long boundary
  796. pTmpB += sizeof(LONG) - ((ULONG_PTR)pTmpB % sizeof(LONG));
  797. pTmpL = (LPLONG)pTmpB;
  798. /*
  799. * Store the Version Number
  800. */
  801. WINS_GET_VERS_NO_FR_STREAM_M(pTmpL, pVersNo);
  802. pTmpL = (LPLONG)((LPBYTE)pTmpL + WINS_VERS_NO_SIZE);
  803. if (NMSDB_ENTRY_TYPE_M(*pFlag) == NMSDB_UNIQUE_ENTRY)
  804. {
  805. NONPORT("Do not rely on the address being a long here")
  806. /*
  807. As an optmization here, we make use of the fact that
  808. the address is an IP address and is therefore a long.
  809. When we start working with more than one address family or
  810. when the size of the IP address changes, we should change
  811. the code here. For now, there is no harm in optimizing
  812. code here
  813. */
  814. pNodeAdd->AddTyp_e = COMM_ADD_E_TCPUDPIP;
  815. COMM_NET_TO_HOST_L_M(*pTmpL, pNodeAdd->Add.IPAdd);
  816. pNodeAdd->AddLen = sizeof(COMM_IP_ADD_T);
  817. pTmpL++;
  818. }
  819. else //it is either a group entry or a multihomed entry
  820. {
  821. DWORD i;
  822. if(NMSDB_ENTRY_TYPE_M(*pFlag) != NMSDB_NORM_GRP_ENTRY)
  823. {
  824. /*
  825. * store the number of addresses first
  826. */
  827. pTmpB = (LPBYTE)pTmpL;
  828. FUTURES("If we start storing > 255 members in a group, then change the")
  829. FUTURES("following (i.e. use COMM_HOST_TO_NET_L_M)")
  830. *pNoOfAdds = *pTmpB++;
  831. pTmpB += sizeof(LONG) - 1;
  832. DBGPRINT2(FLOW, "RplMsgfUfrmSndEntriesRsp: NoOfAdds=(%d) in %s record \n", *pNoOfAdds, NMSDB_ENTRY_TYPE_M(*pFlag) == NMSDB_SPEC_GRP_ENTRY ? "SPECIAL GROUP": "MULTIHOMED");
  833. pTmpL = (LPLONG)pTmpB;
  834. /*
  835. Init the pointer to the list of addresses
  836. Note: The No of addresses is an even number because we
  837. are passing two addresses for each member in the
  838. list (that is what this function returns). The first
  839. address of the pair is the address of the member;
  840. the second address of the pair is the address
  841. of the WINS server that registered or refreshed the
  842. member)
  843. */
  844. for (i = 0; i < *pNoOfAdds ; i++)
  845. {
  846. NONPORT("this will have to be changed when we move to other address families")
  847. //
  848. // Get address of owner
  849. //
  850. pNodeAdd->AddTyp_e = COMM_ADD_E_TCPUDPIP;
  851. pNodeAdd->AddLen = sizeof(COMM_IP_ADD_T);
  852. COMM_NET_TO_HOST_L_M(*pTmpL, pNodeAdd->Add.IPAdd);
  853. pNodeAdd++;
  854. pTmpL++;
  855. //
  856. // Get address of member
  857. //
  858. pNodeAdd->AddTyp_e = COMM_ADD_E_TCPUDPIP;
  859. pNodeAdd->AddLen = sizeof(COMM_IP_ADD_T);
  860. COMM_NET_TO_HOST_L_M(*pTmpL, pNodeAdd->Add.IPAdd);
  861. pNodeAdd++;
  862. pTmpL++;
  863. }
  864. }
  865. else //it is a normal group
  866. {
  867. pNodeAdd->AddTyp_e = COMM_ADD_E_TCPUDPIP;
  868. COMM_NET_TO_HOST_L_M(*pTmpL, pNodeAdd->Add.IPAdd);
  869. pNodeAdd->AddLen = sizeof(COMM_IP_ADD_T);
  870. pTmpL++;
  871. }
  872. }
  873. /*
  874. * Make the ptr point to the location after the ENTRY_DELIM
  875. */
  876. pTmpL++ ;
  877. /*
  878. * Init ppBuff to point to last delimiter, so that next entry if
  879. * there starts from that location. If there is no other entry,
  880. * then two delimiters will be there to mark the end of the message
  881. */
  882. *ppBuff = (LPBYTE)pTmpL;
  883. return;
  884. }
  885. VOID
  886. RplMsgfUfmPullPnrReq(
  887. LPBYTE pMsg,
  888. DWORD MsgLen,
  889. PRPLMSGF_MSG_OPCODE_E pPullReqType_e
  890. )
  891. /*++
  892. Routine Description:
  893. This function unformats a message received from a WINS
  894. that is a pull partner
  895. Arguments:
  896. Externals Used:
  897. None
  898. Return Value:
  899. None
  900. Error Handling:
  901. Called by:
  902. Push Thread
  903. Side Effects:
  904. Comments:
  905. Change this function to a macro
  906. --*/
  907. {
  908. UNREFERENCED_PARAMETER(MsgLen);
  909. //
  910. // First three bytes should be 0s.
  911. //
  912. PERF("since we never use up more than 1 byte for the opcode, we can get")
  913. PERF("rid of the first 3 assignements down below and retrieve the opcode")
  914. PERF("directly from the 4th byte. Make corresponding change in the formatting")
  915. PERF("functions too")
  916. *pPullReqType_e |= *pMsg++ << 24;
  917. *pPullReqType_e |= *pMsg++ << 16;
  918. *pPullReqType_e |= *pMsg++ << 8;
  919. *pPullReqType_e = *pMsg ;
  920. return;
  921. }
  922. VOID
  923. RplMsgfFrmUpdVersNoReq(
  924. IN LPBYTE pBuff,
  925. IN LPBYTE pName,
  926. IN DWORD NameLen,
  927. OUT LPDWORD pMsgLen
  928. )
  929. /*++
  930. Routine Description:
  931. This function is called to format an "update version number" request
  932. Arguments:
  933. pBuff - Buffer that will hold the formatted request
  934. pName - Name in the name-address mapping db that needs to have
  935. its version no. updated
  936. NameLen - Length of the name
  937. pMsgLen - Length of the formatted message
  938. Externals Used:
  939. None
  940. Return Value:
  941. None
  942. Error Handling:
  943. Called by:
  944. InfRemWins() in nmschl.c
  945. Side Effects:
  946. Comments:
  947. None
  948. --*/
  949. {
  950. LPBYTE pTmpB = pBuff;
  951. LPLONG pTmpL = (LPLONG)pBuff;
  952. RPLMSGF_SET_OPC_M(pTmpB, RPLMSGF_E_UPDVERSNO_REQ);
  953. pTmpL = (LPLONG)pTmpB;
  954. /*
  955. * Store the length of the name.
  956. */
  957. COMM_HOST_TO_NET_L_M(NameLen, *pTmpL);
  958. pTmpB += sizeof(LONG);
  959. /*
  960. * Store the name.
  961. */
  962. WINSMSC_COPY_MEMORY_M(pTmpB, pName, NameLen);
  963. /*
  964. * Adjust the pointer
  965. */
  966. pTmpB += NameLen;
  967. //
  968. // Find size of req buffer
  969. //
  970. *pMsgLen = (ULONG) (pTmpB - pBuff);
  971. return;
  972. }
  973. VOID
  974. RplMsgfUfmUpdVersNoReq(
  975. IN LPBYTE pBuff,
  976. OUT LPBYTE pName,
  977. OUT LPDWORD pNameLen
  978. )
  979. /*++
  980. Routine Description:
  981. This function is called to unformat the "update version no" request
  982. sent by a remote WINS
  983. Arguments:
  984. pBuff - Buffer holding the formatted request
  985. pName - Name whose version no. is to be updated
  986. pNameLen - Length of name
  987. Externals Used:
  988. None
  989. Return Value:
  990. None
  991. Error Handling:
  992. Called by:
  993. HandleUpdVersNoReq in rplpush.c
  994. Side Effects:
  995. Comments:
  996. None
  997. --*/
  998. {
  999. LPBYTE pTmpB = pBuff;
  1000. LPLONG pTmpL = (LPLONG)pBuff;
  1001. /*
  1002. * Store the length of the name.
  1003. */
  1004. COMM_NET_TO_HOST_L_M(*pTmpL, *pNameLen);
  1005. pTmpB += sizeof(LONG);
  1006. /*
  1007. * Store the name.
  1008. */
  1009. WINSMSC_COPY_MEMORY_M(pName, pTmpB, *pNameLen);
  1010. /*
  1011. * Adjust the pointer
  1012. */
  1013. pTmpB += *pNameLen;
  1014. return;
  1015. }
  1016. VOID
  1017. RplMsgfFrmUpdVersNoRsp(
  1018. IN LPBYTE pRspBuff,
  1019. IN BYTE Rcode,
  1020. OUT LPDWORD pRspBuffLen
  1021. )
  1022. /*++
  1023. Routine Description:
  1024. This function is called to send the response to the "update version
  1025. # request"
  1026. Arguments:
  1027. pRspBuff - Buffer to hold the formatted response
  1028. Rcode - result of the operation
  1029. pRspBuffLen - Length of response
  1030. Externals Used:
  1031. None
  1032. Return Value:
  1033. None
  1034. Error Handling:
  1035. Called by:
  1036. HandleUpdVersNoReq() in rplpush.c
  1037. Side Effects:
  1038. Comments:
  1039. None
  1040. --*/
  1041. {
  1042. LPBYTE pTmpB = pRspBuff;
  1043. RPLMSGF_SET_OPC_M(pTmpB, RPLMSGF_E_UPDVERSNO_RSP);
  1044. *pTmpB++ = Rcode;
  1045. *pRspBuffLen = (ULONG) (pTmpB - pRspBuff);
  1046. return;
  1047. }
  1048. FUTURES("change to a macro")
  1049. PERF("change to a macro")
  1050. VOID
  1051. RplMsgfUfmUpdVersNoRsp(
  1052. IN LPBYTE pRspBuff,
  1053. OUT LPBYTE pRcode
  1054. )
  1055. /*++
  1056. Routine Description:
  1057. This function is called to unformat the response to the
  1058. "update version number" request.
  1059. Arguments:
  1060. pRspBuff - Buffer holding the formatted response
  1061. pRcode - result of the update
  1062. Externals Used:
  1063. None
  1064. Return Value:
  1065. None
  1066. Error Handling:
  1067. Called by:
  1068. InfRemWins() in nmschl.c
  1069. Side Effects:
  1070. Comments:
  1071. Change to a macro
  1072. --*/
  1073. {
  1074. *pRcode = *pRspBuff;
  1075. return;
  1076. }
  1077.