Leaked source code of windows server 2003
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.

671 lines
22 KiB

  1. //--------------------------------------------------------------------
  2. // NtpParser - implementation
  3. // Copyright (C) Microsoft Corporation, 2000
  4. //
  5. // Created by: Louis Thomas (louisth), 2-29-00
  6. // Based upon the parser created by kumarp, 23-June-1999
  7. //
  8. // NTP parser for NetMon
  9. //
  10. #include <windows.h>
  11. #include <netmon.h>
  12. #include <parser.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <stdio.h>
  16. #include "..\lib\EndianSwap.inl"
  17. //#define MODULEPRIVATE static // so statics show up in VC
  18. #define MODULEPRIVATE // statics don't show up in ntsd either!
  19. #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
  20. //--------------------------------------------------------------------
  21. // Forward declarations
  22. VOID WINAPIV Ntp_FormatSummary(LPPROPERTYINST pPropertyInst);
  23. VOID WINAPIV Ntp_FormatNtpTime(LPPROPERTYINST pPropertyInst);
  24. VOID WINAPIV Ntp_FormatStratum(LPPROPERTYINST pPropertyInst);
  25. VOID WINAPIV Ntp_FormatPollInterval(LPPROPERTYINST pPropertyInst);
  26. VOID WINAPIV Ntp_FormatPrecision(LPPROPERTYINST pPropertyInst);
  27. VOID WINAPIV Ntp_FormatRootDelay(LPPROPERTYINST pPropertyInst);
  28. VOID WINAPIV Ntp_FormatRootDispersion(LPPROPERTYINST pPropertyInst);
  29. VOID WINAPIV Ntp_FormatRefId(LPPROPERTYINST pPropertyInst);
  30. //--------------------------------------------------------------------
  31. // Property Value Labels
  32. // Leap Indicator
  33. LABELED_BYTE NtpLIVals[]={
  34. {0xc0, NULL},
  35. {0x00, "LI: no warning"},
  36. {0x40, "LI: last minute has 61 seconds"},
  37. {0x80, "LI: last minute has 59 seconds"},
  38. {0xc0, "LI: clock not synchronized"},
  39. };
  40. SET NtpLISet={ARRAYSIZE(NtpLIVals), NtpLIVals};
  41. // Version
  42. LABELED_BYTE NtpVersionVals[]={
  43. {0x38, NULL},
  44. {0x00, "Version: 0"},
  45. {0x08, "Version: 1"},
  46. {0x10, "Version: 2"},
  47. {0x18, "Version: 3"},
  48. {0x20, "Version: 4"},
  49. {0x28, "Version: 5"},
  50. {0x30, "Version: 6"},
  51. {0x38, "Version: 7"},
  52. };
  53. SET NtpVersionSet={ARRAYSIZE(NtpVersionVals), NtpVersionVals};
  54. // Mode
  55. LABELED_BYTE NtpModeVals[]={
  56. {7, NULL},
  57. {0, "Mode: reserved"},
  58. {1, "Mode: symmetric active"},
  59. {2, "Mode: symmetric passive"},
  60. {3, "Mode: client"},
  61. {4, "Mode: server"},
  62. {5, "Mode: broadcast"},
  63. {6, "Mode: reserved for NTP control message"},
  64. {7, "Mode: reserved for private use"},
  65. };
  66. SET NtpModeSet={ARRAYSIZE(NtpModeVals), NtpModeVals};
  67. enum {
  68. NTP_MODE_Reserved=0,
  69. NTP_MODE_SymmetricActive,
  70. NTP_MODE_SymmetricPassive,
  71. NTP_MODE_Client,
  72. NTP_MODE_Server,
  73. NTP_MODE_Broadcast,
  74. NTP_MODE_Control,
  75. NTP_MODE_Private,
  76. };
  77. //--------------------------------------------------------------------
  78. // property ordinals (These must be kept in sync with the contents of NtpPropertyTable)
  79. enum {
  80. Ntp_Summary=0,
  81. Ntp_LeapIndicator,
  82. Ntp_Version,
  83. Ntp_Mode,
  84. Ntp_Stratum,
  85. Ntp_PollInterval,
  86. Ntp_Precision,
  87. Ntp_RootDelay,
  88. Ntp_RootDispersion,
  89. Ntp_RefId,
  90. Ntp_ReferenceTimeStamp,
  91. Ntp_OriginateTimeStamp,
  92. Ntp_ReceiveTimeStamp,
  93. Ntp_TransmitTimeStamp
  94. };
  95. // Properties
  96. PROPERTYINFO NtpPropertyTable[]={
  97. {
  98. 0, 0,
  99. "Summary",
  100. "Summary of the NTP Packet",
  101. PROP_TYPE_SUMMARY,
  102. PROP_QUAL_NONE,
  103. NULL,
  104. 80, // max string size
  105. Ntp_FormatSummary
  106. }, {
  107. 0, 0,
  108. "LI",
  109. "Leap Indicator",
  110. PROP_TYPE_BYTE,
  111. PROP_QUAL_LABELED_BITFIELD,
  112. &NtpLISet,
  113. 80,
  114. FormatPropertyInstance
  115. }, {
  116. 0, 0,
  117. "Version",
  118. "NTP Version",
  119. PROP_TYPE_BYTE,
  120. PROP_QUAL_LABELED_BITFIELD,
  121. &NtpVersionSet,
  122. 80,
  123. FormatPropertyInstance
  124. }, {
  125. 0, 0,
  126. "Mode",
  127. "Mode",
  128. PROP_TYPE_BYTE,
  129. PROP_QUAL_LABELED_BITFIELD,
  130. &NtpModeSet,
  131. 80,
  132. FormatPropertyInstance
  133. }, {
  134. 0, 0,
  135. "Stratum",
  136. "Stratum",
  137. PROP_TYPE_BYTE,
  138. PROP_QUAL_NONE,
  139. NULL,
  140. 80,
  141. Ntp_FormatStratum
  142. }, {
  143. 0, 0,
  144. "Poll Interval",
  145. "Maximum interval between two successive messages",
  146. PROP_TYPE_BYTE,
  147. PROP_QUAL_NONE,
  148. NULL,
  149. 80,
  150. Ntp_FormatPollInterval
  151. }, {
  152. 0, 0,
  153. "Precision",
  154. "Precision of the local clock",
  155. PROP_TYPE_BYTE,
  156. PROP_QUAL_NONE,
  157. NULL,
  158. 80,
  159. Ntp_FormatPrecision
  160. }, {
  161. 0, 0,
  162. "Root Delay",
  163. "Total roundtrip delay to the primary reference source",
  164. PROP_TYPE_DWORD,
  165. PROP_QUAL_NONE,
  166. NULL,
  167. 80,
  168. Ntp_FormatRootDelay
  169. }, {
  170. 0, 0,
  171. "Root Dispersion",
  172. "Nominal error relative to the primary reference source",
  173. PROP_TYPE_DWORD,
  174. PROP_QUAL_NONE,
  175. NULL,
  176. 80,
  177. Ntp_FormatRootDispersion
  178. }, {
  179. 0, 0,
  180. "Reference Identifier",
  181. "Reference source identifier",
  182. PROP_TYPE_DWORD,
  183. PROP_QUAL_NONE,
  184. NULL,
  185. 80,
  186. Ntp_FormatRefId
  187. }, {
  188. 0, 0,
  189. "Reference Timestamp",
  190. "Time server was last synchronized",
  191. PROP_TYPE_LARGEINT,
  192. PROP_QUAL_NONE,
  193. NULL,
  194. 150,
  195. Ntp_FormatNtpTime
  196. }, {
  197. 0, 0,
  198. "Originate Timestamp",
  199. "Time at client when packet was transmitted",
  200. PROP_TYPE_LARGEINT,
  201. PROP_QUAL_NONE,
  202. NULL,
  203. 150,
  204. Ntp_FormatNtpTime
  205. }, {
  206. 0, 0,
  207. "Receive Timestamp",
  208. "Time at server when packet was received",
  209. PROP_TYPE_LARGEINT,
  210. PROP_QUAL_NONE,
  211. NULL,
  212. 150,
  213. Ntp_FormatNtpTime
  214. }, {
  215. 0, 0,
  216. "Transmit Timestamp",
  217. "Time at server when packet was transmitted",
  218. PROP_TYPE_LARGEINT,
  219. PROP_QUAL_NONE,
  220. NULL,
  221. 150,
  222. Ntp_FormatNtpTime
  223. },
  224. };
  225. //####################################################################
  226. //--------------------------------------------------------------------
  227. VOID WINAPIV Ntp_FormatSummary(LPPROPERTYINST pPropertyInst) {
  228. BYTE bMode=(*pPropertyInst->lpByte)&7;
  229. switch (bMode) {
  230. case NTP_MODE_Client:
  231. lstrcpy(pPropertyInst->szPropertyText, "Client request");
  232. break;
  233. case NTP_MODE_Server:
  234. lstrcpy(pPropertyInst->szPropertyText, "Server response");
  235. break;
  236. case NTP_MODE_SymmetricActive:
  237. lstrcpy(pPropertyInst->szPropertyText, "Active request");
  238. break;
  239. case NTP_MODE_SymmetricPassive:
  240. lstrcpy(pPropertyInst->szPropertyText, "Passive reponse");
  241. break;
  242. case NTP_MODE_Broadcast:
  243. lstrcpy(pPropertyInst->szPropertyText, "Time broadcast");
  244. break;
  245. default:
  246. lstrcpy(pPropertyInst->szPropertyText, "Other NTP packet");
  247. break;
  248. }
  249. }
  250. //--------------------------------------------------------------------
  251. VOID WINAPIV Ntp_FormatStratum(LPPROPERTYINST pPropertyInst) {
  252. unsigned __int8 nStratum=(*pPropertyInst->lpByte);
  253. char * szMeaning;
  254. if (0==nStratum) {
  255. szMeaning="unspecified or unavailable";
  256. } else if (1==nStratum) {
  257. szMeaning="primary reference (syncd by radio clock)";
  258. } else if (nStratum<16) {
  259. szMeaning="secondary reference (syncd by NTP)";
  260. } else {
  261. szMeaning="reserved";
  262. }
  263. wsprintf(pPropertyInst->szPropertyText, "Stratum: 0x%02X = %u = %s", nStratum, nStratum, szMeaning);
  264. }
  265. //--------------------------------------------------------------------
  266. VOID WINAPIV Ntp_FormatPollInterval(LPPROPERTYINST pPropertyInst) {
  267. char * szMeaning;
  268. char szBuf[30];
  269. signed __int8 nPollInterval=(*pPropertyInst->lpByte);
  270. if (0==nPollInterval) {
  271. szMeaning="unspecified";
  272. } else if (nPollInterval<4 || nPollInterval>14) {
  273. szMeaning="out of valid range";
  274. } else {
  275. wsprintf(szBuf, "%ds", 1<<nPollInterval);
  276. szMeaning=szBuf;
  277. }
  278. wsprintf(pPropertyInst->szPropertyText, "Poll Interval: 0x%02X = %d = %s", (unsigned __int8)nPollInterval, nPollInterval, szMeaning);
  279. }
  280. //--------------------------------------------------------------------
  281. VOID WINAPIV Ntp_FormatPrecision(LPPROPERTYINST pPropertyInst) {
  282. char * szMeaning;
  283. char szBuf[30];
  284. signed __int8 nPrecision=(*pPropertyInst->lpByte);
  285. if (0==nPrecision) {
  286. szMeaning="unspecified";
  287. } else if (nPrecision>-2 || nPrecision<-31) {
  288. szMeaning="out of valid range";
  289. } else {
  290. szMeaning=szBuf;
  291. char * szUnit="s";
  292. double dTickInterval=1.0/(1<<(-nPrecision));
  293. if (dTickInterval<1) {
  294. dTickInterval*=1000;
  295. szUnit="ms";
  296. }
  297. if (dTickInterval<1) {
  298. dTickInterval*=1000;
  299. szUnit="�s";
  300. }
  301. if (dTickInterval<1) {
  302. dTickInterval*=1000;
  303. szUnit="ns";
  304. }
  305. sprintf(szBuf, "%g%s per tick", dTickInterval, szUnit);
  306. }
  307. wsprintf(pPropertyInst->szPropertyText, "Precision: 0x%02X = %d = %s", (unsigned __int8)nPrecision, nPrecision, szMeaning);
  308. }
  309. //--------------------------------------------------------------------
  310. VOID WINAPIV Ntp_FormatRootDelay(LPPROPERTYINST pPropertyInst) {
  311. char * szMeaning;
  312. char szBuf[30];
  313. DWORD dwRootDelay=EndianSwap((unsigned __int32)*pPropertyInst->lpDword);
  314. if (0==dwRootDelay) {
  315. szMeaning="unspecified";
  316. } else {
  317. szMeaning=szBuf;
  318. sprintf(szBuf, "%gs", ((double)((signed __int32)dwRootDelay))/0x00010000);
  319. }
  320. wsprintf(pPropertyInst->szPropertyText, "Root Delay: 0x%04X.%04Xs = %s", dwRootDelay>>16, dwRootDelay&0x0000FFFF, szMeaning);
  321. }
  322. //--------------------------------------------------------------------
  323. VOID WINAPIV Ntp_FormatRootDispersion(LPPROPERTYINST pPropertyInst) {
  324. char * szMeaning;
  325. char szBuf[30];
  326. DWORD dwRootDispersion=EndianSwap((unsigned __int32)*pPropertyInst->lpDword);
  327. if (0==dwRootDispersion) {
  328. szMeaning="unspecified";
  329. } else {
  330. szMeaning=szBuf;
  331. sprintf(szBuf, "%gs", ((double)((signed __int32)dwRootDispersion))/0x00010000);
  332. }
  333. wsprintf(pPropertyInst->szPropertyText, "Root Dispersion: 0x%04X.%04Xs = %s", dwRootDispersion>>16, dwRootDispersion&0x0000FFFF, szMeaning);
  334. }
  335. //--------------------------------------------------------------------
  336. VOID WINAPIV Ntp_FormatRefId(LPPROPERTYINST pPropertyInst) {
  337. char * szMeaning;
  338. char szBuf[30];
  339. DWORD dwRefID=EndianSwap((unsigned __int32)*pPropertyInst->lpDword);
  340. unsigned __int8 nStratum=*(pPropertyInst->lpByte-11);
  341. unsigned int nVersion=*(pPropertyInst->lpByte-12);
  342. nVersion&=0x38;
  343. nVersion>>=3;
  344. if (0==dwRefID) {
  345. szMeaning="unspecified";
  346. } else if (0==nStratum || 1==nStratum) {
  347. szMeaning=szBuf;
  348. char szId[5];
  349. szId[0]=pPropertyInst->lpByte[0];
  350. szId[1]=pPropertyInst->lpByte[1];
  351. szId[2]=pPropertyInst->lpByte[2];
  352. szId[3]=pPropertyInst->lpByte[3];
  353. szId[4]='\0';
  354. sprintf(szBuf, "source name: \"%s\"", szId);
  355. } else if (nVersion<4) {
  356. szMeaning=szBuf;
  357. sprintf(szBuf, "source IP: %u.%u.%u.%u",
  358. pPropertyInst->lpByte[0], pPropertyInst->lpByte[1],
  359. pPropertyInst->lpByte[2], pPropertyInst->lpByte[3]);
  360. } else {
  361. szMeaning=szBuf;
  362. sprintf(szBuf, "last reference timestamp fraction: %gs", ((double)dwRefID)/(4294967296.0));
  363. }
  364. wsprintf(pPropertyInst->szPropertyText, "Reference Identifier: 0x%08X = %s", dwRefID, szMeaning);
  365. }
  366. //--------------------------------------------------------------------
  367. // conversion constants
  368. #define NTPTIMEOFFSET (0x014F373BFDE04000)
  369. #define FIVETOTHESEVETH (0x001312D)
  370. //--------------------------------------------------------------------
  371. // convert from big-endian NTP-stye timestamp to little-endian NT-style timestamp
  372. unsigned __int64 NtTimeFromNtpTime(unsigned __int64 qwNtpTime) {
  373. //return (qwNtpTime*(10**7)/(2**32))+NTPTIMEOFFSET
  374. // ==>
  375. //return (qwNtpTime*(5**7)/(2**25))+NTPTIMEOFFSET
  376. // ==>
  377. //return ((qwNTPtime*FIVETOTHESEVETH)>>25)+NTPTIMEOFFSET;
  378. // ==>
  379. // Note: 'After' division, we round (instead of truncate) the result for better precision
  380. unsigned __int64 qwTemp;
  381. qwNtpTime=EndianSwap(qwNtpTime);
  382. qwTemp=((qwNtpTime&0x00000000FFFFFFFF)*FIVETOTHESEVETH);
  383. qwTemp += qwTemp&0x0000000001000000; //rounding step: if 25th bit is set, round up
  384. return (qwTemp>>25) + (((qwNtpTime>>32)*FIVETOTHESEVETH)<<7) + NTPTIMEOFFSET;
  385. }
  386. //--------------------------------------------------------------------
  387. void FormatNtTimeStr(unsigned __int64 qwNtTime, char * szTime) {
  388. DWORD dwNanoSecs, dwSecs, dwMins, dwHours, dwDays;
  389. dwNanoSecs=(DWORD)(qwNtTime%10000000);
  390. qwNtTime/=10000000;
  391. dwSecs=(DWORD)(qwNtTime%60);
  392. qwNtTime/=60;
  393. dwMins=(DWORD)(qwNtTime%60);
  394. qwNtTime/=60;
  395. dwHours=(DWORD)(qwNtTime%24);
  396. dwDays=(DWORD)(qwNtTime/24);
  397. wsprintf(szTime, "%u %02u:%02u:%02u.%07us",
  398. dwDays, dwHours, dwMins, dwSecs, dwNanoSecs);
  399. }
  400. //--------------------------------------------------------------------
  401. VOID WINAPIV Ntp_FormatNtpTime(LPPROPERTYINST pPropertyInst) {
  402. LARGE_INTEGER liNtpTime;
  403. unsigned __int64 qwNtTime;
  404. unsigned __int64 qwNtTimeEpoch;
  405. char szTime[64];
  406. char szTimeEpoch[64];
  407. liNtpTime=*pPropertyInst->lpLargeInt;
  408. qwNtTime=NtTimeFromNtpTime((((unsigned __int64) liNtpTime.HighPart) << 32) |
  409. liNtpTime.LowPart);
  410. if (liNtpTime.HighPart || liNtpTime.LowPart) {
  411. FormatNtTimeStr(qwNtTime, szTime);
  412. } else {
  413. lstrcpy(szTime, "(not specified)");
  414. }
  415. wsprintf(szTimeEpoch, " -- %I64d00ns",
  416. ((((unsigned __int64)liNtpTime.HighPart) << 32) | liNtpTime.LowPart));;
  417. wsprintf(pPropertyInst->szPropertyText, "%s: 0x%08X.%08Xs %s = %s",
  418. pPropertyInst->lpPropertyInfo->Label,
  419. EndianSwap((unsigned __int32)liNtpTime.LowPart),
  420. EndianSwap((unsigned __int32)liNtpTime.HighPart),
  421. szTimeEpoch,
  422. szTime);
  423. }
  424. //####################################################################
  425. //--------------------------------------------------------------------
  426. // Create our property database and handoff sets.
  427. void BHAPI Ntp_Register(HPROTOCOL hNtp) {
  428. unsigned int nIndex;
  429. // tell netmon to make reserve some space for our property table
  430. CreatePropertyDatabase(hNtp, ARRAYSIZE(NtpPropertyTable));
  431. // add our properties to netmon's database
  432. for(nIndex=0; nIndex<ARRAYSIZE(NtpPropertyTable); nIndex++) {
  433. AddProperty(hNtp, &NtpPropertyTable[nIndex]);
  434. }
  435. }
  436. //--------------------------------------------------------------------
  437. // Destroy our property database and handoff set
  438. VOID WINAPI Ntp_Deregister(HPROTOCOL hNtp) {
  439. // tell netmon that it may now free our database
  440. DestroyPropertyDatabase(hNtp);
  441. }
  442. //--------------------------------------------------------------------
  443. // Determine whether we exist in the frame at the spot
  444. // indicated. We also indicate who (if anyone) follows us
  445. // and how much of the frame we claim.
  446. 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) {
  447. // For now, just assume that if we got called,
  448. // then the packet does contain us and we go to the end of the frame
  449. *pProtocolStatus=PROTOCOL_STATUS_CLAIMED;
  450. return NULL;
  451. }
  452. //--------------------------------------------------------------------
  453. // Indicate where in the frame each of our properties live.
  454. LPBYTE BHAPI Ntp_AttachProperties(HFRAME hFrame, ULPBYTE pMacFrame, ULPBYTE pNtpFrame, DWORD MacType, DWORD BytesLeft, HPROTOCOL hPrevProtocol, DWORD nPrevProtOffset, DWORD_PTR InstData) {
  455. AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_Summary].hProperty, (WORD)BytesLeft, (LPBYTE)pNtpFrame, 0, 0, 0);
  456. AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_LeapIndicator].hProperty, (WORD)1, (LPBYTE) pNtpFrame, 0, 1, 0);
  457. AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_Version].hProperty, (WORD)1, (LPBYTE) pNtpFrame, 0, 1, 0);
  458. AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_Mode].hProperty, (WORD)1, (LPBYTE) pNtpFrame, 0, 1, 0);
  459. AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_Stratum].hProperty, (WORD)1, (LPBYTE) pNtpFrame+1, 0, 1, 0);
  460. AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_PollInterval].hProperty, (WORD)1, (LPBYTE) pNtpFrame+2, 0, 1, 0);
  461. AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_Precision].hProperty, (WORD)1, (LPBYTE) pNtpFrame+3, 0, 1, 0);
  462. AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_RootDelay].hProperty, (WORD)4, (LPBYTE) pNtpFrame+4, 0, 1, 0);
  463. AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_RootDispersion].hProperty, (WORD)4, (LPBYTE) pNtpFrame+8, 0, 1, 0);
  464. AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_RefId].hProperty, (WORD)4, (LPBYTE) pNtpFrame+12, 0, 1, 0);
  465. AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_ReferenceTimeStamp].hProperty, (WORD)8, (LPBYTE) pNtpFrame+16, 0, 1, 0);
  466. AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_OriginateTimeStamp].hProperty, (WORD) 8, (LPBYTE) pNtpFrame+24, 0, 1, 0);
  467. AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_ReceiveTimeStamp].hProperty, (WORD) 8, (LPBYTE) pNtpFrame+32, 0, 1, 0);
  468. AttachPropertyInstance(hFrame, NtpPropertyTable[Ntp_TransmitTimeStamp].hProperty, (WORD) 8, (LPBYTE) pNtpFrame+40, 0, 1, 0);
  469. return NULL;
  470. }
  471. //--------------------------------------------------------------------
  472. // Format the given properties on the given frame.
  473. DWORD BHAPI Ntp_FormatProperties(HFRAME hFrame, ULPBYTE pMacFrame, ULPBYTE pNtpFrame, DWORD nPropertyInsts, LPPROPERTYINST p) {
  474. // loop through the property instances
  475. while(nPropertyInsts-->0) {
  476. // and call the formatter for each
  477. ((FORMAT)(p->lpPropertyInfo->InstanceData))(p);
  478. p++;
  479. }
  480. return NMERR_SUCCESS;
  481. }
  482. //####################################################################
  483. //--------------------------------------------------------------------
  484. // AutoInstall - return all of the information neede to install us
  485. PPF_PARSERDLLINFO WINAPI ParserAutoInstallInfo() {
  486. PPF_PARSERDLLINFO pParserDllInfo;
  487. PPF_PARSERINFO pParserInfo;
  488. DWORD NumProtocols;
  489. DWORD NumHandoffs;
  490. PPF_HANDOFFSET pHandoffSet;
  491. PPF_HANDOFFENTRY pHandoffEntry;
  492. // Allocate memory for parser info:
  493. NumProtocols=1;
  494. pParserDllInfo=(PPF_PARSERDLLINFO)HeapAlloc(GetProcessHeap(),
  495. HEAP_ZERO_MEMORY,
  496. sizeof(PF_PARSERDLLINFO) +
  497. NumProtocols * sizeof(PF_PARSERINFO));
  498. if(pParserDllInfo==NULL) {
  499. return NULL;
  500. }
  501. // fill in the parser DLL info
  502. pParserDllInfo->nParsers=NumProtocols;
  503. // fill in the individual parser infos...
  504. // Ntp ==============================================================
  505. pParserInfo=&(pParserDllInfo->ParserInfo[0]);
  506. wsprintf(pParserInfo->szProtocolName, "NTP");
  507. wsprintf(pParserInfo->szComment, "Network Time Protocol");
  508. wsprintf(pParserInfo->szHelpFile, "");
  509. // the incoming handoff set ----------------------------------------------
  510. // allocate
  511. NumHandoffs = 1;
  512. pHandoffSet = (PPF_HANDOFFSET)HeapAlloc( GetProcessHeap(),
  513. HEAP_ZERO_MEMORY,
  514. sizeof( PF_HANDOFFSET ) +
  515. NumHandoffs * sizeof( PF_HANDOFFENTRY) );
  516. if( pHandoffSet == NULL )
  517. {
  518. // just return early
  519. return pParserDllInfo;
  520. }
  521. // fill in the incoming handoff set
  522. pParserInfo->pWhoHandsOffToMe = pHandoffSet;
  523. pHandoffSet->nEntries = NumHandoffs;
  524. pHandoffEntry = &(pHandoffSet->Entry[0]);
  525. wsprintf( pHandoffEntry->szIniFile, "TCPIP.INI" );
  526. wsprintf( pHandoffEntry->szIniSection, "UDP_HandoffSet" );
  527. wsprintf( pHandoffEntry->szProtocol, "NTP" );
  528. pHandoffEntry->dwHandOffValue = 123;
  529. pHandoffEntry->ValueFormatBase = HANDOFF_VALUE_FORMAT_BASE_DECIMAL;
  530. return pParserDllInfo;
  531. }
  532. //--------------------------------------------------------------------
  533. // Tell netmon about our entry points.
  534. extern "C" BOOL WINAPI DllMain(HANDLE hInstance, ULONG Command, LPVOID Reserved) {
  535. //MessageBox(NULL, "DLLEntry", "NTP ha ha", MB_OK);
  536. static HPROTOCOL hNtp=NULL;
  537. static unsigned int nAttached=0;
  538. // what type of call is this
  539. switch(Command) {
  540. case DLL_PROCESS_ATTACH:
  541. // are we loading for the first time?
  542. if (nAttached==0) {
  543. // the first time in we need to tell netmon
  544. // about ourselves
  545. ENTRYPOINTS NtpEntryPoints={
  546. Ntp_Register,
  547. Ntp_Deregister,
  548. Ntp_RecognizeFrame,
  549. Ntp_AttachProperties,
  550. Ntp_FormatProperties
  551. };
  552. hNtp=CreateProtocol("NTP", &NtpEntryPoints, ENTRYPOINTS_SIZE);
  553. }
  554. nAttached++;
  555. break;
  556. case DLL_PROCESS_DETACH:
  557. nAttached--;
  558. // are we detaching our last instance?
  559. if (nAttached==0) {
  560. // last guy out needs to clean up
  561. DestroyProtocol(hNtp);
  562. }
  563. break;
  564. }
  565. // Netmon parsers ALWAYS return TRUE.
  566. return TRUE;
  567. }