672 lines
21 KiB
C++
672 lines
21 KiB
C++
|
//--------------------------------------------------------------------
|
|||
|
// NtpParser - implementation
|
|||
|
// Copyright (C) Microsoft Corporation, 2000
|
|||
|
//
|
|||
|
// Created by: Louis Thomas (louisth), 2-29-00
|
|||
|
// Based upon the parser created by kumarp, 23-June-1999
|
|||
|
//
|
|||
|
// NTP parser for NetMon
|
|||
|
//
|
|||
|
|
|||
|
#include <windows.h>
|
|||
|
#include <netmon.h>
|
|||
|
#include <parser.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include <string.h>
|
|||
|
#include <stdio.h>
|
|||
|
|
|||
|
#include "..\lib\EndianSwap.inl"
|
|||
|
|
|||
|
//#define MODULEPRIVATE static // so statics show up in VC
|
|||
|
#define MODULEPRIVATE // statics don't show up in ntsd either!
|
|||
|
|
|||
|
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
|
|||
|
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
// Forward declarations
|
|||
|
|
|||
|
VOID WINAPIV Ntp_FormatSummary(LPPROPERTYINST pPropertyInst);
|
|||
|
VOID WINAPIV Ntp_FormatNtpTime(LPPROPERTYINST pPropertyInst);
|
|||
|
VOID WINAPIV Ntp_FormatStratum(LPPROPERTYINST pPropertyInst);
|
|||
|
VOID WINAPIV Ntp_FormatPollInterval(LPPROPERTYINST pPropertyInst);
|
|||
|
VOID WINAPIV Ntp_FormatPrecision(LPPROPERTYINST pPropertyInst);
|
|||
|
VOID WINAPIV Ntp_FormatRootDelay(LPPROPERTYINST pPropertyInst);
|
|||
|
VOID WINAPIV Ntp_FormatRootDispersion(LPPROPERTYINST pPropertyInst);
|
|||
|
VOID WINAPIV Ntp_FormatRefId(LPPROPERTYINST pPropertyInst);
|
|||
|
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
// Property Value Labels
|
|||
|
|
|||
|
// Leap Indicator
|
|||
|
LABELED_BYTE NtpLIVals[]={
|
|||
|
{0xc0, NULL},
|
|||
|
{0x00, "LI: no warning"},
|
|||
|
{0x40, "LI: last minute has 61 seconds"},
|
|||
|
{0x80, "LI: last minute has 59 seconds"},
|
|||
|
{0xc0, "LI: clock not synchronized"},
|
|||
|
};
|
|||
|
SET NtpLISet={ARRAYSIZE(NtpLIVals), NtpLIVals};
|
|||
|
|
|||
|
// Version
|
|||
|
LABELED_BYTE NtpVersionVals[]={
|
|||
|
{0x38, NULL},
|
|||
|
{0x00, "Version: 0"},
|
|||
|
{0x08, "Version: 1"},
|
|||
|
{0x10, "Version: 2"},
|
|||
|
{0x18, "Version: 3"},
|
|||
|
{0x20, "Version: 4"},
|
|||
|
{0x28, "Version: 5"},
|
|||
|
{0x30, "Version: 6"},
|
|||
|
{0x38, "Version: 7"},
|
|||
|
};
|
|||
|
SET NtpVersionSet={ARRAYSIZE(NtpVersionVals), NtpVersionVals};
|
|||
|
|
|||
|
// Mode
|
|||
|
LABELED_BYTE NtpModeVals[]={
|
|||
|
{7, NULL},
|
|||
|
{0, "Mode: reserved"},
|
|||
|
{1, "Mode: symmetric active"},
|
|||
|
{2, "Mode: symmetric passive"},
|
|||
|
{3, "Mode: client"},
|
|||
|
{4, "Mode: server"},
|
|||
|
{5, "Mode: broadcast"},
|
|||
|
{6, "Mode: reserved for NTP control message"},
|
|||
|
{7, "Mode: reserved for private use"},
|
|||
|
};
|
|||
|
SET NtpModeSet={ARRAYSIZE(NtpModeVals), NtpModeVals};
|
|||
|
|
|||
|
enum {
|
|||
|
NTP_MODE_Reserved=0,
|
|||
|
NTP_MODE_SymmetricActive,
|
|||
|
NTP_MODE_SymmetricPassive,
|
|||
|
NTP_MODE_Client,
|
|||
|
NTP_MODE_Server,
|
|||
|
NTP_MODE_Broadcast,
|
|||
|
NTP_MODE_Control,
|
|||
|
NTP_MODE_Private,
|
|||
|
};
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
// property ordinals (These must be kept in sync with the contents of NtpPropertyTable)
|
|||
|
enum {
|
|||
|
Ntp_Summary=0,
|
|||
|
Ntp_LeapIndicator,
|
|||
|
Ntp_Version,
|
|||
|
Ntp_Mode,
|
|||
|
Ntp_Stratum,
|
|||
|
Ntp_PollInterval,
|
|||
|
Ntp_Precision,
|
|||
|
Ntp_RootDelay,
|
|||
|
Ntp_RootDispersion,
|
|||
|
Ntp_RefId,
|
|||
|
Ntp_ReferenceTimeStamp,
|
|||
|
Ntp_OriginateTimeStamp,
|
|||
|
Ntp_ReceiveTimeStamp,
|
|||
|
Ntp_TransmitTimeStamp
|
|||
|
};
|
|||
|
|
|||
|
// Properties
|
|||
|
PROPERTYINFO NtpPropertyTable[]={
|
|||
|
{
|
|||
|
0, 0,
|
|||
|
"Summary",
|
|||
|
"Summary of the NTP Packet",
|
|||
|
PROP_TYPE_SUMMARY,
|
|||
|
PROP_QUAL_NONE,
|
|||
|
NULL,
|
|||
|
80, // max string size
|
|||
|
Ntp_FormatSummary
|
|||
|
}, {
|
|||
|
0, 0,
|
|||
|
"LI",
|
|||
|
"Leap Indicator",
|
|||
|
PROP_TYPE_BYTE,
|
|||
|
PROP_QUAL_LABELED_BITFIELD,
|
|||
|
&NtpLISet,
|
|||
|
80,
|
|||
|
FormatPropertyInstance
|
|||
|
}, {
|
|||
|
0, 0,
|
|||
|
"Version",
|
|||
|
"NTP Version",
|
|||
|
PROP_TYPE_BYTE,
|
|||
|
PROP_QUAL_LABELED_BITFIELD,
|
|||
|
&NtpVersionSet,
|
|||
|
80,
|
|||
|
FormatPropertyInstance
|
|||
|
}, {
|
|||
|
0, 0,
|
|||
|
"Mode",
|
|||
|
"Mode",
|
|||
|
PROP_TYPE_BYTE,
|
|||
|
PROP_QUAL_LABELED_BITFIELD,
|
|||
|
&NtpModeSet,
|
|||
|
80,
|
|||
|
FormatPropertyInstance
|
|||
|
}, {
|
|||
|
0, 0,
|
|||
|
"Stratum",
|
|||
|
"Stratum",
|
|||
|
PROP_TYPE_BYTE,
|
|||
|
PROP_QUAL_NONE,
|
|||
|
NULL,
|
|||
|
80,
|
|||
|
Ntp_FormatStratum
|
|||
|
}, {
|
|||
|
0, 0,
|
|||
|
"Poll Interval",
|
|||
|
"Maximum interval between two successive messages",
|
|||
|
PROP_TYPE_BYTE,
|
|||
|
PROP_QUAL_NONE,
|
|||
|
NULL,
|
|||
|
80,
|
|||
|
Ntp_FormatPollInterval
|
|||
|
}, {
|
|||
|
0, 0,
|
|||
|
"Precision",
|
|||
|
"Precision of the local clock",
|
|||
|
PROP_TYPE_BYTE,
|
|||
|
PROP_QUAL_NONE,
|
|||
|
NULL,
|
|||
|
80,
|
|||
|
Ntp_FormatPrecision
|
|||
|
}, {
|
|||
|
0, 0,
|
|||
|
"Root Delay",
|
|||
|
"Total roundtrip delay to the primary reference source",
|
|||
|
PROP_TYPE_DWORD,
|
|||
|
PROP_QUAL_NONE,
|
|||
|
NULL,
|
|||
|
80,
|
|||
|
Ntp_FormatRootDelay
|
|||
|
}, {
|
|||
|
0, 0,
|
|||
|
"Root Dispersion",
|
|||
|
"Nominal error relative to the primary reference source",
|
|||
|
PROP_TYPE_DWORD,
|
|||
|
PROP_QUAL_NONE,
|
|||
|
NULL,
|
|||
|
80,
|
|||
|
Ntp_FormatRootDispersion
|
|||
|
}, {
|
|||
|
0, 0,
|
|||
|
"Reference Identifier",
|
|||
|
"Reference source identifier",
|
|||
|
PROP_TYPE_DWORD,
|
|||
|
PROP_QUAL_NONE,
|
|||
|
NULL,
|
|||
|
80,
|
|||
|
Ntp_FormatRefId
|
|||
|
}, {
|
|||
|
0, 0,
|
|||
|
"Reference Timestamp",
|
|||
|
"Time server was last synchronized",
|
|||
|
PROP_TYPE_LARGEINT,
|
|||
|
PROP_QUAL_NONE,
|
|||
|
NULL,
|
|||
|
150,
|
|||
|
Ntp_FormatNtpTime
|
|||
|
}, {
|
|||
|
0, 0,
|
|||
|
"Originate Timestamp",
|
|||
|
"Time at client when packet was transmitted",
|
|||
|
PROP_TYPE_LARGEINT,
|
|||
|
PROP_QUAL_NONE,
|
|||
|
NULL,
|
|||
|
150,
|
|||
|
Ntp_FormatNtpTime
|
|||
|
}, {
|
|||
|
0, 0,
|
|||
|
"Receive Timestamp",
|
|||
|
"Time at server when packet was received",
|
|||
|
PROP_TYPE_LARGEINT,
|
|||
|
PROP_QUAL_NONE,
|
|||
|
NULL,
|
|||
|
150,
|
|||
|
Ntp_FormatNtpTime
|
|||
|
}, {
|
|||
|
0, 0,
|
|||
|
"Transmit Timestamp",
|
|||
|
"Time at server when packet was transmitted",
|
|||
|
PROP_TYPE_LARGEINT,
|
|||
|
PROP_QUAL_NONE,
|
|||
|
NULL,
|
|||
|
150,
|
|||
|
Ntp_FormatNtpTime
|
|||
|
},
|
|||
|
};
|
|||
|
|
|||
|
//####################################################################
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
VOID WINAPIV Ntp_FormatSummary(LPPROPERTYINST pPropertyInst) {
|
|||
|
|
|||
|
BYTE bMode=(*pPropertyInst->lpByte)&7;
|
|||
|
|
|||
|
switch (bMode) {
|
|||
|
case NTP_MODE_Client:
|
|||
|
lstrcpy(pPropertyInst->szPropertyText, "Client request");
|
|||
|
break;
|
|||
|
|
|||
|
case NTP_MODE_Server:
|
|||
|
lstrcpy(pPropertyInst->szPropertyText, "Server response");
|
|||
|
break;
|
|||
|
|
|||
|
case NTP_MODE_SymmetricActive:
|
|||
|
lstrcpy(pPropertyInst->szPropertyText, "Active request");
|
|||
|
break;
|
|||
|
|
|||
|
case NTP_MODE_SymmetricPassive:
|
|||
|
lstrcpy(pPropertyInst->szPropertyText, "Passive reponse");
|
|||
|
break;
|
|||
|
|
|||
|
case NTP_MODE_Broadcast:
|
|||
|
lstrcpy(pPropertyInst->szPropertyText, "Time broadcast");
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
lstrcpy(pPropertyInst->szPropertyText, "Other NTP packet");
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
VOID WINAPIV Ntp_FormatStratum(LPPROPERTYINST pPropertyInst) {
|
|||
|
|
|||
|
unsigned __int8 nStratum=(*pPropertyInst->lpByte);
|
|||
|
|
|||
|
char * szMeaning;
|
|||
|
if (0==nStratum) {
|
|||
|
szMeaning="unspecified or unavailable";
|
|||
|
} else if (1==nStratum) {
|
|||
|
szMeaning="primary reference (syncd by radio clock)";
|
|||
|
} else if (nStratum<16) {
|
|||
|
szMeaning="secondary reference (syncd by NTP)";
|
|||
|
} else {
|
|||
|
szMeaning="reserved";
|
|||
|
}
|
|||
|
wsprintf(pPropertyInst->szPropertyText, "Stratum: 0x%02X = %u = %s", nStratum, nStratum, szMeaning);
|
|||
|
}
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
VOID WINAPIV Ntp_FormatPollInterval(LPPROPERTYINST pPropertyInst) {
|
|||
|
char * szMeaning;
|
|||
|
char szBuf[30];
|
|||
|
|
|||
|
signed __int8 nPollInterval=(*pPropertyInst->lpByte);
|
|||
|
|
|||
|
if (0==nPollInterval) {
|
|||
|
szMeaning="unspecified";
|
|||
|
} else if (nPollInterval<4 || nPollInterval>14) {
|
|||
|
szMeaning="out of valid range";
|
|||
|
} else {
|
|||
|
wsprintf(szBuf, "%ds", 1<<nPollInterval);
|
|||
|
szMeaning=szBuf;
|
|||
|
}
|
|||
|
wsprintf(pPropertyInst->szPropertyText, "Poll Interval: 0x%02X = %d = %s", (unsigned __int8)nPollInterval, nPollInterval, szMeaning);
|
|||
|
}
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
VOID WINAPIV Ntp_FormatPrecision(LPPROPERTYINST pPropertyInst) {
|
|||
|
char * szMeaning;
|
|||
|
char szBuf[30];
|
|||
|
|
|||
|
signed __int8 nPrecision=(*pPropertyInst->lpByte);
|
|||
|
|
|||
|
if (0==nPrecision) {
|
|||
|
szMeaning="unspecified";
|
|||
|
} else if (nPrecision>-2 || nPrecision<-31) {
|
|||
|
szMeaning="out of valid range";
|
|||
|
} else {
|
|||
|
szMeaning=szBuf;
|
|||
|
char * szUnit="s";
|
|||
|
double dTickInterval=1.0/(1<<(-nPrecision));
|
|||
|
if (dTickInterval<1) {
|
|||
|
dTickInterval*=1000;
|
|||
|
szUnit="ms";
|
|||
|
}
|
|||
|
if (dTickInterval<1) {
|
|||
|
dTickInterval*=1000;
|
|||
|
szUnit="<EFBFBD>s";
|
|||
|
}
|
|||
|
if (dTickInterval<1) {
|
|||
|
dTickInterval*=1000;
|
|||
|
szUnit="ns";
|
|||
|
}
|
|||
|
sprintf(szBuf, "%g%s per tick", dTickInterval, szUnit);
|
|||
|
}
|
|||
|
wsprintf(pPropertyInst->szPropertyText, "Precision: 0x%02X = %d = %s", (unsigned __int8)nPrecision, nPrecision, szMeaning);
|
|||
|
}
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
VOID WINAPIV Ntp_FormatRootDelay(LPPROPERTYINST pPropertyInst) {
|
|||
|
char * szMeaning;
|
|||
|
char szBuf[30];
|
|||
|
|
|||
|
DWORD dwRootDelay=EndianSwap((unsigned __int32)*pPropertyInst->lpDword);
|
|||
|
|
|||
|
if (0==dwRootDelay) {
|
|||
|
szMeaning="unspecified";
|
|||
|
} else {
|
|||
|
szMeaning=szBuf;
|
|||
|
sprintf(szBuf, "%gs", ((double)((signed __int32)dwRootDelay))/0x00010000);
|
|||
|
}
|
|||
|
|
|||
|
wsprintf(pPropertyInst->szPropertyText, "Root Delay: 0x%04X.%04Xs = %s", dwRootDelay>>16, dwRootDelay&0x0000FFFF, szMeaning);
|
|||
|
}
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
VOID WINAPIV Ntp_FormatRootDispersion(LPPROPERTYINST pPropertyInst) {
|
|||
|
char * szMeaning;
|
|||
|
char szBuf[30];
|
|||
|
|
|||
|
DWORD dwRootDispersion=EndianSwap((unsigned __int32)*pPropertyInst->lpDword);
|
|||
|
|
|||
|
if (0==dwRootDispersion) {
|
|||
|
szMeaning="unspecified";
|
|||
|
} else {
|
|||
|
szMeaning=szBuf;
|
|||
|
sprintf(szBuf, "%gs", ((double)((signed __int32)dwRootDispersion))/0x00010000);
|
|||
|
}
|
|||
|
|
|||
|
wsprintf(pPropertyInst->szPropertyText, "Root Dispersion: 0x%04X.%04Xs = %s", dwRootDispersion>>16, dwRootDispersion&0x0000FFFF, szMeaning);
|
|||
|
}
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
VOID WINAPIV Ntp_FormatRefId(LPPROPERTYINST pPropertyInst) {
|
|||
|
char * szMeaning;
|
|||
|
char szBuf[30];
|
|||
|
|
|||
|
DWORD dwRefID=EndianSwap((unsigned __int32)*pPropertyInst->lpDword);
|
|||
|
unsigned __int8 nStratum=*(pPropertyInst->lpByte-11);
|
|||
|
unsigned int nVersion=*(pPropertyInst->lpByte-12);
|
|||
|
nVersion&=0x38;
|
|||
|
nVersion>>=3;
|
|||
|
|
|||
|
|
|||
|
if (0==dwRefID) {
|
|||
|
szMeaning="unspecified";
|
|||
|
} else if (0==nStratum || 1==nStratum) {
|
|||
|
szMeaning=szBuf;
|
|||
|
char szId[5];
|
|||
|
szId[0]=pPropertyInst->lpByte[0];
|
|||
|
szId[1]=pPropertyInst->lpByte[1];
|
|||
|
szId[2]=pPropertyInst->lpByte[2];
|
|||
|
szId[3]=pPropertyInst->lpByte[3];
|
|||
|
szId[4]='\0';
|
|||
|
sprintf(szBuf, "source name: \"%s\"", szId);
|
|||
|
} else if (nVersion<4) {
|
|||
|
szMeaning=szBuf;
|
|||
|
sprintf(szBuf, "source IP: %u.%u.%u.%u",
|
|||
|
pPropertyInst->lpByte[0], pPropertyInst->lpByte[1],
|
|||
|
pPropertyInst->lpByte[2], pPropertyInst->lpByte[3]);
|
|||
|
} else {
|
|||
|
szMeaning=szBuf;
|
|||
|
sprintf(szBuf, "last reference timestamp fraction: %gs", ((double)dwRefID)/(4294967296.0));
|
|||
|
}
|
|||
|
|
|||
|
wsprintf(pPropertyInst->szPropertyText, "Reference Identifier: 0x%08X = %s", dwRefID, szMeaning);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
// conversion constants
|
|||
|
#define NTPTIMEOFFSET (0x014F373BFDE04000)
|
|||
|
#define FIVETOTHESEVETH (0x001312D)
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
// convert from big-endian NTP-stye timestamp to little-endian NT-style timestamp
|
|||
|
unsigned __int64 NtTimeFromNtpTime(unsigned __int64 qwNtpTime) {
|
|||
|
//return (qwNtpTime*(10**7)/(2**32))+NTPTIMEOFFSET
|
|||
|
// ==>
|
|||
|
//return (qwNtpTime*(5**7)/(2**25))+NTPTIMEOFFSET
|
|||
|
// ==>
|
|||
|
//return ((qwNTPtime*FIVETOTHESEVETH)>>25)+NTPTIMEOFFSET;
|
|||
|
// ==>
|
|||
|
// Note: 'After' division, we round (instead of truncate) the result for better precision
|
|||
|
unsigned __int64 qwTemp;
|
|||
|
qwNtpTime=EndianSwap(qwNtpTime);
|
|||
|
|
|||
|
qwTemp=((qwNtpTime&0x00000000FFFFFFFF)*FIVETOTHESEVETH);
|
|||
|
qwTemp += qwTemp&0x0000000001000000; //rounding step: if 25th bit is set, round up
|
|||
|
return (qwTemp>>25) + (((qwNtpTime>>32)*FIVETOTHESEVETH)<<7) + NTPTIMEOFFSET;
|
|||
|
}
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
void FormatNtTimeStr(unsigned __int64 qwNtTime, char * szTime) {
|
|||
|
DWORD dwNanoSecs, dwSecs, dwMins, dwHours, dwDays;
|
|||
|
|
|||
|
dwNanoSecs=(DWORD)(qwNtTime%10000000);
|
|||
|
qwNtTime/=10000000;
|
|||
|
|
|||
|
dwSecs=(DWORD)(qwNtTime%60);
|
|||
|
qwNtTime/=60;
|
|||
|
|
|||
|
dwMins=(DWORD)(qwNtTime%60);
|
|||
|
qwNtTime/=60;
|
|||
|
|
|||
|
dwHours=(DWORD)(qwNtTime%24);
|
|||
|
|
|||
|
dwDays=(DWORD)(qwNtTime/24);
|
|||
|
|
|||
|
wsprintf(szTime, "%u %02u:%02u:%02u.%07us",
|
|||
|
dwDays, dwHours, dwMins, dwSecs, dwNanoSecs);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
VOID WINAPIV Ntp_FormatNtpTime(LPPROPERTYINST pPropertyInst) {
|
|||
|
LARGE_INTEGER liNtpTime;
|
|||
|
unsigned __int64 qwNtTime;
|
|||
|
unsigned __int64 qwNtTimeEpoch;
|
|||
|
char szTime[64];
|
|||
|
char szTimeEpoch[64];
|
|||
|
|
|||
|
|
|||
|
liNtpTime=*pPropertyInst->lpLargeInt;
|
|||
|
qwNtTime=NtTimeFromNtpTime((((unsigned __int64) liNtpTime.HighPart) << 32) |
|
|||
|
liNtpTime.LowPart);
|
|||
|
|
|||
|
if (liNtpTime.HighPart || liNtpTime.LowPart) {
|
|||
|
FormatNtTimeStr(qwNtTime, szTime);
|
|||
|
} else {
|
|||
|
lstrcpy(szTime, "(not specified)");
|
|||
|
}
|
|||
|
|
|||
|
wsprintf(szTimeEpoch, " -- %I64d00ns",
|
|||
|
((((unsigned __int64)liNtpTime.HighPart) << 32) | liNtpTime.LowPart));;
|
|||
|
|
|||
|
wsprintf(pPropertyInst->szPropertyText, "%s: 0x%08X.%08Xs %s = %s",
|
|||
|
pPropertyInst->lpPropertyInfo->Label,
|
|||
|
EndianSwap((unsigned __int32)liNtpTime.LowPart),
|
|||
|
EndianSwap((unsigned __int32)liNtpTime.HighPart),
|
|||
|
szTimeEpoch,
|
|||
|
szTime);
|
|||
|
}
|
|||
|
|
|||
|
//####################################################################
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
// Create our property database and handoff sets.
|
|||
|
void BHAPI Ntp_Register(HPROTOCOL hNtp) {
|
|||
|
unsigned int nIndex;
|
|||
|
|
|||
|
// tell netmon to make reserve some space for our property table
|
|||
|
CreatePropertyDatabase(hNtp, ARRAYSIZE(NtpPropertyTable));
|
|||
|
|
|||
|
// add our properties to netmon's database
|
|||
|
for(nIndex=0; nIndex<ARRAYSIZE(NtpPropertyTable); nIndex++) {
|
|||
|
AddProperty(hNtp, &NtpPropertyTable[nIndex]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
// Destroy our property database and handoff set
|
|||
|
VOID WINAPI Ntp_Deregister(HPROTOCOL hNtp) {
|
|||
|
|
|||
|
// tell netmon that it may now free our database
|
|||
|
DestroyPropertyDatabase(hNtp);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
// 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 Ntp_RecognizeFrame(HFRAME hFrame, ULPBYTE pMacFrame, ULPBYTE pNtpFrame, DWORD MacType, DWORD BytesLeft, HPROTOCOL hPrevProtocol, DWORD nPrevProtOffset, LPDWORD pProtocolStatus, LPHPROTOCOL phNextProtocol, PDWORD_PTR InstData) {
|
|||
|
|
|||
|
// For now, just assume that if we got called,
|
|||
|
// then the packet does contain us and we go to the end of the frame
|
|||
|
*pProtocolStatus=PROTOCOL_STATUS_CLAIMED;
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
// Indicate where in the frame each of our properties live.
|
|||
|
LPBYTE BHAPI Ntp_AttachProperties(HFRAME hFrame, ULPBYTE pMacFrame, ULPBYTE pNtpFrame, DWORD MacType, DWORD BytesLeft, HPROTOCOL hPrevProtocol, DWORD nPrevProtOffset, DWORD_PTR InstData) {
|
|||
|
|
|||
|
AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_Summary].hProperty, (WORD)BytesLeft, (LPBYTE)pNtpFrame, 0, 0, 0);
|
|||
|
AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_LeapIndicator].hProperty, (WORD)1, (LPBYTE) pNtpFrame, 0, 1, 0);
|
|||
|
AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_Version].hProperty, (WORD)1, (LPBYTE) pNtpFrame, 0, 1, 0);
|
|||
|
AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_Mode].hProperty, (WORD)1, (LPBYTE) pNtpFrame, 0, 1, 0);
|
|||
|
AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_Stratum].hProperty, (WORD)1, (LPBYTE) pNtpFrame+1, 0, 1, 0);
|
|||
|
AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_PollInterval].hProperty, (WORD)1, (LPBYTE) pNtpFrame+2, 0, 1, 0);
|
|||
|
AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_Precision].hProperty, (WORD)1, (LPBYTE) pNtpFrame+3, 0, 1, 0);
|
|||
|
AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_RootDelay].hProperty, (WORD)4, (LPBYTE) pNtpFrame+4, 0, 1, 0);
|
|||
|
AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_RootDispersion].hProperty, (WORD)4, (LPBYTE) pNtpFrame+8, 0, 1, 0);
|
|||
|
AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_RefId].hProperty, (WORD)4, (LPBYTE) pNtpFrame+12, 0, 1, 0);
|
|||
|
AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_ReferenceTimeStamp].hProperty, (WORD)8, (LPBYTE) pNtpFrame+16, 0, 1, 0);
|
|||
|
AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_OriginateTimeStamp].hProperty, (WORD) 8, (LPBYTE) pNtpFrame+24, 0, 1, 0);
|
|||
|
AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_ReceiveTimeStamp].hProperty, (WORD) 8, (LPBYTE) pNtpFrame+32, 0, 1, 0);
|
|||
|
AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_TransmitTimeStamp].hProperty, (WORD) 8, (LPBYTE) pNtpFrame+40, 0, 1, 0);
|
|||
|
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
// Format the given properties on the given frame.
|
|||
|
DWORD BHAPI Ntp_FormatProperties(HFRAME hFrame, ULPBYTE pMacFrame, ULPBYTE pNtpFrame, 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;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//####################################################################
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
// AutoInstall - return all of the information neede to install us
|
|||
|
PPF_PARSERDLLINFO WINAPI ParserAutoInstallInfo() {
|
|||
|
PPF_PARSERDLLINFO pParserDllInfo;
|
|||
|
PPF_PARSERINFO pParserInfo;
|
|||
|
DWORD NumProtocols;
|
|||
|
|
|||
|
DWORD NumHandoffs;
|
|||
|
PPF_HANDOFFSET pHandoffSet;
|
|||
|
PPF_HANDOFFENTRY pHandoffEntry;
|
|||
|
|
|||
|
// Allocate memory for parser info:
|
|||
|
NumProtocols=1;
|
|||
|
pParserDllInfo=(PPF_PARSERDLLINFO)HeapAlloc(GetProcessHeap(),
|
|||
|
HEAP_ZERO_MEMORY,
|
|||
|
sizeof(PF_PARSERDLLINFO) +
|
|||
|
NumProtocols * sizeof(PF_PARSERINFO));
|
|||
|
if(pParserDllInfo==NULL) {
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
// fill in the parser DLL info
|
|||
|
pParserDllInfo->nParsers=NumProtocols;
|
|||
|
|
|||
|
// fill in the individual parser infos...
|
|||
|
|
|||
|
// Ntp ==============================================================
|
|||
|
pParserInfo=&(pParserDllInfo->ParserInfo[0]);
|
|||
|
wsprintf(pParserInfo->szProtocolName, "NTP");
|
|||
|
wsprintf(pParserInfo->szComment, "Network Time Protocol");
|
|||
|
wsprintf(pParserInfo->szHelpFile, "");
|
|||
|
|
|||
|
// the incoming handoff set ----------------------------------------------
|
|||
|
// allocate
|
|||
|
NumHandoffs = 1;
|
|||
|
pHandoffSet = (PPF_HANDOFFSET)HeapAlloc( GetProcessHeap(),
|
|||
|
HEAP_ZERO_MEMORY,
|
|||
|
sizeof( PF_HANDOFFSET ) +
|
|||
|
NumHandoffs * sizeof( PF_HANDOFFENTRY) );
|
|||
|
if( pHandoffSet == NULL )
|
|||
|
{
|
|||
|
// just return early
|
|||
|
return pParserDllInfo;
|
|||
|
}
|
|||
|
|
|||
|
// fill in the incoming handoff set
|
|||
|
pParserInfo->pWhoHandsOffToMe = pHandoffSet;
|
|||
|
pHandoffSet->nEntries = NumHandoffs;
|
|||
|
|
|||
|
pHandoffEntry = &(pHandoffSet->Entry[0]);
|
|||
|
wsprintf( pHandoffEntry->szIniFile, "TCPIP.INI" );
|
|||
|
wsprintf( pHandoffEntry->szIniSection, "UDP_HandoffSet" );
|
|||
|
wsprintf( pHandoffEntry->szProtocol, "NTP" );
|
|||
|
pHandoffEntry->dwHandOffValue = 123;
|
|||
|
pHandoffEntry->ValueFormatBase = HANDOFF_VALUE_FORMAT_BASE_DECIMAL;
|
|||
|
|
|||
|
return pParserDllInfo;
|
|||
|
}
|
|||
|
|
|||
|
//--------------------------------------------------------------------
|
|||
|
// Tell netmon about our entry points.
|
|||
|
extern "C" BOOL WINAPI DllMain(HANDLE hInstance, ULONG Command, LPVOID Reserved) {
|
|||
|
|
|||
|
//MessageBox(NULL, "DLLEntry", "NTP ha ha", MB_OK);
|
|||
|
static HPROTOCOL hNtp=NULL;
|
|||
|
static unsigned int nAttached=0;
|
|||
|
|
|||
|
// what type of call is this
|
|||
|
switch(Command) {
|
|||
|
|
|||
|
case DLL_PROCESS_ATTACH:
|
|||
|
// are we loading for the first time?
|
|||
|
if (nAttached==0) {
|
|||
|
// the first time in we need to tell netmon
|
|||
|
// about ourselves
|
|||
|
|
|||
|
ENTRYPOINTS NtpEntryPoints={
|
|||
|
Ntp_Register,
|
|||
|
Ntp_Deregister,
|
|||
|
Ntp_RecognizeFrame,
|
|||
|
Ntp_AttachProperties,
|
|||
|
Ntp_FormatProperties
|
|||
|
};
|
|||
|
|
|||
|
hNtp=CreateProtocol("NTP", &NtpEntryPoints, ENTRYPOINTS_SIZE);
|
|||
|
}
|
|||
|
nAttached++;
|
|||
|
break;
|
|||
|
|
|||
|
case DLL_PROCESS_DETACH:
|
|||
|
nAttached--;
|
|||
|
// are we detaching our last instance?
|
|||
|
if (nAttached==0) {
|
|||
|
// last guy out needs to clean up
|
|||
|
DestroyProtocol(hNtp);
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
// Netmon parsers ALWAYS return TRUE.
|
|||
|
return TRUE;
|
|||
|
}
|