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.

640 lines
20 KiB

  1. //=============================================================================
  2. // MODULE: ccmp.c
  3. //
  4. // Description:
  5. //
  6. // Bloodhound Parser DLL for the Cluster Control Message Protocol
  7. //
  8. // Modification History
  9. //
  10. // Mike Massa 03/21/97 Created
  11. //=============================================================================
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. //
  15. // Constants
  16. //
  17. #define ClusterDefaultMaxNodes 16 // from clusdef.h
  18. #define ClusterMinNodeId 1 // from clusdef.h
  19. #define MAX_CLUSTER_SIZE ClusterDefaultMaxNodes
  20. #define BYTEL 8 // number of bits in a uint8
  21. #define BYTES_IN_CLUSTER ((MAX_CLUSTER_SIZE + BYTEL - 1) / BYTEL)
  22. #define BYTE(cluster, node) ( (cluster)[(node) / BYTEL] ) // byte# in array
  23. #define BIT(node) ( (node) % BYTEL ) // bit# in byte
  24. typedef UCHAR cluster_t [BYTES_IN_CLUSTER];
  25. typedef SHORT node_t;
  26. typedef union _CX_CLUSTERSCREEN {
  27. ULONG UlongScreen;
  28. cluster_t ClusterScreen;
  29. } CX_CLUSTERSCREEN;
  30. //
  31. // converts external node number to internal
  32. //
  33. #define LOWEST_NODENUM ((node_t)ClusterMinNodeId) // starting node number
  34. #define INT_NODE(ext_node) ((node_t)(ext_node - LOWEST_NODENUM))
  35. #define EXT_NODE(int_node) ((node_t)(int_node + LOWEST_NODENUM))
  36. #define CnpClusterScreenMember(c, i) \
  37. ((BOOLEAN)((BYTE(c,i) >> (BYTEL-1-BIT(i))) & 1))
  38. #define CnpClusterScreenInsert(c, i) \
  39. (BYTE(c, i) |= (1 << (BYTEL-1-BIT(i))))
  40. #define CnpClusterScreenDelete(c, i) \
  41. (BYTE(c, i) &= ~(1 << (BYTEL-1-BIT(i))))
  42. //
  43. // Types
  44. //
  45. typedef enum {
  46. CcmpInvalidMsgType = 0,
  47. CcmpHeartbeatMsgType = 1,
  48. CcmpPoisonMsgType = 2,
  49. CcmpMembershipMsgType = 3,
  50. CcmpMcastHeartbeatMsgType = 4
  51. } CCMP_MSG_TYPE;
  52. typedef enum {
  53. CcmpInvalidMsgCode = 0
  54. } CCMP_MSG_CODE;
  55. typedef struct {
  56. ULONG SeqNumber;
  57. ULONG AckNumber;
  58. } CCMP_HEARTBEAT_MSG, *PCCMP_HEARTBEAT_MSG;
  59. typedef struct {
  60. ULONG NodeCount;
  61. CX_CLUSTERSCREEN McastTargetNodes;
  62. } CCMP_MCAST_HEARTBEAT_HEADER, *PCCMP_MCAST_HEARTBEAT_MSG;
  63. typedef struct _CX_HB_NODE_INFO {
  64. ULONG SeqNumber;
  65. ULONG AckNumber;
  66. } CX_HB_NODE_INFO, *PCX_HB_NODE_INFO;
  67. typedef struct {
  68. ULONG SeqNumber;
  69. } CCMP_POISON_MSG, *PCCMP_POISON_MSG;
  70. typedef struct {
  71. UCHAR Type;
  72. UCHAR Code;
  73. USHORT Checksum;
  74. union {
  75. CCMP_HEARTBEAT_MSG Heartbeat;
  76. CCMP_POISON_MSG Poison;
  77. CCMP_MCAST_HEARTBEAT_HEADER McastHeartbeat;
  78. } Message;
  79. } CCMP_HEADER, *PCCMP_HEADER;
  80. //
  81. // Data
  82. //
  83. LPSTR HeartbeatTypeString = "Heartbeat";
  84. LPSTR MembershipTypeString = "Membership";
  85. LPSTR PoisonTypeString = "Poison";
  86. LPSTR UnknownTypeString = "Unknown";
  87. //=============================================================================
  88. // Forward references.
  89. //=============================================================================
  90. VOID WINAPIV CcmpFormatSummary(LPPROPERTYINST lpPropertyInst);
  91. DWORD WINAPIV CcmpFormatMcastNodeInfo(LPPROPERTYINST lpPropertyInst);
  92. DWORD WINAPIV CcmpFormatMcastNodeData(LPPROPERTYINST lpPropertyInst);
  93. LABELED_BYTE lbCcmpPacketTypes[] =
  94. {
  95. {
  96. CcmpHeartbeatMsgType,
  97. "Heartbeat"
  98. },
  99. {
  100. CcmpPoisonMsgType,
  101. "Poison"
  102. },
  103. {
  104. CcmpMembershipMsgType,
  105. "Membership"
  106. },
  107. {
  108. CcmpMcastHeartbeatMsgType,
  109. "Multicast Heartbeat"
  110. },
  111. };
  112. #define NUM_CCMP_PACKET_TYPES (sizeof(lbCcmpPacketTypes) / sizeof(LABELED_BYTE))
  113. SET sCcmpPacketTypes =
  114. {
  115. NUM_CCMP_PACKET_TYPES,
  116. lbCcmpPacketTypes
  117. };
  118. //=============================================================================
  119. // CCMP database.
  120. //=============================================================================
  121. #define CCMP_SUMMARY 0
  122. #define CCMP_TYPE 1
  123. #define CCMP_CODE 2
  124. #define CCMP_RESERVED 3
  125. #define CCMP_HB_SEQ_NUMBER 4
  126. #define CCMP_HB_ACK_NUMBER 5
  127. #define CCMP_POISON_SEQ_NUMBER 6
  128. #define CCMP_MCASTHB_NODE_COUNT 7
  129. #define CCMP_MCASTHB_NODE_DATA 8
  130. #define CCMP_MCASTHB_NODE_INFO 9
  131. #define CCMP_MCASTHB_NODE_MASK 10
  132. PROPERTYINFO CcmpDatabase[] =
  133. {
  134. { // CCMP_SUMMARY 0
  135. 0,0,
  136. "Summary",
  137. "Summary of the CCMP packet",
  138. PROP_TYPE_SUMMARY,
  139. PROP_QUAL_NONE,
  140. NULL,
  141. 132,
  142. CcmpFormatSummary},
  143. { // CCMP_TYPE 1
  144. 0,0,
  145. "Type",
  146. "Type of CCMP packet",
  147. PROP_TYPE_BYTE,
  148. PROP_QUAL_LABELED_SET,
  149. &sCcmpPacketTypes,
  150. FMT_STR_SIZE,
  151. FormatPropertyInstance},
  152. { // CCMP_CODE 2
  153. 0,0,
  154. "Code",
  155. "Identifying code (Type Specific)",
  156. PROP_TYPE_BYTE,
  157. PROP_QUAL_NONE,
  158. NULL,
  159. 80,
  160. FormatPropertyInstance},
  161. { // CCMP_RESERVED 3
  162. 0,0,
  163. "Reserved",
  164. "Reserved field",
  165. PROP_TYPE_WORD,
  166. PROP_QUAL_NONE,
  167. NULL,
  168. 80,
  169. FormatPropertyInstance},
  170. { // CCMP_HB_SEQ_NUMBER 4
  171. 0,0,
  172. "Sequence Number",
  173. "Sequence number identifying this heartbeat",
  174. PROP_TYPE_DWORD,
  175. PROP_QUAL_NONE,
  176. NULL,
  177. 80,
  178. FormatPropertyInstance},
  179. { // CCMP_HB_ACK_NUMBER 5
  180. 0,0,
  181. "Acknowledgement Number",
  182. "Acknowledgement of the last heartbeat received from the destination",
  183. PROP_TYPE_DWORD,
  184. PROP_QUAL_NONE,
  185. NULL,
  186. 80,
  187. FormatPropertyInstance},
  188. { // CCMP_POISON_SEQ_NUMBER 6
  189. 0,0,
  190. "Sequence Number",
  191. "Sequence number identifying this poison packet",
  192. PROP_TYPE_DWORD,
  193. PROP_QUAL_NONE,
  194. NULL,
  195. 80,
  196. FormatPropertyInstance},
  197. { // CCMP_MCASTHB_NODE_COUNT 7
  198. 0,0,
  199. "Node Count",
  200. "Maximum number of nodes for which this message contains data",
  201. PROP_TYPE_WORD,
  202. PROP_QUAL_NONE,
  203. NULL,
  204. 80,
  205. FormatPropertyInstance},
  206. { // CCMP_MCASTHB_NODE_DATA 8
  207. 0,0,
  208. "Multicast Node Data",
  209. "Array of heartbeat sequence and acknowledgement numbers",
  210. PROP_TYPE_SUMMARY,
  211. PROP_QUAL_NONE,
  212. NULL,
  213. 80,
  214. CcmpFormatMcastNodeData},
  215. { // CCMP_MCASTHB_NODE_INFO 9
  216. 0,0,
  217. "Multicast Node Info",
  218. "Heartbeat sequence and acknowledgement number for a target node",
  219. PROP_TYPE_SUMMARY,
  220. PROP_QUAL_NONE,
  221. NULL,
  222. 80,
  223. CcmpFormatMcastNodeInfo},
  224. { // CCMP_MCASTHB_NODE_MASK 10
  225. 0,0,
  226. "Multicast Target Node Mask",
  227. "Bitmask of nodes for which this heartbeat message contains data",
  228. PROP_TYPE_DWORD,
  229. PROP_QUAL_NONE,
  230. NULL,
  231. 80,
  232. FormatPropertyInstance},
  233. };
  234. DWORD nCcmpProperties = ((sizeof CcmpDatabase) / PROPERTYINFO_SIZE);
  235. //=============================================================================
  236. // FUNCTION: CcmpRegister()
  237. //
  238. // Modification History
  239. //
  240. // Steve Hiskey 07/07/94 Created
  241. //=============================================================================
  242. VOID WINAPI CcmpRegister(HPROTOCOL hCcmpProtocol)
  243. {
  244. register DWORD i;
  245. //=========================================================================
  246. // Create the property database.
  247. //=========================================================================
  248. CreatePropertyDatabase(hCcmpProtocol, nCcmpProperties);
  249. for(i = 0; i < nCcmpProperties; ++i)
  250. {
  251. AddProperty(hCcmpProtocol, &CcmpDatabase[i]);
  252. }
  253. }
  254. //=============================================================================
  255. // FUNCTION: Deregister()
  256. //
  257. // Modification History
  258. //
  259. // Steve Hiskey 07/07/94 Created
  260. //=============================================================================
  261. VOID WINAPI CcmpDeregister(HPROTOCOL hCcmpProtocol)
  262. {
  263. DestroyPropertyDatabase(hCcmpProtocol);
  264. }
  265. //=============================================================================
  266. // FUNCTION: CcmpRecognizeFrame()
  267. //
  268. // Modification History
  269. //
  270. // Steve Hiskey 07/07/94 Created
  271. //=============================================================================
  272. LPBYTE WINAPI CcmpRecognizeFrame(HFRAME hFrame, //... frame handle.
  273. LPBYTE MacFrame, //... Frame pointer.
  274. LPBYTE MyFrame, //... Relative pointer.
  275. DWORD MacType, //... MAC type.
  276. DWORD BytesLeft, //... Bytes left.
  277. HPROTOCOL hPreviousProtocol, //... Previous protocol or NULL if none.
  278. DWORD nPreviousProtocolOffset, //... Offset of previous protocol.
  279. LPDWORD ProtocolStatusCode, //... Pointer to return status code in.
  280. LPHPROTOCOL hNextProtocol, //... Next protocol to call (optional).
  281. LPDWORD InstData) //... Next protocol instance data.
  282. {
  283. CCMP_HEADER UNALIGNED * ccmpHeader = (CCMP_HEADER UNALIGNED *) MyFrame;
  284. LPBYTE lpNextByte = (LPBYTE) (ccmpHeader + 1);
  285. if (ccmpHeader->Type == CcmpMcastHeartbeatMsgType) {
  286. lpNextByte += (ccmpHeader->Message.McastHeartbeat.NodeCount * sizeof(CX_HB_NODE_INFO));
  287. *ProtocolStatusCode = PROTOCOL_STATUS_CLAIMED;
  288. } else {
  289. #ifdef SSP_DECODE
  290. *hNextProtocol = GetProtocolFromName("SSP");
  291. *ProtocolStatusCode = PROTOCOL_STATUS_NEXT_PROTOCOL;
  292. #else
  293. *ProtocolStatusCode = PROTOCOL_STATUS_CLAIMED;
  294. #endif
  295. }
  296. return lpNextByte;
  297. }
  298. //=============================================================================
  299. // FUNCTION: CcmpAttachProperties()
  300. //
  301. // Modification History
  302. //
  303. // Steve Hiskey 07/07/94 Created
  304. //=============================================================================
  305. LPBYTE WINAPI CcmpAttachProperties(HFRAME hFrame,
  306. LPBYTE Frame,
  307. LPBYTE MyFrame,
  308. DWORD MacType,
  309. DWORD BytesLeft,
  310. HPROTOCOL hPreviousProtocol,
  311. DWORD nPreviousProtocolOffset,
  312. DWORD InstData)
  313. {
  314. CCMP_HEADER UNALIGNED * ccmpHeader = (CCMP_HEADER UNALIGNED *) MyFrame;
  315. AttachPropertyInstance(hFrame,
  316. CcmpDatabase[CCMP_SUMMARY].hProperty,
  317. #ifdef SSP_DECODE
  318. sizeof(CCMP_HEADER),
  319. #else
  320. BytesLeft,
  321. #endif
  322. ccmpHeader,
  323. 0, 0, 0);
  324. AttachPropertyInstance(hFrame,
  325. CcmpDatabase[CCMP_TYPE].hProperty,
  326. sizeof(BYTE),
  327. &(ccmpHeader->Type),
  328. 0, 1, 0);
  329. AttachPropertyInstance(hFrame,
  330. CcmpDatabase[CCMP_CODE].hProperty,
  331. sizeof(BYTE),
  332. &(ccmpHeader->Code),
  333. 0, 1, 0);
  334. AttachPropertyInstance(hFrame,
  335. CcmpDatabase[CCMP_RESERVED].hProperty,
  336. sizeof(WORD),
  337. &(ccmpHeader->Checksum),
  338. 0, 1, 0);
  339. if (ccmpHeader->Type == CcmpHeartbeatMsgType) {
  340. AttachPropertyInstance(hFrame,
  341. CcmpDatabase[CCMP_HB_SEQ_NUMBER].hProperty,
  342. sizeof(DWORD),
  343. &(ccmpHeader->Message.Heartbeat.SeqNumber),
  344. 0, 1, 0);
  345. AttachPropertyInstance(hFrame,
  346. CcmpDatabase[CCMP_HB_ACK_NUMBER].hProperty,
  347. sizeof(DWORD),
  348. &(ccmpHeader->Message.Heartbeat.AckNumber),
  349. 0, 1, 0);
  350. } else if (ccmpHeader->Type == CcmpPoisonMsgType) {
  351. AttachPropertyInstance(hFrame,
  352. CcmpDatabase[CCMP_POISON_SEQ_NUMBER].hProperty,
  353. sizeof(DWORD),
  354. &(ccmpHeader->Message.Poison.SeqNumber),
  355. 0, 1, 0);
  356. } else if (ccmpHeader->Type == CcmpMcastHeartbeatMsgType) {
  357. CX_HB_NODE_INFO UNALIGNED * nodeInfo;
  358. DWORD i;
  359. //
  360. // Header
  361. //
  362. AttachPropertyInstance(hFrame,
  363. CcmpDatabase[CCMP_MCASTHB_NODE_COUNT].hProperty,
  364. sizeof(DWORD),
  365. &(ccmpHeader->Message.McastHeartbeat.NodeCount),
  366. 0, 1, 0);
  367. AttachPropertyInstance(hFrame,
  368. CcmpDatabase[CCMP_MCASTHB_NODE_MASK].hProperty,
  369. sizeof(DWORD),
  370. &(ccmpHeader->Message.McastHeartbeat.McastTargetNodes.UlongScreen),
  371. 0, 1, 0);
  372. //
  373. // Format the heartbeat data.
  374. //
  375. nodeInfo = (CX_HB_NODE_INFO UNALIGNED *)(ccmpHeader + 1);
  376. AttachPropertyInstance(hFrame,
  377. CcmpDatabase[CCMP_MCASTHB_NODE_DATA].hProperty,
  378. sizeof(nodeInfo[0]) * ccmpHeader->Message.McastHeartbeat.NodeCount,
  379. &(nodeInfo[0]),
  380. 0, 1, 0);
  381. for (i = ClusterMinNodeId;
  382. i < (DWORD) EXT_NODE(ccmpHeader->Message.McastHeartbeat.NodeCount);
  383. i++) {
  384. if (CnpClusterScreenMember(
  385. ccmpHeader->Message.McastHeartbeat.McastTargetNodes.ClusterScreen,
  386. INT_NODE(i)
  387. )) {
  388. AttachPropertyInstanceEx(hFrame,
  389. CcmpDatabase[CCMP_MCASTHB_NODE_INFO].hProperty,
  390. sizeof(nodeInfo[INT_NODE(i)]),
  391. &(nodeInfo[INT_NODE(i)]),
  392. sizeof(i),
  393. &i,
  394. 0, 2, 0);
  395. }
  396. }
  397. }
  398. return NULL;
  399. }
  400. //==============================================================================
  401. // FUNCTION: CcmpFormatMcastNodeData()
  402. //
  403. // Modification History
  404. //
  405. // David Dion 04/10/2001 Created
  406. //==============================================================================
  407. DWORD WINAPIV CcmpFormatMcastNodeData(LPPROPERTYINST lpPropertyInst)
  408. {
  409. wsprintf( lpPropertyInst->szPropertyText,
  410. "Node Data:"
  411. );
  412. return NMERR_SUCCESS;
  413. }
  414. //==============================================================================
  415. // FUNCTION: CcmpFormatMcastNodeInfo()
  416. //
  417. // Modification History
  418. //
  419. // David Dion 04/10/2001 Created
  420. //==============================================================================
  421. DWORD WINAPIV CcmpFormatMcastNodeInfo(LPPROPERTYINST lpPropertyInst)
  422. {
  423. DWORD Length;
  424. LPPROPERTYINSTEX lpPropertyInstEx = lpPropertyInst->lpPropertyInstEx;
  425. CX_HB_NODE_INFO UNALIGNED * nodeInfo = lpPropertyInstEx->lpData;
  426. DWORD node = (lpPropertyInstEx->Dword[0]);
  427. Length = wsprintf( lpPropertyInst->szPropertyText,
  428. "Node %u Heartbeat: Seq = %u (0x%x); Ack = %u (0x%x)",
  429. node,
  430. nodeInfo->SeqNumber,
  431. nodeInfo->SeqNumber,
  432. nodeInfo->AckNumber,
  433. nodeInfo->AckNumber
  434. );
  435. return NMERR_SUCCESS;
  436. }
  437. //==============================================================================
  438. // FUNCTION: CcmpFormatSummary()
  439. //
  440. // Modification History
  441. //
  442. // Steve Hiskey 07/07/94 Created
  443. //==============================================================================
  444. VOID WINAPIV CcmpFormatSummary(LPPROPERTYINST lpPropertyInst)
  445. {
  446. LPSTR typeString;
  447. LPSTR SummaryStr;
  448. DWORD Length;
  449. CCMP_HEADER UNALIGNED * ccmpHeader =
  450. (CCMP_HEADER UNALIGNED *) lpPropertyInst->lpData;
  451. if (ccmpHeader->Type == CcmpHeartbeatMsgType) {
  452. Length = wsprintf( lpPropertyInst->szPropertyText,
  453. "Heartbeat: Seq = %u (0x%x); Ack = %u (0x%x)",
  454. ccmpHeader->Message.Heartbeat.SeqNumber,
  455. ccmpHeader->Message.Heartbeat.SeqNumber,
  456. ccmpHeader->Message.Heartbeat.AckNumber,
  457. ccmpHeader->Message.Heartbeat.AckNumber
  458. );
  459. }
  460. else if (ccmpHeader->Type == CcmpPoisonMsgType) {
  461. Length = wsprintf( lpPropertyInst->szPropertyText,
  462. "Poison: Seq = %u (0x%x)",
  463. ccmpHeader->Message.Poison.SeqNumber,
  464. ccmpHeader->Message.Poison.SeqNumber
  465. );
  466. }
  467. else if (ccmpHeader->Type == CcmpMembershipMsgType) {
  468. Length = wsprintf( lpPropertyInst->szPropertyText,
  469. "Membership"
  470. );
  471. }
  472. else if (ccmpHeader->Type == CcmpMcastHeartbeatMsgType) {
  473. CX_HB_NODE_INFO UNALIGNED * nodeInfo;
  474. DWORD i;
  475. LPSTR strbuf = lpPropertyInst->szPropertyText;
  476. nodeInfo = (CX_HB_NODE_INFO UNALIGNED *)(ccmpHeader + 1);
  477. Length = wsprintf( strbuf,
  478. "Multicast Heartbeat: "
  479. );
  480. for (i = ClusterMinNodeId;
  481. i < (DWORD) EXT_NODE(ccmpHeader->Message.McastHeartbeat.NodeCount);
  482. i++) {
  483. if (CnpClusterScreenMember(
  484. ccmpHeader->Message.McastHeartbeat.McastTargetNodes.ClusterScreen,
  485. INT_NODE(i)
  486. )) {
  487. strbuf = (LPSTR)((PUCHAR)strbuf + Length);
  488. Length = wsprintf( strbuf,
  489. "(N%u: S%u, A%u) ",
  490. i,
  491. nodeInfo[INT_NODE(i)].SeqNumber,
  492. nodeInfo[INT_NODE(i)].AckNumber
  493. );
  494. }
  495. }
  496. }
  497. else {
  498. Length = wsprintf( lpPropertyInst->szPropertyText,
  499. "Unknown CCMP message type: %u",
  500. ccmpHeader->Type
  501. );
  502. }
  503. }
  504. //==============================================================================
  505. // FUNCTION: CcmpFormatProperties()
  506. //
  507. // Modification History
  508. //
  509. // Steve Hiskey 07/07/94 Created
  510. //==============================================================================
  511. DWORD WINAPI CcmpFormatProperties(HFRAME hFrame,
  512. LPBYTE MacFrame,
  513. LPBYTE FrameData,
  514. DWORD nPropertyInsts,
  515. LPPROPERTYINST p)
  516. {
  517. //=========================================================================
  518. // Format each property in the property instance table.
  519. //
  520. // The property-specific instance data was used to store the address of a
  521. // property-specific formatting function so all we do here is call each
  522. // function via the instance data pointer.
  523. //=========================================================================
  524. while (nPropertyInsts--)
  525. {
  526. ((FORMAT) p->lpPropertyInfo->InstanceData)(p);
  527. p++;
  528. }
  529. return NMERR_SUCCESS;
  530. }
  531.