/*++ Copyright (c) 1995 Microsoft Corporation Module Name: netstats.c Abstract: This module reads the netcard statistics. Author: David Orbits (davidor) 22-March-1995 Revision History: Rod Gamache (rodga) 10-May-1995 Slight mods for using with Ethstat main program. --*/ #include "ethstat.h" NTSTATUS ReadNetCardNames( IN OUT char DeviceNameString[], IN LONG DeviceNameLength ); char *OidListName[] = { "OID_GEN_MEDIA_IN_USE", "OID_GEN_LINK_SPEED", "OID_GEN_XMIT_ERROR", "OID_GEN_RCV_ERROR", "OID_GEN_RCV_NO_BUFFER", "OID_GEN_DIRECTED_BYTES_XMIT", "OID_GEN_DIRECTED_FRAMES_XMIT", "OID_GEN_DIRECTED_BYTES_RCV", "OID_GEN_DIRECTED_FRAMES_RCV", "OID_GEN_MULTICAST_BYTES_XMIT", "OID_GEN_MULTICAST_FRAMES_XMIT", "OID_GEN_BROADCAST_BYTES_XMIT", "OID_GEN_BROADCAST_FRAMES_XMIT", "OID_GEN_MULTICAST_BYTES_RCV", "OID_GEN_MULTICAST_FRAMES_RCV", "OID_GEN_BROADCAST_BYTES_RCV", "OID_GEN_BROADCAST_FRAMES_RCV", "OID_GEN_RCV_CRC_ERROR", "OID_GEN_TRANSMIT_QUEUE_LENGTH", "OID_802_3_RCV_ERROR_ALIGNMENT", "OID_802_3_XMIT_ONE_COLLISION", "OID_802_3_XMIT_MORE_COLLISIONS", "OID_802_3_XMIT_DEFERRED", "OID_802_3_XMIT_MAX_COLLISIONS", "OID_802_3_RCV_OVERRUN", "OID_802_3_XMIT_UNDERRUN", "OID_802_3_XMIT_TIMES_CRS_LOST", "OID_802_3_XMIT_LATE_COLLISIONS" }; NDIS_OID OidList[] = { OID_GEN_MEDIA_IN_USE, OID_GEN_LINK_SPEED, OID_GEN_XMIT_ERROR, OID_GEN_RCV_ERROR, OID_GEN_RCV_NO_BUFFER, OID_GEN_DIRECTED_BYTES_XMIT, OID_GEN_DIRECTED_FRAMES_XMIT, OID_GEN_DIRECTED_BYTES_RCV, OID_GEN_DIRECTED_FRAMES_RCV, OID_GEN_MULTICAST_BYTES_XMIT, OID_GEN_MULTICAST_FRAMES_XMIT, OID_GEN_BROADCAST_BYTES_XMIT, OID_GEN_BROADCAST_FRAMES_XMIT, OID_GEN_MULTICAST_BYTES_RCV, OID_GEN_MULTICAST_FRAMES_RCV, OID_GEN_BROADCAST_BYTES_RCV, OID_GEN_BROADCAST_FRAMES_RCV, OID_GEN_RCV_CRC_ERROR, OID_GEN_TRANSMIT_QUEUE_LENGTH, OID_802_3_RCV_ERROR_ALIGNMENT, OID_802_3_XMIT_ONE_COLLISION, OID_802_3_XMIT_MORE_COLLISIONS, OID_802_3_XMIT_DEFERRED, OID_802_3_XMIT_MAX_COLLISIONS, OID_802_3_RCV_OVERRUN, OID_802_3_XMIT_UNDERRUN, OID_802_3_XMIT_TIMES_CRS_LOST, OID_802_3_XMIT_LATE_COLLISIONS }; LONG OpenNetDevices = 0; extern DEVICE DeviceList[MAX_NIC]; NTSTATUS NetStatsInit( OUT LONG *NumberNetCards ) { PDEVICE device; NTSTATUS Status; char DeviceNameString[64]; char FullDeviceName[256]; LONG i; *NumberNetCards = 0; i = 0; Status = ReadNetCardNames(DeviceNameString, sizeof(DeviceNameString)); if (!NT_SUCCESS(Status)) { printf( "NetStatsInit: No netcard devices found.\n" ); return STATUS_UNSUCCESSFUL; } device = &DeviceList[0]; while ( NT_SUCCESS(Status) ) { strcpy(device->DeviceName, DeviceNameString); // // First create a symbolic link to the driver. // strcpy( FullDeviceName, "\\Device\\" ); strcat( FullDeviceName, DeviceNameString ); if (!DefineDosDevice(DDD_RAW_TARGET_PATH, DeviceNameString, FullDeviceName)) { printf("\nNetStatsInit: DefineDosDevice (%s, %s) failed\n", DeviceNameString, FullDeviceName ); return STATUS_UNSUCCESSFUL; } // // Next, try to open the device. // strcpy( FullDeviceName, "\\\\.\\" ); strcat( FullDeviceName, DeviceNameString ); device->Handle = CreateFile(FullDeviceName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if ( device->Handle == (HANDLE)-1 ) { printf("NetStatsInit: Can't get a handle to %s (%s)\n", DeviceNameString, FullDeviceName ); DefineDosDevice( DDD_REMOVE_DEFINITION, DeviceNameString, NULL ); } else { if (OpenNetDevices == MAX_NIC) { printf( "NetStatsInit: Too many netcard devices.\n" ); printf( "NetStatsInit: Only first %d will be monitored.\n", OpenNetDevices); CloseHandle( device->Handle ); DefineDosDevice( DDD_REMOVE_DEFINITION, DeviceNameString, NULL ); break; } OpenNetDevices += 1; device += 1; } // // Get next netcard device name. // Status = ReadNetCardNames(DeviceNameString, sizeof(DeviceNameString)); } *NumberNetCards = OpenNetDevices; #ifdef debug printf("\nNetcard devices found -- %d\n", OpenNetDevices); for ( i = 0; i < OpenNetDevices; i++ ) { device = &DeviceList[i]; printf("%s ", device->DeviceName); } printf("\n\n"); #endif return STATUS_SUCCESS; } NTSTATUS NetStatsReadSample( PNET_SAMPLE_STATISTICS PNetSampleStatistics ) { ULONG Status; PDEVICE device; LONG i; ULONG j; DWORD cbReturned; PLONGLONG PCounter; PNET_SAMPLE_STATISTICS PDeviceSampleStatistics = PNetSampleStatistics; memset(PDeviceSampleStatistics, 0, sizeof(NET_SAMPLE_STATISTICS)); for ( i = 0; i < OpenNetDevices; i++ ) { device = &DeviceList[i]; PCounter = (PLONGLONG) PDeviceSampleStatistics; // // Now loop through each of our potential OIDs. // for ( j = 0; j < sizeof(OidList)/sizeof(NDIS_OID); j++ ) { *PCounter = 0; if ( !(Status = DeviceIoControl( device->Handle, (DWORD)IOCTL_NDIS_QUERY_GLOBAL_STATS, (PVOID)&OidList[j], sizeof(NDIS_OID), (PVOID)PCounter, sizeof(LONGLONG), &cbReturned, 0 )) ) { #ifdef debug printf("DeviceIoControl Failed!, Status = 0x%lx, OID: %s\n", Status, OidListName[j]); #endif *PCounter = (LONGLONG)-1; } PCounter += 1; } PDeviceSampleStatistics += 1; } #ifdef debug printf("\n "); for ( i = 0; i < OpenNetDevices; i++ ) { device = &DeviceList[i]; printf(" %12s", device->DeviceName); } printf("\n\n"); for ( j = 0; j < sizeof(OidList)/sizeof(NDIS_OID); j++ ) { printf( "%-30s: ", OidListName[j]); PCounter = (PLONGLONG) PNetSampleStatistics + j; for ( i = 0; i < OpenNetDevices; i++ ) { device = &DeviceList[i]; if (OidList[j] != OID_GEN_MEDIA_IN_USE) { printf(" %d", *PCounter ); } else { printf(" Media in use problem\n"); } (PNET_SAMPLE_STATISTICS) PCounter += 1; } printf("\n"); } #endif return STATUS_SUCCESS; } NTSTATUS NetStatsClose( VOID ) { PDEVICE device; LONG i; for ( i = 0; i < OpenNetDevices; i++ ) { device = &DeviceList[i]; if ( device->Handle != (HANDLE)-1 ) { CloseHandle( device->Handle ); } DefineDosDevice( DDD_REMOVE_DEFINITION, device->DeviceName, NULL ); } return STATUS_SUCCESS; } NTSTATUS ReadNetCardNames( IN OUT char DeviceNameString[], IN LONG DeviceNameLength ) { int i; LONG Result; HKEY Key; DWORD Size; char KeyString[128]; static LONG RegNetCardNumber = 0; // // Scan registry for installed netcards. // RegNetCardNumber++; while (RegNetCardNumber < 32) { sprintf(KeyString, "software\\microsoft\\windows nt\\currentversion\\networkcards\\%d", RegNetCardNumber); Result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KeyString, 0, KEY_QUERY_VALUE, &Key); if (Result == ERROR_SUCCESS) { // // Query out the value we are interested in // Size = DeviceNameLength; Result = RegQueryValueEx(Key, "ServiceName", 0, NULL, (LPBYTE)DeviceNameString, &Size); RegCloseKey(Key); if (Result == ERROR_SUCCESS) { //printf("%s netcard = %s\n", KeyString, DeviceNameString); return STATUS_SUCCESS; } else { printf("%s\n", KeyString); printf("reg query failed, status = %08X\n", Result); } } else { //printf("%s\n", KeyString); //printf("reg open key failed, status = %08X\n", Result); } RegNetCardNumber++; } return STATUS_UNSUCCESSFUL; }