From fe86b20ebd62f497564fd3187e8509496b63600e Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Thu, 4 Dec 2003 22:53:17 +0000 Subject: nu_header.h split up in nu_server.h and nu_defines.h --- src/nu_server.c | 131 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 80 insertions(+), 51 deletions(-) (limited to 'src/nu_server.c') diff --git a/src/nu_server.c b/src/nu_server.c index ddd555e..d79967c 100755 --- a/src/nu_server.c +++ b/src/nu_server.c @@ -32,30 +32,58 @@ static void netbios_read( SMB_HEADER **buf) { bailout( "Short read." ); } -static void netbios_write( SMB_COMMAND cmd, - SMB_HEADER *buf, - SMB_PARAMS *buf2, - SMB_BYTES *buf3 ) { - BYTE buf_[4] = { 0, 0, 0, 0 }; - if(!buf2 ) buf2 = (SMB_PARAMS*)buf_; - if(!buf3 ) buf3 = (SMB_BYTES*)buf_; - - struct iovec iov[16] = { {buf , sizeof(SMB_HEADER) }, - {buf2, 1 + buf2->WordCount * 2}, - {buf3, 2 + buf3->ByteCount } }; - - buf->netbios_command = cmd; - buf->netbios_flags = 0; - buf->netbios_size = htons( sizeof(SMB_HEADER) - 4 + - 1 + buf2->WordCount * 2 + - 2 + buf3->ByteCount ); +static void netbios_write( SMB_HEADER *buf, + SMB_DATA *data, + int datacount ) { + struct iovec iov[1 + 2 * SMB_MAXREQUEST] = { {buf , sizeof(SMB_HEADER) } }; + int i, sizeout = sizeof( SMB_HEADER ); + + for( i=0; i < datacount; ++i ) + iov[1+2*i].iov_base = data[i].params, + sizeout += iov[1+2*i].iov_len = 1 + data[i].params->WordCount * 2, + iov[2+2*i].iov_base = data[i].bytes, + sizeout += iov[2+2*i].iov_len = 2 + data[i].bytes->ByteCount; + + buf->netbios_command = buf->netbios_flags = 0; + buf->netbios_size = htons( sizeout ); buf->Flags = 0x88; buf->Flags2 = 0x4001; - if( writev( childsock, iov, 3 ) < htons( buf->netbios_size ) + 4 ) + if( writev( childsock, iov, 1 + 2 * datacount ) < sizeout + 4 ) bailout( "Write failed." ); } +static const BYTE SMB_COM_NEGOTIATE_bytes[] = { 8,0,0x67,0x61,0x74,0x6c,0x69,0x6e,0x67,0 }; +static WORD SMB_COM_NEGOTIATE_params[] = { +0x0511, 0x0000, 0x0001, 0x0001, 0x0000, 0x0100, 0x0000, 0x0100, 0x0000, +0x0000, 0xC049, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; + +static SMB_STATUS handle_SMB_COM_NEGOTIATE( SMB_DATA *data ) { + struct timeval t; gettimeofday( &t, NULL ); + SMB_COM_NEGOTIATE_params[8] = getpid(); + SMB_COM_NEGOTIATE_params[9] = getppid(); + *(QWORD*)(SMB_COM_NEGOTIATE_params+12) = getnttime( &t ); + + data->params = SMB_COM_NEGOTIATE_bytes; data->bytes = SMB_COM_NEGOTIATE_params; + return STATUS_SUCCESS; +} + +static const BYTE SMB_SESSION_SETUP_ANDX_bytes[] = { +19,0,'O','S',0,'g','a','t','l','i','n','g',0,'g','a','t','l','i','n','g',0}; +static BYTE SMB_SESSION_SETUP_ANDX_params[] = { 4, 0, 0, 23, 0, 1, 0, 0, 0 }; + +static SMB_STATUS handle_SMB_SESSION_SETUP_ANDX( SMB_DATA *data ) { + data->params = SMB_SESSION_SETUP_ANDX_bytes; data->bytes = SMB_SESSION_SETUP_ANDX_params; + return STATUS_SUCCESS; +} + +static‰int command_handler_match( const void *a, const void *b ) { return *(BYTE*)a - *(BYTE*)b; } +static SMB_COMMAND_HANDLER command_handler[] = { + { { SMB_COM_NEGOTIATE, 0x00, handle_SMB_COM_NEGOTIATE }, + { SMB_COM_SESSION_SETUP_ANDX, 0x01, handle_SMB_COM_SESSION_SETUP_ANDX } + } +}; + static void child( ) { SMB_HEADER *inpacket = NULL; @@ -69,6 +97,12 @@ static void child( ) { write( childsock, inpacket, 4); while( 1 ) { + SMB_COMMAND cmd; + SMB_DATA requests[ 1 + SMB_MAXREQUESTS ]; + SMB_STATUS status = STATUS_SUCCESS; + WORD sizeout = sizeof( SMB_HEADER ); + int num_requests = 0; + netbios_read( &inpacket ); if( inpacket->netbios_command != 0 ) @@ -76,46 +110,41 @@ static void child( ) { if( inpacket->Protocol != SMB_HEADER_PROTOCOL_MAGIC ) bailout( "Protocol identifier mismatch"); - switch( inpacket->Command ) { - case SMB_COM_NEGOTIATE: - { - const BYTE bytes[] = { 8,0,0x67,0x61,0x74,0x6c,0x69,0x6e,0x67,0 }; - WORD params[] = { 0x0511, 0x0000, 0x0001, 0x0001, 0x0000, 0x0100, - 0x0000, 0x0100, 0x0000, 0x0000, 0xC049, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; - struct timeval t; gettimeofday( &t, NULL ); - - *(DWORD*)&inpacket->Status = STATUS_SUCCESS; - params[8] = getpid(); params[9] = getppid(); - *(QWORD*)¶ms[12] = getnttime( &t ); - netbios_write( 0, inpacket, (SMB_PARAMS*)params, (SMB_BYTES*)bytes); - break; - } -/* case SMB_COM_SESSION_SETUP_ANDX: - { - const BYTE bytes[] = { 19, 0, 'O', 'S', 0, 'g', 'a', 't', 'l', - 'i', 'n', 'g', 0, 'g', 'a', 't', 'l', 'i', - 'n', 'g', 0}; - BYTE params[] = { 4, 0, 0, 23, 0, 1, 0, 0, 0 }; - - } */ - default: - { - fprintf( stderr, "Got message: %02X\n", inpacket->Command ); - *(DWORD*)&inpacket->Status = 0x00400002; - netbios_write( 0, inpacket, NULL, NULL ); - break; - } + cmd = inpacket->Command; + requests[ 0 ].params = (SMB_PARAMS*)(inpacket+1); + + while( (status == STATUS_SUCCESS) && (cmd != 0xff) ) { + SMB_COMMAND_HANDLER *handler = (SMB_COMMAND_HANDLER*)bsearch( cmd, command_handler, + sizeof(command_handler)/sizeof(*command_handler), sizeof(*command_handler), command_handler_match); + + requests[ num_request ].bytes = 2 + *((WORD*)requests[ num_request ].params) + (BYTE*)requests[ num_request ].params; + if( handler ) { + if( handler->flags & SMB_COMMAND_FLAG_ANDX ) { + cmd = ((BYTE*)requests[ num_requests ].params)[3]; + requests[ num_requests+1 ].params = ((BYTE*)inpacket) + ((WORD*)requests[ num_requests ].params)[2]; + } + + status = handler->handler( &requests( num_requests ) ); + + if( (status == STATUS_SUCCESS) && (handler->flags & SMB_COMMAND_FLAG_ANDX) ) { + sizeout += 3 + 2 * requests[ num_requests ].params->WordCount + requests[ num_requests ].bytes->ByteCount; + ((WORD*)requests[ num_requests ].params)[2] = sizeout; + ((BYTE*)requests[ num_requests ].params)[3] = cmd; + } + num_requests++; + } else + status = 0x00400002; } + memcpy( inpacket->status, &status, 4 ); /* not aligned, maybe we might do a store DWORD on x86 */ + netbios_write( inpacket, requests, num_requests ); } /* End main loop */ } -int main() -{ +int main() { struct sockaddr_in sa; int l=1; - + signal( SIGINT, sigint); bzero( &sa, sizeof( sa)); -- cgit v1.2.3