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.

178 lines
4.4 KiB

  1. /*++
  2. Copyright (c) 2000, Microsoft Corporation
  3. Module Name:
  4. rcvall.c
  5. Abstract:
  6. This module demonstrates the use of the SIO_RCVALL socket I/O control
  7. to enable promiscuous reception.
  8. Author:
  9. Abolade Gbadegesin (aboladeg) 28-April-2000
  10. Revision History:
  11. --*/
  12. #include <winsock2.h>
  13. #include <mstcpip.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <process.h>
  17. #define IO_CONTROL_THREADS 20
  18. #define SENDS_PER_ROUND 5000
  19. #define IO_CONTROLS_PER_ROUND 500
  20. CRITICAL_SECTION CriticalSection;
  21. SOCKET Socket;
  22. VOID __cdecl
  23. IoControlThread(
  24. PVOID Parameter
  25. )
  26. {
  27. HANDLE ConsoleHandle;
  28. CONSOLE_SCREEN_BUFFER_INFO Csbi;
  29. ULONG i, j;
  30. ULONG Length;
  31. ULONG Option;
  32. //
  33. // Enter an infinite loop in which promiscuous reception is repeatedly
  34. // enabled and disabled.
  35. //
  36. ConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
  37. GetConsoleScreenBufferInfo(ConsoleHandle, &Csbi);
  38. Csbi.dwCursorPosition.X = 40;
  39. for (i = 0;;i++) {
  40. EnterCriticalSection(&CriticalSection);
  41. if (PtrToUlong(Parameter) == 0) {
  42. SetConsoleCursorPosition(ConsoleHandle, Csbi.dwCursorPosition);
  43. printf("IoControlThread: round %u", i);
  44. }
  45. LeaveCriticalSection(&CriticalSection);
  46. for (j = 0; j < IO_CONTROLS_PER_ROUND; j++) {
  47. Option = 1;
  48. WSAIoctl(
  49. Socket, SIO_RCVALL, &Option, sizeof(Option), NULL, 0,
  50. &Length, NULL, NULL
  51. );
  52. Option = 0;
  53. WSAIoctl(
  54. Socket, SIO_RCVALL, &Option, sizeof(Option), NULL, 0,
  55. &Length, NULL, NULL
  56. );
  57. }
  58. }
  59. }
  60. int __cdecl
  61. main(
  62. int argc,
  63. char* argv[]
  64. )
  65. {
  66. HANDLE ConsoleHandle;
  67. CONSOLE_SCREEN_BUFFER_INFO Csbi;
  68. ULONG i, j;
  69. ULONG Length;
  70. SOCKADDR_IN SockAddrIn;
  71. PSOCKADDR SockAddrp = (PSOCKADDR)&SockAddrIn;
  72. SOCKET UdpSocket;
  73. WSADATA wd;
  74. __try {
  75. InitializeCriticalSection(&CriticalSection);
  76. } __except(EXCEPTION_EXECUTE_HANDLER) {
  77. printf("InitializeCriticalSection: %x\n", GetExceptionCode());
  78. return 0;
  79. }
  80. WSAStartup(0x202, &wd);
  81. //
  82. // Create a datagram socket, connect it to the broadcast address,
  83. // and retrieve the assigned address to determine the 'best' interface
  84. // to use in binding our raw socket.
  85. //
  86. Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  87. if (Socket == INVALID_SOCKET) {
  88. printf("socket: %d\n", WSAGetLastError());
  89. return 0;
  90. }
  91. ZeroMemory(&SockAddrIn, sizeof(SockAddrIn));
  92. SockAddrIn.sin_family = AF_INET;
  93. SockAddrIn.sin_port = 0;
  94. SockAddrIn.sin_addr.s_addr = htonl(INADDR_BROADCAST);
  95. if (connect(Socket, SockAddrp, sizeof(SockAddrIn)) == SOCKET_ERROR) {
  96. printf("connect: %d\n", WSAGetLastError());
  97. return 0;
  98. }
  99. Length = sizeof(SockAddrIn);
  100. if (getsockname(Socket, SockAddrp, &Length) == SOCKET_ERROR) {
  101. printf("getsockname: %d\n", WSAGetLastError());
  102. return 0;
  103. }
  104. printf(
  105. "addr=%s port=%u\n",
  106. inet_ntoa(SockAddrIn.sin_addr), SockAddrIn.sin_port
  107. );
  108. closesocket(Socket);
  109. //
  110. // Create a raw socket and bind it to the address retrieved above.
  111. //
  112. Socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
  113. if (Socket == INVALID_SOCKET) {
  114. printf("socket: %d\n", WSAGetLastError());
  115. return 0;
  116. }
  117. if (bind(Socket, SockAddrp, sizeof(SockAddrIn)) == SOCKET_ERROR) {
  118. printf("bind: %d\n", WSAGetLastError());
  119. return 0;
  120. }
  121. //
  122. // Launch the threads which will continuously enable and disable
  123. // promiscuous reception.
  124. //
  125. for (i = 0; i < IO_CONTROL_THREADS; i++) {
  126. _beginthread(IoControlThread, 0, UlongToPtr(i));
  127. }
  128. //
  129. // Enter a loop in which we continously send a small amount of data
  130. // to our own raw socket, just to exercise TCP/IP's synchronization.
  131. //
  132. ConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
  133. GetConsoleScreenBufferInfo(ConsoleHandle, &Csbi);
  134. Csbi.dwCursorPosition.X = 0;
  135. for (i = 0;; i++) {
  136. EnterCriticalSection(&CriticalSection);
  137. SetConsoleCursorPosition(ConsoleHandle, Csbi.dwCursorPosition);
  138. printf("Main thread: round %u", i);
  139. LeaveCriticalSection(&CriticalSection);
  140. for (j = 0; j < SENDS_PER_ROUND; j++) {
  141. sendto(Socket, (PCHAR)SockAddrp, Length, 0, SockAddrp, Length);
  142. }
  143. }
  144. return 0;
  145. }