From 243841f9486c8b922b8e071ca4b96125808353fe Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Wed, 3 Dec 2003 17:17:23 +0000 Subject: Negotiation Packet handling works --- src/nu_server.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 83 insertions(+), 16 deletions(-) (limited to 'src/nu_server.c') diff --git a/src/nu_server.c b/src/nu_server.c index 942be1b..29819ee 100755 --- a/src/nu_server.c +++ b/src/nu_server.c @@ -1,3 +1,5 @@ +#include +#include #include #include #include @@ -8,29 +10,64 @@ #include "nu_header.h" static void bailout( char *reason ); +static void sigint( int reason ) { bailout( "User interrupt." ); } +static void packet_dump( SMB_HEADER *buf ); static mainsock = -1; static childsock = -1; +static QWORD getnttime( struct timeval *t ) { + return 10000000ll * ( t->tv_sec + 11644473600ll ) + t->tv_usec * 10ll; +} + static void netbios_read( SMB_HEADER **buf) { BYTE bytes[4]; - ssize_t bytesread, bytestoread; + ssize_t bytestoread; if( read( childsock, bytes, 4) < 4 ) bailout( "Short read." ); - bytestoread = htons(*(WORD*)(2+bytes)); + bytestoread = htons(*(WORD*)(bytes+2)); if( (*buf = (SMB_HEADER*)realloc( *buf, 4 + bytestoread )) == NULL) - bailout( "Out of memory"); + bailout( "Out of memory."); *(DWORD*)*buf = *(DWORD*)bytes; - bytesread = read( childsock, ((BYTE*)buf) + 4, bytestoread); - if( bytesread != bytestoread ) + if( read( childsock, ((BYTE*)*buf) + 4, bytestoread) != bytestoread ) bailout( "Short read." ); } -static void netbios_write( BYTE command, BYTE *buf, WORD size ) { - BYTE netbios_header[4] = { command, 0, size >> 8, size & 255 }; - if( write( childsock, netbios_header, 4 ) <= 0 || - write( childsock, buf, size ) < 0 ) - bailout( "Write failed." ); +static void netbios_write( BYTE cmd, SMB_HEADER *buf, SMB_HEADER2 *buf2 ) { + const BYTE buf2_[2] = { 0, 0 }; + if(!buf2 ) buf2 = (SMB_HEADER2*)buf2_; + if( buf ) { + struct iovec iov[2] = { {buf, SIZEOF_SMB_HEADER + 2*buf->WordCount}, + {buf2, 2 + buf2->ByteCount} }; + + buf->netbios_command = cmd; + buf->netbios_flags = 0; + buf->netbios_size = htons( SIZEOF_SMB_HEADER - 4 + + 2 * buf->WordCount + + 2 + buf2->ByteCount ); + buf->Flags = 0x88; + buf->Flags2 = 0x4001; + + if( writev( childsock, iov, 2 ) < htons( buf->netbios_size ) + 4 ) + bailout( "Write failed." ); + } else { + const BYTE buf_[4] = { cmd, 0, 0, 0 }; + if( write( childsock, buf_, 4 ) < 4) + bailout( "Write failed." ); + } +} + +static void packet_dump( SMB_HEADER *buf ) { + fprintf( stderr, "netbios_cmd, flag, size = %02X, %02X, %04X\n", buf->netbios_command, buf->netbios_flags, buf->netbios_size ); + fprintf( stderr, "Protocol = %08X\n", *(DWORD*)&buf->Protocol); + fprintf( stderr, "Command = %02X\n", buf->Command); + fprintf( stderr, "Status = %08X\n", *(DWORD*)&buf->Status); + fprintf( stderr, "Flags, Flags2 = %02X, %04X\n", buf->Flags, buf->Flags2); + fprintf( stderr, "Pad = %04X %04X %04X %04X %04X %04X\n", + buf->Pad[0], buf->Pad[1], buf->Pad[2], + buf->Pad[3], buf->Pad[4], buf->Pad[5] ); + fprintf( stderr, "TreeID,ProcessID,UserID = %04X, %04X, %04X\n", buf->TreeID, buf->ProcessID, buf->UserID); + fprintf( stderr, "MultiplexID, WordCount = %04X, %02X\n", buf->MultiplexID, buf->WordCount); } static void child( ) { @@ -44,25 +81,53 @@ static void child( ) { netbios_read( &inpacket ); if( inpacket->netbios_command != 0x81 ) bailout( "No session request"); - netbios_write( 0x82, NULL, 0 ); + netbios_write( 0x82, NULL, NULL ); while( 1 ) { + WORD *ParameterWords; netbios_read( &inpacket ); + packet_dump( inpacket ); + ParameterWords = (WORD*)(((BYTE*)inpacket)+SIZEOF_SMB_HEADER); + if( inpacket->netbios_command != 0 ) bailout( "Unhandled netbios command" ); - if( inpacket->Protocol != SMB_HEADER_PROTOCOL_MAGIC ) + if( *(DWORD*)&inpacket->Protocol != SMB_HEADER_PROTOCOL_MAGIC ) bailout( "Protocol identifier mismatch"); switch( inpacket->Command ) { case SMB_COM_NEGOTIATE: { - BYTE outblock[5] = { 0xff,0,0,0,0 }; - netbios_write( 0, outblock, sizeof( outblock )); + BYTE myself[] = { 8,0,0x67,0x61,0x74,0x6c,0x69,0x6e,0x67,0x00 }; + struct timeval t; gettimeofday( &t, NULL ); + + inpacket = (SMB_HEADER*)realloc( inpacket, SIZEOF_SMB_HEADER + 17 * 2 ); + *(DWORD*)&inpacket->Status = STATUS_SUCCESS; + + ParameterWords = (WORD*)(((BYTE*)inpacket)+SIZEOF_SMB_HEADER-1); + ParameterWords[0] = 0x0511; /* Protocol Version 5, 17 bytes */ + ParameterWords[1] = 0; /* security mode: share, no c/r */ + ParameterWords[2] = 1; /* Max pending */ + ParameterWords[3] = 1; /* Only one VC */ + ParameterWords[4] = 0; /* Max Buffer Size */ + ParameterWords[5] = 0x100; /* Max Buffer Size #2 */ + ParameterWords[6] = 0; /* Max Raw Size */ + ParameterWords[7] = 0x100; /* Max Raw Size #2 */ + ParameterWords[8] = getpid(); /* unique id */ + ParameterWords[9] = getppid(); /* unique id #2 */ + ParameterWords[10] = 0; /* Capabilities */ + ParameterWords[11] = 0; /* Capabilities #2 */ +*(QWORD*)&ParameterWords[12] = getnttime( &t ); + ParameterWords[16] = 0; +*(BYTE *)&ParameterWords[17] = 0; + netbios_write( 0, inpacket, (SMB_HEADER2*)myself); break; } default: { fprintf( stderr, "Got message: %02X\n", inpacket->Command ); + inpacket->WordCount = 0; +*(DWORD*)&inpacket->Status = 0x00400002; + netbios_write( 0, inpacket, NULL ); break; } } @@ -70,8 +135,6 @@ static void child( ) { } /* End main loop */ } -void sigint( int reason ) { bailout( "User interrupt." ); } - int main() { struct sockaddr_in sa; @@ -86,7 +149,11 @@ int main() if( ( mainsock = socket( PF_INET, SOCK_STREAM, 0) ) == -1) bailout( "Could not open socket"); +#ifdef SO_REUSEPORT setsockopt( mainsock, SOL_SOCKET, SO_REUSEPORT, &l, sizeof(l)); +#else + setsockopt( mainsock, SOL_SOCKET, SO_REUSEADDR, &l, sizeof(l)); +#endif if( bind( mainsock, (struct sockaddr *)&sa, sizeof( sa)) != 0) bailout( "Could not bind socket"); if( listen( mainsock, 1024) != 0 ) -- cgit v1.2.3