2 #pragma warning ( disable : 4786 )
10 typedef unsigned short u_short
;
19 unsigned char hwaddr
[6] = { 0x08, 0x00, 0x20, 0x0b, 0xb7, 0xbb };
24 unsigned long TCP_IPIdentification
;
26 #define MAX_DG_SIZE 0x10000
27 #define TI_DbgPrint(x,y) printf y
29 std::list
<std::string
> output_packets
;
31 typedef struct _CONNECTION_ENDPOINT
{
33 } CONNECTION_ENDPOINT
, *PCONNECTION_ENDPOINT
;
35 extern "C" int is_stack_ptr ( const void* p
)
37 MEMORY_BASIC_INFORMATION mbi1
, mbi2
;
38 VirtualQuery ( p
, &mbi1
, sizeof(mbi1
) );
39 VirtualQuery ( _alloca(1), &mbi2
, sizeof(mbi2
) );
40 return mbi1
.AllocationBase
== mbi2
.AllocationBase
;
43 int TCPSocketState(void *ClientData
,
45 void *WhichConnection
,
47 PCONNECTION_ENDPOINT Connection
= (PCONNECTION_ENDPOINT
)WhichConnection
;
50 TI_DbgPrint(MID_TRACE
,("Called: NewState %x\n", NewState
));
53 TI_DbgPrint(MID_TRACE
,("Socket closing.\n"));
57 if( (NewState
& SEL_CONNECT
) &&
58 !(Connection
->State
& SEL_CONNECT
) ) {
59 } else if( (NewState
& SEL_READ
) || (NewState
& SEL_FIN
) ) {
65 #define STRINGIFY(x) #x
67 char hdr
[14] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 int TCPPacketSend(void *ClientData
, OSK_PCHAR data
, OSK_UINT len
) {
72 output_packets
.push_back( std::string( hdr
, 14 ) +
73 std::string( (char *)data
, (int)len
) );
77 struct ifaddr
*TCPFindInterface( void *ClientData
,
80 struct sockaddr
*ReqAddr
) {
81 static struct sockaddr_in ifa
= { AF_INET
}, nm
= { AF_INET
};
82 static struct ifaddr a
= {
83 (struct sockaddr
*)&ifa
,
85 (struct sockaddr
*)&nm
,
91 ifa
.sin_addr
.s_addr
= inet_addr( "10.10.2.115" );
92 nm
.sin_addr
.s_addr
= inet_addr( "255.255.255.0" );
96 void *TCPMalloc( void *ClientData
,
97 OSK_UINT Bytes
, OSK_PCHAR File
, OSK_UINT Line
) {
98 void *v
= malloc( Bytes
);
99 fprintf( stderr
, "(%s:%d) malloc( %d ) => %x\n", File
, Line
, Bytes
, v
);
103 void TCPFree( void *ClientData
,
104 void *data
, OSK_PCHAR File
, OSK_UINT Line
) {
105 fprintf( stderr
, "(%s:%d) free( %x )\n", File
, Line
, data
);
109 int TCPSleep( void *ClientData
, void *token
, int priority
, char *msg
,
112 PSLEEPING_THREAD SleepingThread
;
114 TI_DbgPrint(MID_TRACE
,
115 ("Called TSLEEP: tok = %x, pri = %d, wmesg = %s, tmio = %x\n",
116 token
, priority
, msg
, tmio
));
118 SleepingThread
= ExAllocatePool( NonPagedPool
, sizeof( *SleepingThread
) );
119 if( SleepingThread
) {
120 KeInitializeEvent( &SleepingThread
->Event
, NotificationEvent
, FALSE
);
121 SleepingThread
->SleepToken
= token
;
123 ExAcquireFastMutex( &SleepingThreadsLock
);
124 InsertTailList( &SleepingThreadsList
, &SleepingThread
->Entry
);
125 ExReleaseFastMutex( &SleepingThreadsLock
);
127 TI_DbgPrint(MID_TRACE
,("Waiting on %x\n", token
));
128 KeWaitForSingleObject( &SleepingThread
->Event
,
134 ExAcquireFastMutex( &SleepingThreadsLock
);
135 RemoveEntryList( &SleepingThread
->Entry
);
136 ExReleaseFastMutex( &SleepingThreadsLock
);
138 ExFreePool( SleepingThread
);
140 TI_DbgPrint(MID_TRACE
,("Waiting finished: %x\n", token
));
145 void TCPWakeup( void *ClientData
, void *token
) {
148 PSLEEPING_THREAD SleepingThread
;
150 ExAcquireFastMutex( &SleepingThreadsLock
);
151 Entry
= SleepingThreadsList
.Flink
;
152 while( Entry
!= &SleepingThreadsList
) {
153 SleepingThread
= CONTAINING_RECORD(Entry
, SLEEPING_THREAD
, Entry
);
154 TI_DbgPrint(MID_TRACE
,("Sleeper @ %x\n", SleepingThread
));
155 if( SleepingThread
->SleepToken
== token
) {
156 TI_DbgPrint(MID_TRACE
,("Setting event to wake %x\n", token
));
157 KeSetEvent( &SleepingThread
->Event
, IO_NETWORK_INCREMENT
, FALSE
);
159 Entry
= Entry
->Flink
;
161 ExReleaseFastMutex( &SleepingThreadsLock
);
165 OSKITTCP_EVENT_HANDLERS EventHandlers
= {
176 void display_row( char *data
, int off
, int len
) {
179 printf( "%08x:", off
);
180 for( i
= off
; i
< len
&& i
< off
+ 16; i
++ ) {
181 printf( " %02x", data
[i
] & 0xff );
186 for( i
= off
; i
< len
&& i
< off
+ 16; i
++ ) {
187 printf( "%c", (data
[i
] >= ' ') ? data
[i
] : '.' );
193 int main( int argc
, char **argv
) {
194 int asock
= INVALID_SOCKET
, selret
, dgrecv
, fromsize
, err
, port
= 5001;
195 char datagram
[MAX_DG_SIZE
];
199 struct sockaddr_in addr_from
= { AF_INET
}, addr_to
= { AF_INET
};
200 std::list
<std::string
>::iterator i
;
203 WSAStartup( 0x101, &wsadata
);
205 if( argc
> 1 ) port
= atoi(argv
[1]);
207 RegisterOskitTCPEventHandlers( &EventHandlers
);
210 asock
= socket( AF_INET
, SOCK_DGRAM
, 0 );
212 addr_from
.sin_port
= htons( port
);
214 if( bind( asock
, (struct sockaddr
*)&addr_from
, sizeof( addr_from
) ) ) {
215 printf( "Bind error\n" );
219 addr_to
.sin_port
= htons( port
& (~1) );
220 addr_to
.sin_addr
.s_addr
= inet_addr("127.0.0.1");
224 FD_SET( asock
, &readf
);
227 selret
= select( asock
+ 1, &readf
, NULL
, NULL
, &tv
);
229 if( FD_ISSET( asock
, &readf
) ) {
230 fromsize
= sizeof( addr_from
);
231 dgrecv
= recvfrom( asock
, datagram
, sizeof(datagram
), 0,
232 (struct sockaddr
*)&addr_from
, &fromsize
);
234 if( datagram
[0] == 'C' && datagram
[1] == 'M' &&
235 datagram
[2] == 'D' && datagram
[3] == ' ' ) {
236 int theport
, bytes
, /*recvret,*/ off
, bytin
;
237 struct sockaddr_in nam
;
238 std::string faddr
, word
;
240 cmdin( std::string( datagram
+ 4, dgrecv
- 4 ) );
244 if( word
== "socket" ) {
245 cmdin
>> faddr
>> theport
;
247 nam
.sin_family
= AF_INET
;
248 nam
.sin_addr
.s_addr
= inet_addr(faddr
.c_str());
249 nam
.sin_port
= htons(theport
);
251 if( (err
= OskitTCPSocket( NULL
, &conn
, AF_INET
,
252 SOCK_STREAM
, 0 )) != 0 ) {
253 fprintf( stderr
, "OskitTCPSocket: error %d\n", err
);
256 if( (err
= OskitTCPConnect( conn
, NULL
, &nam
,
257 sizeof(nam
) )) != 0 ) {
258 fprintf( stderr
, "OskitTCPConnect: error %d\n", err
);
260 printf( "Socket created\n" );
264 /* The rest of the commands apply only to an open socket */
265 if( !conn
) continue;
267 if( word
== "recv" ) {
270 if( (err
= OskitTCPRecv( conn
, (OSK_PCHAR
)datagram
,
272 (unsigned int *)&bytin
, 0 )) != 0 ) {
273 fprintf( stderr
, "OskitTCPRecv: error %d\n", err
);
275 for( off
= 0; off
< bytin
; off
+= 16 ) {
276 display_row( datagram
, off
, bytin
);
280 } else if ( word
== "type" ) {
281 std::string therest
= &cmdin
.str()[word
.size()];
282 char* p
= &therest
[0];
283 p
+= strspn ( p
, " \t" );
289 if ( c
== '\r' || c
== '\n' ) break;
295 case 'b': c
= '\b'; break;
296 case 'n': c
= '\n'; break;
297 case 'r': c
= '\r'; break;
298 case 't': c
= '\t'; break;
299 case 'v': c
= '\v'; break;
305 if ( (err
= OskitTCPSend ( conn
, (OSK_PCHAR
)p
, strlen(p
), (OSK_UINT
*)&bytin
, 0 ))
307 fprintf ( stderr
, "OskitTCPConnect: error %d\n", err
);
309 printf ( "wrote %d bytes\n", bytin
);
311 } else if( word
== "send" ) {
313 while( cmdin
>> word
) {
315 atoi( (std::string("0x") + word
).c_str() );
318 if( (err
= OskitTCPSend( conn
, (OSK_PCHAR
)datagram
,
319 off
, (OSK_UINT
*)&bytin
, 0 ))
321 fprintf( stderr
, "OskitTCPConnect: error %d\n", err
);
323 printf( "wrote %d bytes\n", bytin
);
325 } else if( word
== "close" ) {
326 OskitTCPClose( conn
);
329 } else if( dgrecv
> 14 ) {
332 if( datagram
[12] == 8 && datagram
[13] == 6 ) {
333 /* Answer arp query */
335 /* Mark patch as to the previous sender */
336 memcpy( datagram
+ 32, datagram
+ 6, 6 );
337 memcpy( datagram
, datagram
+ 6, 6 );
338 /* Mark packet as from us */
339 memcpy( datagram
+ 22, hwaddr
, 6 );
340 memcpy( datagram
+ 6, hwaddr
, 6 );
341 /* Swap inet addresses */
342 memcpy( laddr
, datagram
+ 28, 4 );
343 memcpy( datagram
+ 28, datagram
+ 38, 4 );
344 memcpy( datagram
+ 38, laddr
, 4 );
345 /* Set reply opcode */
348 err
= sendto( asock
, datagram
, dgrecv
, 0,
349 (struct sockaddr
*)&addr_to
,
353 printf( "sendto: %d\n", err
);
355 memcpy( hdr
, datagram
+ 6, 6 );
356 memcpy( hdr
+ 6, datagram
, 6 );
357 memcpy( hdr
+ 12, datagram
+ 12, 2 );
358 OskitTCPReceiveDatagram
359 ( (unsigned char *)datagram
+ 14,
367 for( i
= output_packets
.begin(); i
!= output_packets
.end(); i
++ ) {
368 err
= sendto( asock
, i
->c_str(), i
->size(), 0,
369 (struct sockaddr
*)&addr_to
, sizeof(addr_to
) );
371 fprintf( stderr
, "** SENDING PACKET %d bytes **\n", i
->size() );
374 printf( "sendto: %d\n", err
);
377 output_packets
.clear();