Source code of Windows XP (NT5)
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.

1146 lines
28 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 2001
  6. //
  7. // File: query.cpp
  8. // Purpose: query SPD and print IP Security information
  9. //
  10. //
  11. //--------------------------------------------------------------------------
  12. /* Edit History:
  13. 1/18/01 dkalin Created
  14. */
  15. // app's own header file
  16. #include "ipseccmd.h"
  17. #pragma warning(disable:4311)
  18. // forward function declarations
  19. char *LongLongToString( DWORD dwHigh, DWORD dwLow, int iPrintCommas );
  20. int AscMultUint( char *cProduct, char *cA, char *cB );
  21. int AscAddUint( char *cSum, char *cA, char *cB );
  22. void print_vpi(char *str, unsigned char *vpi, int vpi_len);
  23. void reportError ( DWORD dwMessageId )
  24. {
  25. LPVOID myErrString = NULL;
  26. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  27. NULL,
  28. dwMessageId, 0,
  29. (LPTSTR)&myErrString, 0, NULL);
  30. _ftprintf(stderr,
  31. TEXT("%s\n"), myErrString);
  32. LocalFree(myErrString);
  33. }
  34. // run SPD query and display results, uses global flags to determine what needs to be printed
  35. int do_show ( )
  36. {
  37. int iReturn = 0; // success by default
  38. int i, j;
  39. DWORD hr = FALSE; // assume success
  40. bool fTestPass = TRUE;
  41. char* pszLLString;
  42. TCHAR StringTxt[STRING_TEXT_SIZE+1];
  43. PMM_FILTER pmmf; // for MM filter calls
  44. PIPSEC_MM_SA pipsmmsa; // for MM SA calls
  45. PIPSEC_QM_SA pipsqmsa; // for QM SA calls
  46. PIPSEC_MM_POLICY pipsmmp; // for MM policy calls
  47. PIPSEC_QM_POLICY pipsqmp; // for QM policy calls
  48. PMM_AUTH_METHODS pmmam; // for MM auth methods calls
  49. IKE_STATISTICS IKEStats; // for IKE stats calls
  50. PIPSEC_STATISTICS pIPSecStats; // for IPSec stats calls
  51. PTRANSPORT_FILTER ptf; // for transport filter calls
  52. PTUNNEL_FILTER ptunf; // for tunnel filter calls
  53. DWORD dwCount; // counting objects here
  54. DWORD dwResumeHandle; // handle for continuation calls
  55. DWORD dwReserved; // reserved container
  56. GUID gDefaultGUID = {0}; // NULL GUID value
  57. if (ipseccmdShow.bFilters)
  58. {
  59. // print all filters
  60. // main mode generic with details
  61. _tprintf(TEXT("\nGeneric MM Filters\n------------------------------\n"));
  62. pmmf=NULL;
  63. dwResumeHandle=0;
  64. // make the call(s)
  65. for (i = 0; ;i+=dwCount)
  66. {
  67. hr = EnumMMFilters(szServ, ENUM_GENERIC_FILTERS, gDefaultGUID, &pmmf, 0, &dwCount, &dwResumeHandle);
  68. if (hr == ERROR_NO_DATA || dwCount == 0)
  69. {
  70. if (i == 0)
  71. {
  72. _tprintf(TEXT("No filters\n"));
  73. }
  74. break;
  75. }
  76. if (hr != ERROR_SUCCESS)
  77. {
  78. _tprintf(TEXT("EnumMMFilters failed with error %d\n"), hr);
  79. reportError(hr);
  80. fTestPass = FALSE; // indicate an error
  81. break;
  82. }
  83. for (j = 0; j < (int) dwCount; j++)
  84. {
  85. _tprintf(TEXT("\nGeneric MM Filter #%d:\n"), i+j+1);
  86. if (!PrintMMFilter(pmmf[j], TRUE, FALSE))
  87. {
  88. fTestPass = FALSE; // indicate an error
  89. break;
  90. }
  91. }
  92. SPDApiBufferFree(pmmf);
  93. pmmf=NULL;
  94. if(!fTestPass)
  95. break;
  96. }
  97. if (!fTestPass)
  98. {
  99. iReturn++;
  100. fTestPass = TRUE;
  101. }
  102. // main mode specific without details
  103. _tprintf(TEXT("\nSpecific MM Filters\n------------------------------\n"));
  104. pmmf=NULL;
  105. dwResumeHandle=0;
  106. // make the call(s)
  107. for (i = 0; ;i+=dwCount)
  108. {
  109. hr = EnumMMFilters(szServ, ENUM_SPECIFIC_FILTERS, gDefaultGUID, &pmmf, 0, &dwCount, &dwResumeHandle);
  110. if (hr == ERROR_NO_DATA || dwCount == 0)
  111. {
  112. if (i == 0)
  113. {
  114. _tprintf(TEXT("No filters\n"));
  115. }
  116. break;
  117. }
  118. if (hr != ERROR_SUCCESS)
  119. {
  120. _tprintf(TEXT("EnumMMFilters failed with error %d\n"), hr);
  121. reportError(hr);
  122. fTestPass = FALSE; // indicate an error
  123. break;
  124. }
  125. for (j = 0; j < (int) dwCount; j++)
  126. {
  127. _tprintf(TEXT("\nSpecific MM Filter #%d:\n"), i+j+1);
  128. if (!PrintMMFilter(pmmf[j], FALSE, TRUE))
  129. { // error
  130. fTestPass = FALSE; // indicate an error
  131. break;
  132. }
  133. }
  134. SPDApiBufferFree(pmmf);
  135. pmmf=NULL;
  136. if(!fTestPass)
  137. break;
  138. }
  139. if (!fTestPass)
  140. {
  141. iReturn++;
  142. fTestPass = TRUE;
  143. }
  144. // quick mode transport generic with details
  145. _tprintf(TEXT("\nGeneric Transport Filters\n------------------------------\n"));
  146. ptf=NULL;
  147. dwResumeHandle=0;
  148. // make the call(s)
  149. for (i = 0; ;i+=dwCount)
  150. {
  151. hr = EnumTransportFilters(szServ, ENUM_GENERIC_FILTERS, gDefaultGUID, &ptf, 0, &dwCount, &dwResumeHandle);
  152. if (hr == ERROR_NO_DATA || dwCount == 0)
  153. {
  154. if (i == 0)
  155. {
  156. _tprintf(TEXT("No filters\n"));
  157. }
  158. break;
  159. }
  160. if (hr != ERROR_SUCCESS)
  161. {
  162. _tprintf(TEXT("EnumTransportFilters failed with error %d\n"), hr);
  163. reportError(hr);
  164. fTestPass=FALSE;
  165. break;
  166. }
  167. for (j = 0; j < (int) dwCount; j++)
  168. {
  169. _tprintf(TEXT("\nGeneric Transport Filter #%d:\n"), i+j+1);
  170. if (!PrintFilter(ptf[j], TRUE, FALSE))
  171. { // error
  172. fTestPass=FALSE;
  173. break;
  174. }
  175. }
  176. SPDApiBufferFree(ptf);
  177. ptf=NULL;
  178. if(!fTestPass)
  179. break;
  180. }
  181. if (!fTestPass)
  182. {
  183. iReturn++;
  184. fTestPass = TRUE;
  185. }
  186. // quick mode transport specific without details
  187. _tprintf(TEXT("\nSpecific Transport Filters\n------------------------------\n"));
  188. ptf=NULL;
  189. dwResumeHandle=0;
  190. // make the call(s)
  191. for (i = 0; ;i+=dwCount)
  192. {
  193. hr = EnumTransportFilters(szServ, ENUM_SPECIFIC_FILTERS, gDefaultGUID, &ptf, 0, &dwCount, &dwResumeHandle);
  194. if (hr == ERROR_NO_DATA || dwCount == 0)
  195. {
  196. if (i == 0)
  197. {
  198. _tprintf(TEXT("No filters\n"));
  199. }
  200. break;
  201. }
  202. if (hr != ERROR_SUCCESS)
  203. {
  204. _tprintf(TEXT("EnumTransportFilters failed with error %d\n"), hr);
  205. reportError(hr);
  206. fTestPass=FALSE;
  207. break;
  208. }
  209. for (j = 0; j < (int) dwCount; j++)
  210. {
  211. _tprintf(TEXT("\nSpecific Transport Filter #%d:\n"), i+j+1);
  212. if (!PrintFilter(ptf[j], FALSE, TRUE))
  213. { // error
  214. fTestPass=FALSE;
  215. break;
  216. }
  217. }
  218. SPDApiBufferFree(ptf);
  219. ptf=NULL;
  220. if(!fTestPass)
  221. break;
  222. }
  223. if (!fTestPass)
  224. {
  225. iReturn++;
  226. fTestPass = TRUE;
  227. }
  228. // quick mode tunnel generic with details
  229. _tprintf(TEXT("\nGeneric Tunnel Filters\n------------------------------\n"));
  230. ptunf=NULL;
  231. dwResumeHandle=0;
  232. // make the call(s)
  233. for (i = 0; ;i+=dwCount)
  234. {
  235. hr = EnumTunnelFilters(szServ, ENUM_GENERIC_FILTERS, gDefaultGUID, &ptunf, 0, &dwCount, &dwResumeHandle);
  236. if (hr == ERROR_NO_DATA || dwCount == 0)
  237. {
  238. if (i == 0)
  239. {
  240. _tprintf(TEXT("No filters\n"));
  241. }
  242. break;
  243. }
  244. if (hr != ERROR_SUCCESS)
  245. {
  246. _tprintf(TEXT("EnumTunnelFilters failed with error %d\n"), hr);
  247. reportError(hr);
  248. fTestPass=FALSE;
  249. break;
  250. }
  251. for (j = 0; j < (int) dwCount; j++)
  252. {
  253. _tprintf(TEXT("\nGeneric Tunnel Filter #%d:\n"), i+j+1);
  254. if (!PrintTunnelFilter(ptunf[j], TRUE, FALSE))
  255. { // error
  256. fTestPass=FALSE;
  257. break;
  258. }
  259. }
  260. SPDApiBufferFree(ptunf);
  261. ptunf=NULL;
  262. if(!fTestPass)
  263. break;
  264. }
  265. if (!fTestPass)
  266. {
  267. iReturn++;
  268. fTestPass = TRUE;
  269. }
  270. // quick mode tunnel specific without details
  271. _tprintf(TEXT("\nSpecific Tunnel Filters\n------------------------------\n"));
  272. ptunf=NULL;
  273. dwResumeHandle=0;
  274. // make the call(s)
  275. for (i = 0; ;i+=dwCount)
  276. {
  277. hr = EnumTunnelFilters(szServ, ENUM_SPECIFIC_FILTERS, gDefaultGUID, &ptunf, 0, &dwCount, &dwResumeHandle);
  278. if (hr == ERROR_NO_DATA || dwCount == 0)
  279. {
  280. if (i == 0)
  281. {
  282. _tprintf(TEXT("No filters\n"));
  283. }
  284. break;
  285. }
  286. if (hr != ERROR_SUCCESS)
  287. {
  288. _tprintf(TEXT("EnumTunnelFilters failed with error %d\n"), hr);
  289. reportError(hr);
  290. fTestPass=FALSE;
  291. break;
  292. }
  293. for (j = 0; j < (int) dwCount; j++)
  294. {
  295. _tprintf(TEXT("\nSpecific Tunnel Filter #%d:\n"), i+j+1);
  296. if (!PrintTunnelFilter(ptunf[j], FALSE, TRUE))
  297. { // error
  298. fTestPass=FALSE;
  299. break;
  300. }
  301. }
  302. SPDApiBufferFree(ptunf);
  303. ptunf=NULL;
  304. if(!fTestPass)
  305. break;
  306. }
  307. if (!fTestPass)
  308. {
  309. iReturn++;
  310. fTestPass = TRUE;
  311. }
  312. }
  313. if (ipseccmdShow.bPolicies)
  314. {
  315. // print all policies
  316. // main mode policies
  317. _tprintf(TEXT("\nMain Mode Policies\n------------------------------\n"));
  318. pipsmmp=NULL;
  319. dwResumeHandle=0;
  320. // make the call(s)
  321. for (i = 0; ;i+=dwCount)
  322. {
  323. hr = EnumMMPolicies(szServ, &pipsmmp, 0, &dwCount, &dwResumeHandle);
  324. if (hr == ERROR_NO_DATA || dwCount == 0)
  325. {
  326. if (i == 0)
  327. {
  328. _tprintf(TEXT("No policies\n"));
  329. }
  330. break;
  331. }
  332. if (hr != ERROR_SUCCESS)
  333. {
  334. _tprintf(TEXT("EnumMMPolicies failed with error %d\n"), hr);
  335. reportError(hr);
  336. fTestPass=FALSE;
  337. break;
  338. }
  339. for (j = 0; j < (int) dwCount; j++)
  340. {
  341. _tprintf(TEXT("\nMain Mode Policy #%d:\n"), i+j+1);
  342. PrintMMPolicy(pipsmmp[j], _T(" "));
  343. }
  344. SPDApiBufferFree(pipsmmp);
  345. pipsmmp=NULL;
  346. if(!fTestPass)
  347. break;
  348. }
  349. if (!fTestPass)
  350. {
  351. iReturn++;
  352. fTestPass = TRUE;
  353. }
  354. // quick mode policies
  355. _tprintf(TEXT("\nQuick Mode Policies\n------------------------------\n"));
  356. pipsqmp=NULL;
  357. dwResumeHandle=0;
  358. // make the call(s)
  359. for (i = 0; ;i+=dwCount)
  360. {
  361. hr = EnumQMPolicies(szServ, &pipsqmp, 0, &dwCount, &dwResumeHandle);
  362. if (hr == ERROR_NO_DATA || dwCount == 0)
  363. {
  364. if (i == 0)
  365. {
  366. _tprintf(TEXT("No policies\n"));
  367. }
  368. break;
  369. }
  370. if (hr != ERROR_SUCCESS)
  371. {
  372. _tprintf(TEXT("EnumQMPolicies failed with error %d\n"), hr);
  373. reportError(hr);
  374. fTestPass=FALSE;
  375. break;
  376. }
  377. for (j = 0; j < (int) dwCount; j++)
  378. {
  379. _tprintf(TEXT("\nQuick Mode Policy #%d:\n"), i+j+1);
  380. PrintFilterAction(pipsqmp[j], _T(" "));
  381. }
  382. SPDApiBufferFree(pipsqmp);
  383. pipsqmp=NULL;
  384. if(!fTestPass)
  385. break;
  386. }
  387. if (!fTestPass)
  388. {
  389. iReturn++;
  390. fTestPass = TRUE;
  391. }
  392. }
  393. if (ipseccmdShow.bAuth)
  394. {
  395. // print main mode authentication methods
  396. _tprintf(TEXT("\nMain Mode Authentication Methods\n------------------------------\n"));
  397. pmmam=NULL;
  398. dwResumeHandle=0;
  399. // make the call(s)
  400. for (i = 0; ;i+=dwCount)
  401. {
  402. hr = EnumMMAuthMethods(szServ, &pmmam, 0, &dwCount, &dwResumeHandle);
  403. if (hr == ERROR_NO_DATA || dwCount == 0)
  404. {
  405. if (i == 0)
  406. {
  407. _tprintf(TEXT("No authentication methods\n"));
  408. }
  409. break;
  410. }
  411. if (hr != ERROR_SUCCESS)
  412. {
  413. _tprintf(TEXT("EnumMMAuthMethods failed with error %d\n"), hr);
  414. reportError(hr);
  415. fTestPass=FALSE;
  416. break;
  417. }
  418. for (j = 0; j < (int) dwCount; j++)
  419. {
  420. _tprintf(TEXT("\nMain Mode Authentication Methods #%d:\n"), i+j+1);
  421. PrintMMAuthMethods(pmmam[j], _T(" "));
  422. }
  423. SPDApiBufferFree(pmmam);
  424. pmmam=NULL;
  425. if(!fTestPass)
  426. break;
  427. }
  428. if (!fTestPass)
  429. {
  430. iReturn++;
  431. fTestPass = TRUE;
  432. }
  433. }
  434. if (ipseccmdShow.bStats)
  435. {
  436. // print stats
  437. // ike stats
  438. if ((hr = IPSecQueryIKEStatistics(szServ,&IKEStats)) != ERROR_SUCCESS)
  439. {
  440. _tprintf(TEXT("IPSecQueryIKEStatistics failed with error %d\n"), hr);
  441. reportError(hr);
  442. fTestPass=FALSE;
  443. }
  444. if (fTestPass)
  445. {
  446. _tprintf(TEXT("\nIKE Statistics\n------------------------------\n"));
  447. printf(" Main Modes %d\n",IKEStats.dwOakleyMainModes);
  448. printf(" Quick Modes %d\n",IKEStats.dwOakleyQuickModes);
  449. printf(" Soft SAs %d\n",IKEStats.dwSoftAssociations);
  450. printf(" Authentication Failures %d\n",IKEStats.dwAuthenticationFailures);
  451. printf(" Active Acquire %d\n",IKEStats.dwActiveAcquire);
  452. printf(" Active Receive %d\n",IKEStats.dwActiveReceive);
  453. printf(" Acquire fail %d\n",IKEStats.dwAcquireFail);
  454. printf(" Receive fail %d\n",IKEStats.dwReceiveFail);
  455. printf(" Send fail %d\n",IKEStats.dwSendFail);
  456. printf(" Acquire Heap size %d\n",IKEStats.dwAcquireHeapSize);
  457. printf(" Receive Heap size %d\n",IKEStats.dwReceiveHeapSize);
  458. printf(" Negotiation Failures %d\n",IKEStats.dwNegotiationFailures);
  459. printf(" Invalid Cookies Rcvd %d\n",IKEStats.dwInvalidCookiesReceived);
  460. printf(" Total Acquire %d\n",IKEStats.dwTotalAcquire);
  461. printf(" TotalGetSpi %d\n",IKEStats.dwTotalGetSpi);
  462. printf(" TotalKeyAdd %d\n",IKEStats.dwTotalKeyAdd);
  463. printf(" TotalKeyUpdate %d\n",IKEStats.dwTotalKeyUpdate);
  464. printf(" GetSpiFail %d\n",IKEStats.dwGetSpiFail);
  465. printf(" KeyAddFail %d\n",IKEStats.dwKeyAddFail);
  466. printf(" KeyUpdateFail %d\n",IKEStats.dwKeyUpdateFail);
  467. printf(" IsadbListSize %d\n",IKEStats.dwIsadbListSize);
  468. printf(" ConnListSize %d\n",IKEStats.dwConnListSize);
  469. _tprintf(_TEXT("\n"));
  470. }
  471. if (!fTestPass)
  472. {
  473. iReturn++;
  474. fTestPass = TRUE;
  475. }
  476. // ipsec stats
  477. if ((hr = QueryIPSecStatistics(szServ,&pIPSecStats)) != ERROR_SUCCESS)
  478. {
  479. _tprintf(TEXT("QueryIPSecStatistics failed with error %d\n"), hr);
  480. reportError(hr);
  481. fTestPass=FALSE;
  482. }
  483. if (fTestPass)
  484. {
  485. _tprintf(TEXT("\nIPSec Statistics\n------------------------------\n"));
  486. _tprintf(TEXT(" Active Assoc %lu\n"),pIPSecStats->dwNumActiveAssociations);
  487. _tprintf(TEXT(" Pending Key %lu\n"),pIPSecStats->dwNumPendingKeyOps);
  488. _tprintf(TEXT(" Key Adds %lu\n"),pIPSecStats->dwNumKeyAdditions);
  489. _tprintf(TEXT(" Key Deletes %lu\n"),pIPSecStats->dwNumKeyDeletions);
  490. _tprintf(TEXT(" ReKeys %lu\n"),pIPSecStats->dwNumReKeys);
  491. _tprintf(TEXT(" Active Tunnels %lu\n"),pIPSecStats->dwNumActiveTunnels);
  492. _tprintf(TEXT(" Bad SPI Pkts %lu\n"),pIPSecStats->dwNumBadSPIPackets);
  493. _tprintf(TEXT(" Pkts not Decrypted %lu\n"),pIPSecStats->dwNumPacketsNotDecrypted);
  494. _tprintf(TEXT(" Pkts not Authenticated %lu\n"),pIPSecStats->dwNumPacketsNotAuthenticated);
  495. _tprintf(TEXT(" Pkts with Replay Detection %lu\n"),pIPSecStats->dwNumPacketsWithReplayDetection);
  496. pszLLString = LongLongToString(pIPSecStats->uConfidentialBytesSent.HighPart,pIPSecStats->uConfidentialBytesSent.LowPart, 1);
  497. printf(" Confidential Bytes Sent %s\n", pszLLString);
  498. free(pszLLString);
  499. pszLLString = LongLongToString(pIPSecStats->uConfidentialBytesReceived.HighPart,pIPSecStats->uConfidentialBytesReceived.LowPart, 1);
  500. printf(" Confidential Bytes Received %s\n", pszLLString);
  501. free(pszLLString);
  502. pszLLString = LongLongToString(pIPSecStats->uAuthenticatedBytesSent.HighPart,pIPSecStats->uAuthenticatedBytesSent.LowPart, 1);
  503. printf(" Authenticated Bytes Sent %s\n", pszLLString);
  504. free(pszLLString);
  505. pszLLString = LongLongToString(pIPSecStats->uAuthenticatedBytesReceived.HighPart,pIPSecStats->uAuthenticatedBytesReceived.LowPart, 1);
  506. printf(" Authenticated Bytes Received %s\n", pszLLString);
  507. free(pszLLString);
  508. pszLLString = LongLongToString(pIPSecStats->uOffloadedBytesSent.HighPart,pIPSecStats->uOffloadedBytesSent.LowPart, 1);
  509. printf(" Offloaded Bytes Sent %s\n", pszLLString);
  510. free(pszLLString);
  511. pszLLString = LongLongToString(pIPSecStats->uOffloadedBytesReceived.HighPart,pIPSecStats->uOffloadedBytesReceived.LowPart, 1);
  512. printf(" Offloaded Bytes Received %s\n", pszLLString);
  513. free(pszLLString);
  514. pszLLString = LongLongToString(pIPSecStats->uBytesSentInTunnels.HighPart,pIPSecStats->uBytesSentInTunnels.LowPart, 1);
  515. printf(" Bytes Sent In Tunnels %s\n", pszLLString);
  516. free(pszLLString);
  517. pszLLString = LongLongToString(pIPSecStats->uBytesReceivedInTunnels.HighPart,pIPSecStats->uBytesReceivedInTunnels.LowPart, 1);
  518. printf(" Bytes Received In Tunnels %s\n", pszLLString);
  519. free(pszLLString);
  520. pszLLString = LongLongToString(pIPSecStats->uTransportBytesSent.HighPart,pIPSecStats->uTransportBytesSent.LowPart, 1);
  521. printf(" Transport Bytes Sent %s\n", pszLLString);
  522. free(pszLLString);
  523. pszLLString = LongLongToString(pIPSecStats->uTransportBytesReceived.HighPart,pIPSecStats->uTransportBytesReceived.LowPart, 1);
  524. printf(" Transport Bytes Received %s\n", pszLLString);
  525. free(pszLLString);
  526. _tprintf(_TEXT("\n"));
  527. SPDApiBufferFree(pIPSecStats);
  528. }
  529. if (!fTestPass)
  530. {
  531. iReturn++;
  532. fTestPass = TRUE;
  533. }
  534. }
  535. if (ipseccmdShow.bSAs)
  536. {
  537. // print all SAs
  538. // main mode SAs
  539. _tprintf(TEXT("\nMain Mode SAs\n------------------------------\n"));
  540. pipsmmsa=NULL;
  541. dwResumeHandle=0;
  542. dwCount = 2;
  543. dwReserved = 0;
  544. // make the call(s)
  545. for (i = 0; ;i+=dwCount)
  546. {
  547. IPSEC_MM_SA mmsaTemplate;
  548. memset(&mmsaTemplate, 0, sizeof(IPSEC_MM_SA));
  549. hr = IPSecEnumMMSAs(szServ, &mmsaTemplate, &pipsmmsa, &dwCount, &dwReserved, &dwResumeHandle, 0);
  550. if (hr == ERROR_NO_DATA || dwCount == 0)
  551. {
  552. if (i == 0)
  553. {
  554. _tprintf(TEXT("No SAs\n"));
  555. }
  556. break;
  557. }
  558. if (hr != ERROR_SUCCESS)
  559. {
  560. _tprintf(TEXT("IPSecEnumMMSAs failed with error %d\n"), hr);
  561. reportError(hr);
  562. fTestPass=FALSE;
  563. break;
  564. }
  565. for (j = 0; j < (int) dwCount; j++)
  566. {
  567. struct in_addr inAddr;
  568. _tprintf(TEXT("\nMain Mode SA #%d:\n"), i+j+1);
  569. // now print SA data
  570. inAddr.s_addr = pipsmmsa[j].Me.uIpAddr;
  571. printf(" From %s\n", inet_ntoa(inAddr));
  572. inAddr.s_addr = pipsmmsa[j].Peer.uIpAddr;
  573. printf(" To %s\n", inet_ntoa(inAddr));
  574. StringFromGUID2(pipsmmsa[j].gMMPolicyID, StringTxt, STRING_TEXT_SIZE);
  575. _tprintf(TEXT(" Policy Id : %s\n"), StringTxt);
  576. _tprintf(TEXT(" Offer Used : \n"));
  577. PrintMMOffer(pipsmmsa[j].SelectedMMOffer, _T(""), _T("\t"));
  578. _tprintf(TEXT(" Auth Used : %s\n"), oak_auth[pipsmmsa[j].MMAuthEnum]);
  579. // print cookies
  580. print_vpi(" Initiator cookie",(BYTE*)&(pipsmmsa[j].MMSpi.Initiator),sizeof(IKE_COOKIE));
  581. printf("\n");
  582. print_vpi(" Responder cookie",(BYTE*)&(pipsmmsa[j].MMSpi.Responder),sizeof(IKE_COOKIE));
  583. printf("\n");
  584. if (pipsmmsa[j].dwFlags != 0)
  585. {
  586. _tprintf(TEXT(" Flags : %lu\n"), pipsmmsa[j].dwFlags);
  587. }
  588. }
  589. SPDApiBufferFree(pipsmmsa);
  590. pipsmmsa=NULL;
  591. if (dwReserved == 0)
  592. {
  593. break;
  594. }
  595. if(!fTestPass)
  596. break;
  597. }
  598. if (!fTestPass)
  599. {
  600. iReturn++;
  601. fTestPass = TRUE;
  602. }
  603. // quick mode SAs
  604. _tprintf(TEXT("\nQuick Mode SAs\n------------------------------\n"));
  605. pipsqmsa=NULL;
  606. dwResumeHandle=0;
  607. dwCount = 2;
  608. dwReserved = 0;
  609. // make the call(s)
  610. for (i = 0; ;i+=dwCount)
  611. {
  612. hr = EnumQMSAs(szServ, NULL, &pipsqmsa, 0, &dwCount, &dwReserved, &dwResumeHandle, 0);
  613. if (hr == ERROR_NO_DATA || dwCount == 0)
  614. {
  615. if (i == 0)
  616. {
  617. _tprintf(TEXT("No SAs\n"));
  618. }
  619. break;
  620. }
  621. if (hr != ERROR_SUCCESS)
  622. {
  623. _tprintf(TEXT("EnumQMSAs failed with error %d\n"), hr);
  624. fTestPass=FALSE;
  625. break;
  626. }
  627. for (j = 0; j < (int) dwCount; j++)
  628. {
  629. struct in_addr inAddr;
  630. _tprintf(TEXT("\nQuick Mode SA #%d:\n"), i+j+1);
  631. // now print SA data - QM filter
  632. StringFromGUID2(pipsqmsa[j].gQMFilterID, StringTxt, STRING_TEXT_SIZE);
  633. _tprintf(TEXT(" Filter Id : %s\n"), StringTxt);
  634. _tprintf(TEXT(" %s Filter\n"),
  635. (pipsqmsa[j].IpsecQMFilter.QMFilterType == QM_TRANSPORT_FILTER) ? _T("Transport") :
  636. ((pipsqmsa[j].IpsecQMFilter.QMFilterType == QM_TUNNEL_FILTER) ? _T("Tunnel") : _T("Unknown"))
  637. );
  638. printf(" From ");
  639. PrintAddr(pipsqmsa[j].IpsecQMFilter.SrcAddr);
  640. printf("\n");
  641. printf(" To ");
  642. PrintAddr(pipsqmsa[j].IpsecQMFilter.DesAddr);
  643. printf("\n");
  644. _tprintf(TEXT(" Protocol : %lu Src Port : %u Des Port : %u\n"),
  645. pipsqmsa[j].IpsecQMFilter.Protocol.dwProtocol, pipsqmsa[j].IpsecQMFilter.SrcPort.wPort, pipsqmsa[j].IpsecQMFilter.DesPort.wPort);
  646. _tprintf(TEXT(" Direction : %s\n"),
  647. (pipsqmsa[j].IpsecQMFilter.dwFlags & FILTER_DIRECTION_INBOUND) ? _T("Inbound") :
  648. ((pipsqmsa[j].IpsecQMFilter.dwFlags & FILTER_DIRECTION_OUTBOUND) ? _T("Outbound") : _T("Error")));
  649. if (pipsqmsa[j].IpsecQMFilter.QMFilterType == QM_TUNNEL_FILTER)
  650. {
  651. printf(" Tunnel From ");
  652. PrintAddr(pipsqmsa[j].IpsecQMFilter.MyTunnelEndpt);
  653. printf("\n");
  654. printf(" Tunnel To ");
  655. PrintAddr(pipsqmsa[j].IpsecQMFilter.PeerTunnelEndpt);
  656. printf("\n");
  657. }
  658. // policy and cookie
  659. StringFromGUID2(pipsqmsa[j].gQMPolicyID, StringTxt, STRING_TEXT_SIZE);
  660. _tprintf(TEXT(" Policy Id : %s\n"), StringTxt);
  661. _tprintf(TEXT(" Offer Used : \n"));
  662. PrintQMOffer(pipsqmsa[j].SelectedQMOffer, _T(""), _T("\t"));
  663. // print cookies
  664. print_vpi(" Initiator cookie",(BYTE*)&(pipsqmsa[j].MMSpi.Initiator),sizeof(IKE_COOKIE));
  665. printf("\n");
  666. print_vpi(" Responder cookie",(BYTE*)&(pipsqmsa[j].MMSpi.Responder),sizeof(IKE_COOKIE));
  667. printf("\n");
  668. }
  669. SPDApiBufferFree(pipsqmsa);
  670. pipsqmsa=NULL;
  671. if (dwReserved == 0)
  672. {
  673. break;
  674. }
  675. if(!fTestPass)
  676. break;
  677. }
  678. if (!fTestPass)
  679. {
  680. iReturn++;
  681. fTestPass = TRUE;
  682. }
  683. }
  684. return iReturn;
  685. }
  686. // process query command line
  687. // accept command line (argc/argv) and the index where show flags start
  688. // return 0 if command completed successfully,
  689. // IPSECCMD_USAGE if there is usage error,
  690. // any other value indicates failure during execution (gets passed up)
  691. //
  692. // IMPORTANT: we assume that main module provide us with remote vs. local machine information
  693. // in the global variables
  694. //
  695. int ipseccmd_show_main ( int argc, char** argv, int start_index )
  696. {
  697. int i;
  698. ipseccmdShow.bFilters = ipseccmdShow.bPolicies = ipseccmdShow.bAuth = ipseccmdShow.bStats = ipseccmdShow.bSAs = false;
  699. for (i = start_index ; i < argc; i++)
  700. {
  701. if (!_stricmp(argv[i], KEYWORD_SHOW))
  702. {
  703. continue; // skip that
  704. }
  705. else if (!_stricmp(argv[i], KEYWORD_FILTERS))
  706. {
  707. ipseccmdShow.bFilters = true;
  708. }
  709. else if (!_stricmp(argv[i], KEYWORD_POLICIES))
  710. {
  711. ipseccmdShow.bPolicies = true;
  712. }
  713. else if (!_stricmp(argv[i], KEYWORD_AUTH))
  714. {
  715. ipseccmdShow.bAuth = true;
  716. }
  717. else if (!_stricmp(argv[i], KEYWORD_STATS))
  718. {
  719. ipseccmdShow.bStats = true;
  720. }
  721. else if (!_stricmp(argv[i], KEYWORD_SAS))
  722. {
  723. ipseccmdShow.bSAs = true;
  724. }
  725. else if (!_stricmp(argv[i], KEYWORD_ALL))
  726. {
  727. ipseccmdShow.bFilters = ipseccmdShow.bPolicies = ipseccmdShow.bAuth = ipseccmdShow.bStats = ipseccmdShow.bSAs = true;
  728. }
  729. else
  730. {
  731. return IPSECCMD_USAGE;
  732. }
  733. }
  734. return do_show();
  735. }
  736. // print_vpi prints IKE_COOKIE information
  737. // Parms:
  738. // Returns: None
  739. void print_vpi(char *str, unsigned char *vpi, int vpi_len)
  740. {
  741. int i, j;
  742. char msg [256] ;
  743. char c [5];
  744. strcpy ( msg, str) ;
  745. strcat ( msg," ") ;
  746. if (vpi == NULL) {
  747. strcat(msg,"VPI NULL ");
  748. printf("%s", msg) ;
  749. return;
  750. }
  751. for (j=1, i=0; i<vpi_len; i++) {
  752. sprintf(c,"%02x",vpi[i]);
  753. strcat(msg, c) ;
  754. if (j == 16) {
  755. j = 0;
  756. printf("%s", msg);
  757. msg[0] = 0 ;
  758. }
  759. j++;
  760. }
  761. if ( j != 1)
  762. {
  763. printf("%s", msg);
  764. }
  765. else
  766. {
  767. printf("");
  768. }
  769. } // end of print_vpi
  770. /**********************************************************************************
  771. *
  772. * AscAddUint - Add two numbers in ascii strings, storing the results in a third buffer
  773. * cSum - Buffer for the sum
  774. * cA - First addend
  775. * cB - Second addend
  776. *
  777. * This routine will add two arbitrarily long ascii strings. It makes several
  778. * assumptions about them.
  779. * 1) the string is null terminated.
  780. * 2) The LSB is the last char of the string. "1000000" is a million
  781. * 3) There are no signs or decimal points.
  782. * 4) The cSum buffer is large enough to store the result
  783. * 5) The sum will require 254 bytes or less.
  784. *
  785. * returns: 0 on success, else failure code.
  786. *
  787. **********************************************************************************/
  788. int
  789. AscAddUint(
  790. char *cSum,
  791. char *cA,
  792. char *cB
  793. )
  794. {
  795. int iALen, iBLen, iSumLen, iBiggerLen;
  796. int i,j,k, iCarry;
  797. char cTmp[255]={0}, *cBigger;
  798. // Verify parameters
  799. if ((cA == NULL) || (cB == NULL) || (cSum == NULL))
  800. {
  801. printf("AscAddUint(%0X,%0X, %0X) ERROR - bad parameters\n",
  802. (UINT) cA, (UINT) cB, (UINT) cSum);
  803. return(-1);
  804. }
  805. iALen = strlen(cA);
  806. iBLen = strlen(cB);
  807. iCarry = 0;
  808. // Loop through, adding the values. Our result string will be
  809. // backwards, we'll straighten it out when we copy it to the
  810. // cSum buffer.
  811. for (i=0; (i < iALen) && (i < iBLen); i++)
  812. {
  813. // Figure out the actual decimal value of the add.
  814. k = (int) (cA[iALen-i-1] + cB[iBLen-i-1] + iCarry);
  815. k -= 2 * '0';
  816. // Set the carry as appropriate
  817. iCarry = k/10;
  818. // Set the current digit's value.
  819. cTmp[i] = '0' + k%10;
  820. }
  821. // At this point, all digits present in both strings have been added.
  822. // In other words, "12345" + "678901", "12345" has been added to "78901"
  823. // The next step is to account for the high-order digits of the larger number.
  824. if (iALen > iBLen)
  825. {
  826. cBigger = cA;
  827. iBiggerLen = iALen;
  828. }
  829. else
  830. {
  831. cBigger = cB;
  832. iBiggerLen = iBLen;
  833. }
  834. while (i < iBiggerLen)
  835. {
  836. k = cBigger[iBiggerLen - i - 1] + iCarry - '0';
  837. // Set the carry as appropriate
  838. iCarry = k/10;
  839. // Set the current digit's value.
  840. cTmp[i] = '0' + k%10;
  841. i++;
  842. }
  843. // Finally, we might still have a set carry to put in the next
  844. // digit.
  845. if (iCarry)
  846. {
  847. cTmp[i++] = '0' + iCarry;
  848. }
  849. // Now that we've got the entire number, reverse it and put it back in the dest.
  850. // Skip leading 0's.
  851. i = strlen(cTmp) - 1;
  852. while ((i > 0)&&(cTmp[i] == '0'))
  853. {
  854. i--;
  855. }
  856. // and copy the number.
  857. j = 0;
  858. while (i >= 0)
  859. {
  860. cSum[j++] = cTmp[i--];
  861. }
  862. cSum[j] = '\0';
  863. // We're done. Return 0 for success!
  864. return(0);
  865. }
  866. /**********************************************************************************
  867. *
  868. * AscMultUint - Multiply two numbers in ascii strings, storing the results in a third buffer
  869. * cProduct - Buffer for the product
  870. * cA - First multiplicand
  871. * cB - Second multiplicand
  872. *
  873. * This routine will add two arbitrarily long ascii strings. It makes several
  874. * assumptions about them.
  875. * 1) the string is null terminated.
  876. * 2) The LSB is the last char of the string. "1000000" is a million
  877. * 3) There are no signs or decimal points.
  878. * 4) The cProduct buffer is large enough to store the result
  879. * 5) The product will require 254 bytes or less.
  880. *
  881. * returns: 0 on success, else failure code.
  882. *
  883. **********************************************************************************/
  884. int
  885. AscMultUint(
  886. char *cProduct,
  887. char *cA,
  888. char *cB
  889. )
  890. {
  891. int iALen, iBLen, iProductLen;
  892. int i,j,k, iCarry;
  893. char cTmp[255]={0};
  894. // Verify parameters
  895. if ((cA == NULL) || (cB == NULL) || (cProduct == NULL))
  896. {
  897. printf("AscMultUint(%0X,%0X, %0X) ERROR - bad parameters\n",
  898. (UINT) cA, (UINT) cB, (UINT) cProduct);
  899. return(-1);
  900. }
  901. iALen = strlen(cA);
  902. iBLen = strlen(cB);
  903. // We will multiply the traditional longhand way: for each digit in
  904. // cA, we will multiply it against cB and add the incremental result
  905. // into our temporary product.
  906. // for each digit of the first multiplicand
  907. for (i=0; i < iALen; i++)
  908. {
  909. iCarry = 0;
  910. // for each digit of the second multiplicand
  911. for(j=0; j < iBLen; j++)
  912. {
  913. // calculate this digit's value
  914. k = ((int) cA[iALen-i-1]-'0') * ((int) cB[iBLen-j-1]-'0');
  915. k += iCarry;
  916. // Add it in to the appropriate place in the result
  917. if (cTmp[i+j] != '\0')
  918. {
  919. k += (int) cTmp[i+j] - '0';
  920. }
  921. cTmp[i+j] = '0' + (k % 10);
  922. iCarry = k/10;
  923. }
  924. // Take care of the straggler carry. If the higher
  925. // digits happen to be '9999' then this can require
  926. // a loop.
  927. while (iCarry)
  928. {
  929. if (cTmp[i+j] != '\0')
  930. {
  931. iCarry += cTmp[i+j] - '0';
  932. }
  933. cTmp[i+j] = '0' + iCarry%10;
  934. iCarry /= 10;
  935. j++;
  936. }
  937. }
  938. // Now that we've got the entire number, reverse it and put it back in the dest.
  939. // Skip leading 0's.
  940. i = strlen(cTmp) - 1;
  941. while ((i > 0)&&(cTmp[i] == '0'))
  942. {
  943. i--;
  944. }
  945. // Copy the product.
  946. j = 0;
  947. while (i >= 0)
  948. {
  949. cProduct[j++] = cTmp[i--];
  950. }
  951. cProduct[j] = '\0';
  952. // We're done. Return 0 for success!
  953. return(0);
  954. }
  955. /*******************************************************
  956. *
  957. * LongLongToString - Convert a low and high DWORD to a decimal string
  958. * dwLow - Low order dword
  959. * dwHigh - High order dword
  960. * iPrintCommas - insert comma's if non-zero
  961. *
  962. * This routine will make a pretty string to match an input long-long,
  963. * and return it. If iPrintCommas is set, it will put in commas.
  964. *
  965. *
  966. * returns: pointer to newly allocated string with number in it.
  967. * NOTE - the caller is responsible for freeing the memory allocated.
  968. *
  969. *******************************************************/
  970. char *
  971. LongLongToString(
  972. DWORD dwHigh,
  973. DWORD dwLow,
  974. int iPrintCommas
  975. )
  976. {
  977. char cFourGig[]="4294967296"; // "four gigabytes"
  978. char cBuf[255]={0};
  979. char cRes[255]={0}, cFullRes[255]={0}, *cRet;
  980. int iPos, iPosRes, iThreeCount;
  981. // First, multiply the high dword by decimal 2^32 to
  982. // get the right decimal value for it.
  983. sprintf(cBuf,"%u",dwHigh);
  984. AscMultUint(cRes,cBuf,cFourGig);
  985. // next, add in the low DWORD (fine as it is)
  986. // to the previous product
  987. sprintf(cBuf,"%u",dwLow);
  988. AscAddUint(cFullRes, cRes, cBuf);
  989. // Finally, copy the buffer with commas.
  990. iPos = iPosRes = 0;
  991. iThreeCount = strlen(cFullRes)%3;
  992. while(cFullRes[iPosRes] != '\0')
  993. {
  994. cBuf[iPos++] = cFullRes[iPosRes++];
  995. iThreeCount +=2; // Same as subtracting one for modulo math
  996. if ((!(iThreeCount%3))&&(cFullRes[iPosRes] != '\0')&&(iPrintCommas))
  997. {
  998. cBuf[iPos++]=',';
  999. }
  1000. }
  1001. cBuf[iPos] = '\0';
  1002. cRet = _strdup(cBuf);
  1003. return(cRet);
  1004. }