Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

380 lines
9.1 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. netstats.c
  5. Abstract:
  6. This module reads the netcard statistics.
  7. Author:
  8. David Orbits (davidor) 22-March-1995
  9. Revision History:
  10. Rod Gamache (rodga) 10-May-1995
  11. Slight mods for using with Ethstat main program.
  12. --*/
  13. #include "ethstat.h"
  14. NTSTATUS
  15. ReadNetCardNames(
  16. IN OUT char DeviceNameString[],
  17. IN LONG DeviceNameLength
  18. );
  19. char *OidListName[] = {
  20. "OID_GEN_MEDIA_IN_USE",
  21. "OID_GEN_LINK_SPEED",
  22. "OID_GEN_XMIT_ERROR",
  23. "OID_GEN_RCV_ERROR",
  24. "OID_GEN_RCV_NO_BUFFER",
  25. "OID_GEN_DIRECTED_BYTES_XMIT",
  26. "OID_GEN_DIRECTED_FRAMES_XMIT",
  27. "OID_GEN_DIRECTED_BYTES_RCV",
  28. "OID_GEN_DIRECTED_FRAMES_RCV",
  29. "OID_GEN_MULTICAST_BYTES_XMIT",
  30. "OID_GEN_MULTICAST_FRAMES_XMIT",
  31. "OID_GEN_BROADCAST_BYTES_XMIT",
  32. "OID_GEN_BROADCAST_FRAMES_XMIT",
  33. "OID_GEN_MULTICAST_BYTES_RCV",
  34. "OID_GEN_MULTICAST_FRAMES_RCV",
  35. "OID_GEN_BROADCAST_BYTES_RCV",
  36. "OID_GEN_BROADCAST_FRAMES_RCV",
  37. "OID_GEN_RCV_CRC_ERROR",
  38. "OID_GEN_TRANSMIT_QUEUE_LENGTH",
  39. "OID_802_3_RCV_ERROR_ALIGNMENT",
  40. "OID_802_3_XMIT_ONE_COLLISION",
  41. "OID_802_3_XMIT_MORE_COLLISIONS",
  42. "OID_802_3_XMIT_DEFERRED",
  43. "OID_802_3_XMIT_MAX_COLLISIONS",
  44. "OID_802_3_RCV_OVERRUN",
  45. "OID_802_3_XMIT_UNDERRUN",
  46. "OID_802_3_XMIT_TIMES_CRS_LOST",
  47. "OID_802_3_XMIT_LATE_COLLISIONS"
  48. };
  49. NDIS_OID OidList[] = {
  50. OID_GEN_MEDIA_IN_USE,
  51. OID_GEN_LINK_SPEED,
  52. OID_GEN_XMIT_ERROR,
  53. OID_GEN_RCV_ERROR,
  54. OID_GEN_RCV_NO_BUFFER,
  55. OID_GEN_DIRECTED_BYTES_XMIT,
  56. OID_GEN_DIRECTED_FRAMES_XMIT,
  57. OID_GEN_DIRECTED_BYTES_RCV,
  58. OID_GEN_DIRECTED_FRAMES_RCV,
  59. OID_GEN_MULTICAST_BYTES_XMIT,
  60. OID_GEN_MULTICAST_FRAMES_XMIT,
  61. OID_GEN_BROADCAST_BYTES_XMIT,
  62. OID_GEN_BROADCAST_FRAMES_XMIT,
  63. OID_GEN_MULTICAST_BYTES_RCV,
  64. OID_GEN_MULTICAST_FRAMES_RCV,
  65. OID_GEN_BROADCAST_BYTES_RCV,
  66. OID_GEN_BROADCAST_FRAMES_RCV,
  67. OID_GEN_RCV_CRC_ERROR,
  68. OID_GEN_TRANSMIT_QUEUE_LENGTH,
  69. OID_802_3_RCV_ERROR_ALIGNMENT,
  70. OID_802_3_XMIT_ONE_COLLISION,
  71. OID_802_3_XMIT_MORE_COLLISIONS,
  72. OID_802_3_XMIT_DEFERRED,
  73. OID_802_3_XMIT_MAX_COLLISIONS,
  74. OID_802_3_RCV_OVERRUN,
  75. OID_802_3_XMIT_UNDERRUN,
  76. OID_802_3_XMIT_TIMES_CRS_LOST,
  77. OID_802_3_XMIT_LATE_COLLISIONS
  78. };
  79. LONG OpenNetDevices = 0;
  80. extern DEVICE DeviceList[MAX_NIC];
  81. NTSTATUS
  82. NetStatsInit(
  83. OUT LONG *NumberNetCards
  84. )
  85. {
  86. PDEVICE device;
  87. NTSTATUS Status;
  88. char DeviceNameString[64];
  89. char FullDeviceName[256];
  90. LONG i;
  91. *NumberNetCards = 0;
  92. i = 0;
  93. Status = ReadNetCardNames(DeviceNameString, sizeof(DeviceNameString));
  94. if (!NT_SUCCESS(Status)) {
  95. printf( "NetStatsInit: No netcard devices found.\n" );
  96. return STATUS_UNSUCCESSFUL;
  97. }
  98. device = &DeviceList[0];
  99. while ( NT_SUCCESS(Status) ) {
  100. strcpy(device->DeviceName, DeviceNameString);
  101. //
  102. // First create a symbolic link to the driver.
  103. //
  104. strcpy( FullDeviceName, "\\Device\\" );
  105. strcat( FullDeviceName, DeviceNameString );
  106. if (!DefineDosDevice(DDD_RAW_TARGET_PATH, DeviceNameString, FullDeviceName)) {
  107. printf("\nNetStatsInit: DefineDosDevice (%s, %s) failed\n",
  108. DeviceNameString,
  109. FullDeviceName );
  110. return STATUS_UNSUCCESSFUL;
  111. }
  112. //
  113. // Next, try to open the device.
  114. //
  115. strcpy( FullDeviceName, "\\\\.\\" );
  116. strcat( FullDeviceName, DeviceNameString );
  117. device->Handle = CreateFile(FullDeviceName,
  118. GENERIC_READ | GENERIC_WRITE,
  119. 0,
  120. NULL,
  121. OPEN_EXISTING,
  122. FILE_ATTRIBUTE_NORMAL,
  123. NULL
  124. );
  125. if ( device->Handle == (HANDLE)-1 ) {
  126. printf("NetStatsInit: Can't get a handle to %s (%s)\n",
  127. DeviceNameString,
  128. FullDeviceName );
  129. DefineDosDevice( DDD_REMOVE_DEFINITION, DeviceNameString, NULL );
  130. } else {
  131. if (OpenNetDevices == MAX_NIC) {
  132. printf( "NetStatsInit: Too many netcard devices.\n" );
  133. printf( "NetStatsInit: Only first %d will be monitored.\n", OpenNetDevices);
  134. CloseHandle( device->Handle );
  135. DefineDosDevice( DDD_REMOVE_DEFINITION, DeviceNameString, NULL );
  136. break;
  137. }
  138. OpenNetDevices += 1;
  139. device += 1;
  140. }
  141. //
  142. // Get next netcard device name.
  143. //
  144. Status = ReadNetCardNames(DeviceNameString, sizeof(DeviceNameString));
  145. }
  146. *NumberNetCards = OpenNetDevices;
  147. #ifdef debug
  148. printf("\nNetcard devices found -- %d\n", OpenNetDevices);
  149. for ( i = 0; i < OpenNetDevices; i++ ) {
  150. device = &DeviceList[i];
  151. printf("%s ", device->DeviceName);
  152. }
  153. printf("\n\n");
  154. #endif
  155. return STATUS_SUCCESS;
  156. }
  157. NTSTATUS
  158. NetStatsReadSample(
  159. PNET_SAMPLE_STATISTICS PNetSampleStatistics
  160. )
  161. {
  162. ULONG Status;
  163. PDEVICE device;
  164. LONG i;
  165. ULONG j;
  166. DWORD cbReturned;
  167. PLONGLONG PCounter;
  168. PNET_SAMPLE_STATISTICS PDeviceSampleStatistics = PNetSampleStatistics;
  169. memset(PDeviceSampleStatistics, 0, sizeof(NET_SAMPLE_STATISTICS));
  170. for ( i = 0; i < OpenNetDevices; i++ ) {
  171. device = &DeviceList[i];
  172. PCounter = (PLONGLONG) PDeviceSampleStatistics;
  173. //
  174. // Now loop through each of our potential OIDs.
  175. //
  176. for ( j = 0; j < sizeof(OidList)/sizeof(NDIS_OID); j++ ) {
  177. *PCounter = 0;
  178. if ( !(Status = DeviceIoControl(
  179. device->Handle,
  180. (DWORD)IOCTL_NDIS_QUERY_GLOBAL_STATS,
  181. (PVOID)&OidList[j],
  182. sizeof(NDIS_OID),
  183. (PVOID)PCounter,
  184. sizeof(LONGLONG),
  185. &cbReturned,
  186. 0
  187. )) ) {
  188. #ifdef debug
  189. printf("DeviceIoControl Failed!, Status = 0x%lx, OID: %s\n", Status, OidListName[j]);
  190. #endif
  191. *PCounter = (LONGLONG)-1;
  192. }
  193. PCounter += 1;
  194. }
  195. PDeviceSampleStatistics += 1;
  196. }
  197. #ifdef debug
  198. printf("\n ");
  199. for ( i = 0; i < OpenNetDevices; i++ ) {
  200. device = &DeviceList[i];
  201. printf(" %12s", device->DeviceName);
  202. }
  203. printf("\n\n");
  204. for ( j = 0; j < sizeof(OidList)/sizeof(NDIS_OID); j++ ) {
  205. printf( "%-30s: ", OidListName[j]);
  206. PCounter = (PLONGLONG) PNetSampleStatistics + j;
  207. for ( i = 0; i < OpenNetDevices; i++ ) {
  208. device = &DeviceList[i];
  209. if (OidList[j] != OID_GEN_MEDIA_IN_USE) {
  210. printf(" %d", *PCounter );
  211. } else {
  212. printf(" Media in use problem\n");
  213. }
  214. (PNET_SAMPLE_STATISTICS) PCounter += 1;
  215. }
  216. printf("\n");
  217. }
  218. #endif
  219. return STATUS_SUCCESS;
  220. }
  221. NTSTATUS
  222. NetStatsClose(
  223. VOID
  224. )
  225. {
  226. PDEVICE device;
  227. LONG i;
  228. for ( i = 0; i < OpenNetDevices; i++ ) {
  229. device = &DeviceList[i];
  230. if ( device->Handle != (HANDLE)-1 ) {
  231. CloseHandle( device->Handle );
  232. }
  233. DefineDosDevice( DDD_REMOVE_DEFINITION, device->DeviceName, NULL );
  234. }
  235. return STATUS_SUCCESS;
  236. }
  237. NTSTATUS
  238. ReadNetCardNames(
  239. IN OUT char DeviceNameString[],
  240. IN LONG DeviceNameLength
  241. )
  242. {
  243. int i;
  244. LONG Result;
  245. HKEY Key;
  246. DWORD Size;
  247. char KeyString[128];
  248. static LONG RegNetCardNumber = 0;
  249. //
  250. // Scan registry for installed netcards.
  251. //
  252. RegNetCardNumber++;
  253. while (RegNetCardNumber < 32) {
  254. sprintf(KeyString,
  255. "software\\microsoft\\windows nt\\currentversion\\networkcards\\%d",
  256. RegNetCardNumber);
  257. Result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  258. KeyString,
  259. 0,
  260. KEY_QUERY_VALUE,
  261. &Key);
  262. if (Result == ERROR_SUCCESS) {
  263. //
  264. // Query out the value we are interested in
  265. //
  266. Size = DeviceNameLength;
  267. Result = RegQueryValueEx(Key,
  268. "ServiceName",
  269. 0,
  270. NULL,
  271. (LPBYTE)DeviceNameString,
  272. &Size);
  273. RegCloseKey(Key);
  274. if (Result == ERROR_SUCCESS) {
  275. //printf("%s netcard = %s\n", KeyString, DeviceNameString);
  276. return STATUS_SUCCESS;
  277. } else {
  278. printf("%s\n", KeyString);
  279. printf("reg query failed, status = %08X\n", Result);
  280. }
  281. } else {
  282. //printf("%s\n", KeyString);
  283. //printf("reg open key failed, status = %08X\n", Result);
  284. }
  285. RegNetCardNumber++;
  286. }
  287. return STATUS_UNSUCCESSFUL;
  288. }