/*++ Copyright (c) 1998 Microsoft Corporation Module Name: routing\monitor2\ip\ipcfg.c Abstract: Fns to change configuration at the IP Rtr Mgr level Revision History: Anand Mahalingam 7/10/98 Created --*/ #include "precomp.h" #pragma hdrstop DWORD AddDeleteRoutePrefLevel ( IN PPROTOCOL_METRIC ppm, IN DWORD dwNumProto, IN BOOL bAdd ) /*++ Routine Description: Adds, deletes route preferences Arguments: ppm - array of protocols to be added/deleted dwNumProto - Number of protocols to be added/deleted bAdd - To add or not to add Return Value: NO_ERROR --*/ { DWORD dwRes = (DWORD) -1, dwSize = 0; PPRIORITY_INFO ppi = NULL, ppiNew = NULL; DWORD dwBlkSize, dwNewBlkSize, dwCount; DEBUG("In AddDelRoutePrefLevel"); if (dwNumProto is 0) { return NO_ERROR; } do { dwRes = IpmontrGetInfoBlockFromGlobalInfo(IP_PROT_PRIORITY_INFO, (PBYTE *) &ppi, &dwBlkSize, &dwCount); if(dwRes != NO_ERROR) { break; } if(bAdd) { dwRes = AddNewRoutePrefToBlock(ppi, dwBlkSize, ppm, dwNumProto, &ppiNew, &dwNewBlkSize); } else { dwRes = DeleteRoutePrefFromBlock(ppi, dwBlkSize, ppm, dwNumProto, &ppiNew, &dwNewBlkSize); } if(dwRes != NO_ERROR) { if(dwRes is ERROR_NO_CHANGE) { // // No Change in config, proceed to change in router // dwRes = NO_ERROR; ppiNew = NULL; break; } } else { if(ppiNew) { dwRes = IpmontrSetInfoBlockInGlobalInfo(IP_PROT_PRIORITY_INFO, (PBYTE) ppiNew, dwNewBlkSize, dwCount); } } }while(FALSE); // // free allocations // if(ppi) { FreeInfoBuffer(ppi); ppi = NULL; } if(ppiNew) { FREE(ppiNew); ppiNew = NULL; } switch(dwRes) { case NO_ERROR: break; case ERROR_NOT_FOUND: DisplayMessage(g_hModule, EMSG_IP_NO_PRIO_INFO, L"Router"); break; case ERROR_NOT_ENOUGH_MEMORY: DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY); break; default: DisplayError(g_hModule, dwRes); break; } return dwRes; } DWORD AddNewRoutePrefToBlock ( IN PPRIORITY_INFO ppi, IN DWORD dwBlkSize, IN PPROTOCOL_METRIC ppm, IN DWORD dwNumProto, OUT PPRIORITY_INFO *pppi, OUT PDWORD pdwSize ) /*++ Routine Description: creates route preference block Arguments: ppi - preference block dwNumBlkSize - size of block ppm - protocols to be added dwNumProto - number of protocols pppi - new preference block pdwSize - size of new block Return Value: NO_ERROR --*/ { PPRIORITY_INFO pPriorInfoOld = NULL, pPriorInfoNew = NULL; DWORD i = 0, dwNewSize = 0, dwRes = NO_ERROR; BOOL bFound = FALSE; PDWORD pdwValid; DWORD j, dwProtoCount; // // Have an array to tell which ones are valid. // pdwValid = MALLOC( dwNumProto * sizeof(DWORD)); if (pdwValid is NULL) { DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY); return ERROR_NOT_ENOUGH_MEMORY; } ZeroMemory(pdwValid, dwNumProto * sizeof(DWORD)); // // find the PrefLevel block // pPriorInfoOld = ppi; if ( pPriorInfoOld == (PPRIORITY_INFO) NULL ) { DisplayMessage(g_hModule, MSG_IP_CORRUPT_INFO ); FREE(pdwValid); return ERROR_INVALID_PARAMETER; } for ( j = 0, dwNewSize = 0; j < dwNumProto; j++) { // // make sure preference level for the protocol does not already exist. // for ( i = 0; i < pPriorInfoOld-> dwNumProtocols; i++ ) { if (pPriorInfoOld->ppmProtocolMetric[ i ].dwProtocolId == ppm[j].dwProtocolId) { bFound = TRUE; break; } } if (bFound) { pdwValid[j] = 0; DisplayMessage(g_hModule, MSG_IP_PROTO_PREF_LEVEL_EXISTS, pPriorInfoOld->ppmProtocolMetric[ i ].dwMetric); bFound = FALSE; } else { pdwValid[j] = 1; dwNewSize += sizeof(PROTOCOL_METRIC); } } // // allocate new info block // if (dwNewSize is 0) { // // All specified protocols already present // FREE(pdwValid); return ERROR_NO_CHANGE; } dwProtoCount = dwNewSize / sizeof(PROTOCOL_METRIC); dwNewSize += dwBlkSize; pPriorInfoNew = MALLOC(dwNewSize); if ( pPriorInfoNew == NULL ) { DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY ); dwRes = ERROR_NOT_ENOUGH_MEMORY; return dwRes; } do { // // copy the old PrefLevels and set the number of protocols // CopyMemory((PBYTE) &pPriorInfoNew-> ppmProtocolMetric, (PBYTE) &pPriorInfoOld-> ppmProtocolMetric, sizeof(PROTOCOL_METRIC)*pPriorInfoOld-> dwNumProtocols); pPriorInfoNew-> dwNumProtocols = pPriorInfoOld-> dwNumProtocols + dwProtoCount; // // add the new PrefLevel and increment count of protocols // with PrefLevels // i = pPriorInfoOld-> dwNumProtocols; for ( j = 0 ; j < dwNumProto ; j++) { if (pdwValid[j]) { // // Add the protocol priority // pPriorInfoNew-> ppmProtocolMetric[i].dwProtocolId = ppm[j].dwProtocolId; pPriorInfoNew-> ppmProtocolMetric[i++].dwMetric = ppm[j].dwMetric; } } } while (FALSE); FREE(pdwValid); if ( dwRes == NO_ERROR ) { *pppi = pPriorInfoNew; *pdwSize = dwNewSize; } return dwRes; } DWORD DeleteRoutePrefFromBlock ( IN PPRIORITY_INFO ppi, IN DWORD dwBlkSize, IN PPROTOCOL_METRIC ppm, IN DWORD dwNumProto, OUT PPRIORITY_INFO *pppi, OUT PDWORD pdwSize ) /*++ Routine Description: creates route preference block Arguments: ppi - preference block dwNumBlkSize - size of block ppm - protocols to be added dwNumProto - number of protocols pppi - new preference block pdwSize - size of new block Return Value: NO_ERROR --*/ { PPRIORITY_INFO pPriorInfoOld = NULL, pPriorInfoNew = NULL; DWORD dwInd = 0, dwNewSize = 0, dwRes = NO_ERROR, i, j; BOOL bFound = FALSE; PDWORD pdwToDelete; // find the PrefLevel block pPriorInfoOld = ppi; if ( pPriorInfoOld == (PPRIORITY_INFO) NULL ) { DisplayMessage(g_hModule, MSG_IP_CORRUPT_INFO ); return ERROR_INVALID_PARAMETER; } pdwToDelete = MALLOC( pPriorInfoOld-> dwNumProtocols * sizeof(DWORD)); if (pdwToDelete is NULL) { return ERROR_NOT_ENOUGH_MEMORY; } ZeroMemory(pdwToDelete, pPriorInfoOld-> dwNumProtocols * sizeof(DWORD)); for ( i = 0, dwNewSize = 0; i < dwNumProto; i++) { // // make sure preference level for the protocol already exists. // for ( dwInd = 0; dwInd < pPriorInfoOld-> dwNumProtocols; dwInd++ ) { if (pPriorInfoOld-> ppmProtocolMetric[ dwInd ].dwProtocolId == ppm[i].dwProtocolId) { bFound = TRUE; break; } } if (!bFound) { DisplayMessage(g_hModule, MSG_IP_PROTO_PREF_LEVEL_NOT_FOUND, ppm[i].dwProtocolId); } else { bFound = FALSE; pdwToDelete[dwInd] = 1; dwNewSize += sizeof(PROTOCOL_METRIC); } } if (dwNewSize is 0) { // // None of the protocols specified were found. // FREE(pdwToDelete); return ERROR_NO_CHANGE; } // // allocate new info block // dwNewSize = dwBlkSize - dwNewSize; pPriorInfoNew = MALLOC(dwNewSize); if ( pPriorInfoNew == NULL ) { FREE(pdwToDelete); dwRes = ERROR_NOT_ENOUGH_MEMORY; return dwRes; } do { for ( i = 0, j = 0; i < pPriorInfoOld-> dwNumProtocols; i++) { if (pdwToDelete[i]) { // // Do not copy this protocol // } else { pPriorInfoNew->ppmProtocolMetric[j].dwProtocolId = pPriorInfoOld->ppmProtocolMetric[i].dwProtocolId; pPriorInfoNew->ppmProtocolMetric[j++].dwMetric = pPriorInfoOld->ppmProtocolMetric[i].dwMetric; } } pPriorInfoNew-> dwNumProtocols = j; } while (FALSE); FREE(pdwToDelete); if ( dwRes == NO_ERROR ) { *pppi = pPriorInfoNew; *pdwSize = dwNewSize; } return dwRes; } DWORD SetRoutePrefLevel ( IN PROTOCOL_METRIC pm ) /*++ Routine Description: sets route preference Arguments: ppm - preference to set Return Value: NO_ERROR --*/ { DWORD dwRes = (DWORD) -1, dwSize = 0; PPRIORITY_INFO ppi = NULL; DWORD dwBlkSize, dwCount; DEBUG("In SetRoutePrefLevel"); do { // // get router config, add new router preference level, // and set the config // dwRes = IpmontrGetInfoBlockFromGlobalInfo(IP_PROT_PRIORITY_INFO, (PBYTE *) &ppi, &dwBlkSize, &dwCount); if (dwRes != NO_ERROR) { break; } dwRes = UpdateRtrPriority(ppi, pm); if ( dwRes != NO_ERROR ) { break; } dwRes = IpmontrSetInfoBlockInGlobalInfo(IP_PROT_PRIORITY_INFO, (PBYTE) ppi, dwBlkSize, dwCount); if ( dwRes != NO_ERROR ) { break; } PRINT(L"Made Changes to Router Config"); if (!IsRouterRunning()) { break; } } while (FALSE); // // Free all allocations // if ( ppi ) { FREE(ppi); } switch(dwRes) { case NO_ERROR: break; case ERROR_NOT_FOUND: DisplayMessage(g_hModule, EMSG_IP_NO_PRIO_INFO, L"Router"); break; case ERROR_NOT_ENOUGH_MEMORY: DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY); break; case ERROR_INVALID_PARAMETER: break; default: DisplayError(g_hModule, dwRes); break; } return dwRes; } DWORD UpdateRtrPriority( IN PPRIORITY_INFO ppi, IN PROTOCOL_METRIC pm ) /*++ Routine Description: sets route preference Arguments: ppi - route preference block ppm - preference to set Return Value: NO_ERROR --*/ { BOOL bFound = FALSE; DWORD i = 0; if ( ppi == (PPRIORITY_INFO) NULL ) { DisplayMessage(g_hModule, MSG_IP_CORRUPT_INFO ); return ERROR_INVALID_PARAMETER; } // search for the protocol for ( i = 0; i < ppi-> dwNumProtocols; i++ ) { if (ppi-> ppmProtocolMetric[ i ].dwProtocolId == pm.dwProtocolId ) { ppi-> ppmProtocolMetric[ i ].dwMetric = pm.dwMetric; bFound = TRUE; break; } } if (!bFound) { // preference level for that protocolId does not exist DisplayMessage(g_hModule, MSG_IP_NO_PREF_FOR_PROTOCOL_ID, pm.dwProtocolId ); return ERROR_INVALID_PARAMETER; } return NO_ERROR; } DWORD SetGlobalConfigInfo( IN DWORD dwLoggingLevel ) /*++ Routine Description: sets global logging level Arguments: dwLoggingLevel - Loggging level Return Value: NO_ERROR --*/ { PGLOBAL_INFO pgi = NULL; DWORD dwBlkSize, dwCount, dwErr = NO_ERROR; do { // // Get the IP_GLOBAL_INFO block from router config // dwErr = IpmontrGetInfoBlockFromGlobalInfo(IP_GLOBAL_INFO, (PBYTE *) &pgi, &dwBlkSize, &dwCount); if (dwErr isnot NO_ERROR) { break; } pgi->dwLoggingLevel = dwLoggingLevel; // // Set the IP_GLOBAL_INFO block in router config // dwErr = IpmontrSetInfoBlockInGlobalInfo(IP_GLOBAL_INFO, (PBYTE) pgi, dwBlkSize, dwCount); if (dwErr isnot NO_ERROR) { break; } FREE(pgi); pgi = NULL; DEBUG("Set logging level in router config\n"); }while (FALSE); if (pgi) { FREE(pgi); } switch(dwErr) { case NO_ERROR: break; case ERROR_NOT_FOUND: DisplayMessage(g_hModule, EMSG_IP_NO_PRIO_INFO, L"Router"); break; case ERROR_NOT_ENOUGH_MEMORY: DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY); break; default: DisplayError(g_hModule, dwErr); break; } return dwErr; } DWORD UpdateInterfaceStatusInfo( IN DWORD dwAction, IN LPCWSTR pwszIfName, IN DWORD dwStatus ) /*++ Routine Description: Sets interface discovery information Arguments: pwszIfName - interface name dwStatus - enabled or disabled Return Value: NO_ERROR --*/ { PINTERFACE_STATUS_INFO pifStat = (PINTERFACE_STATUS_INFO) NULL; DWORD dwRes = NO_ERROR, dwBlkSize; DWORD dwCount, dwIfType; do { dwRes = IpmontrGetInfoBlockFromInterfaceInfo(pwszIfName, IP_INTERFACE_STATUS_INFO, (PBYTE *) &pifStat, &dwBlkSize, &dwCount, &dwIfType); if (dwRes is ERROR_NOT_FOUND) { // // No info of this type is currently present // dwRes = NO_ERROR; dwCount = 0; // Add interface if (dwAction is ADD_COMMAND) { pifStat = (PINTERFACE_STATUS_INFO)MALLOC( sizeof(INTERFACE_STATUS_INFO)); if (pifStat is NULL) { dwRes = ERROR_NOT_ENOUGH_MEMORY; break; } dwCount++; } } if (dwRes != NO_ERROR) { break; } if (dwCount is 0) return ERROR_NOT_FOUND; if (dwAction is DELETE_COMMAND) { dwCount = 0; } else { pifStat->dwAdminStatus = dwStatus; } dwRes = IpmontrSetInfoBlockInInterfaceInfo( pwszIfName, IP_INTERFACE_STATUS_INFO, (PBYTE) pifStat, dwBlkSize, dwCount); } while (FALSE); // // Free all allocations // if ( pifStat ) { FREE(pifStat); } switch(dwRes) { case NO_ERROR: break; case ERROR_NOT_FOUND: DisplayMessage(g_hModule, EMSG_IP_NO_IF_STATUS_INFO, L"Router"); break; case ERROR_NOT_ENOUGH_MEMORY: DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY); break; default: DisplayError(g_hModule, dwRes); break; } return dwRes; } DWORD ShowRoutePref( HANDLE hFile ) /*++ Routine Description: Displays the protocol route preferences. Arguments: Return Value: NO_ERROR --*/ { PPRIORITY_INFO ppi; DWORD dwBlkSize, dwCount, dwNumProto, i; DWORD dwErr; WCHAR wszBuff[80]; dwErr = IpmontrGetInfoBlockFromGlobalInfo(IP_PROT_PRIORITY_INFO, (PBYTE *)&ppi, &dwBlkSize, &dwCount); if (dwErr isnot NO_ERROR) { DisplayError(g_hModule, dwErr); return ERROR_SUPPRESS_OUTPUT; } dwNumProto = ppi-> dwNumProtocols; if (dwNumProto && (hFile == NULL)) { DisplayMessage(g_hModule, MSG_RTR_PRIO_INFO_HDR); } for (i=0; i < dwNumProto; i++) { PTCHAR ptszProto, ptszToken; switch (ppi-> ppmProtocolMetric[ i ].dwProtocolId) { case PROTO_IP_LOCAL: { ptszProto = MakeString(g_hModule, STRING_LOCAL ); ptszToken = TOKEN_VALUE_LOCAL; break; } case PROTO_IP_NETMGMT: { ptszProto = MakeString(g_hModule, STRING_NETMGMT ); ptszToken = TOKEN_VALUE_NETMGMT; break; } case PROTO_IP_OSPF : { ptszProto = MakeString(g_hModule, STRING_OSPF ); ptszToken = TOKEN_VALUE_OSPF; break; } case PROTO_IP_RIP : { ptszProto = MakeString(g_hModule, STRING_RIP ); ptszToken = TOKEN_VALUE_RIP; break; } case PROTO_IP_NT_AUTOSTATIC : { ptszProto = MakeString(g_hModule, STRING_NT_AUTOSTATIC ); ptszToken = TOKEN_VALUE_AUTOSTATIC; break; } case PROTO_IP_NT_STATIC : { ptszProto = MakeString(g_hModule, STRING_STATIC ); ptszToken = TOKEN_VALUE_STATIC; break; } case PROTO_IP_NT_STATIC_NON_DOD : { ptszProto = MakeString(g_hModule, STRING_NONDOD ); ptszToken = TOKEN_VALUE_NONDOD; break; } default: { ptszProto = NULL; ptszToken = NULL; break; } } if ( ptszProto == NULL || ptszToken == NULL ) { swprintf( wszBuff, L"%d", ppi-> ppmProtocolMetric[ i ].dwProtocolId ); } if(hFile != NULL) { DisplayMessageT( DMP_IP_SET_PROTOPREF, (ptszToken)? ptszToken : wszBuff, ppi->ppmProtocolMetric[i].dwMetric); } else { DisplayMessage(g_hModule, MSG_RTR_PRIO_INFO, (ptszProto)? ptszProto : wszBuff, ppi->ppmProtocolMetric[i].dwMetric); } if(ptszProto) { FreeString(ptszProto); } } FREE(ppi); return NO_ERROR; } DWORD ShowIpGlobal( HANDLE hFile ) /*++ Routine Description: Displays the logging level for IP Arguments: Return Value: NO_ERROR --*/ { PGLOBAL_INFO pgi = NULL; DWORD dwBlkSize, dwCount; DWORD dwErr; PWCHAR ptszLoglevel, ptszLog; WCHAR wszBuff[80]; dwErr = IpmontrGetInfoBlockFromGlobalInfo(IP_GLOBAL_INFO, (PBYTE *)&pgi, &dwBlkSize, &dwCount); if (dwErr isnot NO_ERROR) { DisplayError(g_hModule, dwErr); return dwErr; } switch (pgi->dwLoggingLevel) { case IPRTR_LOGGING_NONE: { ptszLoglevel = MakeString(g_hModule, STRING_LOGGING_NONE); ptszLog = TOKEN_VALUE_NONE; break; } case IPRTR_LOGGING_ERROR: { ptszLoglevel = MakeString(g_hModule, STRING_LOGGING_ERROR); ptszLog = TOKEN_VALUE_ERROR; break; } case IPRTR_LOGGING_WARN: { ptszLoglevel = MakeString(g_hModule, STRING_LOGGING_WARN); ptszLog = TOKEN_VALUE_WARN; break; } case IPRTR_LOGGING_INFO: { ptszLoglevel = MakeString(g_hModule, STRING_LOGGING_INFO); ptszLog = TOKEN_VALUE_INFO; break; } } if ( ptszLoglevel == NULL || ptszLog == NULL ) { swprintf( wszBuff, L"%d", pgi->dwLoggingLevel); } if(hFile) { DisplayMessageT( DMP_IP_SET_LOGLEVEL, (ptszLog) ? ptszLog : wszBuff); } else { DisplayMessage(g_hModule, MSG_IP_GLOBAL_HDR); DisplayMessage(g_hModule, MSG_IP_LOG_LEVEL, (ptszLoglevel) ? ptszLoglevel : wszBuff); } if ( ptszLoglevel ) { FreeString(ptszLoglevel); } FREE(pgi); return NO_ERROR; } PWCHAR GetIfTypeString( DWORD dwIfType ) { PWCHAR pwszStr; static WCHAR buff[80]; VALUE_STRING ppsList[] = {{ROUTER_IF_TYPE_CLIENT, STRING_CLIENT}, {ROUTER_IF_TYPE_HOME_ROUTER, STRING_HOME_ROUTER}, {ROUTER_IF_TYPE_FULL_ROUTER, STRING_FULL_ROUTER}, {ROUTER_IF_TYPE_DEDICATED, STRING_DEDICATED}, {ROUTER_IF_TYPE_INTERNAL, STRING_INTERNAL}, {ROUTER_IF_TYPE_LOOPBACK, STRING_LOOPBACK}, {ROUTER_IF_TYPE_TUNNEL1, STRING_TUNNEL}, }; DWORD dwNum = sizeof(ppsList)/sizeof(VALUE_STRING), i; DWORD dwMsgId = 0; for (i=0; iTocEntriesCount; i++) { // Extract type, vendorid, and protocolid dwProtoType = TYPE_FROM_PROTO_ID( pInfoHdr->TocEntry[i].InfoType); dwProtoVendor = VENDOR_FROM_PROTO_ID(pInfoHdr->TocEntry[i].InfoType); dwProtoProto = PROTO_FROM_PROTO_ID( pInfoHdr->TocEntry[i].InfoType); DisplayMessageT(L"%1!-11s! %2!-13s! %3!s!\n", GetProtoTypeString( dwProtoType), GetProtoVendorString(dwProtoVendor), GetProtoProtoString( dwProtoType, dwProtoVendor, dwProtoProto)); } if (i is 0) { DisplayMessage(g_hModule, MSG_IP_NO_PROTOCOL); } return NO_ERROR; } DWORD ShowIpProtocol( VOID ) /*++ Routine Description: Displays all the protocols under IP RTR MGR. Arguments: Return Value: NO_ERROR --*/ { DWORD dwNumProto, dwErr, i; PBYTE pby; DWORD dwBlkSize, dwCount; RTR_INFO_BLOCK_HEADER *pInfoHdr; DWORD dwProtoType, dwProtoVendor, dwProtoProto; dwErr = ValidateGlobalInfo(&pInfoHdr); if (dwErr isnot NO_ERROR) { return dwErr; } DisplayMessage(g_hModule, MSG_IP_PROTOCOL_HDR); // Walk pInfo and output a line for each protocol found for (i=0; iTocEntriesCount; i++) { // Extract type, vendorid, and protocolid dwProtoType = TYPE_FROM_PROTO_ID( pInfoHdr->TocEntry[i].InfoType); dwProtoVendor = VENDOR_FROM_PROTO_ID(pInfoHdr->TocEntry[i].InfoType); dwProtoProto = PROTO_FROM_PROTO_ID( pInfoHdr->TocEntry[i].InfoType); DisplayMessageT(L"%1!-11s! %2!-13s! %3!s!\n", GetProtoTypeString( dwProtoType), GetProtoVendorString(dwProtoVendor), GetProtoProtoString( dwProtoType, dwProtoVendor, dwProtoProto)); } if (i is 0) { DisplayMessage(g_hModule, MSG_IP_NO_PROTOCOL); } return NO_ERROR; } DWORD ListIpInterface( VOID ) /*++ Routine Description: Lists all interfaces under ip Arguments: Return Value: NO_ERROR --*/ { DWORD dwErr; DWORD dwCount, dwTotal, i, dwNumParsed = 0; PMPR_INTERFACE_0 pmi0; WCHAR wszIfDesc[MAX_INTERFACE_NAME_LEN + 1]; HANDLE hIfTransport = (HANDLE) NULL, hInterface; DisplayMessage(g_hModule, MSG_IP_INTERFACE_HDR); // // No interface name specified. List all interfaces under IP // dwErr = IpmontrInterfaceEnum((PBYTE *) &pmi0, &dwCount, &dwTotal); if (dwErr isnot NO_ERROR) { DisplayError(g_hModule, dwErr); return dwErr; } for ( i = 0; i < dwCount; i++) { // Make sure IP is enabled on this interface dwErr = MprConfigInterfaceGetHandle(g_hMprConfig, pmi0[i].wszInterfaceName, &hInterface); dwErr = MprConfigInterfaceTransportGetHandle(g_hMprConfig, hInterface, PID_IP, &hIfTransport); if (dwErr isnot NO_ERROR) continue; dwErr = GetInterfaceDescription(pmi0[i].wszInterfaceName, wszIfDesc, &dwNumParsed); if (!dwNumParsed) { wcscpy(wszIfDesc, pmi0[i].wszInterfaceName); } DisplayMessage(g_hModule, MSG_IP_INTERFACE_INFO, wszIfDesc); } if (dwCount is 0) { DisplayMessage(g_hModule, MSG_IP_NO_INTERFACE); } return NO_ERROR; } DWORD ShowIpInIpInfo( IN DWORD dwFormat, IN LPCWSTR pwszIfName, IN LPCWSTR pwszQuoted ) { PIPINIP_CONFIG_INFO pIpIpInfo; WCHAR rgwcLocalAddr[ADDR_LENGTH + 1]; WCHAR rgwcRemAddr[ADDR_LENGTH + 1]; DWORD dwBlkSize, dwCount, dwIfType, dwErr; // IP-in-IP info dwErr = IpmontrGetInfoBlockFromInterfaceInfo(pwszIfName, IP_IPINIP_CFG_INFO, (PBYTE *) &pIpIpInfo, &dwBlkSize, &dwCount, &dwIfType); if(dwErr is NO_ERROR) { ASSERT(dwIfType is ROUTER_IF_TYPE_TUNNEL1); IP_TO_WSTR(rgwcLocalAddr, ((PBYTE)&(pIpIpInfo->dwLocalAddress))); IP_TO_WSTR(rgwcRemAddr, ((PBYTE)&(pIpIpInfo->dwRemoteAddress))); switch (dwFormat) { case FORMAT_VERBOSE: DisplayMessage(g_hModule, MSG_RTR_INTERFACE_IPIP_INFO, rgwcLocalAddr, rgwcRemAddr, MAKELONG(MAKEWORD(pIpIpInfo->byTtl, 0x00), 0x0000)); break; // IP-in-IP tunnels need to be added in the interface context in // ifmon.dll, not here. But this is how it works for now!!! So // we'll just dump the command that works. case FORMAT_DUMP: DisplayMessageT(DMP_IP_ADD_IPIPTUNNEL, pwszQuoted, rgwcLocalAddr, rgwcRemAddr, MAKELONG(MAKEWORD(pIpIpInfo->byTtl,0x00), 0x0000)); break; default: break; } } if (pIpIpInfo) { FREE_BUFFER(pIpIpInfo); } return dwErr; } DWORD ShowIpInterface( IN DWORD dwFormat, IN LPCWSTR pwszIfName, IN OUT PDWORD pdwNumRows ) /*++ Routine Description: Show the interface info for the interface The interface info consists of AdminStatus Router Discovery Info Protocols on the interface Other information like filters and routes are should using different commands Arguments: pwszIfName - Interface name Return Value: NO_ERROR --*/ { DWORD dwErr; WCHAR wszIfDesc[MAX_INTERFACE_NAME_LEN + 1]; PVALUE_STRING pps; DWORD dwNumProto, dwBlkSize, dwCount, dwNumParsed; DWORD dwIfType , i; PBYTE pby; PWCHAR pwszStatus, pwszQuoted; PWCHAR pwszTokenStatus, pwszIfType; PINTERFACE_STATUS_INFO pifStat; // // Interface status info // dwErr = IpmontrGetInfoBlockFromInterfaceInfo(pwszIfName, IP_INTERFACE_STATUS_INFO, (PBYTE *) &pifStat, &dwBlkSize, &dwCount, &dwIfType); if (dwErr != NO_ERROR) { // DisplayMessage(g_hModule, EMSG_IP_NO_STATUS_INFO); return dwErr; } if (pifStat->dwAdminStatus is IF_ADMIN_STATUS_UP) { pwszStatus = MakeString(g_hModule, STRING_ENABLED); pwszTokenStatus = TOKEN_VALUE_ENABLE; } else { pwszStatus = MakeString(g_hModule, STRING_DISABLED); pwszTokenStatus = TOKEN_VALUE_DISABLE; } FREE_BUFFER(pifStat); // Get description dwErr = GetInterfaceDescription(pwszIfName, wszIfDesc, &dwNumParsed); if (!dwNumParsed) { wcscpy(wszIfDesc, pwszIfName); } if(dwFormat is FORMAT_DUMP) { pwszQuoted = MakeQuotedString(wszIfDesc); } else { pwszQuoted = NULL; } pwszIfType = GetIfTypeString(dwIfType); // Display generic interface info switch (dwFormat) { case FORMAT_VERBOSE: DisplayMessage(g_hModule, MSG_RTR_INTERFACE_HDR, wszIfDesc); DisplayMessage(g_hModule, MSG_IP_IF_STATUS, pwszStatus); ShowIpIfProtocols(pwszIfName); break; case FORMAT_TABLE: if (*pdwNumRows is 0) { DisplayMessage(g_hModule, MSG_IP_IF_HEADER); } DisplayMessage(g_hModule, MSG_IP_IF_ENTRY, pwszStatus, pwszIfType, wszIfDesc); break; case FORMAT_DUMP: DisplayMessageT(DMP_IP_ADD_IF, pwszQuoted, pwszTokenStatus); break; } (*pdwNumRows)++; ShowIpInIpInfo(dwFormat, pwszIfName, pwszQuoted); FreeQuotedString(pwszQuoted); FreeString(pwszStatus); return NO_ERROR; } DWORD CreateDumpFile( IN LPCWSTR pwszName, OUT PHANDLE phFile ) { HANDLE hFile; *phFile = NULL; hFile = CreateFileW(pwszName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile == INVALID_HANDLE_VALUE) return GetLastError(); *phFile = hFile; return NO_ERROR; } VOID DumpIpInformation( HANDLE hFile ) /*++ Routine Description: Dumps all the IP Router manager information to the given file Arguments: hFile Handle of file Return Value: None --*/ { DWORD dwErr, dwCount, dwTotal; DWORD dwNumParsed, i; PMPR_INTERFACE_0 pmi0; WCHAR wszIfDesc[MAX_INTERFACE_NAME_LEN + 1]; DWORD dwNumRows = 0; // Display dump header DisplayMessage(g_hModule, DMP_IP_HEADER_COMMENTS); DisplayMessageT(DMP_IP_HEADER); // // First dump the global information // ShowIpGlobal(hFile); ShowRoutePref(hFile); ShowScopes(hFile); // // Dump the per interface info // dwErr = IpmontrInterfaceEnum((PBYTE *) &pmi0, &dwCount, &dwTotal); if(dwErr != NO_ERROR) { DisplayError(g_hModule, dwErr); return; } for(i = 0; i < dwCount; i++) { ShowIpInterface(FORMAT_DUMP, pmi0[i].wszInterfaceName, &dwNumRows); ShowIpIfFilter(hFile, FORMAT_DUMP, pmi0[i].wszInterfaceName, &dwNumRows); ShowIpPersistentRoute(hFile, pmi0[i].wszInterfaceName, &dwNumRows); ShowBoundaryInfoForInterface(hFile, pmi0[i].wszInterfaceName, &dwNumRows); } // Display dump footer DisplayMessageT(DMP_POPD); DisplayMessage(g_hModule, DMP_IP_FOOTER_COMMENTS); } DWORD UpdateAutoStaticRoutes( IN LPCWSTR pwszIfName ) { return NO_ERROR; }