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.
1537 lines
49 KiB
1537 lines
49 KiB
//============================================================================
|
|
//
|
|
// Copyright (C) 2000 Microsoft Corporation
|
|
//
|
|
// FILE: PGM.c
|
|
//
|
|
// Description: Parses a PGM frame
|
|
// Displays the PGM header
|
|
// Displays the PGM options
|
|
//
|
|
// Note: info for this parser was gleaned from:
|
|
// (PGM Documentation)
|
|
//
|
|
// Modification History
|
|
//
|
|
// Madhurima Pawar ([email protected]) 08/04/00 Created
|
|
//============================================================================
|
|
|
|
#include "PGM.h"
|
|
|
|
//============================================================================
|
|
//Global variables
|
|
//============================================================================
|
|
|
|
HPROTOCOL hPGM = NULL; //Handle to PGM's parser database properties
|
|
DWORD PGMAttached = 0; //Number of times protocol instances that are running
|
|
|
|
//====================================================================
|
|
//External functions used to regester PGM. These function are exported to Netmon
|
|
//By putting a _delspec the function is immediatly exported and does not have to
|
|
//be exported through a .def file. This is useful when many parsers are in
|
|
//one dll and some are included and some are not.
|
|
//=================================================================================
|
|
|
|
extern VOID _declspec(dllexport) WINAPI PGM_Register( HPROTOCOL hPGM);
|
|
extern VOID _declspec(dllexport) WINAPI PGM_Deregister( HPROTOCOL hPGM);
|
|
extern LPBYTE _declspec(dllexport) WINAPI PGM_RecognizeFrame( HFRAME hFrame,
|
|
LPBYTE pMACFrame,
|
|
LPBYTE pPGMFrame,
|
|
DWORD PGMType,
|
|
DWORD BytesLeft,
|
|
HPROTOCOL hPrevProtocol,
|
|
DWORD nPrevProtOffset,
|
|
LPDWORD pProtocolStatus,
|
|
LPHPROTOCOL phNextProtocol,
|
|
PDWORD_PTR InstData);
|
|
extern LPBYTE _declspec(dllexport) WINAPI PGM_AttachProperties( HFRAME hFrame,
|
|
LPBYTE pMACFrame,
|
|
LPBYTE pPGMFrame,
|
|
DWORD PGMType,
|
|
DWORD BytesLeft,
|
|
HPROTOCOL hPrevProtocol,
|
|
DWORD nPrevProtOffset,
|
|
DWORD_PTR InstData);
|
|
extern DWORD _declspec(dllexport) WINAPI PGM_FormatProperties( HFRAME hFrame,
|
|
LPBYTE pMACFrame,
|
|
LPBYTE pPGMFrame,
|
|
DWORD nPropertyInsts,
|
|
LPPROPERTYINST p);
|
|
extern VOID WINAPIV PGM_FmtSummary( LPPROPERTYINST pPropertyInst );
|
|
|
|
//============================================================================
|
|
//Format functions customize the format of the data. Network Monitor
|
|
//provides baic format structures such as IP version 4 address.
|
|
//All other formats must be writen by the programmer.
|
|
//============================================================================
|
|
|
|
VOID WINAPIV PGM_FormatSummary( LPPROPERTYINST pPropertyInst);
|
|
|
|
//============================================================================
|
|
//Define the entry points that we will pass back to NetMon at dll
|
|
//entry time
|
|
//============================================================================
|
|
|
|
ENTRYPOINTS PGMEntryPoints =
|
|
{
|
|
PGM_Register,
|
|
PGM_Deregister,
|
|
PGM_RecognizeFrame,
|
|
PGM_AttachProperties,
|
|
PGM_FormatProperties,
|
|
};
|
|
|
|
//====================================================================
|
|
//Property Value Labels are tables that map numbers to strings.
|
|
//====================================================================
|
|
|
|
LABELED_BYTE PGMTypes[] = //The types of PGM
|
|
{
|
|
{ 0, "SPM" },
|
|
{ 1, "POLL" },
|
|
{ 2, "POLR" },
|
|
{ 4, "ODATA" },
|
|
{ 5, "RDATA" },
|
|
{ 8, "NACK" },
|
|
{ 9, "NNACK" },
|
|
{ 10, "NCF" } ,
|
|
};
|
|
|
|
LABELED_BIT PGMHeaderOptions[] =
|
|
{
|
|
{ 7, "Non-Parity ", "PARITY " },
|
|
{ 6, "Not a variable-length parity packet", "VARIABLE LENGTH PARITY PACKET" },
|
|
{ 1, "Not Network Significant ", "NETWORK SIGNIFICANT " },
|
|
{ 0, "No header Options ", "Packet header has options " },
|
|
};
|
|
|
|
LABELED_BIT PGMParityOptions[] =
|
|
{
|
|
{ 1, "No Pro-Active Parity ", "PRO-ACTIVE Parity enabled" },
|
|
{ 0, "Selective NAKs Only ", "ON-DEMAND Parity enabled " },
|
|
};
|
|
|
|
//====================================================================
|
|
//Make a set out of the above listings. The set contains the list
|
|
//aswell as the size
|
|
//====================================================================
|
|
|
|
SET PGMTypesSET = {(sizeof(PGMTypes)/sizeof(LABELED_BYTE)), PGMTypes };
|
|
SET PGMHeaderOptionsSET = {(sizeof(PGMHeaderOptions)/sizeof(LABELED_BIT)), PGMHeaderOptions };
|
|
SET PGMParityOptionsSET = {(sizeof(PGMParityOptions)/sizeof(LABELED_BIT)), PGMParityOptions };
|
|
|
|
//====================================================================
|
|
//PGM Database (Properties Table). This table stores the properties
|
|
//of each field in an PGM package. Each field property has a name,
|
|
//size and format function. FormatPropertyInstance is the standard
|
|
//NetMon formatter. The comment is the location of the property in
|
|
//the table
|
|
//====================================================================
|
|
|
|
PROPERTYINFO PGMPropertyTable[] =
|
|
{
|
|
|
|
// PGM_SUMMARY (0)
|
|
{ 0, 0,
|
|
"Summary",
|
|
"Summary of the PGM Packet",
|
|
PROP_TYPE_SUMMARY,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
PGM_FmtSummary
|
|
},
|
|
|
|
// PGM_SOURCE_PORT (1)
|
|
{ 0, 0,
|
|
"Source Port",
|
|
"Source Port",
|
|
PROP_TYPE_BYTESWAPPED_WORD,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_DESTINATION_PORT (2)
|
|
{ 0, 0,
|
|
"Destination Port",
|
|
"Destination Port",
|
|
PROP_TYPE_BYTESWAPPED_WORD,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_TYPE (3)
|
|
{ 0, 0,
|
|
"Type",
|
|
"Type of PGM",
|
|
PROP_TYPE_BYTE,
|
|
PROP_QUAL_LABELED_SET,
|
|
&PGMTypesSET,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_CHECKSUM (4)
|
|
{ 0, 0,
|
|
"Checksum",
|
|
"Checksum for PGM packet",
|
|
PROP_TYPE_BYTESWAPPED_WORD,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_GLOBAL_SOURCE_ID (5)
|
|
{ 0, 0,
|
|
"Global Source Id",
|
|
"Global Source Id for PGM session",
|
|
PROP_TYPE_STRING,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_TSDU_LENGTH (6)
|
|
{ 0, 0,
|
|
"TSDU Length",
|
|
"TSDU Length",
|
|
PROP_TYPE_BYTESWAPPED_WORD,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_SEQUENCE_NUMBER (7)
|
|
{ 0, 0,
|
|
"Sequence Number",
|
|
"Packet Sequence Number",
|
|
PROP_TYPE_BYTESWAPPED_DWORD,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_TRAILING_EDGE (8)
|
|
{ 0, 0,
|
|
"Trailing Edge",
|
|
"Trailing Edge Sequence Number",
|
|
PROP_TYPE_BYTESWAPPED_DWORD,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_LEADING_EDGE (9)
|
|
{ 0, 0,
|
|
"Leading Edge",
|
|
"Leading Edge Sequence Number",
|
|
PROP_TYPE_BYTESWAPPED_DWORD,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_NLA_TYPE_SOURCE (10)
|
|
{ 0, 0,
|
|
"Source Path NLA",
|
|
"Source Path NLA",
|
|
PROP_TYPE_SUMMARY,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_NLA_TYPE_MCAST_GROUP (11)
|
|
{ 0, 0,
|
|
"MCAST Group NLA",
|
|
"MCAST Group NLA",
|
|
PROP_TYPE_SUMMARY,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_NLA_AFI (12)
|
|
{ 0, 0,
|
|
"NLA AFI",
|
|
"NLA AFI",
|
|
PROP_TYPE_BYTESWAPPED_WORD,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_NLA_RESERVED (13)
|
|
{ 0, 0,
|
|
"NLA RESERVED",
|
|
"NLA RESERVED",
|
|
PROP_TYPE_BYTESWAPPED_WORD,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_NLA_IP (14)
|
|
{ 0, 0,
|
|
"NLA ADDRESS",
|
|
"NLA ADDRESS",
|
|
PROP_TYPE_IP_ADDRESS,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTIONS (15)
|
|
{ 0, 0,
|
|
"Options",
|
|
"Options of PGM Packet",
|
|
PROP_TYPE_BYTE,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTIONS_FLAGS (16)
|
|
{ 0, 0,
|
|
"Options Flags",
|
|
"Options Flags",
|
|
PROP_TYPE_BYTE,
|
|
PROP_QUAL_FLAGS,
|
|
&PGMHeaderOptionsSET,
|
|
PGM_FMT_STR_SIZE*4,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_HEADER_OPTIONS (17)
|
|
{ 0, 0,
|
|
"Pgm Header Options",
|
|
"Pgm Header Options",
|
|
PROP_TYPE_SUMMARY,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTION_TYPE_NAK_SEQ (18)
|
|
{ 0, 0,
|
|
"Nak / Ncf Sequences",
|
|
"Nak / Ncf Sequences",
|
|
PROP_TYPE_SUMMARY,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTION_TYPE_FRAGMENT (19)
|
|
{ 0, 0,
|
|
"Message Fragment",
|
|
"Message Fragment",
|
|
PROP_TYPE_SUMMARY,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTION_TYPE_LATE_JOINER (20)
|
|
{ 0, 0,
|
|
"Late Joiner",
|
|
"Late Joiner",
|
|
PROP_TYPE_SUMMARY,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTION_TYPE_SYN (21)
|
|
{ 0, 0,
|
|
"Session SYN",
|
|
"Session SYN",
|
|
PROP_TYPE_SUMMARY,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTION_TYPE_FIN (22)
|
|
{ 0, 0,
|
|
"Session FIN",
|
|
"Session FIN",
|
|
PROP_TYPE_SUMMARY,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTION_TYPE_RST (23)
|
|
{ 0, 0,
|
|
"Session Reset",
|
|
"Session Reset",
|
|
PROP_TYPE_SUMMARY,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTION_TYPE_PARITY_PRM (24)
|
|
{ 0, 0,
|
|
"Parity Parameters",
|
|
"Parity Parameters",
|
|
PROP_TYPE_SUMMARY,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTION_TYPE_PARITY_GRP (25)
|
|
{ 0, 0,
|
|
"Parity Group Option Present",
|
|
"Parity Group Option Present",
|
|
PROP_TYPE_SUMMARY,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTION_TYPE_PARITY_TGSIZE (26)
|
|
{ 0, 0,
|
|
"Parity Current TG Size Option Present",
|
|
"Parity Current TG Size Option Present",
|
|
PROP_TYPE_SUMMARY,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTIONS_FIELD_LENGTH (27)
|
|
{ 0, 0,
|
|
"Options Length",
|
|
"Options Length",
|
|
PROP_TYPE_BYTESWAPPED_WORD,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTIONS_NAK_SEQ (28)
|
|
{ 0, 0,
|
|
"Nak Sequence",
|
|
"Nak Sequence",
|
|
PROP_TYPE_BYTESWAPPED_DWORD,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTIONS_MESSAGE_FIRST_SEQUENCE (29)
|
|
{ 0, 0,
|
|
"Message First Sequence",
|
|
"Message First Sequence",
|
|
PROP_TYPE_BYTESWAPPED_DWORD,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTIONS_MESSAGE_OFFSET (30)
|
|
{ 0, 0,
|
|
"Message Offset",
|
|
"Message Offset",
|
|
PROP_TYPE_BYTESWAPPED_DWORD,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTIONS_MESSAGE_LENGTH (31)
|
|
{ 0, 0,
|
|
"Message Length",
|
|
"Message Length",
|
|
PROP_TYPE_BYTESWAPPED_DWORD,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTIONS_LATE_JOINER (32)
|
|
{ 0, 0,
|
|
"Late Joiner Sequence",
|
|
"Late Joiner Sequence",
|
|
PROP_TYPE_BYTESWAPPED_DWORD,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTIONS_PARITY_OPT (33)
|
|
{ 0, 0,
|
|
"Parity Flags",
|
|
"Parity Flags",
|
|
PROP_TYPE_BYTE,
|
|
PROP_QUAL_FLAGS,
|
|
&PGMParityOptionsSET,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTIONS_PARITY_PRM_GRP_SZ (34)
|
|
{ 0, 0,
|
|
"Parity Group Size",
|
|
"Parity Group Size",
|
|
PROP_TYPE_BYTESWAPPED_DWORD,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTIONS_PARITY_GRP (35)
|
|
{ 0, 0,
|
|
"Parity Group Number",
|
|
"Parity Group Number",
|
|
PROP_TYPE_BYTESWAPPED_DWORD,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_OPTIONS_PARITY_TG_SZ (36)
|
|
{ 0, 0,
|
|
"Parity TG Size",
|
|
"Parity TG Size",
|
|
PROP_TYPE_BYTESWAPPED_DWORD,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance
|
|
},
|
|
|
|
// PGM_DATA (37)
|
|
{ 0,0,
|
|
"Data",
|
|
"Data contained in PGM packet",
|
|
PROP_TYPE_RAW_DATA,
|
|
PROP_QUAL_NONE,
|
|
NULL,
|
|
PGM_FMT_STR_SIZE,
|
|
FormatPropertyInstance },
|
|
};
|
|
|
|
|
|
//====================================================================
|
|
//Number of entries in the property table above
|
|
//====================================================================
|
|
|
|
DWORD nNumPGMProps = (sizeof(PGMPropertyTable)/sizeof(PROPERTYINFO));
|
|
|
|
//============================================================================
|
|
//
|
|
// PGM_LoadParser - Tells Netmon which protocol precedes and follows PGM
|
|
//
|
|
// Modification history: June 30, 1999
|
|
//
|
|
// Madhurima Pawar 08/04/00 Created
|
|
//============================================================================
|
|
DWORD PGM_LoadParser(PPF_PARSERINFO pParserInfo)
|
|
{
|
|
DWORD NumberOfHandOffSets=1;
|
|
|
|
//
|
|
//This information is visible when the parser is selected in NetMon
|
|
//
|
|
wsprintf( pParserInfo->szProtocolName, "PGM" );
|
|
wsprintf( pParserInfo->szComment, "Pragmatic General Multicast (PGM)" );
|
|
wsprintf( pParserInfo->szHelpFile, "");
|
|
|
|
//
|
|
//Allocate memory for the handoffset and its two entries
|
|
//
|
|
pParserInfo->pWhoHandsOffToMe=(PPF_HANDOFFSET)
|
|
HeapAlloc (GetProcessHeap(),
|
|
HEAP_ZERO_MEMORY,
|
|
sizeof (PF_HANDOFFSET) +
|
|
sizeof (PF_HANDOFFENTRY) * (NumberOfHandOffSets));
|
|
|
|
if(NULL==pParserInfo->pWhoHandsOffToMe)
|
|
{
|
|
//
|
|
//Unable to create handoffset
|
|
//
|
|
return 1;
|
|
}
|
|
pParserInfo->pWhoHandsOffToMe->nEntries=NumberOfHandOffSets;
|
|
|
|
//
|
|
//Indicate the port that belong to PGM.
|
|
//
|
|
wsprintf (pParserInfo->pWhoHandsOffToMe->Entry[0].szIniFile, "TCPIP.INI");
|
|
wsprintf (pParserInfo->pWhoHandsOffToMe->Entry[0].szIniSection, "IP_HandoffSet");
|
|
wsprintf (pParserInfo->pWhoHandsOffToMe->Entry[0].szProtocol, "PGM");
|
|
pParserInfo->pWhoHandsOffToMe->Entry[0].dwHandOffValue = PGM_PROTOCOL_NUMBER;
|
|
pParserInfo->pWhoHandsOffToMe->Entry[0].ValueFormatBase = HANDOFF_VALUE_FORMAT_BASE_DECIMAL;
|
|
|
|
return 0;
|
|
}
|
|
|
|
//============================================================================
|
|
// Function: ParserAutoInstallInfo
|
|
//
|
|
// Description: Installs the parser into NetMon. Sets up the Handoff set
|
|
// The handoffset indicates which protocol hands of to the parser and
|
|
// who the parser hands of to.
|
|
//
|
|
//
|
|
// Modification History
|
|
//
|
|
// Madhurima Pawar 08/04/00 Created
|
|
//=============================================================================
|
|
PPF_PARSERDLLINFO WINAPI ParserAutoInstallInfo()
|
|
{
|
|
|
|
PPF_PARSERDLLINFO pParserDllInfo;
|
|
DWORD NumProtocols, Error;
|
|
|
|
//The number of protocols in this parser is 1
|
|
NumProtocols = 1;
|
|
|
|
//Allocate memory for parser info:
|
|
pParserDllInfo = (PPF_PARSERDLLINFO) HeapAlloc (GetProcessHeap(),
|
|
HEAP_ZERO_MEMORY,
|
|
sizeof (PF_PARSERDLLINFO) +
|
|
(NumProtocols) * sizeof (PF_PARSERINFO));
|
|
|
|
//Failed to allocate memory
|
|
if( pParserDllInfo == NULL)
|
|
{
|
|
//
|
|
//Unable to allocate memory
|
|
//
|
|
return NULL;
|
|
}
|
|
|
|
// fill in the parser DLL info
|
|
pParserDllInfo->nParsers = NumProtocols;
|
|
|
|
// fill in the individual parser infos...
|
|
Error = PGM_LoadParser (&(pParserDllInfo->ParserInfo[0]));
|
|
if(Error)
|
|
{
|
|
//
|
|
//Unable to allocate memory
|
|
//
|
|
return(NULL);
|
|
}
|
|
|
|
//Return the parser information to netmon
|
|
return (pParserDllInfo);
|
|
|
|
}
|
|
|
|
//============================================================================
|
|
// Function: DLLEntry
|
|
//
|
|
// Description: Registers the parser with Netmon and creates the PGM
|
|
// Properties table.
|
|
//
|
|
// Modification History
|
|
//
|
|
// Madhurima Pawar 08/04/00 Created
|
|
//=============================================================================
|
|
|
|
BOOL WINAPI DLLEntry( HANDLE hInstance, ULONG Command, LPVOID Reserved)
|
|
{
|
|
|
|
// what type of call is this
|
|
switch( Command )
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
|
|
// are we loading for the first time?
|
|
if (PGMAttached == 0)
|
|
{
|
|
// the first time in we need to tell the kernel
|
|
// about ourselves
|
|
//Create PGM db it PGM added to Parser
|
|
hPGM = CreateProtocol ("PGM", &PGMEntryPoints, ENTRYPOINTS_SIZE);
|
|
}
|
|
|
|
PGMAttached++;
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
|
|
// are we detaching our last instance?
|
|
PGMAttached--;
|
|
if( PGMAttached == 0 )
|
|
{
|
|
// last guy out needs to clean up
|
|
DestroyProtocol( hPGM);
|
|
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Netmon parsers ALWAYS return TRUE.
|
|
return TRUE;
|
|
}
|
|
|
|
//============================================================================
|
|
// Function: PGM_Register
|
|
//
|
|
// Description: Create our property database and handoff sets.
|
|
//
|
|
// Modification History
|
|
//
|
|
// Madhurima Pawar 08/04/00 Created
|
|
//============================================================================
|
|
|
|
VOID BHAPI PGM_Register( HPROTOCOL hPGM)
|
|
{
|
|
WORD i;
|
|
|
|
//
|
|
// tell the kernel to make reserve some space for our property table
|
|
//
|
|
CreatePropertyDatabase (hPGM, nNumPGMProps);
|
|
|
|
//
|
|
// add our properties to the kernel's database
|
|
//
|
|
for (i = 0; i < nNumPGMProps; i++)
|
|
{
|
|
AddProperty (hPGM, &PGMPropertyTable[i]);
|
|
}
|
|
|
|
}
|
|
|
|
//============================================================================
|
|
// Function: PGM_Deregister
|
|
//
|
|
// Description: Destroy our property database and handoff set
|
|
//
|
|
// Modification History
|
|
//
|
|
// Madhurima Pawar 08/04/00 Created
|
|
//============================================================================
|
|
|
|
VOID WINAPI PGM_Deregister( HPROTOCOL hPGM)
|
|
{
|
|
// tell the kernel that it may now free our database
|
|
DestroyPropertyDatabase (hPGM);
|
|
}
|
|
|
|
//============================================================================
|
|
// Function: PGM_RecognizeFrame
|
|
//
|
|
// Description: Determine whether we exist in the frame at the spot
|
|
// indicated. We also indicate who (if anyone) follows us
|
|
// and how much of the frame we claim.
|
|
//
|
|
//============================================================================
|
|
|
|
LPBYTE BHAPI PGM_RecognizeFrame( HFRAME hFrame,
|
|
LPBYTE pMacFrame,
|
|
LPBYTE pPGMFrame,
|
|
DWORD MacType,
|
|
DWORD BytesLeft,
|
|
HPROTOCOL hPrevProtocol,
|
|
DWORD nPrevProtOffset,
|
|
LPDWORD pProtocolStatus,
|
|
LPHPROTOCOL phNextProtocol,
|
|
PDWORD_PTR InstData)
|
|
{
|
|
//
|
|
// Since we do not know of any protocol currently on top of Pgm,
|
|
// we do not need to do much here.
|
|
//
|
|
#if 0
|
|
PPGM_COMMON_HDR pPGMHdr = (PPGM_COMMON_HDR) pPGMFrame;
|
|
SPM_PACKET_HEADER *pSpm = (SPM_PACKET_HEADER *) pPGMFrame;
|
|
DATA_PACKET_HEADER *pData = (DATA_PACKET_HEADER *) pPGMFrame;
|
|
NAK_NCF_PACKET_HEADER *pNakNcf = (NAK_NCF_PACKET_HEADER *) pPGMFrame;
|
|
DWORD BytesRequired = sizeof (PGM_COMMON_HDR);
|
|
BYTE PacketType;
|
|
tPACKET_OPTION_LENGTH UNALIGNED *pPacketExtension = NULL;
|
|
|
|
// do we have the minimum header
|
|
if (BytesLeft < BytesRequired)
|
|
{
|
|
//
|
|
// This not a valid Pgm frame
|
|
//
|
|
*pProtocolStatus = PROTOCOL_STATUS_NOT_RECOGNIZED;
|
|
return NULL;
|
|
}
|
|
|
|
PacketType = pPGMHdr->Type & 0x0f;
|
|
switch (PacketType)
|
|
{
|
|
case (PACKET_TYPE_SPM):
|
|
{
|
|
BytesRequired = sizeof (SPM_PACKET_HEADER);
|
|
pPacketExtension = (tPACKET_OPTION_LENGTH UNALIGNED *) (pSpm + 1);
|
|
break;
|
|
}
|
|
|
|
case (PACKET_TYPE_ODATA):
|
|
case (PACKET_TYPE_RDATA):
|
|
{
|
|
BytesRequired = sizeof (DATA_PACKET_HEADER);
|
|
pPacketExtension = (tPACKET_OPTION_LENGTH UNALIGNED *) (pData + 1);
|
|
break;
|
|
}
|
|
|
|
case (PACKET_TYPE_NAK):
|
|
case (PACKET_TYPE_NCF):
|
|
{
|
|
BytesTaken = sizeof (NAK_NCF_PACKET_HEADER);
|
|
pPacketExtension = (tPACKET_OPTION_LENGTH UNALIGNED *) (pNakNcf + 1);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
//
|
|
// This not a recognized Pgm frame
|
|
//
|
|
*pProtocolStatus = PROTOCOL_STATUS_NOT_RECOGNIZED;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if ((pPGMHdr->Options & PACKET_HEADER_OPTIONS_PRESENT) &&
|
|
(BytesLeft >= BytesRequired + (sizeof(tPACKET_OPTION_LENGTH) + sizeof(tPACKET_OPTION_GENERIC))))
|
|
{
|
|
BytesRequired += pPacketExtension->TotalOptionsLength;
|
|
}
|
|
|
|
// do we have a complete header
|
|
if (BytesLeft < BytesRequired)
|
|
{
|
|
//
|
|
// This not a valid Pgm frame
|
|
//
|
|
*pProtocolStatus = PROTOCOL_STATUS_NOT_RECOGNIZED;
|
|
return NULL;
|
|
}
|
|
|
|
|
|
if (BytesLeft <= BytesRequired)
|
|
{
|
|
// No protocol follows us so claim whole packet
|
|
*pProtocolStatus = PROTOCOL_STATUS_CLAIMED;
|
|
return NULL;
|
|
}
|
|
*pProtocolStatus = PROTOCOL_STATUS_RECOGNIZED;
|
|
|
|
return NULL;
|
|
#endif // 0
|
|
|
|
// this is a Pgm frame but we don't know the next protocol
|
|
*pProtocolStatus = PROTOCOL_STATUS_CLAIMED;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//============================================================================
|
|
//============================================================================
|
|
|
|
DWORD
|
|
ProcessOptions(
|
|
HFRAME hFrame,
|
|
tPACKET_OPTION_LENGTH UNALIGNED *pPacketExtension,
|
|
DWORD BytesLeft,
|
|
BYTE PacketType
|
|
)
|
|
{
|
|
tPACKET_OPTION_GENERIC UNALIGNED *pOptionHeader;
|
|
USHORT TotalOptionsLength;
|
|
DWORD BytesProcessed = 0;
|
|
UCHAR i;
|
|
|
|
if ((BytesLeft < ((sizeof(tPACKET_OPTION_LENGTH) + sizeof(tPACKET_OPTION_GENERIC)))) || // Ext+opt
|
|
(pPacketExtension->Type != PACKET_OPTION_LENGTH) ||
|
|
(pPacketExtension->Length != 4) ||
|
|
(BytesLeft < (TotalOptionsLength = ntohs (pPacketExtension->TotalOptionsLength)))) // Verify length
|
|
{
|
|
//
|
|
// Need to get at least our header from transport!
|
|
//
|
|
return (BytesProcessed);
|
|
}
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_HEADER_OPTIONS].hProperty,
|
|
TotalOptionsLength,
|
|
pPacketExtension,
|
|
0,1,0); // HELPID, Level, Errorflag
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTIONS_FIELD_LENGTH].hProperty,
|
|
sizeof (WORD),
|
|
&pPacketExtension->TotalOptionsLength,
|
|
0,2,0); // HELPID, Level, Errorflag
|
|
|
|
pOptionHeader = (tPACKET_OPTION_GENERIC UNALIGNED *) (pPacketExtension + 1);
|
|
BytesLeft -= PACKET_OPTION_LENGTH;
|
|
BytesProcessed += PGM_PACKET_EXTENSION_LENGTH;
|
|
|
|
do
|
|
{
|
|
if (pOptionHeader->Length > BytesLeft)
|
|
{
|
|
return (BytesProcessed);
|
|
}
|
|
|
|
switch (pOptionHeader->OptionType & ~PACKET_OPTION_TYPE_END_BIT)
|
|
{
|
|
case (PACKET_OPTION_NAK_LIST):
|
|
{
|
|
if (((PacketType != PACKET_TYPE_NAK) &&
|
|
(PacketType != PACKET_TYPE_NCF) &&
|
|
(PacketType != PACKET_TYPE_NNAK)) ||
|
|
(pOptionHeader->Length < PGM_PACKET_OPT_MIN_NAK_LIST_LENGTH) ||
|
|
(pOptionHeader->Length > PGM_PACKET_OPT_MAX_NAK_LIST_LENGTH))
|
|
{
|
|
return (BytesProcessed);
|
|
}
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTION_TYPE_NAK_SEQ].hProperty,
|
|
pOptionHeader->Length,
|
|
pOptionHeader,
|
|
0,2,0); // HELPID, Level, Errorflag
|
|
|
|
for (i=0; i < (pOptionHeader->Length-4)/4; i++)
|
|
{
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTIONS_NAK_SEQ].hProperty,
|
|
sizeof (DWORD),
|
|
&((PULONG)(pOptionHeader+1))[i],
|
|
0,3,0); // HELPID, Level, Errorflag
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case (PACKET_OPTION_FRAGMENT):
|
|
{
|
|
if (pOptionHeader->Length != PGM_PACKET_OPT_FRAGMENT_LENGTH)
|
|
{
|
|
return (BytesProcessed);
|
|
}
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTION_TYPE_FRAGMENT].hProperty,
|
|
PGM_PACKET_OPT_FRAGMENT_LENGTH,
|
|
pOptionHeader,
|
|
0,2,0); // HELPID, Level, Errorflag
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTIONS_MESSAGE_FIRST_SEQUENCE].hProperty,
|
|
sizeof (DWORD),
|
|
&((PULONG)(pOptionHeader+1))[0],
|
|
0,3,0); // HELPID, Level, Errorflag
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTIONS_MESSAGE_OFFSET].hProperty,
|
|
sizeof (DWORD),
|
|
&((PULONG)(pOptionHeader+1))[1],
|
|
0,3,0); // HELPID, Level, Errorflag
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTIONS_MESSAGE_LENGTH].hProperty,
|
|
sizeof (DWORD),
|
|
&((PULONG)(pOptionHeader+1))[2],
|
|
0,3,0); // HELPID, Level, Errorflag
|
|
|
|
break;
|
|
}
|
|
|
|
case (PACKET_OPTION_JOIN):
|
|
{
|
|
if (pOptionHeader->Length != PGM_PACKET_OPT_JOIN_LENGTH)
|
|
{
|
|
return (BytesProcessed);
|
|
}
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTION_TYPE_LATE_JOINER].hProperty,
|
|
PGM_PACKET_OPT_JOIN_LENGTH,
|
|
pOptionHeader,
|
|
0,2,0); // HELPID, Level, Errorflag
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTIONS_LATE_JOINER].hProperty,
|
|
sizeof (DWORD),
|
|
&((PULONG)(pOptionHeader+1))[0],
|
|
0,3,0); // HELPID, Level, Errorflag
|
|
|
|
break;
|
|
}
|
|
|
|
case (PACKET_OPTION_SYN):
|
|
{
|
|
if (pOptionHeader->Length != PGM_PACKET_OPT_SYN_LENGTH)
|
|
{
|
|
return (BytesProcessed);
|
|
}
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTION_TYPE_SYN].hProperty,
|
|
PGM_PACKET_OPT_SYN_LENGTH,
|
|
pOptionHeader,
|
|
0, 2, 0);
|
|
|
|
break;
|
|
}
|
|
|
|
case (PACKET_OPTION_FIN):
|
|
{
|
|
if (pOptionHeader->Length != PGM_PACKET_OPT_FIN_LENGTH)
|
|
{
|
|
return (BytesProcessed);
|
|
}
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTION_TYPE_FIN].hProperty,
|
|
PGM_PACKET_OPT_FIN_LENGTH,
|
|
pOptionHeader,
|
|
0, 2, 0);
|
|
|
|
break;
|
|
}
|
|
|
|
case (PACKET_OPTION_RST):
|
|
{
|
|
if (pOptionHeader->Length != PGM_PACKET_OPT_RST_LENGTH)
|
|
{
|
|
return (BytesProcessed);
|
|
}
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTION_TYPE_RST].hProperty,
|
|
PGM_PACKET_OPT_RST_LENGTH,
|
|
pOptionHeader,
|
|
0, 2, 0);
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// FEC options
|
|
//
|
|
case (PACKET_OPTION_PARITY_PRM):
|
|
{
|
|
if (pOptionHeader->Length != PGM_PACKET_OPT_PARITY_PRM_LENGTH)
|
|
{
|
|
return (BytesProcessed);
|
|
}
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTION_TYPE_PARITY_PRM].hProperty,
|
|
PGM_PACKET_OPT_PARITY_PRM_LENGTH,
|
|
pOptionHeader,
|
|
0, 2, 0);
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTIONS_PARITY_OPT].hProperty,
|
|
sizeof (BYTE),
|
|
&pOptionHeader->OptionSpecific,
|
|
0,3,0); // HELPID, Level, Errorflag
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTIONS_PARITY_PRM_GRP_SZ].hProperty,
|
|
sizeof (DWORD),
|
|
&((PULONG)(pOptionHeader+1))[0],
|
|
0,3,0); // HELPID, Level, Errorflag
|
|
|
|
break;
|
|
}
|
|
|
|
case (PACKET_OPTION_PARITY_GRP):
|
|
{
|
|
if (pOptionHeader->Length != PGM_PACKET_OPT_PARITY_GRP_LENGTH)
|
|
{
|
|
return (BytesProcessed);
|
|
}
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTION_TYPE_PARITY_GRP].hProperty,
|
|
PGM_PACKET_OPT_PARITY_GRP_LENGTH,
|
|
pOptionHeader,
|
|
0, 2, 0);
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTIONS_PARITY_GRP].hProperty,
|
|
sizeof (DWORD),
|
|
&((PULONG)(pOptionHeader+1))[0],
|
|
0,3,0); // HELPID, Level, Errorflag
|
|
|
|
break;
|
|
}
|
|
|
|
case (PACKET_OPTION_CURR_TGSIZE):
|
|
{
|
|
if (pOptionHeader->Length != PGM_PACKET_OPT_PARITY_CUR_TGSIZE_LENGTH)
|
|
{
|
|
return (BytesProcessed);
|
|
}
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTION_TYPE_PARITY_TGSIZE].hProperty,
|
|
PGM_PACKET_OPT_PARITY_CUR_TGSIZE_LENGTH,
|
|
pOptionHeader,
|
|
0, 2, 0);
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTIONS_PARITY_TG_SZ].hProperty,
|
|
sizeof (DWORD),
|
|
&((PULONG)(pOptionHeader+1))[0],
|
|
0,3,0); // HELPID, Level, Errorflag
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
return (BytesProcessed);
|
|
}
|
|
}
|
|
|
|
BytesLeft -= pOptionHeader->Length;
|
|
BytesProcessed += pOptionHeader->Length;
|
|
|
|
if (pOptionHeader->OptionType & PACKET_OPTION_TYPE_END_BIT)
|
|
{
|
|
break;
|
|
}
|
|
|
|
pOptionHeader = (tPACKET_OPTION_GENERIC UNALIGNED *)
|
|
(((UCHAR *) pOptionHeader) + pOptionHeader->Length);
|
|
|
|
} while (BytesLeft >= sizeof(tPACKET_OPTION_GENERIC));
|
|
|
|
return (BytesProcessed);
|
|
}
|
|
|
|
|
|
VOID
|
|
PGM_FmtNLA(
|
|
HFRAME hFrame,
|
|
NLA *pNLA,
|
|
BOOL fIsSourceNLA
|
|
)
|
|
{
|
|
//The type of the PGM frame
|
|
if (fIsSourceNLA)
|
|
{
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_NLA_TYPE_SOURCE].hProperty,
|
|
sizeof (NLA),
|
|
pNLA,
|
|
0,1,0); // HELPID, Level, Errorflag
|
|
}
|
|
else
|
|
{
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_NLA_TYPE_MCAST_GROUP].hProperty,
|
|
sizeof (NLA),
|
|
pNLA,
|
|
0,1,0); // HELPID, Level, Errorflag
|
|
}
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_NLA_AFI].hProperty,
|
|
sizeof (WORD),
|
|
&pNLA->NLA_AFI,
|
|
0,2,0); // HELPID, Level, Errorflag
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_NLA_RESERVED].hProperty,
|
|
sizeof (WORD),
|
|
&pNLA->Reserved,
|
|
0,2,0); // HELPID, Level, Errorflag
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_NLA_IP].hProperty,
|
|
sizeof (DWORD),
|
|
&pNLA->IpAddress,
|
|
0,2,0); // HELPID, Level, Errorflag
|
|
}
|
|
|
|
//============================================================================
|
|
// Function: PGM_AttachProperties
|
|
//
|
|
// Description: Indicate where in the frame each of our properties live.
|
|
//
|
|
// Modification History
|
|
//
|
|
// Madhurima Pawar 08/04/00 Created
|
|
//============================================================================
|
|
|
|
LPBYTE BHAPI PGM_AttachProperties( HFRAME hFrame,
|
|
LPBYTE pMacFrame,
|
|
LPBYTE pPGMFrame,
|
|
DWORD MacType,
|
|
DWORD BytesLeft,
|
|
HPROTOCOL hPrevProtocol,
|
|
DWORD nPrevProtOffset,
|
|
DWORD_PTR InstData)
|
|
|
|
{
|
|
PPGM_COMMON_HDR pPGMHdr = (PPGM_COMMON_HDR)pPGMFrame;
|
|
BYTE PacketType;
|
|
USHORT TSIPort;
|
|
UCHAR pGlobalSrcId [SOURCE_ID_LENGTH*2+1+sizeof(USHORT)*2+1];
|
|
SPM_PACKET_HEADER *pSpm = (SPM_PACKET_HEADER *) pPGMHdr;
|
|
DATA_PACKET_HEADER *pData = (DATA_PACKET_HEADER *) pPGMHdr;
|
|
NAK_NCF_PACKET_HEADER *pNakNcf = (NAK_NCF_PACKET_HEADER *) pPGMHdr;
|
|
tPACKET_OPTION_LENGTH *pOptionsHeader = NULL;
|
|
DWORD BytesTaken = 0;
|
|
DWORD OptionsLength = 0;
|
|
PUCHAR pPgmData;
|
|
|
|
PacketType = pPGMHdr->Type & 0x0f;
|
|
if ((PacketType == PACKET_TYPE_NAK) ||
|
|
(PacketType == PACKET_TYPE_NNAK) ||
|
|
(PacketType == PACKET_TYPE_SPMR) ||
|
|
(PacketType == PACKET_TYPE_POLR))
|
|
{
|
|
TSIPort = ntohs (pPGMHdr->DestPort);
|
|
}
|
|
else
|
|
{
|
|
TSIPort = ntohs (pPGMHdr->SrcPort);
|
|
}
|
|
|
|
wsprintf (pGlobalSrcId, "%02X%02X%02X%02X%02X%02X.%04X",
|
|
pPGMHdr->gSourceId[0],
|
|
pPGMHdr->gSourceId[1],
|
|
pPGMHdr->gSourceId[2],
|
|
pPGMHdr->gSourceId[3],
|
|
pPGMHdr->gSourceId[4],
|
|
pPGMHdr->gSourceId[5],
|
|
TSIPort);
|
|
|
|
//Add the PGM header information
|
|
//PGM summary information transaction ID and Message type
|
|
//Has a special formater PGM_FormatSummary
|
|
AttachPropertyInstance( hFrame,
|
|
PGMPropertyTable[PGM_SUMMARY].hProperty,
|
|
(WORD) BytesLeft,
|
|
(LPBYTE)pPGMFrame,
|
|
0, 0, 0 );
|
|
|
|
//The source port of the PGM frame
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_SOURCE_PORT].hProperty,
|
|
sizeof(WORD),
|
|
&pPGMHdr->SrcPort,
|
|
0, 1, 0);
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_DESTINATION_PORT].hProperty,
|
|
sizeof(WORD),
|
|
&pPGMHdr->DestPort,
|
|
0, 1, 0);
|
|
|
|
//The type of the PGM frame
|
|
AttachPropertyInstanceEx( hFrame,
|
|
PGMPropertyTable[PGM_TYPE].hProperty,
|
|
sizeof(BYTE),
|
|
&pPGMHdr->Type,
|
|
sizeof(BYTE),
|
|
&PacketType,
|
|
0, 1, 0);
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTIONS].hProperty,
|
|
sizeof (BYTE),
|
|
&pPGMHdr->Options,
|
|
0,1,0); // HELPID, Level, Errorflag
|
|
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_OPTIONS_FLAGS].hProperty,
|
|
sizeof (BYTE),
|
|
&pPGMHdr->Options,
|
|
0,2,0); // HELPID, Level, Errorflag
|
|
|
|
|
|
//The checksum of the PGM frame
|
|
AttachPropertyInstance( hFrame,
|
|
PGMPropertyTable[PGM_CHECKSUM].hProperty,
|
|
sizeof(WORD),
|
|
&(pPGMHdr->Checksum),
|
|
0, 1, 0);
|
|
|
|
//The Global Session Id
|
|
AttachPropertyInstanceEx (hFrame,
|
|
PGMPropertyTable[PGM_GLOBAL_SOURCE_ID].hProperty,
|
|
SOURCE_ID_LENGTH,
|
|
pPGMHdr->gSourceId,
|
|
(SOURCE_ID_LENGTH*2+1+sizeof(USHORT)*2+1),
|
|
pGlobalSrcId,
|
|
0, 1, 0);
|
|
|
|
//The source port of the PGM frame
|
|
AttachPropertyInstance( hFrame,
|
|
PGMPropertyTable[PGM_TSDU_LENGTH].hProperty,
|
|
sizeof(WORD),
|
|
&pPGMHdr->TSDULength,
|
|
0, 1, 0);
|
|
switch (PacketType)
|
|
{
|
|
case (PACKET_TYPE_SPM):
|
|
{
|
|
// Spm Sequence Number
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_SEQUENCE_NUMBER].hProperty,
|
|
sizeof(DWORD),
|
|
&pSpm->SpmSequenceNumber,
|
|
0, 1, 0);
|
|
|
|
// Sender's trailing edge
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_TRAILING_EDGE].hProperty,
|
|
sizeof(DWORD),
|
|
&pSpm->TrailingEdgeSeqNumber,
|
|
0, 1, 0);
|
|
|
|
// Sender's trailing edge
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_LEADING_EDGE].hProperty,
|
|
sizeof(DWORD),
|
|
&pSpm->LeadingEdgeSeqNumber,
|
|
0, 1, 0);
|
|
|
|
PGM_FmtNLA (hFrame, &pSpm->PathNLA, TRUE);
|
|
|
|
BytesTaken = sizeof (SPM_PACKET_HEADER);
|
|
pOptionsHeader = (tPACKET_OPTION_LENGTH *) (pSpm + 1);
|
|
|
|
break;
|
|
}
|
|
|
|
case (PACKET_TYPE_ODATA):
|
|
case (PACKET_TYPE_RDATA):
|
|
{
|
|
// Sender's sequence number
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_SEQUENCE_NUMBER].hProperty,
|
|
sizeof(DWORD),
|
|
&pData->DataSequenceNumber,
|
|
0, 1, 0);
|
|
|
|
// Sender's trailing edge
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_TRAILING_EDGE].hProperty,
|
|
sizeof(DWORD),
|
|
&pData->TrailingEdgeSequenceNumber,
|
|
0, 1, 0);
|
|
|
|
BytesTaken = sizeof (DATA_PACKET_HEADER);
|
|
pOptionsHeader = (tPACKET_OPTION_LENGTH *) (pData + 1);
|
|
|
|
break;
|
|
}
|
|
|
|
case (PACKET_TYPE_NAK):
|
|
case (PACKET_TYPE_NCF):
|
|
{
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_SEQUENCE_NUMBER].hProperty,
|
|
sizeof(DWORD),
|
|
&pNakNcf->RequestedSequenceNumber,
|
|
0, 1, 0);
|
|
|
|
PGM_FmtNLA (hFrame, &pNakNcf->SourceNLA, TRUE);
|
|
PGM_FmtNLA (hFrame, &pNakNcf->MCastGroupNLA, FALSE);
|
|
|
|
BytesTaken = sizeof (NAK_NCF_PACKET_HEADER);
|
|
pOptionsHeader = (tPACKET_OPTION_LENGTH *) (pNakNcf + 1);
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((pPGMHdr->Options & PACKET_HEADER_OPTIONS_PRESENT) &&
|
|
(pOptionsHeader))
|
|
{
|
|
OptionsLength = ProcessOptions (hFrame, pOptionsHeader, (BytesLeft-BytesTaken), PacketType);
|
|
}
|
|
|
|
if (((PacketType == PACKET_TYPE_ODATA) ||
|
|
(PacketType == PACKET_TYPE_RDATA)) &&
|
|
(BytesLeft > (BytesTaken+OptionsLength)))
|
|
{
|
|
BytesLeft -= (BytesTaken+OptionsLength);
|
|
|
|
pPgmData = ((PUCHAR) pPGMHdr) + BytesTaken + OptionsLength;
|
|
AttachPropertyInstance (hFrame,
|
|
PGMPropertyTable[PGM_DATA].hProperty,
|
|
BytesLeft,
|
|
pPgmData,
|
|
0,1,0); // HELPID, Level, Errorflag
|
|
}
|
|
|
|
//Always returns NULL
|
|
return NULL;
|
|
}
|
|
|
|
//============================================================================
|
|
// Function: PGM_FormatProperties
|
|
//
|
|
// Description: Format the given properties on the given frame.
|
|
//
|
|
// Modification History
|
|
//
|
|
// Madhurima Pawar 08/04/00 Created
|
|
//============================================================================
|
|
DWORD BHAPI PGM_FormatProperties( HFRAME hFrame,
|
|
LPBYTE pMacFrame,
|
|
LPBYTE pPGMFrame,
|
|
DWORD nPropertyInsts,
|
|
LPPROPERTYINST p)
|
|
{
|
|
// loop through the property instances
|
|
while( nPropertyInsts-- > 0)
|
|
{
|
|
// and call the formatter for each
|
|
( (FORMAT)(p->lpPropertyInfo->InstanceData) )( p);
|
|
p++;
|
|
}
|
|
|
|
return NMERR_SUCCESS;
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Name: PGM_FmtSummary
|
|
//
|
|
// Description:
|
|
//
|
|
// Parameters: LPPROPERTYINST lpPropertyInst: pointer to property instance.
|
|
//
|
|
// Return Code: VOID.
|
|
//
|
|
// History:
|
|
// 10/15/2000 MAlam Created.
|
|
//
|
|
//*****************************************************************************
|
|
|
|
VOID WINAPIV
|
|
PGM_FmtSummary(
|
|
LPPROPERTYINST pPropertyInst
|
|
)
|
|
{
|
|
|
|
LPBYTE pReturnedString = pPropertyInst->szPropertyText;
|
|
PPGM_COMMON_HDR pPgmHeader = (PPGM_COMMON_HDR) (pPropertyInst->lpData);
|
|
SPM_PACKET_HEADER *pSpm = (SPM_PACKET_HEADER *) pPgmHeader;
|
|
DATA_PACKET_HEADER *pData = (DATA_PACKET_HEADER *) pPgmHeader;
|
|
NAK_NCF_PACKET_HEADER *pNakNcf = (NAK_NCF_PACKET_HEADER *) pPgmHeader;
|
|
UCHAR PacketType = pPgmHeader->Type & 0x0f;
|
|
UCHAR *szPacketDesc = NULL;
|
|
USHORT TSIPort;
|
|
|
|
if ((PacketType == PACKET_TYPE_NAK) ||
|
|
(PacketType == PACKET_TYPE_NNAK) ||
|
|
(PacketType == PACKET_TYPE_SPMR) ||
|
|
(PacketType == PACKET_TYPE_POLR))
|
|
{
|
|
TSIPort = ntohs (pPgmHeader->DestPort);
|
|
}
|
|
else
|
|
{
|
|
TSIPort = ntohs (pPgmHeader->SrcPort);
|
|
}
|
|
|
|
szPacketDesc = LookupByteSetString (&PGMTypesSET, PacketType);
|
|
wsprintf (pReturnedString,
|
|
"%s%s:",
|
|
szPacketDesc, (pPgmHeader->Options & PACKET_HEADER_OPTIONS_PARITY ? " (P)" : ""));
|
|
|
|
switch (PacketType)
|
|
{
|
|
case (PACKET_TYPE_SPM):
|
|
{
|
|
wsprintf (&pReturnedString [strlen(pReturnedString)],
|
|
" Seq: %d, Window: %d-%d",
|
|
ntohl (pSpm->SpmSequenceNumber), ntohl (pSpm->TrailingEdgeSeqNumber), ntohl (pSpm->LeadingEdgeSeqNumber));
|
|
|
|
break;
|
|
}
|
|
|
|
case (PACKET_TYPE_ODATA):
|
|
case (PACKET_TYPE_RDATA):
|
|
{
|
|
wsprintf (&pReturnedString [strlen(pReturnedString)],
|
|
" Seq: %d, Trail: %d, DataBytes: %d",
|
|
ntohl (pData->DataSequenceNumber), ntohl (pData->TrailingEdgeSequenceNumber),
|
|
((ULONG) ntohs (pPgmHeader->TSDULength)));
|
|
|
|
break;
|
|
}
|
|
|
|
case (PACKET_TYPE_NAK):
|
|
case (PACKET_TYPE_NCF):
|
|
{
|
|
wsprintf (&pReturnedString [strlen(pReturnedString)],
|
|
" Seq: %d%s",
|
|
ntohl (pNakNcf->RequestedSequenceNumber),
|
|
(pPgmHeader->Options & PACKET_HEADER_OPTIONS_PRESENT ? " ..." : ""));
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
wsprintf (&pReturnedString [strlen(pReturnedString)],
|
|
" TSIPort = %hu", TSIPort);
|
|
}
|
|
|
|
|
|
|