/*++ Copyright (c) 1997 FORE Systems, Inc. Copyright (c) 1997 Microsoft Corporation Module Name: aas.c Abstract: ATM ARP Admin Utility. Usage: atmarp Revision History: Who When What -------- -------- --------------------------------------------- josephj 06-10-1998 Created (adapted from atmlane admin utility). Notes: Modelled after atmlane utility. --*/ #include "common.h" #include "..\atmarps\arp.h" #include "..\atmarps\ioctl.h" #include "atmmsg.h" // // Globals // static CHAR DefaultDeviceName[] = "\\\\.\\AtmArpServer"; static CHAR *pDeviceName = DefaultDeviceName; // // LoadMessages - courtesy IPCONFIG // // Loads all internationalizable messages into the various tables // VOID LoadMessages( ) { } BOOL CheckVersion( HANDLE DeviceHandle ) { return TRUE; } BOOL AasGetInterfaces( HANDLE DeviceHandle, PINTERFACES pInterfaces, ULONG cbInterfaces ) { ULONG BytesReturned; BOOL Result = FALSE; if (DeviceIoControl( DeviceHandle, ARPS_IOCTL_QUERY_INTERFACES, (PVOID)pInterfaces, cbInterfaces, (PVOID)pInterfaces, cbInterfaces, &BytesReturned, 0)) { UINT u = pInterfaces->NumberOfInterfaces; // // Fixup pointers // for (u=0;uNumberOfInterfaces;u++) { INTERFACE_NAME *pInterface = (pInterfaces->Interfaces)+u; pInterface->Buffer = (PWSTR)( (ULONG_PTR)pInterface->Buffer + (PUCHAR)pInterface); // // check that all this is valid... // if ( ((PUCHAR)pInterface->Buffer < (PUCHAR) pInterface) || ( ((PUCHAR)pInterface->Buffer + pInterface->Length) > ((PUCHAR)pInterfaces + cbInterfaces))) { printf("WHOA THERE!\n"); DebugBreak(); } else { #if 0 printf("INTERFACE: Len=%lu, Name=\"%c%c%c%c...\n", pInterface->Length, pInterface->Buffer[0], pInterface->Buffer[1], pInterface->Buffer[2], pInterface->Buffer[3] ); #endif // 0 } } Result = TRUE; } else { DisplayMessage(FALSE, MSG_ERROR_GETTING_INTERFACE_LIST); } return Result; } BOOL AasGetArpCache( HANDLE DeviceHandle, INTERFACE_NAME *pInterface, PIOCTL_QUERY_CACHE pArpCache, ULONG cbArpCache ) { ULONG BytesReturned; BOOL Result = FALSE; UINT BufferOffset; BufferOffset = FIELD_OFFSET(struct QUERY_ARP_CACHE_INPUT_PARAMS, Name) + sizeof(pArpCache->Name); pArpCache->Name.Buffer = (PWSTR)sizeof(pArpCache->Name); pArpCache->Name.Length = pInterface->Length; pArpCache->Name.MaximumLength = pInterface->MaximumLength; memcpy((PUCHAR)pArpCache + BufferOffset, pInterface->Buffer, pInterface->MaximumLength); Result = DeviceIoControl( DeviceHandle, ARPS_IOCTL_QUERY_ARPCACHE, (PVOID)pArpCache, BufferOffset + pInterface->Length, (PVOID)pArpCache, cbArpCache, &BytesReturned, NULL); if (Result) { #if 0 printf( "DeviceIoCtl: cbRet = %lu, cArps=%lu, cArpsInBuf=%lu\n", BytesReturned, pArpCache->Entries.TotalNumberOfEntries, pArpCache->Entries.NumberOfEntriesInBuffer ); #endif // 0 } else { DisplayMessage(FALSE, MSG_ERROR_GETTING_ARP_CACHE); } return Result; } BOOL AasGetMarsCache( HANDLE DeviceHandle, INTERFACE_NAME *pInterface, PIOCTL_QUERY_MARS_CACHE pMarsCache, ULONG cbMarsCache ) { ULONG BytesReturned; BOOL Result = FALSE; UINT BufferOffset; BufferOffset = FIELD_OFFSET(struct QUERY_MARS_CACHE_INPUT_PARAMS, Name) + sizeof(pMarsCache->Name); pMarsCache->Name.Buffer = (PWSTR)sizeof(pMarsCache->Name); pMarsCache->Name.Length = pInterface->Length; pMarsCache->Name.MaximumLength = pInterface->MaximumLength; memcpy((PUCHAR)pMarsCache + BufferOffset, pInterface->Buffer, pInterface->MaximumLength); Result = DeviceIoControl( DeviceHandle, ARPS_IOCTL_QUERY_MARSCACHE, (PVOID)pMarsCache, BufferOffset + pInterface->Length, (PVOID)pMarsCache, cbMarsCache, &BytesReturned, NULL); if (Result) { #if 0 printf( "DeviceIoCtl: cbRet = %lu, Sig=0x%lx, cMars=%lu, cMarsInBuf=%lu\n", BytesReturned, pMarsCache->MarsCache.Sig, pMarsCache->MarsCache.TotalNumberOfEntries, pMarsCache->MarsCache.NumberOfEntriesInBuffer ); #endif // 0 } else { DisplayMessage(FALSE, MSG_ERROR_GETTING_MARS_CACHE); } return Result; } BOOL AasGetArpStats( HANDLE DeviceHandle, INTERFACE_NAME *pInterface, PARP_SERVER_STATISTICS pArpStats ) { ULONG BytesReturned; BOOL Result = FALSE; // printf ( " In AasGetArpStats\n"); // // Temporarily fixup buffer pointer // pInterface->Buffer = (PWSTR)( (PUCHAR)pInterface->Buffer - (PUCHAR)pInterface); Result = DeviceIoControl( DeviceHandle, ARPS_IOCTL_QUERY_ARP_STATISTICS, (PVOID)pInterface, (UINT) (((ULONG_PTR)pInterface->Buffer)+pInterface->Length), (PVOID)pArpStats, sizeof(*pArpStats), &BytesReturned, NULL); // // Restore buffer pointer // pInterface->Buffer = (PWSTR)( (ULONG_PTR)pInterface->Buffer + (PUCHAR)pInterface); if (Result) { #if 0 printf( "DeviceIoCtl: cbRet = %lu, TotRcvPkts=%lu\n", BytesReturned, pArpStats->TotalRecvPkts ); #endif // 0 } else { DisplayMessage(FALSE, MSG_ERROR_GETTING_ARP_STATS); } return Result; } BOOL AasGetMarsStats( HANDLE DeviceHandle, INTERFACE_NAME *pInterface, PMARS_SERVER_STATISTICS pMarsStats ) { ULONG BytesReturned; BOOL Result = FALSE; // printf ( " In AasGetMarsStats\n"); // // Temporarily fixup buffer pointer // pInterface->Buffer = (PWSTR)( (PUCHAR)pInterface->Buffer - (PUCHAR)pInterface); Result = DeviceIoControl( DeviceHandle, ARPS_IOCTL_QUERY_MARS_STATISTICS, (PVOID)pInterface, (UINT) (((ULONG_PTR)pInterface->Buffer)+pInterface->Length), (PVOID)pMarsStats, sizeof(*pMarsStats), &BytesReturned, NULL); // // Restore buffer pointer // pInterface->Buffer = (PWSTR)( (ULONG_PTR)pInterface->Buffer + (PUCHAR)pInterface); if (Result) { #if 0 printf( "DeviceIoCtl: cbRet = %lu, TotRcvPkts=%lu\n", BytesReturned, pMarsStats->TotalRecvPkts ); #endif // 0 } else { DisplayMessage(FALSE, MSG_ERROR_GETTING_MARS_STATS); } return Result; } BOOL AasResetStatistics( HANDLE DeviceHandle, INTERFACE_NAME *pInterface ) { ULONG BytesReturned; BOOL Result = FALSE; // // Temporarily fixup buffer pointer // pInterface->Buffer = (PWSTR)( (PUCHAR)pInterface->Buffer - (PUCHAR)pInterface); Result = DeviceIoControl( DeviceHandle, ARPS_IOCTL_RESET_STATISTICS, (PVOID)pInterface, (UINT) (((ULONG_PTR)pInterface->Buffer)+pInterface->Length), NULL, 0, &BytesReturned, NULL); // // Restore buffer pointer // pInterface->Buffer = (PWSTR)( (ULONG_PTR)pInterface->Buffer + (PUCHAR)pInterface); if (Result) { DisplayMessage(FALSE, MSG_STATS_RESET_STATS); #if 0 printf( "DeviceIoCtl: cbRet = %lu, TotRcvPkts=%lu\n", BytesReturned, pMarsStats->TotalRecvPkts ); #endif // 0 } else { DisplayMessage(FALSE, MSG_ERROR_RESETTING_STATS); } return Result; } #if 0 LPSTR ElanStateToString(ULONG In) { switch(In) { case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: return (ElanState[In].String); default: return (ElanState[0].String); } } LPSTR ElanLanTypeToString(ULONG In) { switch(In) { case 0: return LanType[1].String; case 1: return LanType[2].String; case 2: return LanType[3].String; default: return LanType[0].String; } } LPSTR ElanMaxFrameSizeToString(ULONG In) { switch(In) { case 0: return Misc[3].String; case 1: return "1516"; case 2: return "4544"; case 3: return "9234"; case 4: return "18190"; default: return " ? "; } } LPSTR McastVcTypeToString(ULONG In) { switch(In) { case 0: return McastSendVcType[1].String; case 1: return McastSendVcType[2].String; case 2: return McastSendVcType[3].String; default: return McastSendVcType[0].String; } } PUCHAR MacAddrToString(PVOID In) { static UCHAR String[20]; static PUCHAR HexChars = "0123456789abcdef"; PUCHAR EthAddr = (PUCHAR) In; UINT i; PUCHAR s; for (i = 0, s = String; i < 6; i++, EthAddr++) { *s++ = HexChars[(*EthAddr)>>4]; *s++ = HexChars[(*EthAddr)&0xf]; *s++ = '.'; } *(--s) = '\0'; return String; } #endif // 0 PUCHAR IpAddrToString(IPADDR *pIpAddr) { PUCHAR puc = (PUCHAR) pIpAddr; static UCHAR String[80]; wsprintf(String, "%u.%u.%u.%u", puc[0], puc[1], puc[2], puc[3]); return String; } PUCHAR AtmAddrToString(ATM_ADDRESS *pAtmAddress) { static UCHAR String[80]; static PUCHAR HexChars = "0123456789abcdef"; PUCHAR AtmAddr = (PUCHAR) &(pAtmAddress->Address); PUCHAR s = String; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 1 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 2 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 3 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 4 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 5 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 6 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 7 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 8 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 9 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 10 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 11 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 12 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 13 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 14 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 15 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 16 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 17 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 18 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 19 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 20 *s = '\0'; return String; } VOID AasDisplayArpCache( PIOCTL_QUERY_CACHE pArpCache ) { PARPENTRY pEntry = pArpCache->Entries.Entries; UINT i; for (i = 0; i < pArpCache->Entries.NumberOfEntriesInBuffer; i++) { DisplayMessage(FALSE, MSG_AAS_ARP_CACHE_ENTRY, IpAddrToString(&(pEntry->IpAddr)), AtmAddrToString(&pEntry->AtmAddress)); pEntry ++; } } VOID AasDisplayMarsCache( PIOCTL_QUERY_MARS_CACHE pMarsCache ) { PMARSENTRY pEntry = pMarsCache->MarsCache.Entries; UINT i; for (i = 0; i < pMarsCache->MarsCache.NumberOfEntriesInBuffer; i++, pEntry++) { UINT j; char* szIpAddr = IpAddrToString(&(pEntry->IpAddr)); char rgBlanks[128]; ATM_ADDRESS *pAtmAddr = (ATM_ADDRESS*) ((PUCHAR)pEntry + pEntry->OffsetAtmAddresses); FillMemory(rgBlanks, lstrlen(szIpAddr), ' '); rgBlanks[lstrlen(szIpAddr)]=0; #if 0 printf("Entry[i] @ 0x%lx: Ip=%u.%u.%u.%u NumAddr=%lu Offset=%lu\n", pEntry, ((PUCHAR)&pEntry->IpAddr)[0], ((PUCHAR)&pEntry->IpAddr)[1], ((PUCHAR)&pEntry->IpAddr)[2], ((PUCHAR)&pEntry->IpAddr)[3], pEntry->NumAtmAddresses, pEntry->OffsetAtmAddresses); #endif // 0 for (j = 0; j < pEntry->NumAtmAddresses; j++, pAtmAddr++) { // printf("\t pAddr=%lx\n", pAtmAddr); if (!j) { if (pEntry->IpAddr == 0) { DisplayMessage(FALSE, MSG_AAS_ARP_PROMIS_CACHE_ENTRY, AtmAddrToString(pAtmAddr)); } else { DisplayMessage(FALSE, MSG_AAS_ARP_CACHE_ENTRY, IpAddrToString(&(pEntry->IpAddr)), AtmAddrToString(pAtmAddr)); } } else { DisplayMessage(FALSE, MSG_AAS_ARP_CACHE_ENTRY, rgBlanks, AtmAddrToString(pAtmAddr)); } } } } VOID AasDisplayArpStats( PARP_SERVER_STATISTICS pArpStats ) { #if 0 Recvd Pkts: ->TotalRecvPkts (->DiscardedRecvPkts discarded) Arp Entries: ->CurrentArpEntries current ( ->MaxArpEntries max) Arp Responses: ->Acks acks ( ->Naks naks) Client VCs: ->CurrentClientVCs current (->MaxClientVCs max) Incoming Calls: ->TotalIncomingCalls total (->FailedIncomingCalls failed) Received: 10000 total (100 discarded) Entries: 10 current (15 max) Responses: 1000 acks (200 naks) Client VCs: 5 current (12 max) Incoming Calls: 500 total (20 failed) #endif // DisplayMessage(FALSE, MSG_AAS_C01_ARP_STATS); DisplayMessage(FALSE, MSG_STATS_ELAPSED_TIME, pArpStats->ElapsedSeconds); DisplayMessage(FALSE, MSG_ARPS_RECVD_PKTS, pArpStats->TotalRecvPkts, pArpStats->DiscardedRecvPkts); DisplayMessage(FALSE, MSG_ARPS_ARP_ENTRIES, pArpStats->CurrentArpEntries, pArpStats->MaxArpEntries); DisplayMessage(FALSE, MSG_ARPS_ARP_RESPONSES, pArpStats->Acks, pArpStats->Naks); DisplayMessage(FALSE, MSG_ARPS_CLIENT_VCS, pArpStats->CurrentClientVCs, pArpStats->MaxClientVCs); DisplayMessage(FALSE, MSG_ARPS_INCOMING_CALLS, pArpStats->TotalIncomingCalls); // pArpStats->TotalActiveVCs } VOID AasDisplayMarsStats( PMARS_SERVER_STATISTICS pMarsStats ) { DisplayMessage(FALSE, MSG_AAS_C02_MARS_STATS); DisplayMessage(FALSE, MSG_MARS_RECVD_PKTS, pMarsStats->TotalRecvPkts, pMarsStats->DiscardedRecvPkts); DisplayMessage(FALSE, MSG_MARS_RECVD_MCDATA_PKTS,pMarsStats->TotalMCDataPkts, pMarsStats->DiscardedMCDataPkts, pMarsStats->ReflectedMCDataPkts); DisplayMessage(FALSE, MSG_MARS_MEMBERS, pMarsStats->CurrentClusterMembers, pMarsStats->MaxClusterMembers); DisplayMessage(FALSE, MSG_MARS_PROMIS, pMarsStats->CurrentPromiscuous, pMarsStats->MaxPromiscuous); DisplayMessage(FALSE, MSG_MARS_ADD_PARTY, pMarsStats->TotalCCVCAddParties, pMarsStats->FailedCCVCAddParties); DisplayMessage(FALSE, MSG_MARS_REGISTRATION, pMarsStats->RegistrationRequests, pMarsStats->FailedRegistrations); DisplayMessage(FALSE, MSG_MARS_JOINS, pMarsStats->TotalJoins, pMarsStats->FailedJoins, pMarsStats->DuplicateJoins); DisplayMessage(FALSE, MSG_MARS_LEAVES, pMarsStats->TotalLeaves, pMarsStats->FailedLeaves); DisplayMessage(FALSE, MSG_MARS_REQUESTS, pMarsStats->TotalRequests); DisplayMessage(FALSE, MSG_MARS_RESPONSES, pMarsStats->VCMeshAcks +pMarsStats->MCSAcks, pMarsStats->Naks); DisplayMessage(FALSE, MSG_MARS_VC_MESH, pMarsStats->SuccessfulVCMeshJoins, pMarsStats->VCMeshAcks); DisplayMessage(FALSE, MSG_MARS_GROUPS, pMarsStats->CurrentGroups, pMarsStats->MaxGroups); DisplayMessage(FALSE, MSG_MARS_GROUP_SIZE, pMarsStats->MaxAddressesPerGroup); } void DoAAS(OPTIONS *po) { HANDLE DeviceHandle; char InterfacesBuffer[1024]; PINTERFACES pInterfaces = (PINTERFACES) InterfacesBuffer; ULONG cbInterfaces = sizeof(InterfacesBuffer); #if 0 PUNICODE_STRING pAdapterName; PUNICODE_STRING pElanName; ULONG i, j; BOOL Result; #endif // 0 DisplayMessage(FALSE, MSG_ATMARPS_BANNER); DeviceHandle = OpenDevice(pDeviceName); if (DeviceHandle == INVALID_HANDLE_VALUE) { DisplayMessage(FALSE, MSG_ERROR_OPENING_ATMARPS); return; } // // First check the version // if (!CheckVersion(DeviceHandle)) { CloseDevice(DeviceHandle); return; } // // get the list of available adapters // if (!AasGetInterfaces(DeviceHandle, pInterfaces, cbInterfaces)) { CloseDevice(DeviceHandle); return; } // printf ( " Looping through interfaces...\n"); // // Loop thru the interfaces, displaying info about each. // { UINT u=0; for (u=0;uNumberOfInterfaces;u++) { CHAR Buffer[4000]; ULONG cbBuffer = sizeof(Buffer); PIOCTL_QUERY_CACHE pArpCache = (PIOCTL_QUERY_CACHE) Buffer; PIOCTL_QUERY_MARS_CACHE pMarsCache = (PIOCTL_QUERY_MARS_CACHE) Buffer; INTERFACE_NAME *pInterface = (pInterfaces->Interfaces)+u; PARP_SERVER_STATISTICS pArpStats = (PARP_SERVER_STATISTICS) Buffer; PMARS_SERVER_STATISTICS pMarsStats = (PMARS_SERVER_STATISTICS) Buffer; UINT StartIndex; // // Display the interface name -- must be null terminated. // { WCHAR *pwc = pInterface->Buffer+pInterface->Length/sizeof(WCHAR); WCHAR wc = *pwc; *pwc = 0; DisplayMessage(FALSE, MSG_ADAPTER, pInterface->Buffer ); *pwc = wc; } if (po->DispCache) { StartIndex = pArpCache->StartEntryIndex = 0; DisplayMessage(FALSE, MSG_AAS_C00_ARP_CACHE); while (AasGetArpCache(DeviceHandle, pInterface, pArpCache, cbBuffer) && pArpCache->Entries.NumberOfEntriesInBuffer) { AasDisplayArpCache(pArpCache); StartIndex += pArpCache->Entries.NumberOfEntriesInBuffer; pArpCache->StartEntryIndex = StartIndex; if (StartIndex == pArpCache->Entries.TotalNumberOfEntries) { break; } } StartIndex = pMarsCache->StartEntryIndex = 0; DisplayMessage(FALSE, MSG_AAS_C00_MARS_CACHE); while (AasGetMarsCache(DeviceHandle, pInterface, pMarsCache, cbBuffer) && pMarsCache->MarsCache.NumberOfEntriesInBuffer) { AasDisplayMarsCache(pMarsCache); StartIndex += pMarsCache->MarsCache.NumberOfEntriesInBuffer; pMarsCache->StartEntryIndex = StartIndex; } } if (po->DispStats) { if (AasGetArpStats(DeviceHandle, pInterface, pArpStats)) { AasDisplayArpStats(pArpStats); } if (AasGetMarsStats(DeviceHandle, pInterface, pMarsStats)) { AasDisplayMarsStats(pMarsStats); } } if (po->DoResetStats) { AasResetStatistics(DeviceHandle, pInterface); } } } #if 0 // // Loop thru the adapters getting each adapter's elan list // pAdapterName = &pAdapterList->AdapterList; for (i = 0; i < pAdapterList->AdapterCountReturned; i++) { DisplayMessage(FALSE, MSG_ADAPTER, (PWSTR)((PUCHAR)pAdapterName + sizeof(UNICODE_STRING))); if (GetElanList(DeviceHandle, pAdapterName)) { // // Loop thru the elan list getting ELAN info // pElanName = &pElanList->ElanList; for (j = 0; j < pElanList->ElanCountReturned; j++) { DisplayMessage(FALSE, MSG_ELAN, (PWSTR)((PUCHAR)pElanName + sizeof(UNICODE_STRING))); if (GetElanInfo(DeviceHandle, pAdapterName, pElanName)) { DisplayElanInfo(); } if (GetElanArpTable(DeviceHandle, pAdapterName, pElanName)) { DisplayElanArpTable(); } if (GetElanConnTable(DeviceHandle, pAdapterName, pElanName)) { DisplayElanConnTable(); } // // next elan // pElanName = (PUNICODE_STRING)((PUCHAR)pElanName + sizeof(UNICODE_STRING) + pElanName->Length); } } // // next adapter // pAdapterName = (PUNICODE_STRING)((PUCHAR)pAdapterName + sizeof(UNICODE_STRING) + pAdapterName->Length); } #endif // 0 CloseDevice(DeviceHandle); return; }