Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477#include <iostream>#include <list>#include <string>#include <sstream>extern "C" { typedef unsigned short u_short;#include <stdio.h>#include <windows.h>#include <winsock2.h>#include <ddk/tdi.h>#include <ddk/tdikrnl.h>#include <ddk/tdiinfo.h>#include <ddk/ndis.h>#include <titypes.h>#include <ip.h>#include <tcp.h>#include <receive.h>#include <lan.h>#include <routines.h>};
/* Undis */extern "C" VOID ExpInitLookasideLists();
std::list<std::string> output_packets;DWORD DebugTraceLevel = 0x7fffffff;PVOID GlobalBufferPool, GlobalPacketPool;
#define MAX_DG_SIZE 16384
char hwaddr[6] = { 0x08, 0x00, 0x20, 0x0b, 0xb7, 0xbb };
char hdr[14] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00 };
#define STRINGIFY(x) #x
void display_row( char *data, int off, int len ) { int i;
printf( "%08x:", off ); for( i = off; i < len && i < off + 16; i++ ) { printf( " %02x", data[i] & 0xff ); }
printf( " -- " );
for( i = off; i < len && i < off + 16; i++ ) { printf( "%c", (data[i] >= ' ') ? data[i] : '.' ); }
printf( "\n" );}
void connect_complete( void *context, NTSTATUS status, unsigned long count ) { printf( "Connection: status %x\n", status );}
void receive_complete( void *context, NTSTATUS status, unsigned long count ) { printf( "Receive: status %s (bytes %d)\n", status, count ); if( !status && count ) { for( int off = 0; off < count; off += 16 ) { display_row( (char *)context, off, count ); } printf( "\n" ); }}
class SocketObject {public: virtual ~SocketObject() { } virtual int send( char *buf, int len, int *bytes, struct sockaddr_in *si ) = 0; virtual int recv( char *buf, int len, int *bytes, struct sockaddr_in *si ) = 0;};
UINT TdiAddressSizeFromType( UINT AddressType ) { switch( AddressType ) { case TDI_ADDRESS_TYPE_IP: return sizeof(TA_IP_ADDRESS); default: KeBugCheck( 0 ); } return 0;}
NTSTATUS TdiBuildNullConnectionInfoInPlace( PTDI_CONNECTION_INFORMATION ConnInfo, ULONG Type )/* * FUNCTION: Builds a NULL TDI connection information structure * ARGUMENTS: * ConnectionInfo = Address of buffer to place connection information * Type = TDI style address type (TDI_ADDRESS_TYPE_XXX). * RETURNS: * Status of operation */{ ULONG TdiAddressSize;
TdiAddressSize = TdiAddressSizeFromType(Type);
RtlZeroMemory(ConnInfo, sizeof(TDI_CONNECTION_INFORMATION) + TdiAddressSize);
ConnInfo->OptionsLength = sizeof(ULONG); ConnInfo->RemoteAddressLength = 0; ConnInfo->RemoteAddress = NULL;
return STATUS_SUCCESS;}
NTSTATUS TdiBuildNullConnectionInfo( PTDI_CONNECTION_INFORMATION *ConnectionInfo, ULONG Type )/* * FUNCTION: Builds a NULL TDI connection information structure * ARGUMENTS: * ConnectionInfo = Address of buffer pointer to allocate connection * information in * Type = TDI style address type (TDI_ADDRESS_TYPE_XXX). * RETURNS: * Status of operation */{ PTDI_CONNECTION_INFORMATION ConnInfo; ULONG TdiAddressSize; NTSTATUS Status;
TdiAddressSize = TdiAddressSizeFromType(Type);
ConnInfo = (PTDI_CONNECTION_INFORMATION) ExAllocatePool(NonPagedPool, sizeof(TDI_CONNECTION_INFORMATION) + TdiAddressSize); if (!ConnInfo) return STATUS_INSUFFICIENT_RESOURCES;
Status = TdiBuildNullConnectionInfoInPlace( ConnInfo, Type );
if (!NT_SUCCESS(Status)) ExFreePool( ConnInfo ); else *ConnectionInfo = ConnInfo;
ConnInfo->RemoteAddress = (PTA_ADDRESS)&ConnInfo[1]; ConnInfo->RemoteAddressLength = TdiAddressSize;
return Status;}
UINT TaLengthOfTransportAddress( PTRANSPORT_ADDRESS Addr ) { UINT AddrLen = 2 * sizeof( ULONG ) + Addr->Address[0].AddressLength; printf("AddrLen %x\n", AddrLen); return AddrLen;}
NTSTATUSTdiBuildConnectionInfoInPlace( PTDI_CONNECTION_INFORMATION ConnectionInfo, PTA_ADDRESS Address ) { NTSTATUS Status = STATUS_SUCCESS;
RtlCopyMemory( ConnectionInfo->RemoteAddress, Address, ConnectionInfo->RemoteAddressLength );
return Status;}
NTSTATUSTdiBuildConnectionInfo( PTDI_CONNECTION_INFORMATION *ConnectionInfo, PTA_ADDRESS Address ) { NTSTATUS Status = TdiBuildNullConnectionInfo( ConnectionInfo, Address->AddressType );
if( NT_SUCCESS(Status) ) TdiBuildConnectionInfoInPlace( *ConnectionInfo, Address );
return Status;}
class TCPSocketObject : public SocketObject {public: TCPSocketObject( std::string host, int port, NTSTATUS *status ) { TA_IP_ADDRESS ConnectTo; PTDI_CONNECTION_INFORMATION ConnInfo;
ConnectTo.TAAddressCount = 1; ConnectTo.Address[0].AddressLength = sizeof(TDI_ADDRESS_IP); ConnectTo.Address[0].AddressType = TDI_ADDRESS_TYPE_IP; ConnectTo.Address[0].Address[0].sin_port = htons(port); ConnectTo.Address[0].Address[0].in_addr = 0x6a020a0a;
TdiBuildConnectionInfo( &ConnInfo, (PTA_ADDRESS)&ConnectTo );
Connection = TCPAllocateConnectionEndpoint( NULL ); *status = TCPSocket( Connection, AF_INET, SOCK_STREAM, IPPROTO_TCP ); if( !*status ) *status = TCPConnect( Connection, ConnInfo, NULL, connect_complete, NULL ); }
~TCPSocketObject() { TCPClose( Connection ); if( Connection ) TCPFreeConnectionEndpoint( Connection ); }
int send( char *buf, int len, int *bytes, struct sockaddr_in *si ) { NTSTATUS Status = STATUS_UNSUCCESSFUL;
if( Connection ) Status = TCPSendData( Connection, buf, len, (PULONG)bytes, 0 ); return Status; }
int recv( char *buf, int len, int *bytes, struct sockaddr_in *si ) { NTSTATUS Status = STATUS_UNSUCCESSFUL;
if( Connection ) Status = TCPSendData( Connection, buf, len, (PULONG)bytes, 0 ); return Status; }
private: PCONNECTION_ENDPOINT Connection;};
VOID SendPacket( PVOID Context, PNDIS_PACKET NdisPacket, UINT Offset, PVOID LinkAddress, USHORT Type ) { PCHAR DataOut; PUCHAR Addr = (PUCHAR)LinkAddress; UINT Size; std::string output_packet;
printf( "Sending packet: %02x:%02x:%02x:%02x:%02x:%02x\n", Addr[0], Addr[1], Addr[2], Addr[3], Addr[4], Addr[5] );
GetDataPtr( NdisPacket, Offset, &DataOut, &Size ); for( int off = 0; off < Size; off += 16 ) { display_row( DataOut, off, Size ); } printf( "\n" );
output_packet += std::string( hwaddr, sizeof(hwaddr) ); output_packet += std::string( (char *)LinkAddress, sizeof(hwaddr) ); output_packet += (char)(Type >> 8); output_packet += (char)Type; output_packet += std::string( DataOut + Offset, Size - Offset );
output_packets.push_back( output_packet );}
#if 0UINT CopyBufferToBufferChain( PNDIS_BUFFER DstBuffer, UINT DstOffset, PCHAR SrcData, UINT Length ) { assert( 0 );}#endif
int main( int argc, char **argv ) { int asock = INVALID_SOCKET, selret, dgrecv, fromsize, err, port = 5001; int bytes, adapter_id, mtu, speed; char datagram[MAX_DG_SIZE]; struct fd_set readf; struct timeval tv; struct sockaddr_in addr_from = { AF_INET }, addr_to; std::string word, cmdin, host; std::list<std::string>::iterator i; WSADATA wsadata; NTSTATUS Status; UNICODE_STRING RegistryUnicodePath; PCONNECTION_ENDPOINT Connection; PIP_INTERFACE Interface; IP_PACKET IPPacket; LLIP_BIND_INFO BindInfo; SocketObject *S = NULL;
RtlInitUnicodeString ( &RegistryUnicodePath, L"\\SYSTEM\\CurrentControlSet\\Services" L"\\Tcpip" );
ExpInitLookasideLists();
WSAStartup( 0x101, &wsadata );
if( argc > 1 ) port = atoi(argv[1]);
IPStartup( &RegistryUnicodePath );
BindInfo.Context = NULL; BindInfo.HeaderSize = sizeof(ETH_HEADER); BindInfo.MTU = 1500; /* MTU for ethernet */ BindInfo.Address = (PUCHAR)hwaddr; BindInfo.AddressLength = sizeof(hwaddr); BindInfo.Transmit = SendPacket;
IPCreateInterface( &BindInfo );
asock = socket( AF_INET, SOCK_DGRAM, 0 );
addr_from.sin_port = htons( port );
if( bind( asock, (struct sockaddr *)&addr_from, sizeof( addr_from ) ) ) { printf( "Bind error\n" ); return 0; }
while( true ) { FD_ZERO( &readf ); FD_SET( asock, &readf ); tv.tv_sec = 0; tv.tv_usec = 10000; selret = select( asock + 1, &readf, NULL, NULL, &tv );
if( FD_ISSET( asock, &readf ) ) { fromsize = sizeof( addr_from ); dgrecv = recvfrom( asock, datagram, sizeof(datagram), 0, (struct sockaddr *)&addr_from, &fromsize );
if( datagram[0] == 'C' && datagram[1] == 'M' && datagram[2] == 'D' && datagram[3] == ' ' ) { int theport, bytes, recvret, off, bytin; struct sockaddr_in nam; std::string faddr, word; std::istringstream cmdin( std::string( datagram + 4, dgrecv - 4 ) );
cmdin >> word;
/* UDP Section */ if( word == "udpsocket" ) {/* TCP Section */ } else if( word == "tcpsocket" ) { cmdin >> host >> port; S = new TCPSocketObject( host, port, &Status ); fprintf( stderr, "Socket: Result %x\n", Status ); } else if( word == "close" ) { TCPClose( Connection ); TCPFreeConnectionEndpoint( Connection ); } else if( word == "type" ) { std::string therest = &cmdin.str()[word.size()]; char* p = &therest[0]; p += strspn ( p, " \t" ); char* src = p; char* dst = p; while ( *src ) { char c = *src++; if ( c == '\r' || c == '\n' ) break; if ( c == '\\' ) { c = *src++; switch ( c ) { case 'b': c = '\b'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'v': c = '\v'; break; } } *dst++ = c; } *dst = '\0'; if( S ) err = S->send( p, strlen(p), &bytes, NULL ); if( err > 0 ) { bytin = err; err = 0; }
if( err ) fprintf ( stderr, "OskitTCPConnect: error %d\n", err ); else { printf ( "wrote %d bytes\n", bytin ); } } else if( word == "send" ) { off = 0; while( cmdin >> word ) { datagram[off++] = atoi( (std::string("0x") + word).c_str() ); }
if( (err = S->send( datagram, off, &bytin, NULL )) != 0 ) { fprintf( stderr, "OskitTCPConnect: error %d\n", err ); } else { printf( "wrote %d bytes\n", bytin ); } } else if( word == "recv" ) { cmdin >> bytes;
if( (err = S->recv( datagram, sizeof(datagram), &bytes, NULL )) != 0 ) { fprintf( stderr, "OskitTCPRecv: error %d\n", err ); }
/* Misc section */ } else if( word == "end" ) { return 0; } } else if( dgrecv > 14 ) { addr_to = addr_from;
if( datagram[12] == 8 && datagram[13] == 6 ) { /* Answer arp query */ char laddr[4]; /* Mark patch as to the previous sender */ memcpy( datagram + 32, datagram + 6, 6 ); memcpy( datagram, datagram + 6, 6 ); /* Mark packet as from us */ memcpy( datagram + 22, hwaddr, 6 ); memcpy( datagram + 6, hwaddr, 6 ); /* Swap inet addresses */ memcpy( laddr, datagram + 28, 4 ); memcpy( datagram + 28, datagram + 38, 4 ); memcpy( datagram + 38, laddr, 4 ); /* Set reply opcode */ datagram[21] = 2;
err = sendto( asock, datagram, dgrecv, 0, (struct sockaddr *)&addr_to, sizeof(addr_to) );
if( err != 0 ) printf( "sendto: %d\n", err ); } else { memcpy( hdr, datagram + 6, 6 ); memcpy( hdr + 6, datagram, 6 ); memcpy( hdr + 12, datagram + 12, 2 ); IPPacket.Header = datagram; IPPacket.Data = datagram + 14; IPPacket.TotalSize = dgrecv; IPReceive( Interface, &IPPacket ); } } }
IPTimeout(NULL, NULL, NULL, NULL);
for( i = output_packets.begin(); i != output_packets.end(); i++ ) { err = sendto( asock, i->c_str(), i->size(), 0, (struct sockaddr *)&addr_to, sizeof(addr_to) );
fprintf( stderr, "** SENDING PACKET %d bytes **\n", i->size() );
if( err != 0 ) printf( "sendto: %d\n", err ); }
output_packets.clear(); }}