summaryrefslogtreecommitdiff
path: root/source3/nmbd/nmbd_subnetdb.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2010-01-28 11:04:05 +0100
committerStefan Metzmacher <metze@samba.org>2010-02-08 18:35:10 +0100
commit30a1bc365071befd07e68e24ca4fa3843159ab13 (patch)
tree46c66e57dda4239d21079d31ea3fbc4a6c49a4b7 /source3/nmbd/nmbd_subnetdb.c
parent6339de7f4fef46fb3ad32d1ecf9379f5b5d24ccb (diff)
downloadsamba-30a1bc365071befd07e68e24ca4fa3843159ab13.tar.gz
samba-30a1bc365071befd07e68e24ca4fa3843159ab13.tar.bz2
samba-30a1bc365071befd07e68e24ca4fa3843159ab13.zip
s3:nmbd: also listen explicit on the subnet broadcast addresses
And send replies always via the unicast address of the subnet. This behavior is off by default (as before) and can be enabled with "nmbd:bind explicit broadcast = yes". metze
Diffstat (limited to 'source3/nmbd/nmbd_subnetdb.c')
-rw-r--r--source3/nmbd/nmbd_subnetdb.c123
1 files changed, 79 insertions, 44 deletions
diff --git a/source3/nmbd/nmbd_subnetdb.c b/source3/nmbd/nmbd_subnetdb.c
index 13bc931863..96d7b3211e 100644
--- a/source3/nmbd/nmbd_subnetdb.c
+++ b/source3/nmbd/nmbd_subnetdb.c
@@ -76,18 +76,21 @@ static struct subnet_record *make_subnet(const char *name, enum subnet_type type
struct in_addr mask_ip)
{
struct subnet_record *subrec = NULL;
- int nmb_sock, dgram_sock;
+ int nmb_sock = -1;
+ int dgram_sock = -1;
+ int nmb_bcast = -1;
+ int dgram_bcast = -1;
+ bool bind_bcast = lp_parm_bool(-1, "nmbd", "bind explicit broadcast", false);
/* Check if we are creating a non broadcast subnet - if so don't create
sockets. */
- if(type != NORMAL_SUBNET) {
- nmb_sock = -1;
- dgram_sock = -1;
- } else {
+ if (type == NORMAL_SUBNET) {
struct sockaddr_storage ss;
+ struct sockaddr_storage ss_bcast;
in_addr_to_sockaddr_storage(&ss, myip);
+ in_addr_to_sockaddr_storage(&ss_bcast, bcast_ip);
/*
* Attempt to open the sockets on port 137/138 for this interface
@@ -95,60 +98,74 @@ static struct subnet_record *make_subnet(const char *name, enum subnet_type type
* Fail the subnet creation if this fails.
*/
- if((nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,0, &ss,true)) == -1) {
- if( DEBUGLVL( 0 ) ) {
- Debug1( "nmbd_subnetdb:make_subnet()\n" );
- Debug1( " Failed to open nmb socket on interface %s ", inet_ntoa(myip) );
- Debug1( "for port %d. ", global_nmb_port );
- Debug1( "Error was %s\n", strerror(errno) );
+ nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,
+ 0, &ss, true);
+ if (nmb_sock == -1) {
+ DEBUG(0, ("nmbd_subnetdb:make_subnet()\n"));
+ DEBUGADD(0,(" Failed to open nmb socket on interface %s ",
+ inet_ntoa(myip)));
+ DEBUGADD(0,("for port %d. ", global_nmb_port));
+ DEBUGADD(0,("Error was %s\n", strerror(errno)));
+ goto failed;
+ }
+ set_socket_options(nmb_sock,"SO_BROADCAST");
+ set_blocking(nmb_sock, false);
+
+ if (bind_bcast) {
+ nmb_bcast = open_socket_in(SOCK_DGRAM, global_nmb_port,
+ 0, &ss_bcast, true);
+ if (nmb_bcast == -1) {
+ DEBUG(0, ("nmbd_subnetdb:make_subnet()\n"));
+ DEBUGADD(0,(" Failed to open nmb bcast socket on interface %s ",
+ inet_ntoa(bcast_ip)));
+ DEBUGADD(0,("for port %d. ", global_nmb_port));
+ DEBUGADD(0,("Error was %s\n", strerror(errno)));
+ goto failed;
}
- return NULL;
+ set_socket_options(nmb_bcast, "SO_BROADCAST");
+ set_blocking(nmb_bcast, false);
}
- if((dgram_sock = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3, &ss, true)) == -1) {
- if( DEBUGLVL( 0 ) ) {
- Debug1( "nmbd_subnetdb:make_subnet()\n" );
- Debug1( " Failed to open dgram socket on interface %s ", inet_ntoa(myip) );
- Debug1( "for port %d. ", DGRAM_PORT );
- Debug1( "Error was %s\n", strerror(errno) );
+ dgram_sock = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
+ 3, &ss, true);
+ if (dgram_sock == -1) {
+ DEBUG(0, ("nmbd_subnetdb:make_subnet()\n"));
+ DEBUGADD(0,(" Failed to open dgram socket on interface %s ",
+ inet_ntoa(myip)));
+ DEBUGADD(0,("for port %d. ", DGRAM_PORT));
+ DEBUGADD(0,("Error was %s\n", strerror(errno)));
+ goto failed;
+ }
+ set_socket_options(dgram_sock, "SO_BROADCAST");
+ set_blocking(dgram_sock, false);
+
+ if (bind_bcast) {
+ dgram_bcast = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
+ 3, &ss_bcast, true);
+ if (dgram_bcast == -1) {
+ DEBUG(0, ("nmbd_subnetdb:make_subnet()\n"));
+ DEBUGADD(0,(" Failed to open dgram bcast socket on interface %s ",
+ inet_ntoa(bcast_ip)));
+ DEBUGADD(0,("for port %d. ", DGRAM_PORT));
+ DEBUGADD(0,("Error was %s\n", strerror(errno)));
+ goto failed;
}
- return NULL;
+ set_socket_options(dgram_bcast, "SO_BROADCAST");
+ set_blocking(dgram_bcast, false);
}
-
- /* Make sure we can broadcast from these sockets. */
- set_socket_options(nmb_sock,"SO_BROADCAST");
- set_socket_options(dgram_sock,"SO_BROADCAST");
-
- /* Set them non-blocking. */
- set_blocking(nmb_sock, False);
- set_blocking(dgram_sock, False);
}
subrec = SMB_MALLOC_P(struct subnet_record);
if (!subrec) {
DEBUG(0,("make_subnet: malloc fail !\n"));
- if (nmb_sock != -1) {
- close(nmb_sock);
- }
- if (dgram_sock != -1) {
- close(dgram_sock);
- }
- return(NULL);
+ goto failed;
}
ZERO_STRUCTP(subrec);
if((subrec->subnet_name = SMB_STRDUP(name)) == NULL) {
DEBUG(0,("make_subnet: malloc fail for subnet name !\n"));
- if (nmb_sock != -1) {
- close(nmb_sock);
- }
- if (dgram_sock != -1) {
- close(dgram_sock);
- }
- ZERO_STRUCTP(subrec);
- SAFE_FREE(subrec);
- return(NULL);
+ goto failed;
}
DEBUG(2, ("making subnet name:%s ", name ));
@@ -163,9 +180,27 @@ static struct subnet_record *make_subnet(const char *name, enum subnet_type type
subrec->myip = myip;
subrec->type = type;
subrec->nmb_sock = nmb_sock;
+ subrec->nmb_bcast = nmb_bcast;
subrec->dgram_sock = dgram_sock;
-
+ subrec->dgram_bcast = dgram_bcast;
+
return subrec;
+
+failed:
+ SAFE_FREE(subrec);
+ if (nmb_sock != -1) {
+ close(nmb_sock);
+ }
+ if (nmb_bcast != -1) {
+ close(nmb_bcast);
+ }
+ if (dgram_sock != -1) {
+ close(dgram_sock);
+ }
+ if (dgram_bcast != -1) {
+ close(dgram_bcast);
+ }
+ return NULL;
}
/****************************************************************************