//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 2001 // // File: query.cpp // Purpose: query SPD and print IP Security information // // //-------------------------------------------------------------------------- /* Edit History: 1/18/01 dkalin Created */ // app's own header file #include "ipseccmd.h" #pragma warning(disable:4311) // forward function declarations char *LongLongToString( DWORD dwHigh, DWORD dwLow, int iPrintCommas ); int AscMultUint( char *cProduct, char *cA, char *cB ); int AscAddUint( char *cSum, char *cA, char *cB ); void print_vpi(char *str, unsigned char *vpi, int vpi_len); void reportError ( DWORD dwMessageId ) { LPVOID myErrString = NULL; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, dwMessageId, 0, (LPTSTR)&myErrString, 0, NULL); _ftprintf(stderr, TEXT("%s\n"), myErrString); LocalFree(myErrString); } // run SPD query and display results, uses global flags to determine what needs to be printed int do_show ( ) { int iReturn = 0; // success by default int i, j; DWORD hr = FALSE; // assume success bool fTestPass = TRUE; char* pszLLString; TCHAR StringTxt[STRING_TEXT_SIZE+1]; PMM_FILTER pmmf; // for MM filter calls PIPSEC_MM_SA pipsmmsa; // for MM SA calls PIPSEC_QM_SA pipsqmsa; // for QM SA calls PIPSEC_MM_POLICY pipsmmp; // for MM policy calls PIPSEC_QM_POLICY pipsqmp; // for QM policy calls PMM_AUTH_METHODS pmmam; // for MM auth methods calls IKE_STATISTICS IKEStats; // for IKE stats calls PIPSEC_STATISTICS pIPSecStats; // for IPSec stats calls PTRANSPORT_FILTER ptf; // for transport filter calls PTUNNEL_FILTER ptunf; // for tunnel filter calls DWORD dwCount; // counting objects here DWORD dwResumeHandle; // handle for continuation calls DWORD dwReserved; // reserved container GUID gDefaultGUID = {0}; // NULL GUID value if (ipseccmdShow.bFilters) { // print all filters // main mode generic with details _tprintf(TEXT("\nGeneric MM Filters\n------------------------------\n")); pmmf=NULL; dwResumeHandle=0; // make the call(s) for (i = 0; ;i+=dwCount) { hr = EnumMMFilters(szServ, ENUM_GENERIC_FILTERS, gDefaultGUID, &pmmf, 0, &dwCount, &dwResumeHandle); if (hr == ERROR_NO_DATA || dwCount == 0) { if (i == 0) { _tprintf(TEXT("No filters\n")); } break; } if (hr != ERROR_SUCCESS) { _tprintf(TEXT("EnumMMFilters failed with error %d\n"), hr); reportError(hr); fTestPass = FALSE; // indicate an error break; } for (j = 0; j < (int) dwCount; j++) { _tprintf(TEXT("\nGeneric MM Filter #%d:\n"), i+j+1); if (!PrintMMFilter(pmmf[j], TRUE, FALSE)) { fTestPass = FALSE; // indicate an error break; } } SPDApiBufferFree(pmmf); pmmf=NULL; if(!fTestPass) break; } if (!fTestPass) { iReturn++; fTestPass = TRUE; } // main mode specific without details _tprintf(TEXT("\nSpecific MM Filters\n------------------------------\n")); pmmf=NULL; dwResumeHandle=0; // make the call(s) for (i = 0; ;i+=dwCount) { hr = EnumMMFilters(szServ, ENUM_SPECIFIC_FILTERS, gDefaultGUID, &pmmf, 0, &dwCount, &dwResumeHandle); if (hr == ERROR_NO_DATA || dwCount == 0) { if (i == 0) { _tprintf(TEXT("No filters\n")); } break; } if (hr != ERROR_SUCCESS) { _tprintf(TEXT("EnumMMFilters failed with error %d\n"), hr); reportError(hr); fTestPass = FALSE; // indicate an error break; } for (j = 0; j < (int) dwCount; j++) { _tprintf(TEXT("\nSpecific MM Filter #%d:\n"), i+j+1); if (!PrintMMFilter(pmmf[j], FALSE, TRUE)) { // error fTestPass = FALSE; // indicate an error break; } } SPDApiBufferFree(pmmf); pmmf=NULL; if(!fTestPass) break; } if (!fTestPass) { iReturn++; fTestPass = TRUE; } // quick mode transport generic with details _tprintf(TEXT("\nGeneric Transport Filters\n------------------------------\n")); ptf=NULL; dwResumeHandle=0; // make the call(s) for (i = 0; ;i+=dwCount) { hr = EnumTransportFilters(szServ, ENUM_GENERIC_FILTERS, gDefaultGUID, &ptf, 0, &dwCount, &dwResumeHandle); if (hr == ERROR_NO_DATA || dwCount == 0) { if (i == 0) { _tprintf(TEXT("No filters\n")); } break; } if (hr != ERROR_SUCCESS) { _tprintf(TEXT("EnumTransportFilters failed with error %d\n"), hr); reportError(hr); fTestPass=FALSE; break; } for (j = 0; j < (int) dwCount; j++) { _tprintf(TEXT("\nGeneric Transport Filter #%d:\n"), i+j+1); if (!PrintFilter(ptf[j], TRUE, FALSE)) { // error fTestPass=FALSE; break; } } SPDApiBufferFree(ptf); ptf=NULL; if(!fTestPass) break; } if (!fTestPass) { iReturn++; fTestPass = TRUE; } // quick mode transport specific without details _tprintf(TEXT("\nSpecific Transport Filters\n------------------------------\n")); ptf=NULL; dwResumeHandle=0; // make the call(s) for (i = 0; ;i+=dwCount) { hr = EnumTransportFilters(szServ, ENUM_SPECIFIC_FILTERS, gDefaultGUID, &ptf, 0, &dwCount, &dwResumeHandle); if (hr == ERROR_NO_DATA || dwCount == 0) { if (i == 0) { _tprintf(TEXT("No filters\n")); } break; } if (hr != ERROR_SUCCESS) { _tprintf(TEXT("EnumTransportFilters failed with error %d\n"), hr); reportError(hr); fTestPass=FALSE; break; } for (j = 0; j < (int) dwCount; j++) { _tprintf(TEXT("\nSpecific Transport Filter #%d:\n"), i+j+1); if (!PrintFilter(ptf[j], FALSE, TRUE)) { // error fTestPass=FALSE; break; } } SPDApiBufferFree(ptf); ptf=NULL; if(!fTestPass) break; } if (!fTestPass) { iReturn++; fTestPass = TRUE; } // quick mode tunnel generic with details _tprintf(TEXT("\nGeneric Tunnel Filters\n------------------------------\n")); ptunf=NULL; dwResumeHandle=0; // make the call(s) for (i = 0; ;i+=dwCount) { hr = EnumTunnelFilters(szServ, ENUM_GENERIC_FILTERS, gDefaultGUID, &ptunf, 0, &dwCount, &dwResumeHandle); if (hr == ERROR_NO_DATA || dwCount == 0) { if (i == 0) { _tprintf(TEXT("No filters\n")); } break; } if (hr != ERROR_SUCCESS) { _tprintf(TEXT("EnumTunnelFilters failed with error %d\n"), hr); reportError(hr); fTestPass=FALSE; break; } for (j = 0; j < (int) dwCount; j++) { _tprintf(TEXT("\nGeneric Tunnel Filter #%d:\n"), i+j+1); if (!PrintTunnelFilter(ptunf[j], TRUE, FALSE)) { // error fTestPass=FALSE; break; } } SPDApiBufferFree(ptunf); ptunf=NULL; if(!fTestPass) break; } if (!fTestPass) { iReturn++; fTestPass = TRUE; } // quick mode tunnel specific without details _tprintf(TEXT("\nSpecific Tunnel Filters\n------------------------------\n")); ptunf=NULL; dwResumeHandle=0; // make the call(s) for (i = 0; ;i+=dwCount) { hr = EnumTunnelFilters(szServ, ENUM_SPECIFIC_FILTERS, gDefaultGUID, &ptunf, 0, &dwCount, &dwResumeHandle); if (hr == ERROR_NO_DATA || dwCount == 0) { if (i == 0) { _tprintf(TEXT("No filters\n")); } break; } if (hr != ERROR_SUCCESS) { _tprintf(TEXT("EnumTunnelFilters failed with error %d\n"), hr); reportError(hr); fTestPass=FALSE; break; } for (j = 0; j < (int) dwCount; j++) { _tprintf(TEXT("\nSpecific Tunnel Filter #%d:\n"), i+j+1); if (!PrintTunnelFilter(ptunf[j], FALSE, TRUE)) { // error fTestPass=FALSE; break; } } SPDApiBufferFree(ptunf); ptunf=NULL; if(!fTestPass) break; } if (!fTestPass) { iReturn++; fTestPass = TRUE; } } if (ipseccmdShow.bPolicies) { // print all policies // main mode policies _tprintf(TEXT("\nMain Mode Policies\n------------------------------\n")); pipsmmp=NULL; dwResumeHandle=0; // make the call(s) for (i = 0; ;i+=dwCount) { hr = EnumMMPolicies(szServ, &pipsmmp, 0, &dwCount, &dwResumeHandle); if (hr == ERROR_NO_DATA || dwCount == 0) { if (i == 0) { _tprintf(TEXT("No policies\n")); } break; } if (hr != ERROR_SUCCESS) { _tprintf(TEXT("EnumMMPolicies failed with error %d\n"), hr); reportError(hr); fTestPass=FALSE; break; } for (j = 0; j < (int) dwCount; j++) { _tprintf(TEXT("\nMain Mode Policy #%d:\n"), i+j+1); PrintMMPolicy(pipsmmp[j], _T(" ")); } SPDApiBufferFree(pipsmmp); pipsmmp=NULL; if(!fTestPass) break; } if (!fTestPass) { iReturn++; fTestPass = TRUE; } // quick mode policies _tprintf(TEXT("\nQuick Mode Policies\n------------------------------\n")); pipsqmp=NULL; dwResumeHandle=0; // make the call(s) for (i = 0; ;i+=dwCount) { hr = EnumQMPolicies(szServ, &pipsqmp, 0, &dwCount, &dwResumeHandle); if (hr == ERROR_NO_DATA || dwCount == 0) { if (i == 0) { _tprintf(TEXT("No policies\n")); } break; } if (hr != ERROR_SUCCESS) { _tprintf(TEXT("EnumQMPolicies failed with error %d\n"), hr); reportError(hr); fTestPass=FALSE; break; } for (j = 0; j < (int) dwCount; j++) { _tprintf(TEXT("\nQuick Mode Policy #%d:\n"), i+j+1); PrintFilterAction(pipsqmp[j], _T(" ")); } SPDApiBufferFree(pipsqmp); pipsqmp=NULL; if(!fTestPass) break; } if (!fTestPass) { iReturn++; fTestPass = TRUE; } } if (ipseccmdShow.bAuth) { // print main mode authentication methods _tprintf(TEXT("\nMain Mode Authentication Methods\n------------------------------\n")); pmmam=NULL; dwResumeHandle=0; // make the call(s) for (i = 0; ;i+=dwCount) { hr = EnumMMAuthMethods(szServ, &pmmam, 0, &dwCount, &dwResumeHandle); if (hr == ERROR_NO_DATA || dwCount == 0) { if (i == 0) { _tprintf(TEXT("No authentication methods\n")); } break; } if (hr != ERROR_SUCCESS) { _tprintf(TEXT("EnumMMAuthMethods failed with error %d\n"), hr); reportError(hr); fTestPass=FALSE; break; } for (j = 0; j < (int) dwCount; j++) { _tprintf(TEXT("\nMain Mode Authentication Methods #%d:\n"), i+j+1); PrintMMAuthMethods(pmmam[j], _T(" ")); } SPDApiBufferFree(pmmam); pmmam=NULL; if(!fTestPass) break; } if (!fTestPass) { iReturn++; fTestPass = TRUE; } } if (ipseccmdShow.bStats) { // print stats // ike stats if ((hr = IPSecQueryIKEStatistics(szServ,&IKEStats)) != ERROR_SUCCESS) { _tprintf(TEXT("IPSecQueryIKEStatistics failed with error %d\n"), hr); reportError(hr); fTestPass=FALSE; } if (fTestPass) { _tprintf(TEXT("\nIKE Statistics\n------------------------------\n")); printf(" Main Modes %d\n",IKEStats.dwOakleyMainModes); printf(" Quick Modes %d\n",IKEStats.dwOakleyQuickModes); printf(" Soft SAs %d\n",IKEStats.dwSoftAssociations); printf(" Authentication Failures %d\n",IKEStats.dwAuthenticationFailures); printf(" Active Acquire %d\n",IKEStats.dwActiveAcquire); printf(" Active Receive %d\n",IKEStats.dwActiveReceive); printf(" Acquire fail %d\n",IKEStats.dwAcquireFail); printf(" Receive fail %d\n",IKEStats.dwReceiveFail); printf(" Send fail %d\n",IKEStats.dwSendFail); printf(" Acquire Heap size %d\n",IKEStats.dwAcquireHeapSize); printf(" Receive Heap size %d\n",IKEStats.dwReceiveHeapSize); printf(" Negotiation Failures %d\n",IKEStats.dwNegotiationFailures); printf(" Invalid Cookies Rcvd %d\n",IKEStats.dwInvalidCookiesReceived); printf(" Total Acquire %d\n",IKEStats.dwTotalAcquire); printf(" TotalGetSpi %d\n",IKEStats.dwTotalGetSpi); printf(" TotalKeyAdd %d\n",IKEStats.dwTotalKeyAdd); printf(" TotalKeyUpdate %d\n",IKEStats.dwTotalKeyUpdate); printf(" GetSpiFail %d\n",IKEStats.dwGetSpiFail); printf(" KeyAddFail %d\n",IKEStats.dwKeyAddFail); printf(" KeyUpdateFail %d\n",IKEStats.dwKeyUpdateFail); printf(" IsadbListSize %d\n",IKEStats.dwIsadbListSize); printf(" ConnListSize %d\n",IKEStats.dwConnListSize); _tprintf(_TEXT("\n")); } if (!fTestPass) { iReturn++; fTestPass = TRUE; } // ipsec stats if ((hr = QueryIPSecStatistics(szServ,&pIPSecStats)) != ERROR_SUCCESS) { _tprintf(TEXT("QueryIPSecStatistics failed with error %d\n"), hr); reportError(hr); fTestPass=FALSE; } if (fTestPass) { _tprintf(TEXT("\nIPSec Statistics\n------------------------------\n")); _tprintf(TEXT(" Active Assoc %lu\n"),pIPSecStats->dwNumActiveAssociations); _tprintf(TEXT(" Pending Key %lu\n"),pIPSecStats->dwNumPendingKeyOps); _tprintf(TEXT(" Key Adds %lu\n"),pIPSecStats->dwNumKeyAdditions); _tprintf(TEXT(" Key Deletes %lu\n"),pIPSecStats->dwNumKeyDeletions); _tprintf(TEXT(" ReKeys %lu\n"),pIPSecStats->dwNumReKeys); _tprintf(TEXT(" Active Tunnels %lu\n"),pIPSecStats->dwNumActiveTunnels); _tprintf(TEXT(" Bad SPI Pkts %lu\n"),pIPSecStats->dwNumBadSPIPackets); _tprintf(TEXT(" Pkts not Decrypted %lu\n"),pIPSecStats->dwNumPacketsNotDecrypted); _tprintf(TEXT(" Pkts not Authenticated %lu\n"),pIPSecStats->dwNumPacketsNotAuthenticated); _tprintf(TEXT(" Pkts with Replay Detection %lu\n"),pIPSecStats->dwNumPacketsWithReplayDetection); pszLLString = LongLongToString(pIPSecStats->uConfidentialBytesSent.HighPart,pIPSecStats->uConfidentialBytesSent.LowPart, 1); printf(" Confidential Bytes Sent %s\n", pszLLString); free(pszLLString); pszLLString = LongLongToString(pIPSecStats->uConfidentialBytesReceived.HighPart,pIPSecStats->uConfidentialBytesReceived.LowPart, 1); printf(" Confidential Bytes Received %s\n", pszLLString); free(pszLLString); pszLLString = LongLongToString(pIPSecStats->uAuthenticatedBytesSent.HighPart,pIPSecStats->uAuthenticatedBytesSent.LowPart, 1); printf(" Authenticated Bytes Sent %s\n", pszLLString); free(pszLLString); pszLLString = LongLongToString(pIPSecStats->uAuthenticatedBytesReceived.HighPart,pIPSecStats->uAuthenticatedBytesReceived.LowPart, 1); printf(" Authenticated Bytes Received %s\n", pszLLString); free(pszLLString); pszLLString = LongLongToString(pIPSecStats->uOffloadedBytesSent.HighPart,pIPSecStats->uOffloadedBytesSent.LowPart, 1); printf(" Offloaded Bytes Sent %s\n", pszLLString); free(pszLLString); pszLLString = LongLongToString(pIPSecStats->uOffloadedBytesReceived.HighPart,pIPSecStats->uOffloadedBytesReceived.LowPart, 1); printf(" Offloaded Bytes Received %s\n", pszLLString); free(pszLLString); pszLLString = LongLongToString(pIPSecStats->uBytesSentInTunnels.HighPart,pIPSecStats->uBytesSentInTunnels.LowPart, 1); printf(" Bytes Sent In Tunnels %s\n", pszLLString); free(pszLLString); pszLLString = LongLongToString(pIPSecStats->uBytesReceivedInTunnels.HighPart,pIPSecStats->uBytesReceivedInTunnels.LowPart, 1); printf(" Bytes Received In Tunnels %s\n", pszLLString); free(pszLLString); pszLLString = LongLongToString(pIPSecStats->uTransportBytesSent.HighPart,pIPSecStats->uTransportBytesSent.LowPart, 1); printf(" Transport Bytes Sent %s\n", pszLLString); free(pszLLString); pszLLString = LongLongToString(pIPSecStats->uTransportBytesReceived.HighPart,pIPSecStats->uTransportBytesReceived.LowPart, 1); printf(" Transport Bytes Received %s\n", pszLLString); free(pszLLString); _tprintf(_TEXT("\n")); SPDApiBufferFree(pIPSecStats); } if (!fTestPass) { iReturn++; fTestPass = TRUE; } } if (ipseccmdShow.bSAs) { // print all SAs // main mode SAs _tprintf(TEXT("\nMain Mode SAs\n------------------------------\n")); pipsmmsa=NULL; dwResumeHandle=0; dwCount = 2; dwReserved = 0; // make the call(s) for (i = 0; ;i+=dwCount) { IPSEC_MM_SA mmsaTemplate; memset(&mmsaTemplate, 0, sizeof(IPSEC_MM_SA)); hr = IPSecEnumMMSAs(szServ, &mmsaTemplate, &pipsmmsa, &dwCount, &dwReserved, &dwResumeHandle, 0); if (hr == ERROR_NO_DATA || dwCount == 0) { if (i == 0) { _tprintf(TEXT("No SAs\n")); } break; } if (hr != ERROR_SUCCESS) { _tprintf(TEXT("IPSecEnumMMSAs failed with error %d\n"), hr); reportError(hr); fTestPass=FALSE; break; } for (j = 0; j < (int) dwCount; j++) { struct in_addr inAddr; _tprintf(TEXT("\nMain Mode SA #%d:\n"), i+j+1); // now print SA data inAddr.s_addr = pipsmmsa[j].Me.uIpAddr; printf(" From %s\n", inet_ntoa(inAddr)); inAddr.s_addr = pipsmmsa[j].Peer.uIpAddr; printf(" To %s\n", inet_ntoa(inAddr)); StringFromGUID2(pipsmmsa[j].gMMPolicyID, StringTxt, STRING_TEXT_SIZE); _tprintf(TEXT(" Policy Id : %s\n"), StringTxt); _tprintf(TEXT(" Offer Used : \n")); PrintMMOffer(pipsmmsa[j].SelectedMMOffer, _T(""), _T("\t")); _tprintf(TEXT(" Auth Used : %s\n"), oak_auth[pipsmmsa[j].MMAuthEnum]); // print cookies print_vpi(" Initiator cookie",(BYTE*)&(pipsmmsa[j].MMSpi.Initiator),sizeof(IKE_COOKIE)); printf("\n"); print_vpi(" Responder cookie",(BYTE*)&(pipsmmsa[j].MMSpi.Responder),sizeof(IKE_COOKIE)); printf("\n"); if (pipsmmsa[j].dwFlags != 0) { _tprintf(TEXT(" Flags : %lu\n"), pipsmmsa[j].dwFlags); } } SPDApiBufferFree(pipsmmsa); pipsmmsa=NULL; if (dwReserved == 0) { break; } if(!fTestPass) break; } if (!fTestPass) { iReturn++; fTestPass = TRUE; } // quick mode SAs _tprintf(TEXT("\nQuick Mode SAs\n------------------------------\n")); pipsqmsa=NULL; dwResumeHandle=0; dwCount = 2; dwReserved = 0; // make the call(s) for (i = 0; ;i+=dwCount) { hr = EnumQMSAs(szServ, NULL, &pipsqmsa, 0, &dwCount, &dwReserved, &dwResumeHandle, 0); if (hr == ERROR_NO_DATA || dwCount == 0) { if (i == 0) { _tprintf(TEXT("No SAs\n")); } break; } if (hr != ERROR_SUCCESS) { _tprintf(TEXT("EnumQMSAs failed with error %d\n"), hr); fTestPass=FALSE; break; } for (j = 0; j < (int) dwCount; j++) { struct in_addr inAddr; _tprintf(TEXT("\nQuick Mode SA #%d:\n"), i+j+1); // now print SA data - QM filter StringFromGUID2(pipsqmsa[j].gQMFilterID, StringTxt, STRING_TEXT_SIZE); _tprintf(TEXT(" Filter Id : %s\n"), StringTxt); _tprintf(TEXT(" %s Filter\n"), (pipsqmsa[j].IpsecQMFilter.QMFilterType == QM_TRANSPORT_FILTER) ? _T("Transport") : ((pipsqmsa[j].IpsecQMFilter.QMFilterType == QM_TUNNEL_FILTER) ? _T("Tunnel") : _T("Unknown")) ); printf(" From "); PrintAddr(pipsqmsa[j].IpsecQMFilter.SrcAddr); printf("\n"); printf(" To "); PrintAddr(pipsqmsa[j].IpsecQMFilter.DesAddr); printf("\n"); _tprintf(TEXT(" Protocol : %lu Src Port : %u Des Port : %u\n"), pipsqmsa[j].IpsecQMFilter.Protocol.dwProtocol, pipsqmsa[j].IpsecQMFilter.SrcPort.wPort, pipsqmsa[j].IpsecQMFilter.DesPort.wPort); _tprintf(TEXT(" Direction : %s\n"), (pipsqmsa[j].IpsecQMFilter.dwFlags & FILTER_DIRECTION_INBOUND) ? _T("Inbound") : ((pipsqmsa[j].IpsecQMFilter.dwFlags & FILTER_DIRECTION_OUTBOUND) ? _T("Outbound") : _T("Error"))); if (pipsqmsa[j].IpsecQMFilter.QMFilterType == QM_TUNNEL_FILTER) { printf(" Tunnel From "); PrintAddr(pipsqmsa[j].IpsecQMFilter.MyTunnelEndpt); printf("\n"); printf(" Tunnel To "); PrintAddr(pipsqmsa[j].IpsecQMFilter.PeerTunnelEndpt); printf("\n"); } // policy and cookie StringFromGUID2(pipsqmsa[j].gQMPolicyID, StringTxt, STRING_TEXT_SIZE); _tprintf(TEXT(" Policy Id : %s\n"), StringTxt); _tprintf(TEXT(" Offer Used : \n")); PrintQMOffer(pipsqmsa[j].SelectedQMOffer, _T(""), _T("\t")); // print cookies print_vpi(" Initiator cookie",(BYTE*)&(pipsqmsa[j].MMSpi.Initiator),sizeof(IKE_COOKIE)); printf("\n"); print_vpi(" Responder cookie",(BYTE*)&(pipsqmsa[j].MMSpi.Responder),sizeof(IKE_COOKIE)); printf("\n"); } SPDApiBufferFree(pipsqmsa); pipsqmsa=NULL; if (dwReserved == 0) { break; } if(!fTestPass) break; } if (!fTestPass) { iReturn++; fTestPass = TRUE; } } return iReturn; } // process query command line // accept command line (argc/argv) and the index where show flags start // return 0 if command completed successfully, // IPSECCMD_USAGE if there is usage error, // any other value indicates failure during execution (gets passed up) // // IMPORTANT: we assume that main module provide us with remote vs. local machine information // in the global variables // int ipseccmd_show_main ( int argc, char** argv, int start_index ) { int i; ipseccmdShow.bFilters = ipseccmdShow.bPolicies = ipseccmdShow.bAuth = ipseccmdShow.bStats = ipseccmdShow.bSAs = false; for (i = start_index ; i < argc; i++) { if (!_stricmp(argv[i], KEYWORD_SHOW)) { continue; // skip that } else if (!_stricmp(argv[i], KEYWORD_FILTERS)) { ipseccmdShow.bFilters = true; } else if (!_stricmp(argv[i], KEYWORD_POLICIES)) { ipseccmdShow.bPolicies = true; } else if (!_stricmp(argv[i], KEYWORD_AUTH)) { ipseccmdShow.bAuth = true; } else if (!_stricmp(argv[i], KEYWORD_STATS)) { ipseccmdShow.bStats = true; } else if (!_stricmp(argv[i], KEYWORD_SAS)) { ipseccmdShow.bSAs = true; } else if (!_stricmp(argv[i], KEYWORD_ALL)) { ipseccmdShow.bFilters = ipseccmdShow.bPolicies = ipseccmdShow.bAuth = ipseccmdShow.bStats = ipseccmdShow.bSAs = true; } else { return IPSECCMD_USAGE; } } return do_show(); } // print_vpi prints IKE_COOKIE information // Parms: // Returns: None void print_vpi(char *str, unsigned char *vpi, int vpi_len) { int i, j; char msg [256] ; char c [5]; strcpy ( msg, str) ; strcat ( msg," ") ; if (vpi == NULL) { strcat(msg,"VPI NULL "); printf("%s", msg) ; return; } for (j=1, i=0; i iBLen) { cBigger = cA; iBiggerLen = iALen; } else { cBigger = cB; iBiggerLen = iBLen; } while (i < iBiggerLen) { k = cBigger[iBiggerLen - i - 1] + iCarry - '0'; // Set the carry as appropriate iCarry = k/10; // Set the current digit's value. cTmp[i] = '0' + k%10; i++; } // Finally, we might still have a set carry to put in the next // digit. if (iCarry) { cTmp[i++] = '0' + iCarry; } // Now that we've got the entire number, reverse it and put it back in the dest. // Skip leading 0's. i = strlen(cTmp) - 1; while ((i > 0)&&(cTmp[i] == '0')) { i--; } // and copy the number. j = 0; while (i >= 0) { cSum[j++] = cTmp[i--]; } cSum[j] = '\0'; // We're done. Return 0 for success! return(0); } /********************************************************************************** * * AscMultUint - Multiply two numbers in ascii strings, storing the results in a third buffer * cProduct - Buffer for the product * cA - First multiplicand * cB - Second multiplicand * * This routine will add two arbitrarily long ascii strings. It makes several * assumptions about them. * 1) the string is null terminated. * 2) The LSB is the last char of the string. "1000000" is a million * 3) There are no signs or decimal points. * 4) The cProduct buffer is large enough to store the result * 5) The product will require 254 bytes or less. * * returns: 0 on success, else failure code. * **********************************************************************************/ int AscMultUint( char *cProduct, char *cA, char *cB ) { int iALen, iBLen, iProductLen; int i,j,k, iCarry; char cTmp[255]={0}; // Verify parameters if ((cA == NULL) || (cB == NULL) || (cProduct == NULL)) { printf("AscMultUint(%0X,%0X, %0X) ERROR - bad parameters\n", (UINT) cA, (UINT) cB, (UINT) cProduct); return(-1); } iALen = strlen(cA); iBLen = strlen(cB); // We will multiply the traditional longhand way: for each digit in // cA, we will multiply it against cB and add the incremental result // into our temporary product. // for each digit of the first multiplicand for (i=0; i < iALen; i++) { iCarry = 0; // for each digit of the second multiplicand for(j=0; j < iBLen; j++) { // calculate this digit's value k = ((int) cA[iALen-i-1]-'0') * ((int) cB[iBLen-j-1]-'0'); k += iCarry; // Add it in to the appropriate place in the result if (cTmp[i+j] != '\0') { k += (int) cTmp[i+j] - '0'; } cTmp[i+j] = '0' + (k % 10); iCarry = k/10; } // Take care of the straggler carry. If the higher // digits happen to be '9999' then this can require // a loop. while (iCarry) { if (cTmp[i+j] != '\0') { iCarry += cTmp[i+j] - '0'; } cTmp[i+j] = '0' + iCarry%10; iCarry /= 10; j++; } } // Now that we've got the entire number, reverse it and put it back in the dest. // Skip leading 0's. i = strlen(cTmp) - 1; while ((i > 0)&&(cTmp[i] == '0')) { i--; } // Copy the product. j = 0; while (i >= 0) { cProduct[j++] = cTmp[i--]; } cProduct[j] = '\0'; // We're done. Return 0 for success! return(0); } /******************************************************* * * LongLongToString - Convert a low and high DWORD to a decimal string * dwLow - Low order dword * dwHigh - High order dword * iPrintCommas - insert comma's if non-zero * * This routine will make a pretty string to match an input long-long, * and return it. If iPrintCommas is set, it will put in commas. * * * returns: pointer to newly allocated string with number in it. * NOTE - the caller is responsible for freeing the memory allocated. * *******************************************************/ char * LongLongToString( DWORD dwHigh, DWORD dwLow, int iPrintCommas ) { char cFourGig[]="4294967296"; // "four gigabytes" char cBuf[255]={0}; char cRes[255]={0}, cFullRes[255]={0}, *cRet; int iPos, iPosRes, iThreeCount; // First, multiply the high dword by decimal 2^32 to // get the right decimal value for it. sprintf(cBuf,"%u",dwHigh); AscMultUint(cRes,cBuf,cFourGig); // next, add in the low DWORD (fine as it is) // to the previous product sprintf(cBuf,"%u",dwLow); AscAddUint(cFullRes, cRes, cBuf); // Finally, copy the buffer with commas. iPos = iPosRes = 0; iThreeCount = strlen(cFullRes)%3; while(cFullRes[iPosRes] != '\0') { cBuf[iPos++] = cFullRes[iPosRes++]; iThreeCount +=2; // Same as subtracting one for modulo math if ((!(iThreeCount%3))&&(cFullRes[iPosRes] != '\0')&&(iPrintCommas)) { cBuf[iPos++]=','; } } cBuf[iPos] = '\0'; cRet = _strdup(cBuf); return(cRet); }