Adding rostests as part of the tree restructure
[reactos.git] / rosapps / tests / lantst / lantest.cpp
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 STDCALL 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 }