From 1c08e25544486561657e5b753a166a530cf263fb Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Fri, 17 Sep 2004 16:07:41 +0000 Subject: [PATCH] Userland test for lan.sys svn path=/trunk/; revision=10887 --- reactos/apps/tests/lan/lantest.cpp | 218 +++++++++++++++++++++++++++++ reactos/apps/tests/lan/makefile | 24 ++++ 2 files changed, 242 insertions(+) create mode 100644 reactos/apps/tests/lan/lantest.cpp create mode 100644 reactos/apps/tests/lan/makefile diff --git a/reactos/apps/tests/lan/lantest.cpp b/reactos/apps/tests/lan/lantest.cpp new file mode 100644 index 00000000000..5a02cc3e9ae --- /dev/null +++ b/reactos/apps/tests/lan/lantest.cpp @@ -0,0 +1,218 @@ +#include +#include +#include +#include +#include +#include + +using std::string; +using std::cin; +using std::cout; +using std::cerr; +using std::endl; + +void display_row( char *data, int off, int len ) { + int i; + + printf( "%08x:", off ); + for( i = off; i < len && i < off + 16; i++ ) { + printf( " %02x", data[i] & 0xff ); + } + + for( ; i < off + 16; i++ ) + printf(" "); + + printf( " -- " ); + + for( i = off; i < len && i < off + 16; i++ ) { + printf( "%c", (data[i] >= ' ' && data[i] <= '~') ? data[i] : '.' ); + } + + printf( "\n" ); +} + +void display_buffer( char *Packet, int ReadLen ) { + UINT PktLen; + for( PktLen = 0; PktLen < ReadLen; PktLen += 16 ) + display_row( Packet, PktLen, ReadLen ); +} + +int byte_till_end( char *Packet, int PktLen ) { + int byte; + std::string word; + + cin >> word; + while( word != "end" ) { + byte = strtoul( (string("0x") + word).c_str(), 0, 0 ); + fprintf( stderr, "Byte[%d]: %x\n", PktLen, byte & 0xff ); + Packet[PktLen++] = byte; + cin >> word; + } + + return PktLen; +} + +/* Ethernet types. We swap constants so we can compare values at runtime + without swapping them there */ +#define ETYPE_IPv4 WH2N(0x0800) +#define ETYPE_IPv6 WH2N(0x86DD) +#define ETYPE_ARP WH2N(0x0806) + +extern "C" +NTSTATUS STDCALL NtCreateFile( + PHANDLE FileHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + PIO_STATUS_BLOCK IoStatusBlock, + PLARGE_INTEGER AllocationSize, + ULONG FileAttributes, + ULONG ShareAccess, + ULONG CreateDisposition, + ULONG CreateOptions, + PVOID EaBuffer, + ULONG EaLength); + +int main( int argc, char **argv ) { + string word; + HANDLE LanFile; + OBJECT_ATTRIBUTES Attributes; + UNICODE_STRING LanDevice; + IO_STATUS_BLOCK Iosb; + HANDLE Event; + PFILE_FULL_EA_INFORMATION EaBuffer; + NTSTATUS Status; + DWORD On = 1, PktLen; + CHAR Packet[1600]; + PLAN_PACKET_HEADER Hdr = (PLAN_PACKET_HEADER)Packet; + PLAN_ADDRESS Addr = (PLAN_ADDRESS)Packet; + USHORT TypesToListen[] = { ETYPE_IPv4, ETYPE_IPv6, ETYPE_ARP }; + UINT EaLength = LAN_EA_INFO_SIZE(sizeof(TypesToListen)/sizeof(USHORT)); + + Status = NtCreateEvent(&Event, + EVENT_ALL_ACCESS, + NULL, + 0, + 0 ); + + RtlInitUnicodeString( &LanDevice, L"\\Device\\Lan" ); + + InitializeObjectAttributes( &Attributes, + &LanDevice, + OBJ_CASE_INSENSITIVE, + NULL, + NULL ); + + EaBuffer = (PFILE_FULL_EA_INFORMATION)calloc( EaLength, 1 ); + LAN_FILL_EA_INFO(EaBuffer,sizeof(TypesToListen)/sizeof(USHORT), + TypesToListen); + + Status = ZwCreateFile( &LanFile, + SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE | + GENERIC_EXECUTE, + &Attributes, + &Iosb, + NULL, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN_IF, + FILE_SYNCHRONOUS_IO_NONALERT, + EaBuffer, + EaLength ); + + if( !NT_SUCCESS(Status) ) { + cerr << "Could not open lan device " << Status << "\n"; + return 1; + } + + Status = DeviceIoControl( LanFile, + IOCTL_IF_BUFFERED_MODE, + &On, + sizeof(On), + 0, + 0, + &PktLen, + NULL ); + + if( !Status ) { + cerr << "Could not turn on buffered mode " << Status << "\n"; + return 1; + } + + while( cin >> word ) { + if( word == "end" ) { + NtClose( LanFile ); + return 0; + } else if( word == "enum" ) { + Status = DeviceIoControl( LanFile, + IOCTL_IF_ENUM_ADAPTERS, + NULL, + 0, + Packet, + sizeof(Packet), + &PktLen, + NULL ); + + cout << "EnumAdapters: " << Status << "\n"; + if( Status ) + display_buffer( Packet, PktLen ); + } else if( word == "query" ) { + cin >> PktLen; + + Status = DeviceIoControl( LanFile, + IOCTL_IF_ADAPTER_INFO, + &PktLen, + sizeof(PktLen), + Packet, + sizeof(Packet), + &PktLen, + NULL ); + + cout << "QueryAdapterInfo: " << Status << "\n"; + if( Status ) + display_buffer( Packet, PktLen ); + } else if( word == "send" ) { + cin >> Hdr->Fixed.Adapter + >> Hdr->Fixed.AddressType + >> Hdr->Fixed.AddressLen + >> Hdr->Fixed.PacketType; + Hdr->Fixed.Mdl = NULL; + PktLen = byte_till_end( Packet, Hdr->Address - (PCHAR)Hdr ); + Status = NtWriteFile( LanFile, + NULL, + NULL, + NULL, + &Iosb, + Packet, + PktLen, + NULL, + NULL ); + + cout << "NtWriteFile: " << Status << "\n"; + } else if( word == "recv" ) { + ULONG ReadLen; + Status = NtReadFile( LanFile, + Event, + NULL, + NULL, + &Iosb, + Packet, + sizeof(Packet), + NULL, + NULL ); + cout << "NtReadFile: " << Status << "\n"; + if( Status == STATUS_PENDING ) { + LARGE_INTEGER Timeout = { 0 }; + Status = NtWaitForSingleObject( Event, 1, &Timeout ); + } + + ReadLen = Iosb.Information; + + if( Status == STATUS_SUCCESS ) { + cout << "Read " << ReadLen << " bytes\n"; + display_buffer( Packet, ReadLen ); + } + } + } + + return 0; +} diff --git a/reactos/apps/tests/lan/makefile b/reactos/apps/tests/lan/makefile new file mode 100644 index 00000000000..f8d57337c65 --- /dev/null +++ b/reactos/apps/tests/lan/makefile @@ -0,0 +1,24 @@ +# +# $Id: makefile,v 1.1 2004/09/17 16:07:41 arty Exp $ + +PATH_TO_TOP = ../../.. + +TARGET_NORC = yes + +TARGET_TYPE = program + +TARGET_APPTYPE = console + +TARGET_NAME = lantest + +TARGET_SDKLIBS = ws2_32.a ntdll.a + +TARGET_OBJECTS = lantest.o -lstdc++ + +TARGET_CPPFLAGS = -I$(PATH_TO_TOP)/include -g + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF