6 #include <rosrtl/string.h>
14 void display_row( char *data
, int off
, int len
) {
17 printf( "%08x:", off
);
18 for( i
= off
; i
< len
&& i
< off
+ 16; i
++ ) {
19 printf( " %02x", data
[i
] & 0xff );
22 for( ; i
< off
+ 16; i
++ )
27 for( i
= off
; i
< len
&& i
< off
+ 16; i
++ ) {
28 printf( "%c", (data
[i
] >= ' ' && data
[i
] <= '~') ? data
[i
] : '.' );
34 void display_buffer( char *Packet
, int ReadLen
) {
36 for( PktLen
= 0; PktLen
< ReadLen
; PktLen
+= 16 )
37 display_row( Packet
, PktLen
, ReadLen
);
40 int byte_till_end( char *Packet
, int PktLen
) {
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
;
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)
62 NTSTATUS STDCALL
NtCreateFile(
64 ACCESS_MASK DesiredAccess
,
65 POBJECT_ATTRIBUTES ObjectAttributes
,
66 PIO_STATUS_BLOCK IoStatusBlock
,
67 PLARGE_INTEGER AllocationSize
,
70 ULONG CreateDisposition
,
75 int main( int argc
, char **argv
) {
78 OBJECT_ATTRIBUTES Attributes
;
79 UNICODE_STRING LanDevice
;
82 PFILE_FULL_EA_INFORMATION EaBuffer
;
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
));
91 Status
= NtCreateEvent(&Event
,
97 RtlInitUnicodeString( &LanDevice
, L
"\\Device\\Lan" );
99 InitializeObjectAttributes( &Attributes
,
101 OBJ_CASE_INSENSITIVE
,
105 EaBuffer
= (PFILE_FULL_EA_INFORMATION
)calloc( EaLength
, 1 );
106 LAN_FILL_EA_INFO(EaBuffer
,sizeof(TypesToListen
)/sizeof(USHORT
),
109 Status
= ZwCreateFile( &LanFile
,
110 SYNCHRONIZE
| GENERIC_READ
| GENERIC_WRITE
|
115 FILE_ATTRIBUTE_NORMAL
,
116 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
118 FILE_SYNCHRONOUS_IO_NONALERT
,
122 if( !NT_SUCCESS(Status
) ) {
123 cerr
<< "Could not open lan device " << Status
<< "\n";
127 Status
= DeviceIoControl( LanFile
,
128 IOCTL_IF_BUFFERED_MODE
,
137 cerr
<< "Could not turn on buffered mode " << Status
<< "\n";
141 while( cin
>> word
) {
142 if( word
== "end" ) {
145 } else if( word
== "enum" ) {
146 Status
= DeviceIoControl( LanFile
,
147 IOCTL_IF_ENUM_ADAPTERS
,
155 cout
<< "EnumAdapters: " << Status
<< "\n";
157 display_buffer( Packet
, PktLen
);
158 } else if( word
== "query" ) {
161 Status
= DeviceIoControl( LanFile
,
162 IOCTL_IF_ADAPTER_INFO
,
170 cout
<< "QueryAdapterInfo: " << Status
<< "\n";
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
,
190 cout
<< "NtWriteFile: " << Status
<< "\n";
191 } else if( word
== "recv" ) {
193 Status
= NtReadFile( LanFile
,
202 cout
<< "NtReadFile: " << Status
<< "\n";
203 if( Status
== STATUS_PENDING
) {
204 LARGE_INTEGER Timeout
= { 0 };
205 Status
= NtWaitForSingleObject( Event
, 1, &Timeout
);
208 ReadLen
= Iosb
.Information
;
210 if( Status
== STATUS_SUCCESS
) {
211 cout
<< "Read " << ReadLen
<< " bytes\n";
212 display_buffer( Packet
, ReadLen
);