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.

647 lines
19 KiB

  1. //=============================================================================
  2. // MODULE: RGP.c
  3. //
  4. // Description:
  5. //
  6. // Bloodhound parser RGP Protocol
  7. //
  8. // Modification History
  9. //
  10. // Steve Hiskey 07/19/96 Started
  11. //=============================================================================
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. //
  15. // a recent change to clusapi.h defined HNETWORK which collides with netmon's
  16. // use of the same name. consequently, all defs for RGP have been pulled in
  17. // so it can build
  18. //
  19. enum
  20. {
  21. RGP_EVT_POWERFAIL = 1,
  22. RGP_EVT_NODE_UNREACHABLE = 2,
  23. RGP_EVT_PHASE1_CLEANUP_DONE = 3,
  24. RGP_EVT_PHASE2_CLEANUP_DONE = 4,
  25. RGP_EVT_LATEPOLLPACKET = 5,
  26. RGP_EVT_CLOCK_TICK = 6,
  27. RGP_EVT_RECEIVED_PACKET = 7,
  28. };
  29. typedef unsigned char uint8;
  30. typedef unsigned short uint16;
  31. typedef unsigned int uint32;
  32. #define MAX_CLUSTER_SIZE 16
  33. typedef SHORT node_t;
  34. /* The cluster_t data type is a bit array with MAX_CLUSTER_SIZE
  35. * bits. It is implemented as an array of MAX_CLUSTER_SIZE/8
  36. * (rounded up) uint8s.
  37. */
  38. #define BYTEL 8 /* number of bits in a uint8 */
  39. #define BYTES_IN_CLUSTER ((MAX_CLUSTER_SIZE + BYTEL - 1) / BYTEL)
  40. typedef uint8 cluster_t [BYTES_IN_CLUSTER];
  41. typedef struct rgpinfo
  42. {
  43. uint32 version;
  44. uint32 seqnum;
  45. uint16 a_tick; /* in ms.== clockPeriod */
  46. uint16 iamalive_ticks; /* number of ticks between imalive sends == sendHBRate */
  47. uint16 check_ticks; /* number of imalive ticks before at least 1 imalive == rcvHBRate */
  48. uint16 Min_Stage1_ticks; /* precomputed to be imalive_ticks*check_ticks */
  49. cluster_t cluster;
  50. } rgpinfo_t;
  51. /* Maximum payload of packets sent by Regroup is 56 bytes.
  52. * This allows a maximum transport overhead of 8 bytes in the
  53. * ServerNet interrupt packet which has a size of 64 bytes.
  54. */
  55. #define RGP_UNACK_PKTLEN 56 /*bytes*/
  56. typedef struct
  57. {
  58. uint8 pktsubtype;
  59. uint8 subtype_specific[RGP_UNACK_PKTLEN - sizeof(uint8)];
  60. } rgp_unseq_pkt_t;
  61. /* Regroup unacknowledged packet subtypes */
  62. #define RGP_UNACK_IAMALIVE (uint8) 1 /* I am alive packet */
  63. #define RGP_UNACK_REGROUP (uint8) 2 /* regroup status packet */
  64. #define RGP_UNACK_POISON (uint8) 3 /* poison packet */
  65. typedef struct iamalive_pkt
  66. {
  67. uint8 pktsubtype;
  68. uint8 filler[3];
  69. union
  70. {
  71. uint8 bytes[RGP_UNACK_PKTLEN - 4];
  72. uint32 words[(RGP_UNACK_PKTLEN - 4)/4];
  73. } testpattern;
  74. } iamalive_pkt_t;
  75. typedef struct poison_pkt
  76. {
  77. uint8 pktsubtype;
  78. uint8 unused1;
  79. uint16 reason;
  80. uint32 seqno;
  81. uint8 activatingnode;
  82. uint8 causingnode;
  83. uint16 unused2;
  84. cluster_t initnodes;
  85. cluster_t endnodes;
  86. } poison_pkt_t;
  87. typedef cluster_t connectivity_matrix_t[MAX_CLUSTER_SIZE];
  88. typedef struct rgp_pkt
  89. {
  90. uint8 pktsubtype;
  91. uint8 stage;
  92. uint16 reason;
  93. uint32 seqno;
  94. uint8 activatingnode;
  95. uint8 causingnode;
  96. cluster_t hadpowerfail;
  97. cluster_t knownstage1;
  98. cluster_t knownstage2;
  99. cluster_t knownstage3;
  100. cluster_t knownstage4;
  101. cluster_t knownstage5;
  102. cluster_t pruning_result;
  103. connectivity_matrix_t connectivity_matrix;
  104. } rgp_pkt_t;
  105. typedef struct
  106. {
  107. int event;
  108. union
  109. {
  110. node_t node;
  111. rgpinfo_t rgpinfo;
  112. } data; /* depends on the event */
  113. rgp_unseq_pkt_t unseq_pkt;
  114. } rgp_msgbuf;
  115. //=============================================================================
  116. // Forward references.
  117. //=============================================================================
  118. VOID WINAPIV RGPFormatSummary(LPPROPERTYINST lpPropertyInst);
  119. //=============================================================================
  120. // Labeled RGP command set.
  121. //=============================================================================
  122. LABELED_DWORD EventID[] =
  123. {
  124. { RGP_EVT_POWERFAIL, "PowerFailure"},
  125. { RGP_EVT_NODE_UNREACHABLE, "Node Unreachable"},
  126. { RGP_EVT_PHASE1_CLEANUP_DONE,"Phase 1 Cleanup Done"},
  127. { RGP_EVT_PHASE2_CLEANUP_DONE,"Phase 2 Cleanup Done"},
  128. { RGP_EVT_LATEPOLLPACKET, "Late Poll Packet"},
  129. { RGP_EVT_CLOCK_TICK, "Clock Tick"},
  130. { RGP_EVT_RECEIVED_PACKET, "Received Packet"},
  131. };
  132. SET EventIDSET = { (sizeof EventID / sizeof(LABELED_DWORD)), EventID };
  133. LABELED_WORD RegroupReason[] =
  134. {
  135. { RGP_EVT_POWERFAIL, "Power Failure"},
  136. { RGP_EVT_NODE_UNREACHABLE, "Node Unreachable"},
  137. { RGP_EVT_PHASE1_CLEANUP_DONE,"Phase 1 Cleanup Done"},
  138. { RGP_EVT_PHASE2_CLEANUP_DONE,"Phase 2 Cleanup Done"},
  139. { RGP_EVT_LATEPOLLPACKET, "Late Poll Packet"},
  140. { RGP_EVT_CLOCK_TICK, "Clock Tick"},
  141. { RGP_EVT_RECEIVED_PACKET, "Received Packet"},
  142. };
  143. SET RegroupReasonSET = { (sizeof RegroupReason / sizeof(LABELED_WORD)), RegroupReason };
  144. LABELED_BYTE PacketType[] =
  145. {
  146. { RGP_UNACK_IAMALIVE, "IAmAlive" },
  147. { RGP_UNACK_REGROUP, "Regroup" },
  148. { RGP_UNACK_POISON, "Poison" },
  149. };
  150. SET PacketTypeSET = { (sizeof PacketType / sizeof(LABELED_BYTE)), PacketType };
  151. //=============================================================================
  152. // RGP database.
  153. //=============================================================================
  154. enum RGP_PROP_IDS
  155. {
  156. RGP_SUMMARY,
  157. RGP_EVENT,
  158. RGP_SRC_NODE,
  159. RGP_PACKET_TYPE,
  160. RGP_RGP_STAGE,
  161. RGP_REASON,
  162. RGP_SEQNO,
  163. RGP_ACTIVATING_NODE,
  164. RGP_CAUSING_NODE,
  165. };
  166. PROPERTYINFO RGPDatabase[] =
  167. {
  168. { // RGP_SUMMARY
  169. 0,0,
  170. "Summary",
  171. "RGP packet",
  172. PROP_TYPE_SUMMARY,
  173. PROP_QUAL_NONE,
  174. 0,
  175. FORMAT_BUFFER_SIZE,
  176. RGPFormatSummary},
  177. { // RGP_EVENT
  178. 0,0,
  179. "Event ID",
  180. "RGP Event ID.",
  181. PROP_TYPE_DWORD,
  182. PROP_QUAL_LABELED_SET,
  183. &EventIDSET,
  184. FORMAT_BUFFER_SIZE,
  185. FormatPropertyInstance},
  186. { // RGP_SRC_NODE
  187. 0,0,
  188. "Source Node ID",
  189. "Source Node ID.",
  190. PROP_TYPE_WORD,
  191. PROP_QUAL_NONE,
  192. NULL,
  193. FORMAT_BUFFER_SIZE,
  194. FormatPropertyInstance},
  195. { // RGP_PACKET_TYPE
  196. 0,0,
  197. "Packet Type",
  198. "Packet Type.", // comment
  199. PROP_TYPE_BYTE,
  200. PROP_QUAL_LABELED_SET,
  201. &PacketTypeSET,
  202. FORMAT_BUFFER_SIZE,
  203. FormatPropertyInstance},
  204. { // RGP_RGP_STAGE
  205. 0,0,
  206. "Stage",
  207. "Regroup Stage.",
  208. PROP_TYPE_BYTE,
  209. PROP_QUAL_NONE,
  210. NULL,
  211. FORMAT_BUFFER_SIZE,
  212. FormatPropertyInstance},
  213. { // RGP_REASON
  214. 0,0,
  215. "Reason",
  216. "Reason.",
  217. PROP_TYPE_WORD,
  218. PROP_QUAL_LABELED_SET,
  219. &RegroupReasonSET,
  220. FORMAT_BUFFER_SIZE,
  221. FormatPropertyInstance},
  222. { // RGP_SEQNO
  223. 0,0,
  224. "Sequence Number",
  225. "Sequence Number.",
  226. PROP_TYPE_DWORD,
  227. PROP_QUAL_NONE,
  228. NULL,
  229. FORMAT_BUFFER_SIZE,
  230. FormatPropertyInstance},
  231. { // RGP_ACTIVATING_NODE
  232. 0,0,
  233. "Activating Node ID",
  234. "Activating Node ID.",
  235. PROP_TYPE_BYTE,
  236. PROP_QUAL_NONE,
  237. NULL,
  238. FORMAT_BUFFER_SIZE,
  239. FormatPropertyInstance},
  240. { // RGP_CAUSING_NODE
  241. 0,0,
  242. "Causing Node ID",
  243. "Causing Node ID.",
  244. PROP_TYPE_BYTE,
  245. PROP_QUAL_NONE,
  246. NULL,
  247. FORMAT_BUFFER_SIZE,
  248. FormatPropertyInstance},
  249. };
  250. DWORD nRGPProperties = ((sizeof RGPDatabase) / PROPERTYINFO_SIZE);
  251. //=============================================================================
  252. // FUNCTION: RGPRegister()
  253. //
  254. // Modification History
  255. //
  256. // Steve Hiskey 07/19/96 Started
  257. //=============================================================================
  258. VOID WINAPI RGPRegister(HPROTOCOL hRGPProtocol)
  259. {
  260. register DWORD i;
  261. //=========================================================================
  262. // Create the property database.
  263. //=========================================================================
  264. CreatePropertyDatabase(hRGPProtocol, nRGPProperties);
  265. for(i = 0; i < nRGPProperties; ++i)
  266. {
  267. AddProperty(hRGPProtocol, &RGPDatabase[i]);
  268. }
  269. }
  270. //=============================================================================
  271. // FUNCTION: Deregister()
  272. //
  273. // Modification History
  274. //
  275. // Steve Hiskey 07/19/96 Started
  276. //=============================================================================
  277. VOID WINAPI RGPDeregister(HPROTOCOL hRGPProtocol)
  278. {
  279. DestroyPropertyDatabase(hRGPProtocol);
  280. }
  281. //=============================================================================
  282. // FUNCTION: RGPRecognizeFrame()
  283. //
  284. // Modification History
  285. //
  286. // Steve Hiskey 07/19/96 Started
  287. //=============================================================================
  288. LPBYTE WINAPI RGPRecognizeFrame(HFRAME hFrame, //... frame handle.
  289. LPBYTE MacFrame, //... Frame pointer.
  290. LPBYTE RGPFrame, //... Relative pointer.
  291. DWORD MacType, //... MAC type.
  292. DWORD BytesLeft, //... Bytes left.
  293. HPROTOCOL hPreviousProtocol, //... Previous protocol or NULL if none.
  294. DWORD nPreviousProtocolOffset, //... Offset of previous protocol.
  295. LPDWORD ProtocolStatusCode, //... Pointer to return status code in.
  296. LPHPROTOCOL hNextProtocol, //... Next protocol to call (optional).
  297. LPDWORD InstData) //... Next protocol instance data.
  298. {
  299. #ifdef SSP_DECODE
  300. *hNextProtocol = GetProtocolFromName("SSP");
  301. *ProtocolStatusCode = PROTOCOL_STATUS_NEXT_PROTOCOL;
  302. #else
  303. *ProtocolStatusCode = PROTOCOL_STATUS_CLAIMED;
  304. #endif
  305. return NULL;
  306. }
  307. //=============================================================================
  308. // FUNCTION: RGPAttachProperties()
  309. //
  310. // Modification History
  311. //
  312. // Steve Hiskey 07/19/96 Started
  313. //=============================================================================
  314. LPBYTE WINAPI RGPAttachProperties(HFRAME hFrame,
  315. LPBYTE Frame,
  316. LPBYTE RGPFrame,
  317. DWORD MacType,
  318. DWORD BytesLeft,
  319. HPROTOCOL hPreviousProtocol,
  320. DWORD nPreviousProtocolOffset,
  321. DWORD InstData)
  322. {
  323. rgp_msgbuf UNALIGNED * pMsgBuf = (rgp_msgbuf UNALIGNED *)RGPFrame;
  324. AttachPropertyInstance(hFrame,
  325. RGPDatabase[RGP_SUMMARY].hProperty,
  326. #ifdef SSP_DECODE
  327. sizeof(rgp_msgbuf),
  328. #else
  329. BytesLeft,
  330. #endif
  331. RGPFrame,
  332. 0, 0, 0);
  333. switch ( pMsgBuf->event )
  334. {
  335. case RGP_EVT_RECEIVED_PACKET:
  336. AttachPropertyInstance(hFrame,
  337. RGPDatabase[RGP_SRC_NODE].hProperty,
  338. sizeof(pMsgBuf->data.node),
  339. &pMsgBuf->data.node,
  340. 0,
  341. 1, // level
  342. 0);
  343. break;
  344. default:
  345. AttachPropertyInstance(hFrame,
  346. RGPDatabase[RGP_EVENT].hProperty,
  347. sizeof(pMsgBuf->event),
  348. &pMsgBuf->event,
  349. 0,
  350. 1, // level
  351. 0);
  352. break;
  353. }
  354. AttachPropertyInstance(hFrame,
  355. RGPDatabase[RGP_PACKET_TYPE].hProperty,
  356. sizeof(pMsgBuf->unseq_pkt.pktsubtype),
  357. &pMsgBuf->unseq_pkt.pktsubtype,
  358. 0,
  359. 1, // level
  360. 0);
  361. switch(pMsgBuf->unseq_pkt.pktsubtype) {
  362. case RGP_UNACK_REGROUP:
  363. {
  364. rgp_pkt_t UNALIGNED *pRgpPkt = (rgp_pkt_t UNALIGNED *)
  365. &(pMsgBuf->unseq_pkt);
  366. AttachPropertyInstance(hFrame,
  367. RGPDatabase[RGP_RGP_STAGE].hProperty,
  368. sizeof(pRgpPkt->stage),
  369. &pRgpPkt->stage,
  370. 0,
  371. 1, // level
  372. 0);
  373. AttachPropertyInstance(hFrame,
  374. RGPDatabase[RGP_REASON].hProperty,
  375. sizeof(pRgpPkt->reason),
  376. &pRgpPkt->reason,
  377. 0,
  378. 1, // level
  379. 0);
  380. AttachPropertyInstance(hFrame,
  381. RGPDatabase[RGP_SEQNO].hProperty,
  382. sizeof(pRgpPkt->seqno),
  383. &pRgpPkt->seqno,
  384. 0,
  385. 1, // level
  386. 0);
  387. AttachPropertyInstance(hFrame,
  388. RGPDatabase[RGP_ACTIVATING_NODE].hProperty,
  389. sizeof(pRgpPkt->activatingnode),
  390. &pRgpPkt->activatingnode,
  391. 0,
  392. 1, // level
  393. 0);
  394. AttachPropertyInstance(hFrame,
  395. RGPDatabase[RGP_CAUSING_NODE].hProperty,
  396. sizeof(pRgpPkt->causingnode),
  397. &pRgpPkt->causingnode,
  398. 0,
  399. 1, // level
  400. 0);
  401. }
  402. break;
  403. case RGP_UNACK_IAMALIVE:
  404. {
  405. iamalive_pkt_t UNALIGNED *pIAmAlivePkt =
  406. (iamalive_pkt_t UNALIGNED *)
  407. &(pMsgBuf->unseq_pkt);
  408. }
  409. break;
  410. case RGP_UNACK_POISON:
  411. {
  412. poison_pkt_t UNALIGNED *pPoisonPkt = (poison_pkt_t UNALIGNED *)
  413. &(pMsgBuf->unseq_pkt);
  414. AttachPropertyInstance(hFrame,
  415. RGPDatabase[RGP_REASON].hProperty,
  416. sizeof(pPoisonPkt->reason),
  417. &pPoisonPkt->reason,
  418. 0,
  419. 1, // level
  420. 0);
  421. AttachPropertyInstance(hFrame,
  422. RGPDatabase[RGP_SEQNO].hProperty,
  423. sizeof(pPoisonPkt->seqno),
  424. &pPoisonPkt->seqno,
  425. 0,
  426. 1, // level
  427. 0);
  428. AttachPropertyInstance(hFrame,
  429. RGPDatabase[RGP_ACTIVATING_NODE].hProperty,
  430. sizeof(pPoisonPkt->activatingnode),
  431. &pPoisonPkt->activatingnode,
  432. 0,
  433. 1, // level
  434. 0);
  435. AttachPropertyInstance(hFrame,
  436. RGPDatabase[RGP_CAUSING_NODE].hProperty,
  437. sizeof(pPoisonPkt->causingnode),
  438. &pPoisonPkt->causingnode,
  439. 0,
  440. 1, // level
  441. 0);
  442. }
  443. break;
  444. default:
  445. break;
  446. }
  447. return NULL;
  448. }
  449. //==============================================================================
  450. // FUNCTION: RGPFormatSummary()
  451. //
  452. // Modification History
  453. //
  454. // Steve Hiskey 07/19/96 Started
  455. //==============================================================================
  456. VOID WINAPIV RGPFormatSummary(LPPROPERTYINST lpPropertyInst)
  457. {
  458. DWORD Length;
  459. LPSTR EventStr;
  460. LPSTR PacketTypeStr;
  461. rgp_msgbuf UNALIGNED * pMsgBuf = (rgp_msgbuf UNALIGNED *)
  462. lpPropertyInst->lpData;
  463. rgp_pkt_t UNALIGNED *pRgpPkt = (rgp_pkt_t UNALIGNED *)
  464. &(pMsgBuf->unseq_pkt);
  465. if (pMsgBuf->event == RGP_EVT_RECEIVED_PACKET) {
  466. Length = wsprintf (
  467. lpPropertyInst->szPropertyText,
  468. "Src Node = %d",
  469. pMsgBuf->data.node
  470. );
  471. }
  472. else {
  473. EventStr = LookupDwordSetString ( &EventIDSET, pMsgBuf->event );
  474. Length = wsprintf(
  475. lpPropertyInst->szPropertyText,
  476. "Event (%d) %s",
  477. pMsgBuf->event,
  478. EventStr?EventStr:"Unknown"
  479. );
  480. }
  481. PacketTypeStr = LookupByteSetString (
  482. &PacketTypeSET,
  483. pMsgBuf->unseq_pkt.pktsubtype
  484. );
  485. Length += wsprintf (
  486. &lpPropertyInst->szPropertyText[Length],
  487. ", %s",
  488. PacketTypeStr?PacketTypeStr:"Packet Type Unknown"
  489. );
  490. if (pMsgBuf->unseq_pkt.pktsubtype == RGP_UNACK_REGROUP) {
  491. Length += wsprintf (
  492. &lpPropertyInst->szPropertyText[Length],
  493. ", Stage = %d",
  494. pRgpPkt->stage
  495. );
  496. Length += wsprintf (
  497. &lpPropertyInst->szPropertyText[Length],
  498. ", Causing Node = %d",
  499. pRgpPkt->causingnode
  500. );
  501. }
  502. else if (pMsgBuf->unseq_pkt.pktsubtype == RGP_UNACK_POISON) {
  503. Length += wsprintf (
  504. &lpPropertyInst->szPropertyText[Length],
  505. ", Causing Node = %d",
  506. pRgpPkt->causingnode
  507. );
  508. }
  509. }
  510. //==============================================================================
  511. // FUNCTION: RGPFormatProperties()
  512. //
  513. // Modification History
  514. //
  515. // Steve Hiskey 07/19/96 Started
  516. //==============================================================================
  517. DWORD WINAPI RGPFormatProperties(HFRAME hFrame,
  518. LPBYTE MacFrame,
  519. LPBYTE FrameData,
  520. DWORD nPropertyInsts,
  521. LPPROPERTYINST p)
  522. {
  523. //=========================================================================
  524. // Format each property in the property instance table.
  525. //
  526. // The property-specific instance data was used to store the address of a
  527. // property-specific formatting function so all we do here is call each
  528. // function via the instance data pointer.
  529. //=========================================================================
  530. while (nPropertyInsts--)
  531. {
  532. ((FORMAT) p->lpPropertyInfo->InstanceData)(p);
  533. p++;
  534. }
  535. return NMERR_SUCCESS;
  536. }