381 lines
9.1 KiB
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;
|
|
|
|
|
|
}
|
|
|
|
|