2005-04-08 12:57:09 +04:00
/*
Unix SMB / CIFS implementation .
NBT datagram server
Copyright ( C ) Andrew Tridgell 2005
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
# include "nbt_server/nbt_server.h"
# include "smbd/service_task.h"
# include "lib/socket/socket.h"
2006-03-07 14:07:23 +03:00
# include "libcli/resolve/resolve.h"
# include "nbt_server/dgram/proto.h"
2005-04-08 12:57:09 +04:00
/*
a list of mailslots that we have static handlers for
*/
static const struct {
const char * mailslot_name ;
dgram_mailslot_handler_t handler ;
} mailslot_handlers [ ] = {
{ NBT_MAILSLOT_NETLOGON , nbtd_mailslot_netlogon_handler } ,
2005-04-13 09:07:04 +04:00
{ NBT_MAILSLOT_NTLOGON , nbtd_mailslot_ntlogon_handler } ,
2005-04-08 12:57:09 +04:00
{ NBT_MAILSLOT_BROWSE , nbtd_mailslot_browse_handler }
} ;
/*
receive an incoming dgram request . This is used for general datagram
requests . Mailslot requests for our listening mailslots
are handled in the specific mailslot handlers
*/
void dgram_request_handler ( struct nbt_dgram_socket * dgmsock ,
2005-11-10 18:51:57 +03:00
struct nbt_dgram_packet * packet ,
2006-01-10 01:12:53 +03:00
struct socket_address * src )
2005-04-08 12:57:09 +04:00
{
2005-11-10 18:51:57 +03:00
DEBUG ( 0 , ( " General datagram request from %s:%d \n " , src - > addr , src - > port ) ) ;
2005-04-08 12:57:09 +04:00
NDR_PRINT_DEBUG ( nbt_dgram_packet , packet ) ;
}
/*
setup the port 138 datagram listener for a given interface
*/
NTSTATUS nbtd_dgram_setup ( struct nbtd_interface * iface , const char * bind_address )
{
2006-01-16 17:01:34 +03:00
struct nbt_dgram_socket * bcast_dgmsock = NULL ;
2005-04-08 12:57:09 +04:00
struct nbtd_server * nbtsrv = iface - > nbtsrv ;
2006-01-10 01:12:53 +03:00
struct socket_address * bcast_addr , * bind_addr ;
2005-04-08 12:57:09 +04:00
NTSTATUS status ;
2006-01-10 01:12:53 +03:00
TALLOC_CTX * tmp_ctx = talloc_new ( iface ) ;
2005-04-08 12:57:09 +04:00
/* the list of mailslots that we are interested in */
int i ;
2006-01-10 01:12:53 +03:00
if ( ! tmp_ctx ) {
return NT_STATUS_NO_MEMORY ;
}
2006-01-16 17:01:34 +03:00
if ( strcmp ( " 0.0.0.0 " , iface - > netmask ) ! = 0 ) {
/* listen for broadcasts on port 138 */
bcast_dgmsock = nbt_dgram_socket_init ( iface , nbtsrv - > task - > event_ctx ) ;
if ( ! bcast_dgmsock ) {
talloc_free ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2005-04-08 12:57:09 +04:00
2006-01-16 17:01:34 +03:00
bcast_addr = socket_address_from_strings ( tmp_ctx , bcast_dgmsock - > sock - > backend_name ,
iface - > bcast_address , lp_dgram_port ( ) ) ;
if ( ! bcast_addr ) {
talloc_free ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
status = socket_listen ( bcast_dgmsock - > sock , bcast_addr , 0 , 0 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
talloc_free ( tmp_ctx ) ;
DEBUG ( 0 , ( " Failed to bind to %s:%d - %s \n " ,
iface - > bcast_address , lp_dgram_port ( ) , nt_errstr ( status ) ) ) ;
return status ;
}
2005-04-08 12:57:09 +04:00
2006-01-16 17:01:34 +03:00
dgram_set_incoming_handler ( bcast_dgmsock , dgram_request_handler , iface ) ;
}
2006-01-10 01:12:53 +03:00
2005-04-08 12:57:09 +04:00
/* listen for unicasts on port 138 */
iface - > dgmsock = nbt_dgram_socket_init ( iface , nbtsrv - > task - > event_ctx ) ;
2006-01-10 01:12:53 +03:00
if ( ! iface - > dgmsock ) {
talloc_free ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2005-04-08 12:57:09 +04:00
2006-01-16 17:01:34 +03:00
bind_addr = socket_address_from_strings ( tmp_ctx , iface - > dgmsock - > sock - > backend_name ,
bind_address , lp_dgram_port ( ) ) ;
if ( ! bind_addr ) {
talloc_free ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2006-01-10 01:12:53 +03:00
status = socket_listen ( iface - > dgmsock - > sock , bind_addr , 0 , 0 ) ;
2005-04-08 12:57:09 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2006-01-10 01:12:53 +03:00
talloc_free ( tmp_ctx ) ;
2005-04-08 12:57:09 +04:00
DEBUG ( 0 , ( " Failed to bind to %s:%d - %s \n " ,
bind_address , lp_dgram_port ( ) , nt_errstr ( status ) ) ) ;
return status ;
}
2006-01-10 01:12:53 +03:00
2005-04-08 12:57:09 +04:00
dgram_set_incoming_handler ( iface - > dgmsock , dgram_request_handler , iface ) ;
2006-01-10 01:12:53 +03:00
talloc_free ( tmp_ctx ) ;
2005-04-08 12:57:09 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( mailslot_handlers ) ; i + + ) {
/* note that we don't need to keep the pointer
to the dgmslot around - the callback is all
we need */
struct dgram_mailslot_handler * dgmslot ;
2006-01-16 17:01:34 +03:00
if ( bcast_dgmsock ) {
dgmslot = dgram_mailslot_listen ( bcast_dgmsock ,
2005-04-08 12:57:09 +04:00
mailslot_handlers [ i ] . mailslot_name ,
mailslot_handlers [ i ] . handler , iface ) ;
2006-01-16 17:01:34 +03:00
NT_STATUS_HAVE_NO_MEMORY ( dgmslot ) ;
}
2005-04-08 12:57:09 +04:00
dgmslot = dgram_mailslot_listen ( iface - > dgmsock ,
mailslot_handlers [ i ] . mailslot_name ,
mailslot_handlers [ i ] . handler , iface ) ;
NT_STATUS_HAVE_NO_MEMORY ( dgmslot ) ;
}
return NT_STATUS_OK ;
}