179 lines
4.4 KiB
C
179 lines
4.4 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 2000, Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
rcvall.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This module demonstrates the use of the SIO_RCVALL socket I/O control
|
||
|
to enable promiscuous reception.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Abolade Gbadegesin (aboladeg) 28-April-2000
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include <winsock2.h>
|
||
|
#include <mstcpip.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <process.h>
|
||
|
|
||
|
#define IO_CONTROL_THREADS 20
|
||
|
#define SENDS_PER_ROUND 5000
|
||
|
#define IO_CONTROLS_PER_ROUND 500
|
||
|
|
||
|
CRITICAL_SECTION CriticalSection;
|
||
|
SOCKET Socket;
|
||
|
|
||
|
VOID __cdecl
|
||
|
IoControlThread(
|
||
|
PVOID Parameter
|
||
|
)
|
||
|
{
|
||
|
HANDLE ConsoleHandle;
|
||
|
CONSOLE_SCREEN_BUFFER_INFO Csbi;
|
||
|
ULONG i, j;
|
||
|
ULONG Length;
|
||
|
ULONG Option;
|
||
|
|
||
|
//
|
||
|
// Enter an infinite loop in which promiscuous reception is repeatedly
|
||
|
// enabled and disabled.
|
||
|
//
|
||
|
|
||
|
ConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||
|
GetConsoleScreenBufferInfo(ConsoleHandle, &Csbi);
|
||
|
Csbi.dwCursorPosition.X = 40;
|
||
|
|
||
|
for (i = 0;;i++) {
|
||
|
|
||
|
EnterCriticalSection(&CriticalSection);
|
||
|
if (PtrToUlong(Parameter) == 0) {
|
||
|
SetConsoleCursorPosition(ConsoleHandle, Csbi.dwCursorPosition);
|
||
|
printf("IoControlThread: round %u", i);
|
||
|
}
|
||
|
LeaveCriticalSection(&CriticalSection);
|
||
|
|
||
|
for (j = 0; j < IO_CONTROLS_PER_ROUND; j++) {
|
||
|
Option = 1;
|
||
|
WSAIoctl(
|
||
|
Socket, SIO_RCVALL, &Option, sizeof(Option), NULL, 0,
|
||
|
&Length, NULL, NULL
|
||
|
);
|
||
|
Option = 0;
|
||
|
WSAIoctl(
|
||
|
Socket, SIO_RCVALL, &Option, sizeof(Option), NULL, 0,
|
||
|
&Length, NULL, NULL
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int __cdecl
|
||
|
main(
|
||
|
int argc,
|
||
|
char* argv[]
|
||
|
)
|
||
|
{
|
||
|
HANDLE ConsoleHandle;
|
||
|
CONSOLE_SCREEN_BUFFER_INFO Csbi;
|
||
|
ULONG i, j;
|
||
|
ULONG Length;
|
||
|
SOCKADDR_IN SockAddrIn;
|
||
|
PSOCKADDR SockAddrp = (PSOCKADDR)&SockAddrIn;
|
||
|
SOCKET UdpSocket;
|
||
|
WSADATA wd;
|
||
|
|
||
|
__try {
|
||
|
InitializeCriticalSection(&CriticalSection);
|
||
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
||
|
printf("InitializeCriticalSection: %x\n", GetExceptionCode());
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
WSAStartup(0x202, &wd);
|
||
|
|
||
|
//
|
||
|
// Create a datagram socket, connect it to the broadcast address,
|
||
|
// and retrieve the assigned address to determine the 'best' interface
|
||
|
// to use in binding our raw socket.
|
||
|
//
|
||
|
|
||
|
Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||
|
if (Socket == INVALID_SOCKET) {
|
||
|
printf("socket: %d\n", WSAGetLastError());
|
||
|
return 0;
|
||
|
}
|
||
|
ZeroMemory(&SockAddrIn, sizeof(SockAddrIn));
|
||
|
SockAddrIn.sin_family = AF_INET;
|
||
|
SockAddrIn.sin_port = 0;
|
||
|
SockAddrIn.sin_addr.s_addr = htonl(INADDR_BROADCAST);
|
||
|
if (connect(Socket, SockAddrp, sizeof(SockAddrIn)) == SOCKET_ERROR) {
|
||
|
printf("connect: %d\n", WSAGetLastError());
|
||
|
return 0;
|
||
|
}
|
||
|
Length = sizeof(SockAddrIn);
|
||
|
if (getsockname(Socket, SockAddrp, &Length) == SOCKET_ERROR) {
|
||
|
printf("getsockname: %d\n", WSAGetLastError());
|
||
|
return 0;
|
||
|
}
|
||
|
printf(
|
||
|
"addr=%s port=%u\n",
|
||
|
inet_ntoa(SockAddrIn.sin_addr), SockAddrIn.sin_port
|
||
|
);
|
||
|
closesocket(Socket);
|
||
|
|
||
|
//
|
||
|
// Create a raw socket and bind it to the address retrieved above.
|
||
|
//
|
||
|
|
||
|
Socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
|
||
|
if (Socket == INVALID_SOCKET) {
|
||
|
printf("socket: %d\n", WSAGetLastError());
|
||
|
return 0;
|
||
|
}
|
||
|
if (bind(Socket, SockAddrp, sizeof(SockAddrIn)) == SOCKET_ERROR) {
|
||
|
printf("bind: %d\n", WSAGetLastError());
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Launch the threads which will continuously enable and disable
|
||
|
// promiscuous reception.
|
||
|
//
|
||
|
|
||
|
for (i = 0; i < IO_CONTROL_THREADS; i++) {
|
||
|
_beginthread(IoControlThread, 0, UlongToPtr(i));
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Enter a loop in which we continously send a small amount of data
|
||
|
// to our own raw socket, just to exercise TCP/IP's synchronization.
|
||
|
//
|
||
|
|
||
|
ConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||
|
GetConsoleScreenBufferInfo(ConsoleHandle, &Csbi);
|
||
|
Csbi.dwCursorPosition.X = 0;
|
||
|
|
||
|
for (i = 0;; i++) {
|
||
|
|
||
|
EnterCriticalSection(&CriticalSection);
|
||
|
SetConsoleCursorPosition(ConsoleHandle, Csbi.dwCursorPosition);
|
||
|
printf("Main thread: round %u", i);
|
||
|
LeaveCriticalSection(&CriticalSection);
|
||
|
|
||
|
for (j = 0; j < SENDS_PER_ROUND; j++) {
|
||
|
sendto(Socket, (PCHAR)SockAddrp, Length, 0, SockAddrp, Length);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|