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.

2540 lines
54 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. nmsmsgf.c
  5. Abstract:
  6. This module contains the functions for formatting and unformatting
  7. the various messages that are sent and/or received from nbt nodes.
  8. It also contains the function called by the NBT threads to service
  9. a name request
  10. Functions:
  11. NmsMsgfProcNbtReq
  12. GetName
  13. GetOtherInfo
  14. NmsMsgfFrmNamRspMsg
  15. FrmNamRegRsp
  16. FrmNamRelRsp
  17. FrmNamQueryRsp
  18. FormatQueryRspBuff
  19. FormatName
  20. NmsMsgfFrmNamQueryReq
  21. NmsMsgfFrmNamRelReq
  22. NmsMsgfFrmWACK
  23. NmsMsgfUfmNamRsp
  24. Author:
  25. Pradeep Bahl (PradeepB) Dec-1992
  26. Revision History:
  27. --*/
  28. /*
  29. Includes
  30. */
  31. #include "wins.h"
  32. #include "nms.h"
  33. #include "nmsdb.h"
  34. #include "winsevt.h"
  35. #include "winscnf.h"
  36. #include "winsmsc.h"
  37. #include "nmsmsgf.h"
  38. #include "nmsnmh.h"
  39. #include "nmschl.h"
  40. #include "comm.h"
  41. #include "winsintf.h"
  42. /*
  43. defines
  44. */
  45. #define NAME_HEADER_SIZE 12 /* header size (bytes before the Ques
  46. * name section of a name packet
  47. */
  48. #define NAME_FORMAT_MASK 0xC0 /*top two bits of a byte*/
  49. #define NODE_TYPE_MASK 0x60 /*bit 13 and 14 of NBFLAGs field */
  50. #define SHIFT_NODE_BITS 5 //shift the node bits in the byte
  51. //containing them by this amount
  52. #define LENGTH_MASK 0x3F /*6 LSBs of the top byte of the
  53. * QuesNamSec field
  54. */
  55. #define GROUP_BIT_MASK 0x80 /*bit 7 of the 1st byte (MSB)of the
  56. *16 bit NBFLAGS field
  57. */
  58. /*
  59. * Max length of a Name (including label length octets) in RFC packet
  60. */
  61. #define RFC_MAX_NAM_LEN 255
  62. //
  63. // Max size of internal name as derived from the rfc packet name
  64. //
  65. #define MAX_SIZE_INTERNAL_NAME (RFC_MAX_NAM_LEN - 16)
  66. //This should be = (255 - 16)
  67. //since the max size of the netbios
  68. //name (with scope attached) can be
  69. //be 255. The first 32 bytes
  70. //are encoded. These map to 16
  71. //bytes in the internal name
  72. /*
  73. * Max length of a label in a name
  74. */
  75. #define RFC_MAX_LABEL_LEN 63
  76. /*
  77. * Sizes of the various fields in the name service packets received or sent
  78. * by the WINS server. These sizes are specified in RFC 1002
  79. */
  80. #define RFC_LEN_QTYP (2)
  81. #define RFC_LEN_QCLS (2)
  82. #define RFC_LEN_TTL (4)
  83. #define RFC_LEN_RDLEN (2)
  84. #define RFC_LEN_NBFLAGS (2)
  85. #define RFC_LEN_NBADD (4)
  86. #define RFC_LEN_RRTYP (2)
  87. #define RFC_LEN_RRCLS (2)
  88. #define RFC_LEN_RRPTR (2)
  89. #define RFC_LEN_QTYP_N_QCLS (RFC_LEN_QTYP + RFC_LEN_QCLS) /* page 10 -
  90. *RFC 1002
  91. */
  92. #define RFC_LEN_RRTYP_N_RRCLS (RFC_LEN_RRTYP + RFC_LEN_RRCLS) /* page 11 -
  93. *RFC 1002
  94. */
  95. /*
  96. * The following is used by FrmNamQueryRsp in its calculation to determine
  97. * if the name query buffer would be big enough for the response
  98. */
  99. #define RFC_LEN_TTL_N_RDLEN (RFC_LEN_TTL + RFC_LEN_RDLEN)
  100. #define RFC_LEN_RR_N_TTL (RFC_LEN_RRTYP_N_RRCLS + RFC_LEN_TTL)
  101. #define RFC_LEN_RR_N_TTL_N_RDLEN_N_NBF (RFC_LEN_RR_N_TTL + \
  102. RFC_LEN_RDLEN + RFC_LEN_NBFLAGS)
  103. //
  104. // Length of NBFLAGS and the NB address
  105. //
  106. #define RFC_LEN_NBF_N_NBA (RFC_LEN_NBFLAGS + RFC_LEN_NBADD)
  107. #define RFC_LEN_RDLEN_N_NBF (RFC_LEN_RDLEN + RFC_LEN_NBFLAGS)
  108. //
  109. // Length of the RDLEN, NB flags and NB address section. Page 13 of RFC 1002
  110. //
  111. #define RFC_LEN_RDLEN_N_NBF_N_NBA (RFC_LEN_RDLEN + RFC_LEN_NBF_N_NBA)
  112. /*
  113. * Size of the TTL, RDLEN, NB Flags and NB address section
  114. */
  115. #define RFC_LEN_TTL_N_RDLEN_N_NBF_N_NBA (RFC_LEN_TTL + RFC_LEN_RDLEN_N_NBF_N_NBA)
  116. /*
  117. The value of the 3rd and 4 th byte of the first long of the response packets
  118. for the different name requests. The bytes are numbered from the start of
  119. the pkt.
  120. Note: for a negative response the Rcode value (4 LSBs of the 4th byte of the
  121. message) has to be ORed with the LBFW values
  122. */
  123. #define RFC_NAM_REG_RSP_OPC (0xAD) /*+ve registration response*/
  124. #define RFC_NAM_REG_RSP_4THB (0x80) /*4th byte of the above pkt */
  125. #define RFC_NAM_REL_RSP_OPC (0xB4) /*+ve release response*/
  126. #define RFC_NAM_REL_RSP_4THB (0x00) /*4th byte of the above pkt*/
  127. #define RFC_NAM_QUERY_RSP_OPC_NO_T (0x85) /*+ve query resp (complete)*/
  128. #define RFC_NAM_QUERY_RSP_OPC_T (0x87) /*+ve query resp (truncated)*/
  129. #define RFC_NAM_QUERY_RSP_4THB (0x80) /*4th byte of the above pkt */
  130. /*
  131. * Values of different fields in RFC response packet
  132. */
  133. /*
  134. QD Count and AN count fields of the Name Reg. Rsp pkt
  135. */
  136. #define RFC_NAM_REG_RSP_QDCNT_1STB (0x00)
  137. #define RFC_NAM_REG_RSP_QDCNT_2NDB (0x00)
  138. #define RFC_NAM_REG_RSP_ANCNT_1STB (0x00)
  139. #define RFC_NAM_REG_RSP_ANCNT_2NDB (0x01)
  140. /*
  141. NS Count and AR count fields of the Name Reg. Rsp pkt
  142. */
  143. #define RFC_NAM_REG_RSP_NSCNT_1STB (0x00)
  144. #define RFC_NAM_REG_RSP_NSCNT_2NDB (0x00)
  145. #define RFC_NAM_REG_RSP_ARCNT_1STB (0x00)
  146. #define RFC_NAM_REG_RSP_ARCNT_2NDB (0x00)
  147. /*
  148. QD Count and AN count fields of the Name Rel. Rsp pkt
  149. */
  150. #define RFC_NAM_REL_RSP_QDCNT_1STB (0x00)
  151. #define RFC_NAM_REL_RSP_QDCNT_2NDB (0x00)
  152. #define RFC_NAM_REL_RSP_ANCNT_1STB (0x00)
  153. #define RFC_NAM_REL_RSP_ANCNT_2NDB (0x01)
  154. /*
  155. NS Count and AR count fields of the Name Rel. Rsp pkt
  156. */
  157. #define RFC_NAM_REL_RSP_NSCNT_1STB (0x00)
  158. #define RFC_NAM_REL_RSP_NSCNT_2NDB (0x00)
  159. #define RFC_NAM_REL_RSP_ARCNT_1STB (0x00)
  160. #define RFC_NAM_REL_RSP_ARCNT_2NDB (0x00)
  161. /*
  162. QD Count and AN count fields of the Name Query. Rsp pkt
  163. */
  164. #define RFC_NAM_QUERY_RSP_QDCNT_1STB (0x00)
  165. #define RFC_NAM_QUERY_RSP_QDCNT_2NDB (0x00)
  166. #define RFC_NAM_QUERY_RSP_ANCNT_1STB (0x00)
  167. #define RFC_NAM_QUERY_POS_RSP_ANCNT_2NDB (0x01)
  168. #define RFC_NAM_QUERY_NEG_RSP_ANCNT_2NDB (0x00)
  169. /*
  170. NS Count and AR count fields of the Name Query. Rsp pkt
  171. */
  172. #define RFC_NAM_QUERY_RSP_NSCNT_1STB (0x00)
  173. #define RFC_NAM_QUERY_RSP_NSCNT_2NDB (0x00)
  174. #define RFC_NAM_QUERY_RSP_ARCNT_1STB (0x00)
  175. #define RFC_NAM_QUERY_RSP_ARCNT_2NDB (0x00)
  176. /*
  177. * NB and IN fields of the name query response pkt
  178. * Page 21 and 22 of RFC 1002
  179. */
  180. /*
  181. Positive name query response
  182. */
  183. #define RFC_NAM_QUERY_POS_RSP_NB_1STB (0x00)
  184. #define RFC_NAM_QUERY_POS_RSP_NB_2NDB (0x20)
  185. #define RFC_NAM_QUERY_POS_RSP_IN_1STB (0x00)
  186. #define RFC_NAM_QUERY_POS_RSP_IN_2NDB (0x01)
  187. /*
  188. Negative name query response
  189. */
  190. #define RFC_NAM_QUERY_NEG_RSP_NB_1STB (0x00)
  191. #define RFC_NAM_QUERY_NEG_RSP_NB_2NDB (0x0A)
  192. #define RFC_NAM_QUERY_NEG_RSP_IN_1STB (0x00)
  193. #define RFC_NAM_QUERY_NEG_RSP_IN_2NDB (0x01)
  194. /*
  195. name query request opcode byte and 4th byte
  196. */
  197. #define RFC_NAM_QUERY_REQ_OPCB (0x01)
  198. #define RFC_NAM_QUERY_REQ_4THB (0x0)
  199. /*
  200. name query request QDCOUNT and ANCOUNT bytes
  201. */
  202. #define RFC_NAM_QUERY_REQ_QDCNT_1STB (0x00)
  203. #define RFC_NAM_QUERY_REQ_QDCNT_2NDB (0x01)
  204. #define RFC_NAM_QUERY_REQ_ANCNT_1STB (0x00)
  205. #define RFC_NAM_QUERY_REQ_ANCNT_2NDB (0x00)
  206. /*
  207. name query request NSCOUNT and ARCOUNT bytes
  208. */
  209. #define RFC_NAM_QUERY_REQ_NSCNT_1STB (0x00)
  210. #define RFC_NAM_QUERY_REQ_NSCNT_2NDB (0x00)
  211. #define RFC_NAM_QUERY_REQ_ARCNT_1STB (0x00)
  212. #define RFC_NAM_QUERY_REQ_ARCNT_2NDB (0x00)
  213. /*
  214. name query request QTYP and QCLS bytes
  215. */
  216. #define RFC_NAM_QUERY_REQ_QTYP_1STB (0x00)
  217. #define RFC_NAM_QUERY_REQ_QTYP_2NDB (0x20)
  218. #define RFC_NAM_QUERY_REQ_QCLS_1STB (0x00)
  219. #define RFC_NAM_QUERY_REQ_QCLS_2NDB (0x01)
  220. /*
  221. name release request opcode byte and 4th byte
  222. */
  223. #define RFC_NAM_REL_REQ_OPCB (0x30)
  224. #define RFC_NAM_REL_REQ_4THB (0x00)
  225. /*
  226. name release request QDCOUNT and ANCOUNT bytes
  227. */
  228. #define RFC_NAM_REL_REQ_QDCNT_1STB (0x00)
  229. #define RFC_NAM_REL_REQ_QDCNT_2NDB (0x01)
  230. #define RFC_NAM_REL_REQ_ANCNT_1STB (0x00)
  231. #define RFC_NAM_REL_REQ_ANCNT_2NDB (0x00)
  232. /*
  233. name release request NSCOUNT and ARCOUNT bytes
  234. */
  235. #define RFC_NAM_REL_REQ_NSCNT_1STB (0x00)
  236. #define RFC_NAM_REL_REQ_NSCNT_2NDB (0x00)
  237. #define RFC_NAM_REL_REQ_ARCNT_1STB (0x00)
  238. #define RFC_NAM_REL_REQ_ARCNT_2NDB (0x01)
  239. /*
  240. name release request QTYP and QCLS bytes
  241. */
  242. #define RFC_NAM_REL_REQ_QTYP_1STB (0x00)
  243. #define RFC_NAM_REL_REQ_QTYP_2NDB (0x20)
  244. #define RFC_NAM_REL_REQ_QCLS_1STB (0x00)
  245. #define RFC_NAM_REL_REQ_QCLS_2NDB (0x01)
  246. /*
  247. name Release request RRTYP and RRCLS bytes
  248. */
  249. #define RFC_NAM_REL_REQ_RRTYP_1STB (0x00)
  250. #define RFC_NAM_REL_REQ_RRTYP_2NDB (0x20)
  251. #define RFC_NAM_REL_REQ_RRCLS_1STB (0x00)
  252. #define RFC_NAM_REL_REQ_RRCLS_2NDB (0x01)
  253. /*
  254. WACK opcode byte and 4th byte
  255. */
  256. #define RFC_WACK_OPCB (0xBC)
  257. #define RFC_WACK_4THB (0x0)
  258. /*
  259. WACK QDCOUNT and ANCOUNT bytes
  260. */
  261. #define RFC_WACK_QDCNT_1STB (0x0)
  262. #define RFC_WACK_QDCNT_2NDB (0x0)
  263. #define RFC_WACK_ANCNT_1STB (0x0)
  264. #define RFC_WACK_ANCNT_2NDB (0x1)
  265. /*
  266. WACK NSCOUNT and ARCOUNT bytes
  267. */
  268. #define RFC_WACK_NSCNT_1STB (0x0)
  269. #define RFC_WACK_NSCNT_2NDB (0x0)
  270. #define RFC_WACK_ARCNT_1STB (0x0)
  271. #define RFC_WACK_ARCNT_2NDB (0x0)
  272. /*
  273. WACK RRTYP and RRCLS bytes
  274. */
  275. #define RFC_WACK_RRTYP_1STB (0x00)
  276. #define RFC_WACK_RRTYP_2NDB (0x20)
  277. #define RFC_WACK_RRCLS_1STB (0x00)
  278. #define RFC_WACK_RRCLS_2NDB (0x01)
  279. // WACK RDLENGTH Field
  280. #define RFC_WACK_RDLENGTH_1STB (0x0)
  281. #define RFC_WACK_RDLENGTH_2NDB (0x02)
  282. /*
  283. Local variable declarations
  284. */
  285. /*
  286. Local function declarations
  287. */
  288. /*
  289. *GetName -- Extract name out of packet
  290. */
  291. STATIC
  292. VOID
  293. GetName(
  294. IN OUT LPBYTE *ppName,
  295. IN OUT LPBYTE pName,
  296. OUT LPDWORD pNameLen
  297. );
  298. /*
  299. * Format Name - Format (encode) name for placing in RFC packet
  300. */
  301. STATIC
  302. VOID
  303. FormatName(
  304. IN LPBYTE pNameToFormat,
  305. IN DWORD LengthOfName,
  306. IN OUT LPBYTE *ppFormattedName
  307. );
  308. /*
  309. * GetOtherInfo -- Get information (excluding the name) from the pkt
  310. */
  311. STATIC
  312. STATUS
  313. GetOtherInfo(
  314. IN NMSMSGF_NAM_REQ_TYP_E Opcode_e,
  315. IN LPBYTE pRR, /*point to the RR_NAME section in the
  316. *name registration packet
  317. */
  318. IN INT QuesNamSecLen, //Size of Ques name section
  319. OUT LPBOOL pfGrp, //Flag -- unique/group entry
  320. OUT PNMSMSGF_CNT_ADD_T pCntAdd, //Address
  321. OUT PNMSMSGF_NODE_TYP_E pNodeTyp_e //Node Type if unique
  322. );
  323. /*
  324. * FrmNamRegRsp - Format name registration response
  325. */
  326. STATIC
  327. STATUS
  328. FrmNamRegRsp(
  329. PCOMM_HDL_T pDlgHdl,
  330. PNMSMSGF_RSP_INFO_T pRspInfo
  331. );
  332. /*
  333. * FrmNamRelRsp - Format name release response
  334. */
  335. STATIC
  336. STATUS
  337. FrmNamRelRsp(
  338. PCOMM_HDL_T pDlgHdl,
  339. PNMSMSGF_RSP_INFO_T pRspInfo
  340. );
  341. #if 0
  342. /*
  343. * FrmNamQueryRsp - Format name query response
  344. */
  345. STATIC
  346. STATUS
  347. FrmNamQueryRsp(
  348. IN PCOMM_HDL_T pDlgHdl,
  349. PNMSMSGF_RSP_INFO_T pRspInfo
  350. );
  351. #endif
  352. /*
  353. * FormatQueryRspBuff - Format name query response buffer
  354. */
  355. STATIC
  356. STATUS
  357. FormatQueryRspBuff(
  358. IN LPBYTE pDest,
  359. IN LPBYTE pSrc,
  360. IN PNMSMSGF_RSP_INFO_T pRspInfo,
  361. IN BOOL fTrunc
  362. );
  363. /*
  364. function definitions
  365. */
  366. STATUS
  367. NmsMsgfProcNbtReq(
  368. PCOMM_HDL_T pDlgHdl,
  369. MSG_T pMsg,
  370. MSG_LEN_T MsgLen
  371. )
  372. /*++
  373. Routine Description:
  374. This function is called by an nbt request thread after it dequeues an nbt
  375. request message from the work-queue. The function unformats the message
  376. and then calls the appropriate function to process it.
  377. Arguments:
  378. pDlgHdl - Dlg Handle
  379. pMsg - Message Buffer (contains that RFC packet containing
  380. the request received from an NBT node)
  381. MsgLen - Length of above buffer
  382. Externals Used:
  383. None
  384. Called by:
  385. NbtThdInitFn() in nms.c
  386. Comments:
  387. None
  388. Return Value:
  389. Success status codes -- WINS_SUCCESS
  390. Error status codes -- WINS_FAILURE
  391. --*/
  392. {
  393. NMSMSGF_NAM_REQ_TYP_E Opcode;
  394. BYTE Name[NMSDB_MAX_NAM_LEN];
  395. DWORD NameLen; /*length of name */
  396. DWORD QuesNamSecLen; /*length of question
  397. *name section in
  398. *packet
  399. */
  400. NMSMSGF_NODE_TYP_E NodeTyp_e = NMSMSGF_E_PNODE;
  401. // BOOL fRefresh;
  402. NMSMSGF_CNT_ADD_T CntAdd;
  403. COMM_ADD_T Address;
  404. BOOL fGrp; /*flag indicating whether the name
  405. *is a Unique/Group Netbios name.
  406. *fGrp is TRUE if the name is a
  407. *group name, else it is FALSE
  408. */
  409. BOOL fBuffFreed = FALSE; //indicates whether buffer has
  410. //been freed or not
  411. LPBYTE pTmp = (LPBYTE)pMsg;
  412. LPBYTE pTmp2;
  413. DBGENTER("NmsMsgfProcNbtReq\n");
  414. try {
  415. // get the opcode
  416. Opcode = (NMS_OPCODE_MASK & *(pTmp + 2)) >> 3;
  417. #ifdef JIM
  418. {
  419. BYTE TransId = *pTmp;
  420. ASSERT(TransId == 0x80);
  421. }
  422. #endif
  423. /*
  424. * make pTmp point to the Question Section. All name request
  425. * packets have a name header of standard size (RFC 1002) at the top
  426. */
  427. pTmp += NAME_HEADER_SIZE;
  428. /*
  429. * Extract the name ind store in Name. GetName will update pTmp to
  430. * point just beyond the name in the question section
  431. */
  432. pTmp2 = pTmp; /*save pTmp so that when GetName returns we can
  433. * determine the length of the question name section
  434. */
  435. GetName(
  436. &pTmp,
  437. Name,
  438. &NameLen
  439. );
  440. QuesNamSecLen = (ULONG) (pTmp - pTmp2);
  441. pTmp += RFC_LEN_QTYP_N_QCLS; /* skip past the ques. type and ques.
  442. * class fields We don't need to examine
  443. * these. The question type field
  444. * will always be NB and question class
  445. *field will always be INTERNET
  446. */
  447. #ifdef TESTWITHUB
  448. //
  449. // Check if the broadcast bit is set. If yes, drop the pkt.
  450. //
  451. if (*(pMsg + 3) & 0x10)
  452. {
  453. DBGPRINT2(SPEC, "Broadcast pkt BEING DROPPED; name is (%s). Opcode is (%d)\n", Name, Opcode);
  454. #if 0
  455. printf("Broadcast pkt BEING DROPPED; name is (%s). Opcode is (%d)\n", Name, Opcode);
  456. #endif
  457. ECommFreeBuff(pMsg);
  458. ECommEndDlg(pDlgHdl);
  459. return(WINS_SUCCESS);
  460. }
  461. #endif
  462. //
  463. // Let us set the flag to TRUE. If any of the following called
  464. // functions raises an exception, then it is a requirement that
  465. // it does so only after freeing the buffer (i.e. it must catch
  466. // all exceptions, free the buffer and then reraise the
  467. // exception - if it wants)
  468. //
  469. fBuffFreed = TRUE;
  470. //
  471. // If the 16th character is a 1B switch it with the 1st character.
  472. // This is done to support Browsing. Browsers want a list of all
  473. // names with 16th character being 1B. Putting 1B as the
  474. // 1st character enables WINS to find all 1B names quickly.
  475. //
  476. NMSMSGF_MODIFY_NAME_IF_REQD_M(Name);
  477. /*
  478. * Switch on the type of request as determined by the Opcode
  479. */
  480. switch(Opcode)
  481. {
  482. /*
  483. name registration and refresh are handled the same way
  484. */
  485. case(NMSMSGF_E_NAM_REF):
  486. case(NMSMSGF_E_NAM_REF_UB):
  487. DBGPRINT0(FLOW, "It is a name refresh request\n");
  488. case(NMSMSGF_E_NAM_REG): /* fall through */
  489. case(NMSMSGF_E_MULTIH_REG): /* fall through */
  490. /*
  491. * Get the flag indicating whether the request is a group
  492. * registration or a unique name registration. The IP
  493. * address(es) is (are) also retrieved
  494. */
  495. GetOtherInfo(
  496. Opcode,
  497. pTmp,
  498. QuesNamSecLen,
  499. &fGrp,
  500. &CntAdd,
  501. &NodeTyp_e
  502. );
  503. //
  504. // If it is not a group or a multihomed registration or
  505. //
  506. if (!fGrp && (Opcode != NMSMSGF_E_MULTIH_REG))
  507. {
  508. /*
  509. * Register the unique name
  510. */
  511. NmsNmhNamRegInd(
  512. pDlgHdl,
  513. Name,
  514. NameLen,
  515. CntAdd.Add,
  516. (BYTE)NodeTyp_e,
  517. pMsg,
  518. MsgLen,
  519. QuesNamSecLen,
  520. Opcode == NMSMSGF_E_NAM_REG ? FALSE : TRUE,
  521. NMSDB_ENTRY_IS_NOT_STATIC,
  522. FALSE //is it admin flag ?
  523. );
  524. }
  525. else //it is a group or is mutihomed
  526. {
  527. /*
  528. * Register the group name
  529. */
  530. NmsNmhNamRegGrp(
  531. pDlgHdl,
  532. Name,
  533. NameLen,
  534. &CntAdd,
  535. (BYTE)NodeTyp_e,
  536. pMsg,
  537. MsgLen,
  538. QuesNamSecLen,
  539. fGrp ? NMSDB_NORM_GRP_ENTRY : (Opcode == NMSMSGF_E_MULTIH_REG) ? NMSDB_MULTIHOMED_ENTRY : NMSDB_NORM_GRP_ENTRY,
  540. //passing NMSDB_NORM_GRP_ENTRY for spec. grp is fine
  541. //see NmsNmhNamRegGrp()
  542. Opcode == NMSMSGF_E_NAM_REG ? FALSE : TRUE,
  543. NMSDB_ENTRY_IS_NOT_STATIC,
  544. FALSE //is it admin ?
  545. );
  546. }
  547. break;
  548. case(NMSMSGF_E_NAM_QUERY):
  549. #if 0
  550. Address.AddTyp_e = COMM_ADD_E_TCPUDPIP;
  551. Address.AddLen = sizeof(COMM_IP_ADD_T);
  552. COMM_GET_IPADD_M(pDlgHdl, &Address.Add.IPAdd);
  553. #endif
  554. #if 0
  555. //
  556. // NOTE: Multiple NBT threads could be doing this simultaneously
  557. //
  558. // This is the best I can do without a critical section
  559. //
  560. FUTURES("The count may not be correct when retrieved by an RPC thread")
  561. WinsIntfStat.Counters.NoOfQueries++;
  562. #endif
  563. /*
  564. Query the name
  565. */
  566. NmsNmhNamQuery(
  567. pDlgHdl,
  568. Name,
  569. NameLen,
  570. pMsg,
  571. MsgLen,
  572. QuesNamSecLen,
  573. FALSE, // is it admin flag
  574. NULL //should be non NULL only in
  575. //an RPC thread
  576. );
  577. break;
  578. case(NMSMSGF_E_NAM_REL):
  579. GetOtherInfo(
  580. NMSMSGF_E_NAM_REL,
  581. pTmp,
  582. QuesNamSecLen,
  583. &fGrp,
  584. &CntAdd,
  585. &NodeTyp_e
  586. );
  587. //
  588. // We should pass down to NmsNmhNamRel function the
  589. // address of the client requesting name release, not
  590. // the address passed in the RFC pkt. The address
  591. // will be used by NmsDbRelRow to check if the client
  592. // is authorized to release the record
  593. //
  594. Address.AddTyp_e = COMM_ADD_E_TCPUDPIP;
  595. Address.AddLen = sizeof(COMM_IP_ADD_T);
  596. COMM_GET_IPADD_M(pDlgHdl, &Address.Add.IPAdd);
  597. /*
  598. * Release the name
  599. */
  600. NmsNmhNamRel(
  601. pDlgHdl,
  602. Name,
  603. NameLen,
  604. &Address,
  605. fGrp,
  606. pMsg,
  607. MsgLen,
  608. QuesNamSecLen,
  609. FALSE //is it admin flag ?
  610. );
  611. break;
  612. default:
  613. fBuffFreed = FALSE;
  614. DBGPRINT1(EXC, "NmsMsgfProcNbtReq: Invalid Opcode\n", Opcode);
  615. WINS_RAISE_EXC_M(WINS_EXC_PKT_FORMAT_ERR);
  616. WINSEVT_LOG_M(Opcode, WINS_EVT_INVALID_OPCODE);
  617. break;
  618. }
  619. }
  620. except(EXCEPTION_EXECUTE_HANDLER) {
  621. DBGPRINTEXC("NmsMsgfProcNbtReq");
  622. if (GetExceptionCode() == WINS_EXC_NBT_ERR)
  623. {
  624. WINS_RERAISE_EXC_M();
  625. }
  626. //
  627. // Free the message buffer if not already freed, delete the
  628. // dialogue if it is a UDP dialogue.
  629. //
  630. if (!fBuffFreed)
  631. {
  632. ECommFreeBuff(pMsg);
  633. ECommEndDlg(pDlgHdl);
  634. }
  635. }
  636. DBGLEAVE("NmsMsgfProcNbtReq\n");
  637. return(WINS_SUCCESS);
  638. }
  639. VOID
  640. GetName(
  641. IN OUT LPBYTE *ppName,
  642. IN OUT LPBYTE pName,
  643. OUT LPDWORD pNameLen
  644. )
  645. /*++
  646. Routine Description:
  647. This function is called to retrieve the name from the name
  648. request packet.
  649. Arguments:
  650. ppName -- address of ptr to question section in datagram received
  651. pName -- Address of array to hold the name. It is assumed that this is
  652. atleast NMSMSGF_RFC_MAX_NAM_LEN long.
  653. pNameLen -- address of variable to hold length of name
  654. Externals Used:
  655. None
  656. Called by:
  657. NmsNmhProcNbtReq
  658. Comments:
  659. None
  660. Return Value:
  661. None
  662. --*/
  663. {
  664. INT HighTwoBits; //First two bits of Question Name section
  665. INT Length; //length of label in Question Name section
  666. BYTE ch;
  667. LPBYTE pNmInPkt = *ppName;
  668. INT inLen = NMSMSGF_RFC_MAX_NAM_LEN; // Store the length of the name.
  669. *pNameLen = 0;
  670. /*
  671. Get the high two bits of the first byte of the Question_NAME
  672. section. The bits have to be 00. If they are not, something
  673. is really wrong.
  674. */
  675. if ((HighTwoBits = (NAME_FORMAT_MASK & *pNmInPkt)) != 0)
  676. {
  677. goto BadFormat;
  678. }
  679. /*
  680. * Get the length of the label. Length, extracted this way, is
  681. * guranteed to be <= 63.
  682. */
  683. Length = LENGTH_MASK & *pNmInPkt;
  684. pNmInPkt++; //increment past the length byte
  685. /*
  686. * Decode the first label of the name (the netbios name without the
  687. * scope).
  688. */
  689. while(Length > 0 )
  690. {
  691. ch = *pNmInPkt++ - 'A';
  692. *pName++ = (ch << 4) | (*pNmInPkt++ - 'A');
  693. (*pNameLen)++;
  694. Length -= 2;
  695. }
  696. inLen -= Length;
  697. /*
  698. Extract the netbios scope if present
  699. The netbios scope is not in encoded form
  700. */
  701. while(TRUE)
  702. {
  703. /*
  704. * if length byte is not 0, there is a netbios scope.
  705. * We make sure that if the packet is ill-formed (i.e. the
  706. * length of the name (including the length bytes) is > 255, we raise
  707. * an exception. Since *pNameLen is counting the number of bytes
  708. * in the name that we are forming, we need to compare it with
  709. * (255 - 16) = 239 since the first 32 bytes of the netbios name
  710. * map to 16 bytes of our internal name.
  711. */
  712. if (*pNmInPkt != 0)
  713. {
  714. if (*pNameLen > MAX_SIZE_INTERNAL_NAME)
  715. {
  716. goto BadFormat;
  717. }
  718. if ( --inLen <= 0) {
  719. goto BadFormat;
  720. }
  721. *pName++ = '.';
  722. (*pNameLen)++;
  723. Length = LENGTH_MASK & *pNmInPkt;
  724. // check that the we have enough space remaining in the input buffer.
  725. //
  726. if ( (inLen -= Length) <= 0 ) {
  727. goto BadFormat;
  728. }
  729. ++pNmInPkt; //increment past length byte
  730. while(Length-- != 0)
  731. {
  732. *pName++ = *pNmInPkt++;
  733. (*pNameLen)++;
  734. }
  735. }
  736. else
  737. {
  738. ++pNmInPkt; //increment past end byte (00)
  739. break;
  740. }
  741. }
  742. if (--inLen >= 0) {
  743. *pName++ = 0; /* EOS */
  744. } else {
  745. goto BadFormat;
  746. }
  747. (*pNameLen)++; //include 0 in the name's length so that it is stored
  748. //in the db. Check out FormatName too since it expects
  749. //the length to include this 0
  750. *ppName = pNmInPkt; //init the ppName ptr to point just past the name
  751. return;
  752. BadFormat:
  753. // log error and raise an exception
  754. WINSEVT_LOG_M(WINS_FAILURE, WINS_EVT_PKT_FORMAT_ERR);
  755. WINS_RAISE_EXC_M(WINS_EXC_PKT_FORMAT_ERR);
  756. return;
  757. }
  758. STATUS
  759. GetOtherInfo(
  760. NMSMSGF_NAM_REQ_TYP_E Opcode_e,
  761. IN LPBYTE pRR, /*point to the RR_NAME section in the
  762. *name registration packet
  763. */
  764. IN INT QuesNamSecLen, /*size of Ques name section*/
  765. OUT LPBOOL pfGrp, /*flag -- unique/group entry */
  766. OUT PNMSMSGF_CNT_ADD_T pCntAdd, /*Counted address array*/
  767. OUT PNMSMSGF_NODE_TYP_E pNodeTyp_e
  768. )
  769. /*++
  770. Routine Description:
  771. The function is called to retrieve information other than the
  772. the name from the pkt
  773. Arguments:
  774. pRR - address of RR_NAME section in the request packet
  775. QuesNamSecLen - length of the question names section in the request pkt
  776. pfGrp - TRUE if it is a group registration request
  777. pAddress - Address contained in the request
  778. NodeTyp_e - Type of node doing the registeration (P, B, M)
  779. Externals Used:
  780. None
  781. Called by:
  782. NmsMsgfProcNbtReq
  783. Comments:
  784. None
  785. Return Value:
  786. Success status codes -- WINS_SUCCESS
  787. Error status codes -- WINS_FAILURE
  788. --*/
  789. {
  790. INT HighTwoBits;
  791. BYTE *pTmp = pRR;
  792. LONG UNALIGNED *pTmpL;
  793. /*
  794. * RR_NAME section should contain a pointer to the Question Section. So
  795. * we could skip it. We are not, however, just in case another
  796. * implementation of NBT does not follow the recommendations of the
  797. * RFC and passes us the full name in RR_NAME section
  798. */
  799. if ((HighTwoBits = NAME_FORMAT_MASK & *pTmp) == 0)
  800. {
  801. /*
  802. * skip the name (same size as in question_name section) and the
  803. * RR_TYPE, RR_CLASS, TTL and RDLENGTH fields
  804. */
  805. pTmp += QuesNamSecLen + RFC_LEN_RRTYP_N_RRCLS +
  806. RFC_LEN_TTL + RFC_LEN_RDLEN;
  807. }
  808. else
  809. {
  810. /*
  811. * skip the pointer bytes (2), RR_TYPE, RR_CLASS, TTL, and
  812. * RDLENGTH flds
  813. */
  814. pTmp += RFC_LEN_RRPTR + RFC_LEN_RRTYP_N_RRCLS + RFC_LEN_TTL
  815. + RFC_LEN_RDLEN;
  816. }
  817. /*
  818. * RFC 1002 - page 12 and 14.
  819. *
  820. * First 16 buts of the RData section (right after the RDLEN section
  821. * has its top most bit set to 0 if the registration is for a group
  822. */
  823. *pfGrp = GROUP_BIT_MASK & *pTmp; // get the group bit
  824. /*
  825. *Next two MS bits indicate the node type
  826. */
  827. *pNodeTyp_e = (NODE_TYPE_MASK & *pTmp) >> SHIFT_NODE_BITS;
  828. /*
  829. * Get the IP address. IP address is 2 bytes away,
  830. */
  831. pTmp += 2;
  832. NONPORT("Port when porting to NON TCP/IP protocols")
  833. pCntAdd->NoOfAdds = 1;
  834. /*
  835. * Use ntohl to get the address which is a long in the correct
  836. * byte order
  837. */
  838. pTmpL = (LPLONG)pTmp;
  839. pCntAdd->Add[0].Add.IPAdd = ntohl(*pTmpL);
  840. pCntAdd->Add[0].AddTyp_e = COMM_ADD_E_TCPUDPIP;
  841. pCntAdd->Add[0].AddLen = sizeof(COMM_IP_ADD_T);
  842. if (Opcode_e == NMSMSGF_E_MULTIH_REG)
  843. {
  844. USHORT RdLen;
  845. USHORT NoOfAddsLeft;
  846. //
  847. // We are going to register a group of addresses
  848. //
  849. //
  850. // Extract the RDLEN (decrement the pointer)
  851. //
  852. RdLen = (USHORT)((*(pTmp - RFC_LEN_RDLEN_N_NBF) << 8) +
  853. *(pTmp - RFC_LEN_RDLEN_N_NBF + 1));
  854. NoOfAddsLeft = ((RdLen - RFC_LEN_NBFLAGS)/COMM_IP_ADD_SIZE) - 1;
  855. if (NoOfAddsLeft >= NMSMSGF_MAX_NO_MULTIH_ADDS)
  856. {
  857. DBGPRINT0(FLOW, "The packet for multi-homed registration has more than the max. number of ip addresses supported for a multi-homed client. \n");
  858. WINSEVT_LOG_M(
  859. NoOfAddsLeft,
  860. WINS_EVT_LIMIT_MULTIH_ADD_REACHED
  861. );
  862. NoOfAddsLeft = NMSMSGF_MAX_NO_MULTIH_ADDS - 1;
  863. }
  864. //
  865. // Get the remaining addresses
  866. //
  867. pTmp += RFC_LEN_NBADD;
  868. for(
  869. ; //null first expr
  870. pCntAdd->NoOfAdds < (DWORD)(NoOfAddsLeft + 1);
  871. pTmp += RFC_LEN_NBADD, pCntAdd->NoOfAdds++
  872. )
  873. {
  874. pCntAdd->Add[pCntAdd->NoOfAdds].Add.IPAdd =
  875. ntohl(*((LPLONG)pTmp));
  876. pCntAdd->Add[pCntAdd->NoOfAdds].AddTyp_e =
  877. COMM_ADD_E_TCPUDPIP;
  878. pCntAdd->Add[pCntAdd->NoOfAdds].AddLen =
  879. sizeof(COMM_IP_ADD_T);
  880. }
  881. }
  882. return(WINS_SUCCESS);
  883. }
  884. STATUS
  885. NmsMsgfFrmNamRspMsg(
  886. PCOMM_HDL_T pDlgHdl,
  887. NMSMSGF_NAM_REQ_TYP_E NamRspTyp_e,
  888. PNMSMSGF_RSP_INFO_T pRspInfo
  889. )
  890. /*++
  891. Routine Description:
  892. This function is called to format a response message for sending
  893. to an nbt node.
  894. Arguments:
  895. pDlgHdl -- Dlg Handle
  896. NameRspTye_e -- Type of response message (registration, query, release)
  897. that needs to be formatted.
  898. pRspInfo -- Response Info.
  899. Externals Used:
  900. None
  901. Called by:
  902. NmsNmhNamRegInd, NmsNmhNamRegGrp, NmsNmhNamRel, NmsNmhNamQuery
  903. Comments:
  904. None
  905. Return Value:
  906. Success status codes -- WINS_SUCCESS
  907. Error status codes -- WINS_FAILURE
  908. --*/
  909. {
  910. STATUS RetStat = WINS_SUCCESS;
  911. LPBYTE pReqBuff = pRspInfo->pMsg;
  912. LPBYTE pNewBuff = pReqBuff;
  913. //
  914. // Switch on type of response
  915. //
  916. switch(NamRspTyp_e)
  917. {
  918. case(NMSMSGF_E_NAM_REG): /* fall through */
  919. case(NMSMSGF_E_NAM_REF):
  920. case(NMSMSGF_E_NAM_REF_UB):
  921. (VOID)FrmNamRegRsp(
  922. pDlgHdl,
  923. pRspInfo
  924. );
  925. break;
  926. case(NMSMSGF_E_NAM_QUERY):
  927. #if 0
  928. FrmNamQueryRsp(
  929. pDlgHdl,
  930. pRspInfo
  931. );
  932. #endif
  933. (VOID)FormatQueryRspBuff(
  934. pNewBuff, //ptr to buffer to fill
  935. pReqBuff, // ptr to req buffer
  936. pRspInfo,
  937. FALSE //no danger of truncation since
  938. //we never send more than 25 ip add
  939. //in the response
  940. );
  941. break;
  942. case(NMSMSGF_E_NAM_REL):
  943. (VOID)FrmNamRelRsp(
  944. pDlgHdl,
  945. pRspInfo
  946. );
  947. break;
  948. default:
  949. // error
  950. RetStat = WINS_FAILURE;
  951. break;
  952. }
  953. return(RetStat);
  954. }
  955. STATUS
  956. FrmNamRegRsp(
  957. PCOMM_HDL_T pDlgHdl,
  958. PNMSMSGF_RSP_INFO_T pRspInfo
  959. )
  960. /*++
  961. Routine Description:
  962. This function formats a positive or a negative name registration
  963. response.
  964. Arguments:
  965. pDlgHdl -- Dialogue Handle
  966. pRspInfo -- Information used to format the response pkt
  967. Externals Used:
  968. None
  969. Called by:
  970. NmsMsgfFrmNamRspMsg
  971. Comments:
  972. None
  973. Return Value:
  974. Success status codes --
  975. Error status codes --
  976. --*/
  977. {
  978. LPBYTE pTmpB = pRspInfo->pMsg + 2;
  979. BYTE SavedByte;
  980. /*
  981. We will use the same buffer that carried the request. Simple
  982. moves will be done. These should be faster than doing
  983. all the construction from scratch
  984. */
  985. /*
  986. Set the the Transaction Id, Opcode, NMFlags and Rcode field
  987. */
  988. *pTmpB++ = RFC_NAM_REG_RSP_OPC;
  989. *pTmpB++ = RFC_NAM_REG_RSP_4THB + pRspInfo->Rcode_e;
  990. /*
  991. Set the QD count and the AN count fields
  992. */
  993. *pTmpB++ = RFC_NAM_REG_RSP_QDCNT_1STB;
  994. *pTmpB++ = RFC_NAM_REG_RSP_QDCNT_2NDB;
  995. *pTmpB++ = RFC_NAM_REG_RSP_ANCNT_1STB;
  996. *pTmpB++ = RFC_NAM_REG_RSP_ANCNT_2NDB;
  997. /*
  998. Set the NSCOUNT and ARCOUNT fields
  999. */
  1000. *pTmpB++ = RFC_NAM_REG_RSP_NSCNT_1STB;
  1001. *pTmpB++ = RFC_NAM_REG_RSP_NSCNT_2NDB;
  1002. *pTmpB++ = RFC_NAM_REG_RSP_ARCNT_1STB;
  1003. *pTmpB++ = RFC_NAM_REG_RSP_ARCNT_2NDB;
  1004. /*
  1005. Increment the pointer past the Question_Class Section
  1006. RR_NAME, RR_TYPE, and RR_CLASS of response are same as
  1007. Question_Name, Question_Type, and Question_Class of
  1008. nbt request.
  1009. */
  1010. pTmpB += pRspInfo->QuesNamSecLen + RFC_LEN_QTYP_N_QCLS;
  1011. SavedByte = *pTmpB & NAME_FORMAT_MASK; //save the format bits of RR section
  1012. CHECK("In case of a negative response, does it matter what I put in the TTL")
  1013. CHECK("field. It shouldn't matter -- RFC is silent about this")
  1014. //
  1015. // put the TTL in the response
  1016. //
  1017. *pTmpB++ = (BYTE)(pRspInfo->RefreshInterval >> 24);
  1018. *pTmpB++ = (BYTE)((pRspInfo->RefreshInterval >> 16) & 0xFF);
  1019. *pTmpB++ = (BYTE)((pRspInfo->RefreshInterval >> 8) & 0xFF);
  1020. *pTmpB++ = (BYTE)(pRspInfo->RefreshInterval & 0xFF);
  1021. /*
  1022. Move memory that is after RR_NAME into appropriate place
  1023. First we check what form the name in the RR_NAME section is.
  1024. It should be in pointer form (pointer to the QuesNamSec) but
  1025. could be in the regular form.
  1026. */
  1027. if (SavedByte == 0)
  1028. {
  1029. DWORD RRSecLen = pRspInfo->QuesNamSecLen + RFC_LEN_QTYP_N_QCLS;
  1030. // RR_NAME is as big as the Question_name section.
  1031. WINSMSC_MOVE_MEMORY_M(
  1032. pTmpB,
  1033. pTmpB + RRSecLen,
  1034. RFC_LEN_RDLEN_N_NBF_N_NBA
  1035. );
  1036. }
  1037. else
  1038. {
  1039. // RR_NAME is a ptr so it takes up 2 bytes.
  1040. WINSMSC_MOVE_MEMORY_M(
  1041. pTmpB,
  1042. pTmpB + RFC_LEN_RRPTR + RFC_LEN_RRTYP_N_RRCLS,
  1043. RFC_LEN_RDLEN_N_NBF_N_NBA
  1044. );
  1045. }
  1046. pTmpB += RFC_LEN_RDLEN_N_NBF_N_NBA;
  1047. pRspInfo->MsgLen = (ULONG) (pTmpB - (LPBYTE)pRspInfo->pMsg);
  1048. return(WINS_SUCCESS);
  1049. }
  1050. STATUS
  1051. FrmNamRelRsp(
  1052. PCOMM_HDL_T pDlgHdl,
  1053. PNMSMSGF_RSP_INFO_T pRspInfo
  1054. )
  1055. /*++
  1056. Routine Description:
  1057. This function formats a positive or negative name query response.
  1058. The request buffer is made use of for the response.
  1059. Arguments:
  1060. pDlgHdl -- Dialogue Handle
  1061. pRspInfo -- Response Info
  1062. Externals Used:
  1063. None
  1064. Called by:
  1065. NmsMsgfFrmRspMsg()
  1066. Comments:
  1067. None
  1068. Return Value:
  1069. Success status codes --
  1070. Error status codes --
  1071. --*/
  1072. {
  1073. LPBYTE pTmpB = pRspInfo->pMsg + 2;
  1074. //LPBYTE pTmpB2;
  1075. /*
  1076. We will use the same buffer that carried the request. Simple
  1077. moves will be done. These should be faster than doing
  1078. all the construction from scratch
  1079. */
  1080. /*
  1081. Set the the Transaction Id, Opcode, NMFlags and Rcode field
  1082. */
  1083. *pTmpB++ = RFC_NAM_REL_RSP_OPC;
  1084. *pTmpB++ = RFC_NAM_REL_RSP_4THB + pRspInfo->Rcode_e;
  1085. /*
  1086. Set the QD count and the AN count fields
  1087. */
  1088. *pTmpB++ = RFC_NAM_REL_RSP_QDCNT_1STB;
  1089. *pTmpB++ = RFC_NAM_REL_RSP_QDCNT_2NDB;
  1090. *pTmpB++ = RFC_NAM_REL_RSP_ANCNT_1STB;
  1091. *pTmpB++ = RFC_NAM_REL_RSP_ANCNT_2NDB;
  1092. /*
  1093. Set the NSCOUNT and ARCOUNT fields
  1094. */
  1095. *pTmpB++ = RFC_NAM_REL_RSP_NSCNT_1STB;
  1096. *pTmpB++ = RFC_NAM_REL_RSP_NSCNT_2NDB;
  1097. *pTmpB++ = RFC_NAM_REL_RSP_ARCNT_1STB;
  1098. *pTmpB++ = RFC_NAM_REL_RSP_ARCNT_2NDB;
  1099. /*
  1100. Increment the pointer past the Question_Class Section
  1101. RR_NAME, RR_TYPE, and RR_CLASS of response are same as
  1102. Question_Name, Question_Type, and Question_Class of
  1103. nbt request.
  1104. */
  1105. pTmpB += pRspInfo->QuesNamSecLen + RFC_LEN_QTYP_N_QCLS;
  1106. if ((*pTmpB & NAME_FORMAT_MASK) == 0)
  1107. {
  1108. DWORD RRSecLen = pRspInfo->QuesNamSecLen + RFC_LEN_QTYP_N_QCLS;
  1109. // RR_NAME is as big as the Question_name section.
  1110. WINSMSC_MOVE_MEMORY_M(
  1111. pTmpB,
  1112. pTmpB + RRSecLen,
  1113. RFC_LEN_TTL_N_RDLEN_N_NBF_N_NBA
  1114. );
  1115. }
  1116. else
  1117. {
  1118. // RR_NAME is a ptr so it takes up 2 bytes. 2 + 4 = 6
  1119. WINSMSC_MOVE_MEMORY_M(
  1120. pTmpB,
  1121. pTmpB + RFC_LEN_RRPTR + RFC_LEN_RRTYP_N_RRCLS,
  1122. RFC_LEN_TTL_N_RDLEN_N_NBF_N_NBA
  1123. );
  1124. }
  1125. pTmpB += RFC_LEN_TTL_N_RDLEN_N_NBF_N_NBA;
  1126. #if 0
  1127. // not needed. We always return the NBFLAGS and Address of the requestor
  1128. pTmpB2 = pTmpB - RFC_LEN_NBFLAGS - RFC_LEN_NBADD;
  1129. //
  1130. // Set the NBFLAGS field
  1131. //
  1132. if (pRspInfo->EntTyp == NMSDB_SPEC_GRP_ENTRY)
  1133. {
  1134. *pTmpB2++ = 0x80;
  1135. *pTmpB2++ = 0x00;
  1136. }
  1137. else
  1138. {
  1139. COMM_IP_ADD_T IPAdd = pRspInfo->pNodeAdds->Mem[0].Add.Add.IPAdd;
  1140. if (pRspInfo->EntTyp == NMSDB_NORM_GRP_ENTRY)
  1141. {
  1142. *pTmpB2++ = 0x80;
  1143. }
  1144. else //it is a unique entry
  1145. {
  1146. *pTmpB2++ = pRspInfo->NodeTyp_e << NMSDB_SHIFT_NODE_TYP;
  1147. }
  1148. *pTmpB2++ = 0x00;
  1149. *pTmpB2++ = (BYTE)(IPAdd >> 24); //MSB
  1150. *pTmpB2++ = (BYTE)((IPAdd >> 16) % 256);
  1151. *pTmpB2++ = (BYTE)((IPAdd >> 8) % 256);
  1152. *pTmpB2++ = (BYTE)(IPAdd % 256); //LSB
  1153. }
  1154. #endif
  1155. pRspInfo->MsgLen = (ULONG) (pTmpB - (LPBYTE)pRspInfo->pMsg);
  1156. return(WINS_SUCCESS);
  1157. }
  1158. #if 0
  1159. STATUS
  1160. FrmNamQueryRsp(
  1161. IN PCOMM_HDL_T pDlgHdl,
  1162. IN PNMSMSGF_RSP_INFO_T pRspInfo
  1163. )
  1164. /*++
  1165. Routine Description:
  1166. This function formats a name query response
  1167. Arguments:
  1168. pDlgHdl -- Dialogue Handle
  1169. pRspInfo -- Response Info
  1170. Externals Used:
  1171. None
  1172. Called by:
  1173. NmsNmhFrmRspMsg()
  1174. Comments:
  1175. None
  1176. Return Value:
  1177. Success status codes -- WINS_SUCCESS
  1178. Error status codes -- WINS_FAILURE
  1179. Comments: Not used currently. Will make use of it when we have the
  1180. potential to send more data than can fit in a query response
  1181. datagram
  1182. --*/
  1183. {
  1184. BOOL fTrunc = FALSE;
  1185. LPBYTE pReqBuff = pRspInfo->pMsg;
  1186. LPBYTE pNewBuff = pReqBuff;
  1187. STATUS RetStat = WINS_SUCCESS;
  1188. FUTURES("Currently, since we never send more than 25 addresses, there is no")
  1189. FUTURES(" danger of overflowing the buffer. In the future, if we ever change")
  1190. FUTURES("that, we should unconditinalize the code below, compile it and check")
  1191. FUTURES("it out. It needs to be modified. The computation of the size")
  1192. FUTURES("is faulty")
  1193. DWORD RspLen = 0;
  1194. BYTE *pTmpB = NULL;
  1195. /*
  1196. If this is to be sent as a datagram we will use the same buffer
  1197. that carries the request.
  1198. If it is to be sent on a TCP connection
  1199. we will still use the same buffer if it is a negative name query
  1200. response. If, however, a positive name query response has to be
  1201. sent, we will allocate a buffer storing the response
  1202. */
  1203. if ((!COMM_IS_TCP_MSG_M(pDlgHdl))
  1204. {
  1205. /*
  1206. In the following there is no need to check fGrp flag but
  1207. let us do it for insurance
  1208. */
  1209. if ((Rcode_e == NMSMSGF_E_SUCCESS) && (NodeAdds.fGrp))
  1210. {
  1211. /*
  1212. Check if we need to set the truncation bit in the
  1213. datagram.
  1214. To do the above,
  1215. Compute the size of the buffer required to house all
  1216. the information and compare with the datagram size
  1217. */
  1218. if (
  1219. (
  1220. RspLen = pDlgHdl->MsgLen + RFC_LEN_TTL_N_RDLEN +
  1221. (NodeAdds.NoOfMems * sizeof(COMM_IP_ADD_T))
  1222. )
  1223. > COMM_DATAGRAM_SIZE
  1224. )
  1225. {
  1226. fTrunc = TRUE;
  1227. }
  1228. }
  1229. }
  1230. else // TCP message with Rcode_e of success
  1231. {
  1232. if (
  1233. (
  1234. RspLen = *pMsgLen + RFC_LEN_TTL_N_RDLEN +
  1235. (NodeAdds.NoOfMems * sizeof(COMM_IP_ADD))
  1236. )
  1237. > COMM_DATAGRAM_SIZE
  1238. )
  1239. {
  1240. WinsMscAlloc(RspLen, &pNewBuff);
  1241. if (pNewBuff == NULL)
  1242. {
  1243. return(WINS_FAILURE);
  1244. }
  1245. }
  1246. *ppMsg = pNewBuff;
  1247. Status = FormatQueryRspBuff(
  1248. pNewBuff, //ptr to buffer to fill
  1249. pReqBuff, // ptr to req buffer
  1250. pRspInfo,
  1251. ftrunc
  1252. );
  1253. WinsMscHeapFree(
  1254. CommUdpBuffHeapHdl,
  1255. pReqBuff
  1256. ); // get rid of the old buffer
  1257. return(Status);
  1258. }
  1259. RetStat = FormatQueryRspBuff(
  1260. pNewBuff, //ptr to buffer to fill
  1261. pReqBuff, // ptr to req buffer
  1262. pRspInfo,
  1263. fTrunc
  1264. );
  1265. return(RetStat);
  1266. }
  1267. #endif
  1268. STATUS
  1269. FormatQueryRspBuff(
  1270. IN LPBYTE pDest,
  1271. IN LPBYTE pSrc,
  1272. IN PNMSMSGF_RSP_INFO_T pRspInfo,
  1273. IN BOOL fTrunc
  1274. )
  1275. /*++
  1276. Routine Description:
  1277. This function formats the response for a name query request
  1278. Arguments:
  1279. pDest - Buffer to contain the formatted response
  1280. pSrc - Buffer containing the formatted request
  1281. pRspInfo - Response Information
  1282. fTrunc - whether the response packet is to have the truncation bit set
  1283. Externals Used:
  1284. None
  1285. Called by:
  1286. FrmNamQueryRsp()
  1287. Comments:
  1288. None
  1289. Return Value:
  1290. Success status codes -- WINS_SUCCESS
  1291. Error status codes -- WINS_FAILURE
  1292. --*/
  1293. {
  1294. DWORD no;
  1295. LPBYTE pDestB = pDest;
  1296. DWORD LenOfAdds;
  1297. DWORD IPAdd;
  1298. *pDestB++ = *pSrc;
  1299. *pDestB++ = *(pSrc + 1);
  1300. /*
  1301. The Transaction Id, Opcode, NMFlags and Rcode field
  1302. */
  1303. *pDestB++ =
  1304. ( *(pSrc + 2) |
  1305. ((fTrunc == FALSE)
  1306. ? RFC_NAM_QUERY_RSP_OPC_NO_T
  1307. : RFC_NAM_QUERY_RSP_OPC_T)
  1308. );
  1309. *pDestB++ = RFC_NAM_QUERY_RSP_4THB + pRspInfo->Rcode_e;
  1310. /*
  1311. * Set the QD count and the AN count fields
  1312. */
  1313. *pDestB++ = RFC_NAM_QUERY_RSP_QDCNT_1STB;
  1314. *pDestB++ = RFC_NAM_QUERY_RSP_QDCNT_2NDB;
  1315. *pDestB++ = RFC_NAM_QUERY_RSP_ANCNT_1STB;
  1316. *pDestB++ = (pRspInfo->Rcode_e == NMSMSGF_E_SUCCESS) ?
  1317. RFC_NAM_QUERY_POS_RSP_ANCNT_2NDB
  1318. : RFC_NAM_QUERY_NEG_RSP_ANCNT_2NDB;
  1319. /*
  1320. Set the NSCOUNT and ARCOUNT fields
  1321. */
  1322. *pDestB++ = RFC_NAM_QUERY_RSP_NSCNT_1STB;
  1323. *pDestB++ = RFC_NAM_QUERY_RSP_NSCNT_2NDB;
  1324. *pDestB++ = RFC_NAM_QUERY_RSP_ARCNT_1STB;
  1325. *pDestB++ = RFC_NAM_QUERY_RSP_ARCNT_2NDB;
  1326. pSrc += pDestB - pDest;
  1327. /*
  1328. Increment the counter past the Question_Name Section (which is known
  1329. as the RR_NAME section here).
  1330. Use MoveMemory here instead of Copy Memory. Move Memory handles
  1331. overlapped copies which will happen if pDest and pSrc are
  1332. pointing to the same buffer
  1333. */
  1334. WINSMSC_MOVE_MEMORY_M(
  1335. pDestB,
  1336. pSrc,
  1337. pRspInfo->QuesNamSecLen
  1338. );
  1339. pDestB += pRspInfo->QuesNamSecLen;
  1340. if (pRspInfo->Rcode_e == NMSMSGF_E_SUCCESS)
  1341. {
  1342. *pDestB++ = RFC_NAM_QUERY_POS_RSP_NB_1STB; //RFC 1002 -- page 22
  1343. *pDestB++ = RFC_NAM_QUERY_POS_RSP_NB_2NDB; //RFC 1002 -- page 22
  1344. *pDestB++ = RFC_NAM_QUERY_POS_RSP_IN_1STB; //RFC 1002 -- page 22
  1345. *pDestB++ = RFC_NAM_QUERY_POS_RSP_IN_2NDB; //RFC 1002 -- page 22
  1346. }
  1347. else
  1348. {
  1349. *pDestB++ = RFC_NAM_QUERY_NEG_RSP_NB_1STB; //RFC 1002 -- page 22
  1350. *pDestB++ = RFC_NAM_QUERY_NEG_RSP_NB_2NDB; //RFC 1002 -- page 22
  1351. *pDestB++ = RFC_NAM_QUERY_NEG_RSP_IN_1STB; //RFC 1002 -- page 22
  1352. *pDestB++ = RFC_NAM_QUERY_NEG_RSP_IN_2NDB; //RFC 1002 -- page 22
  1353. }
  1354. if (!fTrunc)
  1355. {
  1356. if (pRspInfo->Rcode_e == NMSMSGF_E_SUCCESS)
  1357. {
  1358. CHECK("In case of a negative response, does it matter what I put in the TTL")
  1359. CHECK("field. It shouldn't matter -- RFC is silent about this")
  1360. /*
  1361. Put 0 in the TTL field. TTL field will not be looked at by the
  1362. Client.
  1363. */
  1364. *pDestB++ = 0;
  1365. *pDestB++ = 0;
  1366. *pDestB++ = 0;
  1367. *pDestB++ = 0;
  1368. //
  1369. // Get the RDLENGTH value
  1370. //
  1371. LenOfAdds = pRspInfo->pNodeAdds->NoOfMems *
  1372. (RFC_LEN_NBFLAGS + sizeof(COMM_IP_ADD_T));
  1373. *pDestB++ = (BYTE)(LenOfAdds >> 8); //MSB
  1374. *pDestB++ = (BYTE)(LenOfAdds % 256); //LSB
  1375. //
  1376. // Put the NBFLAGS here
  1377. //
  1378. if (
  1379. (pRspInfo->EntTyp != NMSDB_UNIQUE_ENTRY)
  1380. )
  1381. {
  1382. BYTE Nbflags;
  1383. DWORD StartIndex;
  1384. if ( pRspInfo->EntTyp == NMSDB_MULTIHOMED_ENTRY)
  1385. {
  1386. Nbflags =
  1387. pRspInfo->NodeTyp_e << NMSDB_SHIFT_NODE_TYP;
  1388. }
  1389. else
  1390. {
  1391. //
  1392. // it is a group (normal/special)
  1393. //
  1394. Nbflags = 0x80;
  1395. }
  1396. //
  1397. // It is a group (normal or special) or a multihomed
  1398. // entry
  1399. //
  1400. if (pRspInfo->pNodeAdds->NoOfMems &&
  1401. WinsCnf.fRandomize1CList &&
  1402. NMSDB_SPEC_GRP_ENTRY == pRspInfo->EntTyp ) {
  1403. StartIndex = rand() % pRspInfo->pNodeAdds->NoOfMems;;
  1404. } else {
  1405. StartIndex = 0;
  1406. }
  1407. for (no = StartIndex; no < pRspInfo->pNodeAdds->NoOfMems; no++)
  1408. {
  1409. *pDestB++ = Nbflags;
  1410. *pDestB++ = 0x0;
  1411. IPAdd = pRspInfo->pNodeAdds->Mem[no].Add.Add.IPAdd;
  1412. NMSMSGF_INSERT_IPADD_M(pDestB, IPAdd);
  1413. }
  1414. for (no = 0; no < StartIndex; no++)
  1415. {
  1416. *pDestB++ = Nbflags;
  1417. *pDestB++ = 0x0;
  1418. IPAdd = pRspInfo->pNodeAdds->Mem[no].Add.Add.IPAdd;
  1419. NMSMSGF_INSERT_IPADD_M(pDestB, IPAdd);
  1420. }
  1421. }
  1422. else
  1423. {
  1424. //
  1425. // It is a unique entry
  1426. //
  1427. *pDestB++ = pRspInfo->NodeTyp_e << NMSDB_SHIFT_NODE_TYP;
  1428. *pDestB++ = 0x0;
  1429. IPAdd = pRspInfo->pNodeAdds->Mem[0].Add.Add.IPAdd;
  1430. NMSMSGF_INSERT_IPADD_M(pDestB, IPAdd);
  1431. }
  1432. }
  1433. else //this is a negative name query response
  1434. {
  1435. /*
  1436. Put 0 in the TTL field. TTL field will not be looked at by the
  1437. Client.
  1438. */
  1439. *pDestB++ = 0;
  1440. *pDestB++ = 0;
  1441. *pDestB++ = 0;
  1442. *pDestB++ = 0;
  1443. /*
  1444. Put 0 in the RDLENGTH field since we are not passing any
  1445. address(es)
  1446. */
  1447. *pDestB++ = 0;
  1448. *pDestB++ = 0;
  1449. }
  1450. CHECK("When a truncated response is sent to the client, is it ok to not")
  1451. CHECK("Send any field after the RR_NAME section. RFC is silent about this")
  1452. CHECK("For now, it is ok, since we will never have a situation where a ")
  1453. CHECK("truncated response needs to be sent")
  1454. pRspInfo->MsgLen = (ULONG) (pDestB - pDest);
  1455. }
  1456. else
  1457. {
  1458. //this is a truncated response (does not have any field after
  1459. //RR_NAME section
  1460. pRspInfo->MsgLen = (ULONG) (pDestB - pDest);
  1461. }
  1462. return(WINS_SUCCESS);
  1463. }
  1464. VOID
  1465. FormatName(
  1466. IN LPBYTE pNameToFormat,
  1467. IN DWORD NamLen,
  1468. IN OUT LPBYTE *ppFormattedName
  1469. )
  1470. /*++
  1471. Routine Description:
  1472. This function is called to format a name
  1473. Arguments:
  1474. pNameToFormat -- Name to format
  1475. LengthOfName -- Length of Name
  1476. pFormattedName -- Name after it has been formatted
  1477. Externals Used:
  1478. None
  1479. Return Value:
  1480. Success status codes --
  1481. Error status codes --
  1482. Error Handling:
  1483. Called by:
  1484. Side Effects:
  1485. Comments:
  1486. Note: This function should be called to format only those names
  1487. whose length as indicated by NameLen includes the ending
  1488. 0. All names stored in the database are valid.
  1489. --*/
  1490. {
  1491. LPBYTE pTmpB = *ppFormattedName;
  1492. DWORD Length;
  1493. LPBYTE pSaveAdd = pTmpB; //save address of length octet
  1494. FUTURES("take out the check below to improve performance")
  1495. //
  1496. // If NamLen is more then what is prescribed in RFC 1002,
  1497. // there is something really wrong. This calls for raising
  1498. // an exception
  1499. //
  1500. if (NamLen > RFC_MAX_NAM_LEN)
  1501. {
  1502. WINS_RAISE_EXC_M(WINS_FATAL_ERR);
  1503. }
  1504. pTmpB++; //skip the length octet. We will write to
  1505. //it later. We have stored the address in
  1506. //pSaveAdd
  1507. NamLen--; //decrement Namelen since we always store
  1508. //0 at the end of the name. NameLen includes
  1509. //this extra byte
  1510. for (
  1511. Length = 0;
  1512. (*pNameToFormat != '.') && (NamLen != 0);
  1513. Length += 2, NamLen--
  1514. )
  1515. {
  1516. *pTmpB++ = 'A' + (*pNameToFormat >> 4);
  1517. *pTmpB++ = 'A' + (*pNameToFormat++ & 0x0F);
  1518. }
  1519. *pSaveAdd = (BYTE)Length;
  1520. while(NamLen != 0)
  1521. {
  1522. pNameToFormat++; //increment past the '.'
  1523. pSaveAdd = pTmpB++; //save add; skip past length octet
  1524. NamLen--; //to account for the '.'
  1525. for (
  1526. Length = 0;
  1527. (*pNameToFormat != '.') && (NamLen != 0);
  1528. Length++, NamLen--
  1529. )
  1530. {
  1531. *pTmpB++ = *pNameToFormat++;
  1532. }
  1533. FUTURES("take out the check below to improve performance")
  1534. //
  1535. // Make sure there is no weirdness
  1536. //
  1537. if (Length > RFC_MAX_LABEL_LEN)
  1538. {
  1539. WINS_RAISE_EXC_M(WINS_FATAL_ERR);
  1540. }
  1541. *pSaveAdd = (BYTE)Length;
  1542. if (NamLen == 0)
  1543. {
  1544. break; //reached end of name
  1545. }
  1546. }
  1547. *pTmpB++ = EOS;
  1548. *ppFormattedName = pTmpB;
  1549. return;
  1550. }
  1551. VOID
  1552. NmsMsgfFrmNamQueryReq(
  1553. IN DWORD TransId,
  1554. IN MSG_T pMsg,
  1555. OUT PMSG_LEN_T pMsgLen,
  1556. IN LPBYTE pNameToFormat,
  1557. IN DWORD NameLen
  1558. )
  1559. /*++
  1560. Routine Description:
  1561. This function formats a name query request packet
  1562. Arguments:
  1563. TransId - Transaction Id. to use
  1564. pMsg - Msg Buffer to format
  1565. pMsgLen - Length of formatted message
  1566. pNameToFormat - Name to format
  1567. NameLen - Length of Name
  1568. Externals Used:
  1569. None
  1570. Return Value:
  1571. None
  1572. Error Handling:
  1573. Called by:
  1574. HandleWrkItm in nmschl.c
  1575. Side Effects:
  1576. Comments:
  1577. None
  1578. --*/
  1579. {
  1580. LPBYTE pTmpB = pMsg;
  1581. /*
  1582. * Put the Transaction Id in
  1583. */
  1584. *pTmpB++ = (BYTE)(TransId >> 8);
  1585. *pTmpB++ = (BYTE)(TransId & 0xFF);
  1586. *pTmpB++ = RFC_NAM_QUERY_REQ_OPCB;
  1587. *pTmpB++ = RFC_NAM_QUERY_REQ_4THB;
  1588. *pTmpB++ = RFC_NAM_QUERY_REQ_QDCNT_1STB;
  1589. *pTmpB++ = RFC_NAM_QUERY_REQ_QDCNT_2NDB;
  1590. *pTmpB++ = RFC_NAM_QUERY_REQ_ANCNT_1STB;
  1591. *pTmpB++ = RFC_NAM_QUERY_REQ_ANCNT_2NDB;
  1592. *pTmpB++ = RFC_NAM_QUERY_REQ_NSCNT_1STB;
  1593. *pTmpB++ = RFC_NAM_QUERY_REQ_NSCNT_2NDB;
  1594. *pTmpB++ = RFC_NAM_QUERY_REQ_ARCNT_1STB;
  1595. *pTmpB++ = RFC_NAM_QUERY_REQ_ARCNT_2NDB;
  1596. FormatName(pNameToFormat, NameLen, &pTmpB);
  1597. *pTmpB++ = RFC_NAM_QUERY_REQ_QTYP_1STB;
  1598. *pTmpB++ = RFC_NAM_QUERY_REQ_QTYP_2NDB;
  1599. *pTmpB++ = RFC_NAM_QUERY_REQ_QCLS_1STB;
  1600. *pTmpB++ = RFC_NAM_QUERY_REQ_QCLS_2NDB;
  1601. *pMsgLen = (ULONG) (pTmpB - pMsg);
  1602. return;
  1603. }
  1604. VOID
  1605. NmsMsgfFrmNamRelReq(
  1606. IN DWORD TransId,
  1607. IN MSG_T pMsg,
  1608. OUT PMSG_LEN_T pMsgLen,
  1609. IN LPBYTE pNameToFormat,
  1610. IN DWORD NameLen,
  1611. IN NMSMSGF_NODE_TYP_E NodeTyp_e,
  1612. IN PCOMM_ADD_T pNodeAdd
  1613. )
  1614. /*++
  1615. Routine Description:
  1616. This function formats a name release request packet
  1617. Arguments:
  1618. TransId - Transaction Id. to use
  1619. pMsg - Msg Buffer to format
  1620. pMsgLen - Length of formatted message
  1621. pNameToFormat - Name to format
  1622. NameLen - Length of Name
  1623. NodeTyp_e - Type of Node
  1624. NodeAdd - IP address of node
  1625. Externals Used:
  1626. None
  1627. Return Value:
  1628. None
  1629. Error Handling:
  1630. Called by:
  1631. HandleWrkItm() in nmschl.c
  1632. Side Effects:
  1633. Comments:
  1634. None
  1635. --*/
  1636. {
  1637. LPBYTE pTmpB = pMsg;
  1638. /*
  1639. * Put the Transaction Id in
  1640. */
  1641. *pTmpB++ = (BYTE)(TransId >> 8);
  1642. *pTmpB++ = (BYTE)(TransId & 0xFF);
  1643. *pTmpB++ = RFC_NAM_REL_REQ_OPCB;
  1644. *pTmpB++ = RFC_NAM_REL_REQ_4THB;
  1645. *pTmpB++ = RFC_NAM_REL_REQ_QDCNT_1STB;
  1646. *pTmpB++ = RFC_NAM_REL_REQ_QDCNT_2NDB;
  1647. *pTmpB++ = RFC_NAM_REL_REQ_ANCNT_1STB;
  1648. *pTmpB++ = RFC_NAM_REL_REQ_ANCNT_2NDB;
  1649. *pTmpB++ = RFC_NAM_REL_REQ_NSCNT_1STB;
  1650. *pTmpB++ = RFC_NAM_REL_REQ_NSCNT_2NDB;
  1651. *pTmpB++ = RFC_NAM_REL_REQ_ARCNT_1STB;
  1652. *pTmpB++ = RFC_NAM_REL_REQ_ARCNT_2NDB;
  1653. FormatName(pNameToFormat, NameLen, &pTmpB);
  1654. *pTmpB++ = RFC_NAM_REL_REQ_QTYP_1STB;
  1655. *pTmpB++ = RFC_NAM_REL_REQ_QTYP_2NDB;
  1656. *pTmpB++ = RFC_NAM_REL_REQ_QCLS_1STB;
  1657. *pTmpB++ = RFC_NAM_REL_REQ_QCLS_2NDB;
  1658. *pTmpB++ = 0xC0;
  1659. *pTmpB++ = 0x0C; //Name is at offset 12 from start of message
  1660. *pTmpB++ = RFC_NAM_REL_REQ_RRTYP_1STB;
  1661. *pTmpB++ = RFC_NAM_REL_REQ_RRTYP_2NDB;
  1662. *pTmpB++ = RFC_NAM_REL_REQ_RRCLS_1STB;
  1663. *pTmpB++ = RFC_NAM_REL_REQ_RRCLS_2NDB;
  1664. //
  1665. // TTL
  1666. //
  1667. *pTmpB++ = 0;
  1668. *pTmpB++ = 0;
  1669. *pTmpB++ = 0;
  1670. *pTmpB++ = 0;
  1671. //
  1672. // RDLENGTH field
  1673. //
  1674. *pTmpB++ = 0x0;
  1675. *pTmpB++ = 0x6; //number of bytes to follow
  1676. //
  1677. // NBFLAGS word (Bit 15 is Group bit (0); bit 13 and 14 are node
  1678. // type bits, rest of the bits are reserved
  1679. //
  1680. *pTmpB++ = NodeTyp_e << 13;
  1681. *pTmpB++ = 0;
  1682. //
  1683. // Store the IP address. MSB first, LSB last (Network Byte Order)
  1684. //
  1685. NMSMSGF_INSERT_IPADD_M(pTmpB, pNodeAdd->Add.IPAdd);
  1686. *pMsgLen = (ULONG) (pTmpB - pMsg);
  1687. return;
  1688. }
  1689. VOID
  1690. NmsMsgfFrmWACK(
  1691. IN LPBYTE pBuff,
  1692. OUT LPDWORD pBuffLen,
  1693. IN MSG_T pMsg,
  1694. IN DWORD QuesNamSecLen,
  1695. IN DWORD WackTtl
  1696. )
  1697. /*++
  1698. Routine Description:
  1699. This function is called to format a WACK for a name registration
  1700. request.
  1701. Arguments:
  1702. Buff - Buffer to be filled up with WACK msg fields
  1703. pBuffLen - size of Buffer
  1704. pMsg - Request Message received
  1705. QuesNamSecLen - Length of Ques Nam Sec of the request message
  1706. WackTtl - TTL in msecs
  1707. Externals Used:
  1708. None
  1709. Return Value:
  1710. None
  1711. Error Handling:
  1712. Called by:
  1713. NmsChlHdlNamReg()
  1714. Side Effects:
  1715. Comments:
  1716. --*/
  1717. {
  1718. LPBYTE pTmpB = pBuff;
  1719. LPBYTE pName = pMsg + NAME_HEADER_SIZE;
  1720. DWORD Ttl;
  1721. //
  1722. // Compute the TTL in secs (WackTtl is in msecs)
  1723. //
  1724. Ttl = WackTtl / 1000;
  1725. if (WackTtl % 1000 > 0)
  1726. {
  1727. Ttl++;
  1728. }
  1729. /*
  1730. * Put the Transaction Id in
  1731. */
  1732. *pTmpB++ = *pMsg;
  1733. *pTmpB++ = *(pMsg + 1);
  1734. *pTmpB++ = RFC_WACK_OPCB;
  1735. *pTmpB++ = RFC_WACK_4THB;
  1736. *pTmpB++ = RFC_WACK_QDCNT_1STB;
  1737. *pTmpB++ = RFC_WACK_QDCNT_2NDB;
  1738. *pTmpB++ = RFC_WACK_ANCNT_1STB;
  1739. *pTmpB++ = RFC_WACK_ANCNT_2NDB;
  1740. *pTmpB++ = RFC_WACK_NSCNT_1STB;
  1741. *pTmpB++ = RFC_WACK_NSCNT_2NDB;
  1742. *pTmpB++ = RFC_WACK_ARCNT_1STB;
  1743. *pTmpB++ = RFC_WACK_ARCNT_2NDB;
  1744. WINSMSC_COPY_MEMORY_M(
  1745. pTmpB,
  1746. pName,
  1747. QuesNamSecLen
  1748. );
  1749. pTmpB += QuesNamSecLen;
  1750. *pTmpB++ = RFC_WACK_RRTYP_1STB;
  1751. *pTmpB++ = RFC_WACK_RRTYP_2NDB;
  1752. *pTmpB++ = RFC_WACK_RRCLS_1STB;
  1753. *pTmpB++ = RFC_WACK_RRCLS_2NDB;
  1754. //
  1755. // TTL
  1756. //
  1757. *pTmpB++ = (BYTE)(Ttl >> 24);
  1758. *pTmpB++ = (BYTE)((Ttl >> 16) % 256);
  1759. *pTmpB++ = (BYTE)((Ttl >> 8) % 256);
  1760. *pTmpB++ = (BYTE)(Ttl % 256);
  1761. *pTmpB++ = RFC_WACK_RDLENGTH_1STB;
  1762. *pTmpB++ = RFC_WACK_RDLENGTH_2NDB;
  1763. //
  1764. // Store the Opcode and NM_FLAGS field. These fields can
  1765. // be retrieved directly from the 3rd and 4th byte of the message
  1766. //
  1767. *pTmpB++ = *(pMsg + 2);
  1768. *pTmpB++ = *(pMsg + 3);
  1769. *pBuffLen = (ULONG) (pTmpB - pBuff);
  1770. return;
  1771. }
  1772. STATUS
  1773. NmsMsgfUfmNamRsp(
  1774. IN LPBYTE pMsg,
  1775. OUT PNMSMSGF_NAM_REQ_TYP_E pOpcode_e,
  1776. OUT LPDWORD pTransId,
  1777. OUT LPBYTE pName,
  1778. OUT LPDWORD pNameLen,
  1779. OUT PNMSMSGF_CNT_ADD_T pCntAdd,
  1780. //OUT PCOMM_IP_ADD_T pIpAdd,
  1781. OUT PNMSMSGF_ERR_CODE_E pRcode_e,
  1782. OUT BOOL *fGroup
  1783. )
  1784. /*++
  1785. Routine Description:
  1786. The function unformats the response message
  1787. Arguments:
  1788. pMsg - Msg received (to unformat)
  1789. pOpcde_e - Opcode
  1790. pTransId - Transaction Id.
  1791. pName - Name
  1792. pNameLen - Name length returned.
  1793. pIpAdd - IP address
  1794. pRcode_e - error type (or success)
  1795. Externals Used:
  1796. None
  1797. Called by:
  1798. ProcRsp in NmsChl.c
  1799. Comments:
  1800. None
  1801. Return Value:
  1802. Success status codes -- WINS_SUCCESS
  1803. Error status codes -- WINS_FAILURE
  1804. --*/
  1805. {
  1806. LPBYTE pTmpB = pMsg;
  1807. //
  1808. // get the opcode. Extracts the 4 bits in the 3rd byte (bit 11-bit 14)
  1809. //
  1810. *pOpcode_e = (NMS_OPCODE_MASK & *(pTmpB + 2)) >> 3;
  1811. if ( (*pOpcode_e != NMSMSGF_E_NAM_QUERY) &&
  1812. (*pOpcode_e != NMSMSGF_E_NAM_REL)
  1813. )
  1814. {
  1815. *pOpcode_e = NMSMSGF_E_INV_REQ;
  1816. return(WINS_FAILURE);
  1817. }
  1818. //
  1819. // Get the transaction id
  1820. //
  1821. *pTransId = (DWORD)((*pTmpB << 8) + *(pTmpB + 1));
  1822. // *pTransId |= (DWORD)(*(pTmpB + 1));
  1823. //
  1824. // get the Rcode_e
  1825. //
  1826. *pRcode_e = *(pTmpB + 3) % 16;
  1827. /*
  1828. * make pTmpB point to the RR Section. All name request/response
  1829. * packets have a name header of standard size (RFC 1002) at the top
  1830. */
  1831. pTmpB += NAME_HEADER_SIZE;
  1832. /*
  1833. * Extract the name ind store in Name. GetName will update pTmp to
  1834. * point just beyond the name in the RR section
  1835. */
  1836. GetName(
  1837. &pTmpB,
  1838. pName,
  1839. pNameLen
  1840. );
  1841. //
  1842. // If it is a negative name query response we are done
  1843. //
  1844. if (
  1845. (*pOpcode_e == NMSMSGF_E_NAM_QUERY) &&
  1846. (*pRcode_e != NMSMSGF_E_SUCCESS)
  1847. )
  1848. {
  1849. return(WINS_SUCCESS);
  1850. }
  1851. else
  1852. {
  1853. DWORD i;
  1854. pTmpB += RFC_LEN_RR_N_TTL;
  1855. pCntAdd->NoOfAdds =
  1856. ((*pTmpB << 8) + *(pTmpB + 1))/RFC_LEN_NBF_N_NBA;
  1857. pTmpB += RFC_LEN_RDLEN;
  1858. // 15th bit in NBFLAGS indicates if this is a group name
  1859. *fGroup = (*pTmpB & 0x80 ? TRUE:FALSE);
  1860. pTmpB += RFC_LEN_NBFLAGS;
  1861. //
  1862. // we have either positive query response or a response to a
  1863. // release
  1864. //
  1865. for ( i = 0;
  1866. #if 0
  1867. i < min(pCntAdd->NoOfAdds, NMSMSGF_MAX_NO_MULTIH_ADDS);
  1868. #endif
  1869. i < min(pCntAdd->NoOfAdds, NMSMSGF_MAX_ADDRESSES_IN_UDP_PKT);
  1870. i++
  1871. )
  1872. {
  1873. //
  1874. // Get the IP address. This macro will increment pTmpB by
  1875. // 4
  1876. //
  1877. NMSMSGF_RETRIEVE_IPADD_M(pTmpB, pCntAdd->Add[i].Add.IPAdd);
  1878. pCntAdd->Add[i].AddTyp_e = COMM_ADD_E_TCPUDPIP;
  1879. pCntAdd->Add[i].AddLen = sizeof(PCOMM_IP_ADD_T);
  1880. pTmpB += RFC_LEN_NBFLAGS;
  1881. }
  1882. }
  1883. return(WINS_SUCCESS);
  1884. }
  1885. VOID
  1886. NmsMsgfSndNamRsp(
  1887. PCOMM_HDL_T pDlgHdl,
  1888. LPBYTE pMsg,
  1889. DWORD MsgLen,
  1890. DWORD BlockOfReq
  1891. )
  1892. {
  1893. NMSMSGF_NAM_REQ_TYP_E Opcode;
  1894. DWORD NameLen; //length of name
  1895. DWORD QuesNamSecLen; //length of question name section in
  1896. //packet
  1897. DWORD Length;
  1898. LPBYTE pTmp = (LPBYTE)pMsg;
  1899. LPBYTE pTmp2;
  1900. NMSMSGF_RSP_INFO_T RspInfo;
  1901. static DWORD sNoOfTimes = 0;
  1902. DBGPRINT1(DET, "NmsMsgfSndNamRsp: BlockOfReq is (%d)\n", BlockOfReq);
  1903. // get the opcode
  1904. Opcode = (NMS_OPCODE_MASK & *(pTmp + 2)) >> 3;
  1905. //
  1906. // if it is a release request, we drop the datagram
  1907. //
  1908. if (Opcode == NMSMSGF_E_NAM_REL)
  1909. {
  1910. ECommFreeBuff(pMsg);
  1911. ECommEndDlg(pDlgHdl);
  1912. return;
  1913. }
  1914. /*
  1915. * make pTmp point to the Question Section. All name request
  1916. * packets have a name header of standard size (RFC 1002) at the top
  1917. */
  1918. pTmp += NAME_HEADER_SIZE;
  1919. pTmp2 = pTmp;
  1920. NameLen = LENGTH_MASK & *pTmp;
  1921. pTmp += NameLen + 1; //pt pTmp to past the first label
  1922. NameLen /= 2;
  1923. while (TRUE)
  1924. {
  1925. if (*pTmp != 0)
  1926. {
  1927. if (NameLen > MAX_SIZE_INTERNAL_NAME)
  1928. {
  1929. ECommFreeBuff(pMsg);
  1930. ECommEndDlg(pDlgHdl);
  1931. return;
  1932. }
  1933. Length = LENGTH_MASK & *pTmp;
  1934. NameLen += Length + 1;
  1935. pTmp += Length + 1; //increment past length and label
  1936. }
  1937. else
  1938. {
  1939. pTmp++;
  1940. break;
  1941. }
  1942. }
  1943. QuesNamSecLen = (ULONG) (pTmp - pTmp2);
  1944. RspInfo.RefreshInterval = 300 * BlockOfReq; // 5 mts
  1945. RspInfo.Rcode_e = NMSMSGF_E_SUCCESS;
  1946. RspInfo.pMsg = pMsg;
  1947. RspInfo.MsgLen = MsgLen;
  1948. RspInfo.QuesNamSecLen = QuesNamSecLen;
  1949. NmsNmhSndNamRegRsp( pDlgHdl, &RspInfo );
  1950. return;
  1951. }
  1952. #if 0
  1953. STATUS
  1954. NmsMsgfFrmNamRegReq(
  1955. IN DWORD TransId,
  1956. IN MSG_T pMsg,
  1957. OUT PMSG_LEN_T pMsgLen,
  1958. IN LPBYTE pNameToFormat,
  1959. IN DWORD NameLen,
  1960. IN NMSMSGF_NODE_TYP_E NodeTyp_e,
  1961. IN PCOMM_ADD_T pNodeAdd
  1962. )
  1963. /*++
  1964. Routine Description:
  1965. This function is called to format a name registration request
  1966. Arguments:
  1967. Externals Used:
  1968. None
  1969. Return Value:
  1970. Success status codes --
  1971. Error status codes --
  1972. Error Handling:
  1973. Called by:
  1974. Side Effects:
  1975. Comments:
  1976. This fn gets called when a remote WINS has to be told to
  1977. increment the version number of
  1978. --*/
  1979. {
  1980. //
  1981. // Lets format a name release request since this is exactly the
  1982. // same as a name registration request except for the 2nd and
  1983. // 3rd bytes (counting from 0) which house the opcode and
  1984. // nmflags. We will set these bytes apprropriately after
  1985. // the following call
  1986. //
  1987. NmsMsgfNamRelReq(
  1988. TransId,
  1989. pMsg,
  1990. pMsgLen,
  1991. pNameToFormat,
  1992. NameLen,
  1993. NodeTyp_e,
  1994. pNodeAdd
  1995. );
  1996. *(pMsg + 2) = 0x29;
  1997. *(pMsg + 3) = 0x00;
  1998. return;
  1999. }
  2000. #endif
  2001.