Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219#include <windows.h>#include <net/lan.h>#include <iostream>#include <string>#include <ddk/ntddk.h>#include <rosrtl/string.h>
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 NTAPI 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;}