6 typedef unsigned short u_short
;
11 #include <ddk/tdikrnl.h>
12 #include <ddk/tdiinfo.h>
23 extern "C" VOID
ExpInitLookasideLists();
25 std::list
<std::string
> output_packets
;
26 DWORD DebugTraceLevel
= 0x7fffffff;
27 PVOID GlobalBufferPool
, GlobalPacketPool
;
29 #define MAX_DG_SIZE 16384
31 char hwaddr
[6] = { 0x08, 0x00, 0x20, 0x0b, 0xb7, 0xbb };
33 char hdr
[14] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37 #define STRINGIFY(x) #x
39 void display_row( char *data
, int off
, int len
) {
42 printf( "%08x:", off
);
43 for( i
= off
; i
< len
&& i
< off
+ 16; i
++ ) {
44 printf( " %02x", data
[i
] & 0xff );
49 for( i
= off
; i
< len
&& i
< off
+ 16; i
++ ) {
50 printf( "%c", (data
[i
] >= ' ') ? data
[i
] : '.' );
56 void connect_complete( void *context
, NTSTATUS status
, unsigned long count
) {
57 printf( "Connection: status %x\n", status
);
60 void receive_complete( void *context
, NTSTATUS status
, unsigned long count
) {
61 printf( "Receive: status %s (bytes %d)\n", status
, count
);
62 if( !status
&& count
) {
63 for( int off
= 0; off
< count
; off
+= 16 ) {
64 display_row( (char *)context
, off
, count
);
72 virtual ~SocketObject() { }
73 virtual int send( char *buf
, int len
, int *bytes
,
74 struct sockaddr_in
*si
) = 0;
75 virtual int recv( char *buf
, int len
, int *bytes
,
76 struct sockaddr_in
*si
) = 0;
79 UINT
TdiAddressSizeFromType( UINT AddressType
) {
80 switch( AddressType
) {
81 case TDI_ADDRESS_TYPE_IP
:
82 return sizeof(TA_IP_ADDRESS
);
89 NTSTATUS TdiBuildNullConnectionInfoInPlace
90 ( PTDI_CONNECTION_INFORMATION ConnInfo
,
93 * FUNCTION: Builds a NULL TDI connection information structure
95 * ConnectionInfo = Address of buffer to place connection information
96 * Type = TDI style address type (TDI_ADDRESS_TYPE_XXX).
101 ULONG TdiAddressSize
;
103 TdiAddressSize
= TdiAddressSizeFromType(Type
);
105 RtlZeroMemory(ConnInfo
,
106 sizeof(TDI_CONNECTION_INFORMATION
) +
109 ConnInfo
->OptionsLength
= sizeof(ULONG
);
110 ConnInfo
->RemoteAddressLength
= 0;
111 ConnInfo
->RemoteAddress
= NULL
;
113 return STATUS_SUCCESS
;
116 NTSTATUS TdiBuildNullConnectionInfo
117 ( PTDI_CONNECTION_INFORMATION
*ConnectionInfo
,
120 * FUNCTION: Builds a NULL TDI connection information structure
122 * ConnectionInfo = Address of buffer pointer to allocate connection
124 * Type = TDI style address type (TDI_ADDRESS_TYPE_XXX).
126 * Status of operation
129 PTDI_CONNECTION_INFORMATION ConnInfo
;
130 ULONG TdiAddressSize
;
133 TdiAddressSize
= TdiAddressSizeFromType(Type
);
135 ConnInfo
= (PTDI_CONNECTION_INFORMATION
)
136 ExAllocatePool(NonPagedPool
,
137 sizeof(TDI_CONNECTION_INFORMATION
) +
140 return STATUS_INSUFFICIENT_RESOURCES
;
142 Status
= TdiBuildNullConnectionInfoInPlace( ConnInfo
, Type
);
144 if (!NT_SUCCESS(Status
))
145 ExFreePool( ConnInfo
);
147 *ConnectionInfo
= ConnInfo
;
149 ConnInfo
->RemoteAddress
= (PTA_ADDRESS
)&ConnInfo
[1];
150 ConnInfo
->RemoteAddressLength
= TdiAddressSize
;
156 UINT
TaLengthOfTransportAddress( PTRANSPORT_ADDRESS Addr
) {
157 UINT AddrLen
= 2 * sizeof( ULONG
) + Addr
->Address
[0].AddressLength
;
158 printf("AddrLen %x\n", AddrLen
);
163 TdiBuildConnectionInfoInPlace
164 ( PTDI_CONNECTION_INFORMATION ConnectionInfo
,
165 PTA_ADDRESS Address
) {
166 NTSTATUS Status
= STATUS_SUCCESS
;
168 RtlCopyMemory( ConnectionInfo
->RemoteAddress
,
170 ConnectionInfo
->RemoteAddressLength
);
176 TdiBuildConnectionInfo
177 ( PTDI_CONNECTION_INFORMATION
*ConnectionInfo
,
178 PTA_ADDRESS Address
) {
179 NTSTATUS Status
= TdiBuildNullConnectionInfo( ConnectionInfo
,
180 Address
->AddressType
);
182 if( NT_SUCCESS(Status
) )
183 TdiBuildConnectionInfoInPlace( *ConnectionInfo
, Address
);
188 class TCPSocketObject
: public SocketObject
{
190 TCPSocketObject( std::string host
, int port
, NTSTATUS
*status
) {
191 TA_IP_ADDRESS ConnectTo
;
192 PTDI_CONNECTION_INFORMATION ConnInfo
;
194 ConnectTo
.TAAddressCount
= 1;
195 ConnectTo
.Address
[0].AddressLength
= sizeof(TDI_ADDRESS_IP
);
196 ConnectTo
.Address
[0].AddressType
= TDI_ADDRESS_TYPE_IP
;
197 ConnectTo
.Address
[0].Address
[0].sin_port
= htons(port
);
198 ConnectTo
.Address
[0].Address
[0].in_addr
= 0x6a020a0a;
200 TdiBuildConnectionInfo( &ConnInfo
, (PTA_ADDRESS
)&ConnectTo
);
202 Connection
= TCPAllocateConnectionEndpoint( NULL
);
203 *status
= TCPSocket( Connection
,
205 SOCK_STREAM
, IPPROTO_TCP
);
207 *status
= TCPConnect( Connection
,
215 TCPClose( Connection
);
216 if( Connection
) TCPFreeConnectionEndpoint( Connection
);
219 int send( char *buf
, int len
, int *bytes
, struct sockaddr_in
*si
) {
220 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
223 Status
= TCPSendData( Connection
,
231 int recv( char *buf
, int len
, int *bytes
, struct sockaddr_in
*si
) {
232 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
235 Status
= TCPSendData( Connection
,
244 PCONNECTION_ENDPOINT Connection
;
247 VOID
SendPacket( PVOID Context
,
248 PNDIS_PACKET NdisPacket
,
253 PUCHAR Addr
= (PUCHAR
)LinkAddress
;
255 std::string output_packet
;
257 printf( "Sending packet: %02x:%02x:%02x:%02x:%02x:%02x\n",
258 Addr
[0], Addr
[1], Addr
[2], Addr
[3], Addr
[4], Addr
[5] );
260 GetDataPtr( NdisPacket
, Offset
, &DataOut
, &Size
);
261 for( int off
= 0; off
< Size
; off
+= 16 ) {
262 display_row( DataOut
, off
, Size
);
266 output_packet
+= std::string( hwaddr
, sizeof(hwaddr
) );
267 output_packet
+= std::string( (char *)LinkAddress
, sizeof(hwaddr
) );
268 output_packet
+= (char)(Type
>> 8);
269 output_packet
+= (char)Type
;
270 output_packet
+= std::string( DataOut
+ Offset
, Size
- Offset
);
272 output_packets
.push_back( output_packet
);
276 UINT CopyBufferToBufferChain
277 ( PNDIS_BUFFER DstBuffer
, UINT DstOffset
, PCHAR SrcData
, UINT Length
) {
282 int main( int argc
, char **argv
) {
283 int asock
= INVALID_SOCKET
, selret
, dgrecv
, fromsize
, err
, port
= 5001;
284 int bytes
, adapter_id
, mtu
, speed
;
285 char datagram
[MAX_DG_SIZE
];
288 struct sockaddr_in addr_from
= { AF_INET
}, addr_to
;
289 std::string word
, cmdin
, host
;
290 std::list
<std::string
>::iterator i
;
293 UNICODE_STRING RegistryUnicodePath
;
294 PCONNECTION_ENDPOINT Connection
;
295 PIP_INTERFACE Interface
;
297 LLIP_BIND_INFO BindInfo
;
298 SocketObject
*S
= NULL
;
301 ( &RegistryUnicodePath
,
302 L
"\\SYSTEM\\CurrentControlSet\\Services"
305 ExpInitLookasideLists();
307 WSAStartup( 0x101, &wsadata
);
309 if( argc
> 1 ) port
= atoi(argv
[1]);
311 IPStartup( &RegistryUnicodePath
);
313 BindInfo
.Context
= NULL
;
314 BindInfo
.HeaderSize
= sizeof(ETH_HEADER
);
315 BindInfo
.MTU
= 1500; /* MTU for ethernet */
316 BindInfo
.Address
= (PUCHAR
)hwaddr
;
317 BindInfo
.AddressLength
= sizeof(hwaddr
);
318 BindInfo
.Transmit
= SendPacket
;
320 IPCreateInterface( &BindInfo
);
322 asock
= socket( AF_INET
, SOCK_DGRAM
, 0 );
324 addr_from
.sin_port
= htons( port
);
326 if( bind( asock
, (struct sockaddr
*)&addr_from
, sizeof( addr_from
) ) ) {
327 printf( "Bind error\n" );
333 FD_SET( asock
, &readf
);
336 selret
= select( asock
+ 1, &readf
, NULL
, NULL
, &tv
);
338 if( FD_ISSET( asock
, &readf
) ) {
339 fromsize
= sizeof( addr_from
);
340 dgrecv
= recvfrom( asock
, datagram
, sizeof(datagram
), 0,
341 (struct sockaddr
*)&addr_from
, &fromsize
);
343 if( datagram
[0] == 'C' && datagram
[1] == 'M' &&
344 datagram
[2] == 'D' && datagram
[3] == ' ' ) {
345 int theport
, bytes
, recvret
, off
, bytin
;
346 struct sockaddr_in nam
;
347 std::string faddr
, word
;
349 cmdin( std::string( datagram
+ 4, dgrecv
- 4 ) );
354 if( word
== "udpsocket" ) {
356 } else if( word
== "tcpsocket" ) {
357 cmdin
>> host
>> port
;
358 S
= new TCPSocketObject( host
, port
, &Status
);
359 fprintf( stderr
, "Socket: Result %x\n", Status
);
360 } else if( word
== "close" ) {
361 TCPClose( Connection
);
362 TCPFreeConnectionEndpoint( Connection
);
363 } else if( word
== "type" ) {
364 std::string therest
= &cmdin
.str()[word
.size()];
365 char* p
= &therest
[0];
366 p
+= strspn ( p
, " \t" );
372 if ( c
== '\r' || c
== '\n' ) break;
378 case 'b': c
= '\b'; break;
379 case 'n': c
= '\n'; break;
380 case 'r': c
= '\r'; break;
381 case 't': c
= '\t'; break;
382 case 'v': c
= '\v'; break;
389 err
= S
->send( p
, strlen(p
), &bytes
, NULL
);
390 if( err
> 0 ) { bytin
= err
; err
= 0; }
393 fprintf ( stderr
, "OskitTCPConnect: error %d\n",
396 printf ( "wrote %d bytes\n", bytin
);
398 } else if( word
== "send" ) {
400 while( cmdin
>> word
) {
402 atoi( (std::string("0x") + word
).c_str() );
405 if( (err
= S
->send( datagram
, off
, &bytin
, NULL
)) != 0 ) {
406 fprintf( stderr
, "OskitTCPConnect: error %d\n", err
);
408 printf( "wrote %d bytes\n", bytin
);
410 } else if( word
== "recv" ) {
413 if( (err
= S
->recv( datagram
,
417 fprintf( stderr
, "OskitTCPRecv: error %d\n", err
);
421 } else if( word
== "end" ) {
424 } else if( dgrecv
> 14 ) {
427 if( datagram
[12] == 8 && datagram
[13] == 6 ) {
428 /* Answer arp query */
430 /* Mark patch as to the previous sender */
431 memcpy( datagram
+ 32, datagram
+ 6, 6 );
432 memcpy( datagram
, datagram
+ 6, 6 );
433 /* Mark packet as from us */
434 memcpy( datagram
+ 22, hwaddr
, 6 );
435 memcpy( datagram
+ 6, hwaddr
, 6 );
436 /* Swap inet addresses */
437 memcpy( laddr
, datagram
+ 28, 4 );
438 memcpy( datagram
+ 28, datagram
+ 38, 4 );
439 memcpy( datagram
+ 38, laddr
, 4 );
440 /* Set reply opcode */
443 err
= sendto( asock
, datagram
, dgrecv
, 0,
444 (struct sockaddr
*)&addr_to
,
448 printf( "sendto: %d\n", err
);
450 memcpy( hdr
, datagram
+ 6, 6 );
451 memcpy( hdr
+ 6, datagram
, 6 );
452 memcpy( hdr
+ 12, datagram
+ 12, 2 );
453 IPPacket
.Header
= datagram
;
454 IPPacket
.Data
= datagram
+ 14;
455 IPPacket
.TotalSize
= dgrecv
;
456 IPReceive( Interface
, &IPPacket
);
461 IPTimeout(NULL
, NULL
, NULL
, NULL
);
463 for( i
= output_packets
.begin(); i
!= output_packets
.end(); i
++ ) {
464 err
= sendto( asock
, i
->c_str(), i
->size(), 0,
465 (struct sockaddr
*)&addr_to
, sizeof(addr_to
) );
467 fprintf( stderr
, "** SENDING PACKET %d bytes **\n", i
->size() );
470 printf( "sendto: %d\n", err
);
473 output_packets
.clear();