|
|
//=============================================================================
// MODULE: RGP.c
//
// Description:
//
// Bloodhound parser RGP Protocol
//
// Modification History
//
// Steve Hiskey 07/19/96 Started
//=============================================================================
#include "precomp.h"
#pragma hdrstop
//
// a recent change to clusapi.h defined HNETWORK which collides with netmon's
// use of the same name. consequently, all defs for RGP have been pulled in
// so it can build
//
enum { RGP_EVT_POWERFAIL = 1, RGP_EVT_NODE_UNREACHABLE = 2, RGP_EVT_PHASE1_CLEANUP_DONE = 3, RGP_EVT_PHASE2_CLEANUP_DONE = 4, RGP_EVT_LATEPOLLPACKET = 5, RGP_EVT_CLOCK_TICK = 6, RGP_EVT_RECEIVED_PACKET = 7, };
typedef unsigned char uint8; typedef unsigned short uint16; typedef unsigned int uint32;
#define MAX_CLUSTER_SIZE 16
typedef SHORT node_t;
/* The cluster_t data type is a bit array with MAX_CLUSTER_SIZE
* bits. It is implemented as an array of MAX_CLUSTER_SIZE/8 * (rounded up) uint8s. */ #define BYTEL 8 /* number of bits in a uint8 */
#define BYTES_IN_CLUSTER ((MAX_CLUSTER_SIZE + BYTEL - 1) / BYTEL)
typedef uint8 cluster_t [BYTES_IN_CLUSTER];
typedef struct rgpinfo { uint32 version; uint32 seqnum; uint16 a_tick; /* in ms.== clockPeriod */ uint16 iamalive_ticks; /* number of ticks between imalive sends == sendHBRate */ uint16 check_ticks; /* number of imalive ticks before at least 1 imalive == rcvHBRate */ uint16 Min_Stage1_ticks; /* precomputed to be imalive_ticks*check_ticks */ cluster_t cluster; } rgpinfo_t;
/* Maximum payload of packets sent by Regroup is 56 bytes.
* This allows a maximum transport overhead of 8 bytes in the * ServerNet interrupt packet which has a size of 64 bytes. */ #define RGP_UNACK_PKTLEN 56 /*bytes*/
typedef struct { uint8 pktsubtype; uint8 subtype_specific[RGP_UNACK_PKTLEN - sizeof(uint8)]; } rgp_unseq_pkt_t;
/* Regroup unacknowledged packet subtypes */ #define RGP_UNACK_IAMALIVE (uint8) 1 /* I am alive packet */
#define RGP_UNACK_REGROUP (uint8) 2 /* regroup status packet */
#define RGP_UNACK_POISON (uint8) 3 /* poison packet */
typedef struct iamalive_pkt { uint8 pktsubtype; uint8 filler[3]; union { uint8 bytes[RGP_UNACK_PKTLEN - 4]; uint32 words[(RGP_UNACK_PKTLEN - 4)/4]; } testpattern; } iamalive_pkt_t;
typedef struct poison_pkt { uint8 pktsubtype; uint8 unused1; uint16 reason; uint32 seqno; uint8 activatingnode; uint8 causingnode; uint16 unused2; cluster_t initnodes; cluster_t endnodes; } poison_pkt_t;
typedef cluster_t connectivity_matrix_t[MAX_CLUSTER_SIZE];
typedef struct rgp_pkt { uint8 pktsubtype; uint8 stage; uint16 reason; uint32 seqno; uint8 activatingnode; uint8 causingnode; cluster_t hadpowerfail; cluster_t knownstage1; cluster_t knownstage2; cluster_t knownstage3; cluster_t knownstage4; cluster_t knownstage5; cluster_t pruning_result; connectivity_matrix_t connectivity_matrix; } rgp_pkt_t;
typedef struct { int event; union { node_t node; rgpinfo_t rgpinfo; } data; /* depends on the event */ rgp_unseq_pkt_t unseq_pkt; } rgp_msgbuf;
//=============================================================================
// Forward references.
//=============================================================================
VOID WINAPIV RGPFormatSummary(LPPROPERTYINST lpPropertyInst);
//=============================================================================
// Labeled RGP command set.
//=============================================================================
LABELED_DWORD EventID[] = { { RGP_EVT_POWERFAIL, "PowerFailure"}, { RGP_EVT_NODE_UNREACHABLE, "Node Unreachable"}, { RGP_EVT_PHASE1_CLEANUP_DONE,"Phase 1 Cleanup Done"}, { RGP_EVT_PHASE2_CLEANUP_DONE,"Phase 2 Cleanup Done"}, { RGP_EVT_LATEPOLLPACKET, "Late Poll Packet"}, { RGP_EVT_CLOCK_TICK, "Clock Tick"}, { RGP_EVT_RECEIVED_PACKET, "Received Packet"}, };
SET EventIDSET = { (sizeof EventID / sizeof(LABELED_DWORD)), EventID };
LABELED_WORD RegroupReason[] = { { RGP_EVT_POWERFAIL, "Power Failure"}, { RGP_EVT_NODE_UNREACHABLE, "Node Unreachable"}, { RGP_EVT_PHASE1_CLEANUP_DONE,"Phase 1 Cleanup Done"}, { RGP_EVT_PHASE2_CLEANUP_DONE,"Phase 2 Cleanup Done"}, { RGP_EVT_LATEPOLLPACKET, "Late Poll Packet"}, { RGP_EVT_CLOCK_TICK, "Clock Tick"}, { RGP_EVT_RECEIVED_PACKET, "Received Packet"}, };
SET RegroupReasonSET = { (sizeof RegroupReason / sizeof(LABELED_WORD)), RegroupReason };
LABELED_BYTE PacketType[] = { { RGP_UNACK_IAMALIVE, "IAmAlive" }, { RGP_UNACK_REGROUP, "Regroup" }, { RGP_UNACK_POISON, "Poison" }, };
SET PacketTypeSET = { (sizeof PacketType / sizeof(LABELED_BYTE)), PacketType };
//=============================================================================
// RGP database.
//=============================================================================
enum RGP_PROP_IDS { RGP_SUMMARY, RGP_EVENT, RGP_SRC_NODE, RGP_PACKET_TYPE, RGP_RGP_STAGE, RGP_REASON, RGP_SEQNO, RGP_ACTIVATING_NODE, RGP_CAUSING_NODE, };
PROPERTYINFO RGPDatabase[] = { { // RGP_SUMMARY
0,0, "Summary", "RGP packet", PROP_TYPE_SUMMARY, PROP_QUAL_NONE, 0, FORMAT_BUFFER_SIZE, RGPFormatSummary},
{ // RGP_EVENT
0,0, "Event ID", "RGP Event ID.", PROP_TYPE_DWORD, PROP_QUAL_LABELED_SET, &EventIDSET, FORMAT_BUFFER_SIZE, FormatPropertyInstance},
{ // RGP_SRC_NODE
0,0, "Source Node ID", "Source Node ID.", PROP_TYPE_WORD, PROP_QUAL_NONE, NULL, FORMAT_BUFFER_SIZE, FormatPropertyInstance},
{ // RGP_PACKET_TYPE
0,0, "Packet Type", "Packet Type.", // comment
PROP_TYPE_BYTE, PROP_QUAL_LABELED_SET, &PacketTypeSET, FORMAT_BUFFER_SIZE, FormatPropertyInstance},
{ // RGP_RGP_STAGE
0,0, "Stage", "Regroup Stage.", PROP_TYPE_BYTE, PROP_QUAL_NONE, NULL, FORMAT_BUFFER_SIZE, FormatPropertyInstance},
{ // RGP_REASON
0,0, "Reason", "Reason.", PROP_TYPE_WORD, PROP_QUAL_LABELED_SET, &RegroupReasonSET, FORMAT_BUFFER_SIZE, FormatPropertyInstance},
{ // RGP_SEQNO
0,0, "Sequence Number", "Sequence Number.", PROP_TYPE_DWORD, PROP_QUAL_NONE, NULL, FORMAT_BUFFER_SIZE, FormatPropertyInstance},
{ // RGP_ACTIVATING_NODE
0,0, "Activating Node ID", "Activating Node ID.", PROP_TYPE_BYTE, PROP_QUAL_NONE, NULL, FORMAT_BUFFER_SIZE, FormatPropertyInstance},
{ // RGP_CAUSING_NODE
0,0, "Causing Node ID", "Causing Node ID.", PROP_TYPE_BYTE, PROP_QUAL_NONE, NULL, FORMAT_BUFFER_SIZE, FormatPropertyInstance},
};
DWORD nRGPProperties = ((sizeof RGPDatabase) / PROPERTYINFO_SIZE);
//=============================================================================
// FUNCTION: RGPRegister()
//
// Modification History
//
// Steve Hiskey 07/19/96 Started
//=============================================================================
VOID WINAPI RGPRegister(HPROTOCOL hRGPProtocol) { register DWORD i;
//=========================================================================
// Create the property database.
//=========================================================================
CreatePropertyDatabase(hRGPProtocol, nRGPProperties);
for(i = 0; i < nRGPProperties; ++i) { AddProperty(hRGPProtocol, &RGPDatabase[i]); }
}
//=============================================================================
// FUNCTION: Deregister()
//
// Modification History
//
// Steve Hiskey 07/19/96 Started
//=============================================================================
VOID WINAPI RGPDeregister(HPROTOCOL hRGPProtocol) { DestroyPropertyDatabase(hRGPProtocol); }
//=============================================================================
// FUNCTION: RGPRecognizeFrame()
//
// Modification History
//
// Steve Hiskey 07/19/96 Started
//=============================================================================
LPBYTE WINAPI RGPRecognizeFrame(HFRAME hFrame, //... frame handle.
LPBYTE MacFrame, //... Frame pointer.
LPBYTE RGPFrame, //... Relative pointer.
DWORD MacType, //... MAC type.
DWORD BytesLeft, //... Bytes left.
HPROTOCOL hPreviousProtocol, //... Previous protocol or NULL if none.
DWORD nPreviousProtocolOffset, //... Offset of previous protocol.
LPDWORD ProtocolStatusCode, //... Pointer to return status code in.
LPHPROTOCOL hNextProtocol, //... Next protocol to call (optional).
LPDWORD InstData) //... Next protocol instance data.
{ #ifdef SSP_DECODE
*hNextProtocol = GetProtocolFromName("SSP"); *ProtocolStatusCode = PROTOCOL_STATUS_NEXT_PROTOCOL; #else
*ProtocolStatusCode = PROTOCOL_STATUS_CLAIMED; #endif
return NULL; }
//=============================================================================
// FUNCTION: RGPAttachProperties()
//
// Modification History
//
// Steve Hiskey 07/19/96 Started
//=============================================================================
LPBYTE WINAPI RGPAttachProperties(HFRAME hFrame, LPBYTE Frame, LPBYTE RGPFrame, DWORD MacType, DWORD BytesLeft, HPROTOCOL hPreviousProtocol, DWORD nPreviousProtocolOffset, DWORD InstData) {
rgp_msgbuf UNALIGNED * pMsgBuf = (rgp_msgbuf UNALIGNED *)RGPFrame;
AttachPropertyInstance(hFrame, RGPDatabase[RGP_SUMMARY].hProperty, #ifdef SSP_DECODE
sizeof(rgp_msgbuf), #else
BytesLeft, #endif
RGPFrame, 0, 0, 0);
switch ( pMsgBuf->event ) { case RGP_EVT_RECEIVED_PACKET: AttachPropertyInstance(hFrame, RGPDatabase[RGP_SRC_NODE].hProperty, sizeof(pMsgBuf->data.node), &pMsgBuf->data.node, 0, 1, // level
0); break;
default: AttachPropertyInstance(hFrame, RGPDatabase[RGP_EVENT].hProperty, sizeof(pMsgBuf->event), &pMsgBuf->event, 0, 1, // level
0); break; }
AttachPropertyInstance(hFrame, RGPDatabase[RGP_PACKET_TYPE].hProperty, sizeof(pMsgBuf->unseq_pkt.pktsubtype), &pMsgBuf->unseq_pkt.pktsubtype, 0, 1, // level
0);
switch(pMsgBuf->unseq_pkt.pktsubtype) {
case RGP_UNACK_REGROUP: { rgp_pkt_t UNALIGNED *pRgpPkt = (rgp_pkt_t UNALIGNED *) &(pMsgBuf->unseq_pkt);
AttachPropertyInstance(hFrame, RGPDatabase[RGP_RGP_STAGE].hProperty, sizeof(pRgpPkt->stage), &pRgpPkt->stage, 0, 1, // level
0);
AttachPropertyInstance(hFrame, RGPDatabase[RGP_REASON].hProperty, sizeof(pRgpPkt->reason), &pRgpPkt->reason, 0, 1, // level
0);
AttachPropertyInstance(hFrame, RGPDatabase[RGP_SEQNO].hProperty, sizeof(pRgpPkt->seqno), &pRgpPkt->seqno, 0, 1, // level
0);
AttachPropertyInstance(hFrame, RGPDatabase[RGP_ACTIVATING_NODE].hProperty, sizeof(pRgpPkt->activatingnode), &pRgpPkt->activatingnode, 0, 1, // level
0);
AttachPropertyInstance(hFrame, RGPDatabase[RGP_CAUSING_NODE].hProperty, sizeof(pRgpPkt->causingnode), &pRgpPkt->causingnode, 0, 1, // level
0);
} break;
case RGP_UNACK_IAMALIVE: { iamalive_pkt_t UNALIGNED *pIAmAlivePkt = (iamalive_pkt_t UNALIGNED *) &(pMsgBuf->unseq_pkt);
} break;
case RGP_UNACK_POISON: { poison_pkt_t UNALIGNED *pPoisonPkt = (poison_pkt_t UNALIGNED *) &(pMsgBuf->unseq_pkt);
AttachPropertyInstance(hFrame, RGPDatabase[RGP_REASON].hProperty, sizeof(pPoisonPkt->reason), &pPoisonPkt->reason, 0, 1, // level
0);
AttachPropertyInstance(hFrame, RGPDatabase[RGP_SEQNO].hProperty, sizeof(pPoisonPkt->seqno), &pPoisonPkt->seqno, 0, 1, // level
0);
AttachPropertyInstance(hFrame, RGPDatabase[RGP_ACTIVATING_NODE].hProperty, sizeof(pPoisonPkt->activatingnode), &pPoisonPkt->activatingnode, 0, 1, // level
0);
AttachPropertyInstance(hFrame, RGPDatabase[RGP_CAUSING_NODE].hProperty, sizeof(pPoisonPkt->causingnode), &pPoisonPkt->causingnode, 0, 1, // level
0);
} break;
default: break; }
return NULL; }
//==============================================================================
// FUNCTION: RGPFormatSummary()
//
// Modification History
//
// Steve Hiskey 07/19/96 Started
//==============================================================================
VOID WINAPIV RGPFormatSummary(LPPROPERTYINST lpPropertyInst) { DWORD Length; LPSTR EventStr; LPSTR PacketTypeStr; rgp_msgbuf UNALIGNED * pMsgBuf = (rgp_msgbuf UNALIGNED *) lpPropertyInst->lpData; rgp_pkt_t UNALIGNED *pRgpPkt = (rgp_pkt_t UNALIGNED *) &(pMsgBuf->unseq_pkt);
if (pMsgBuf->event == RGP_EVT_RECEIVED_PACKET) { Length = wsprintf ( lpPropertyInst->szPropertyText, "Src Node = %d", pMsgBuf->data.node ); } else { EventStr = LookupDwordSetString ( &EventIDSET, pMsgBuf->event );
Length = wsprintf( lpPropertyInst->szPropertyText, "Event (%d) %s", pMsgBuf->event, EventStr?EventStr:"Unknown" ); }
PacketTypeStr = LookupByteSetString ( &PacketTypeSET, pMsgBuf->unseq_pkt.pktsubtype );
Length += wsprintf ( &lpPropertyInst->szPropertyText[Length], ", %s", PacketTypeStr?PacketTypeStr:"Packet Type Unknown" );
if (pMsgBuf->unseq_pkt.pktsubtype == RGP_UNACK_REGROUP) { Length += wsprintf ( &lpPropertyInst->szPropertyText[Length], ", Stage = %d", pRgpPkt->stage );
Length += wsprintf ( &lpPropertyInst->szPropertyText[Length], ", Causing Node = %d", pRgpPkt->causingnode ); } else if (pMsgBuf->unseq_pkt.pktsubtype == RGP_UNACK_POISON) { Length += wsprintf ( &lpPropertyInst->szPropertyText[Length], ", Causing Node = %d", pRgpPkt->causingnode ); }
}
//==============================================================================
// FUNCTION: RGPFormatProperties()
//
// Modification History
//
// Steve Hiskey 07/19/96 Started
//==============================================================================
DWORD WINAPI RGPFormatProperties(HFRAME hFrame, LPBYTE MacFrame, LPBYTE FrameData, DWORD nPropertyInsts, LPPROPERTYINST p) { //=========================================================================
// Format each property in the property instance table.
//
// The property-specific instance data was used to store the address of a
// property-specific formatting function so all we do here is call each
// function via the instance data pointer.
//=========================================================================
while (nPropertyInsts--) { ((FORMAT) p->lpPropertyInfo->InstanceData)(p);
p++; }
return NMERR_SUCCESS; }
|