648 lines
19 KiB
C
648 lines
19 KiB
C
|
|
//=============================================================================
|
|
// 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;
|
|
}
|