Windows-Server-2003/sdktools/ethstat/netstats.c

381 lines
9.1 KiB
C

/*++
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;
}