1 #include <windows.h> 2 #include <net/lan.h> 3 #include <iostream> 4 #include <string> 5 #include <ddk/ntddk.h> 6 #include <rosrtl/string.h> 7 8 using std::string; 9 using std::cin; 10 using std::cout; 11 using std::cerr; 12 using std::endl; 13 14 void display_row( char *data, int off, int len ) { 15 int i; 16 17 printf( "%08x:", off ); 18 for( i = off; i < len && i < off + 16; i++ ) { 19 printf( " %02x", data[i] & 0xff ); 20 } 21 22 for( ; i < off + 16; i++ ) 23 printf(" "); 24 25 printf( " -- " ); 26 27 for( i = off; i < len && i < off + 16; i++ ) { 28 printf( "%c", (data[i] >= ' ' && data[i] <= '~') ? data[i] : '.' ); 29 } 30 31 printf( "\n" ); 32 } 33 34 void display_buffer( char *Packet, int ReadLen ) { 35 UINT PktLen; 36 for( PktLen = 0; PktLen < ReadLen; PktLen += 16 ) 37 display_row( Packet, PktLen, ReadLen ); 38 } 39 40 int byte_till_end( char *Packet, int PktLen ) { 41 int byte; 42 std::string word; 43 44 cin >> word; 45 while( word != "end" ) { 46 byte = strtoul( (string("0x") + word).c_str(), 0, 0 ); 47 fprintf( stderr, "Byte[%d]: %x\n", PktLen, byte & 0xff ); 48 Packet[PktLen++] = byte; 49 cin >> word; 50 } 51 52 return PktLen; 53 } 54 55 /* Ethernet types. We swap constants so we can compare values at runtime 56 without swapping them there */ 57 #define ETYPE_IPv4 WH2N(0x0800) 58 #define ETYPE_IPv6 WH2N(0x86DD) 59 #define ETYPE_ARP WH2N(0x0806) 60 61 extern "C" 62 NTSTATUS NTAPI NtCreateFile( 63 PHANDLE FileHandle, 64 ACCESS_MASK DesiredAccess, 65 POBJECT_ATTRIBUTES ObjectAttributes, 66 PIO_STATUS_BLOCK IoStatusBlock, 67 PLARGE_INTEGER AllocationSize, 68 ULONG FileAttributes, 69 ULONG ShareAccess, 70 ULONG CreateDisposition, 71 ULONG CreateOptions, 72 PVOID EaBuffer, 73 ULONG EaLength); 74 75 int main( int argc, char **argv ) { 76 string word; 77 HANDLE LanFile; 78 OBJECT_ATTRIBUTES Attributes; 79 UNICODE_STRING LanDevice; 80 IO_STATUS_BLOCK Iosb; 81 HANDLE Event; 82 PFILE_FULL_EA_INFORMATION EaBuffer; 83 NTSTATUS Status; 84 DWORD On = 1, PktLen; 85 CHAR Packet[1600]; 86 PLAN_PACKET_HEADER Hdr = (PLAN_PACKET_HEADER)Packet; 87 PLAN_ADDRESS Addr = (PLAN_ADDRESS)Packet; 88 USHORT TypesToListen[] = { ETYPE_IPv4, ETYPE_IPv6, ETYPE_ARP }; 89 UINT EaLength = LAN_EA_INFO_SIZE(sizeof(TypesToListen)/sizeof(USHORT)); 90 91 Status = NtCreateEvent(&Event, 92 EVENT_ALL_ACCESS, 93 NULL, 94 0, 95 0 ); 96 97 RtlInitUnicodeString( &LanDevice, L"\\Device\\Lan" ); 98 99 InitializeObjectAttributes( &Attributes, 100 &LanDevice, 101 OBJ_CASE_INSENSITIVE, 102 NULL, 103 NULL ); 104 105 EaBuffer = (PFILE_FULL_EA_INFORMATION)calloc( EaLength, 1 ); 106 LAN_FILL_EA_INFO(EaBuffer,sizeof(TypesToListen)/sizeof(USHORT), 107 TypesToListen); 108 109 Status = ZwCreateFile( &LanFile, 110 SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE | 111 GENERIC_EXECUTE, 112 &Attributes, 113 &Iosb, 114 NULL, 115 FILE_ATTRIBUTE_NORMAL, 116 FILE_SHARE_READ | FILE_SHARE_WRITE, 117 FILE_OPEN_IF, 118 FILE_SYNCHRONOUS_IO_NONALERT, 119 EaBuffer, 120 EaLength ); 121 122 if( !NT_SUCCESS(Status) ) { 123 cerr << "Could not open lan device " << Status << "\n"; 124 return 1; 125 } 126 127 Status = DeviceIoControl( LanFile, 128 IOCTL_IF_BUFFERED_MODE, 129 &On, 130 sizeof(On), 131 0, 132 0, 133 &PktLen, 134 NULL ); 135 136 if( !Status ) { 137 cerr << "Could not turn on buffered mode " << Status << "\n"; 138 return 1; 139 } 140 141 while( cin >> word ) { 142 if( word == "end" ) { 143 NtClose( LanFile ); 144 return 0; 145 } else if( word == "enum" ) { 146 Status = DeviceIoControl( LanFile, 147 IOCTL_IF_ENUM_ADAPTERS, 148 NULL, 149 0, 150 Packet, 151 sizeof(Packet), 152 &PktLen, 153 NULL ); 154 155 cout << "EnumAdapters: " << Status << "\n"; 156 if( Status ) 157 display_buffer( Packet, PktLen ); 158 } else if( word == "query" ) { 159 cin >> PktLen; 160 161 Status = DeviceIoControl( LanFile, 162 IOCTL_IF_ADAPTER_INFO, 163 &PktLen, 164 sizeof(PktLen), 165 Packet, 166 sizeof(Packet), 167 &PktLen, 168 NULL ); 169 170 cout << "QueryAdapterInfo: " << Status << "\n"; 171 if( Status ) 172 display_buffer( Packet, PktLen ); 173 } else if( word == "send" ) { 174 cin >> Hdr->Fixed.Adapter 175 >> Hdr->Fixed.AddressType 176 >> Hdr->Fixed.AddressLen 177 >> Hdr->Fixed.PacketType; 178 Hdr->Fixed.Mdl = NULL; 179 PktLen = byte_till_end( Packet, Hdr->Address - (PCHAR)Hdr ); 180 Status = NtWriteFile( LanFile, 181 NULL, 182 NULL, 183 NULL, 184 &Iosb, 185 Packet, 186 PktLen, 187 NULL, 188 NULL ); 189 190 cout << "NtWriteFile: " << Status << "\n"; 191 } else if( word == "recv" ) { 192 ULONG ReadLen; 193 Status = NtReadFile( LanFile, 194 Event, 195 NULL, 196 NULL, 197 &Iosb, 198 Packet, 199 sizeof(Packet), 200 NULL, 201 NULL ); 202 cout << "NtReadFile: " << Status << "\n"; 203 if( Status == STATUS_PENDING ) { 204 LARGE_INTEGER Timeout = { 0 }; 205 Status = NtWaitForSingleObject( Event, 1, &Timeout ); 206 } 207 208 ReadLen = Iosb.Information; 209 210 if( Status == STATUS_SUCCESS ) { 211 cout << "Read " << ReadLen << " bytes\n"; 212 display_buffer( Packet, ReadLen ); 213 } 214 } 215 } 216 217 return 0; 218 } 219