More simple const fixes.
[samba.git] / source3 / nmbd / nmbd_subnetdb.c
index 7fd241cf624c58cc0f1f6b4d87b8b120fdf28cb3..666679a90b4a80c2a61cc77c2f50df930891b263 100644 (file)
@@ -23,6 +23,7 @@
 */
 
 #include "includes.h"
+#include "nmbd/nmbd.h"
 
 extern int global_nmb_port;
 
@@ -76,75 +77,96 @@ 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_nmbd_bind_explicit_broadcast();
 
        /* 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
                 * and bind them.
                 * Fail the subnet creation if this fails.
                 */
 
-               if((nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,0, myip.s_addr,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, myip.s_addr,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 ));
@@ -159,9 +181,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;
 }
 
 /****************************************************************************
@@ -188,37 +228,40 @@ struct subnet_record *make_normal_subnet(const struct interface *iface)
   Create subnet entries.
 **************************************************************************/
 
-BOOL create_subnets(void)
+bool create_subnets(void)
 {
        /* We only count IPv4 interfaces whilst we're waiting. */
-       int num_interfaces = iface_count_v4();
+       int num_interfaces;
        int i;
        struct in_addr unicast_ip, ipzero;
 
-       if(num_interfaces == 0) {
-               void (*saved_handler)(int);
+  try_interfaces_again:
 
-               DEBUG(0,("create_subnets: No local interfaces !\n"));
+       /* Only count IPv4, non-loopback interfaces. */
+       if (iface_count_v4_nl() == 0) {
+               DEBUG(0,("create_subnets: No local IPv4 non-loopback interfaces !\n"));
                DEBUG(0,("create_subnets: Waiting for an interface to appear ...\n"));
+       }
+
+       /* We only count IPv4, non-loopback interfaces here. */
+       while (iface_count_v4_nl() == 0) {
+               void (*saved_handler)(int);
 
                /*
                 * Whilst we're waiting for an interface, allow SIGTERM to
                 * cause us to exit.
                 */
 
-               saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );
+               saved_handler = CatchSignal(SIGTERM, SIG_DFL);
 
-               /* We only count IPv4 interfaces here. */
-               while (iface_count_v4() == 0) {
-                       sleep(5);
-                       load_interfaces();
-               }
+               sleep(5);
+               load_interfaces();
 
                /*
                 * We got an interface, restore our normal term handler.
                 */
 
-               CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
+               CatchSignal(SIGTERM, saved_handler);
        }
 
        /*
@@ -253,7 +296,7 @@ BOOL create_subnets(void)
                 * ignore it here. JRA.
                 */
 
-               if (is_loopback_addr(&iface->ip)) {
+               if (is_loopback_addr((const struct sockaddr *)&iface->ip)) {
                        DEBUG(2,("create_subnets: Ignoring loopback interface.\n" ));
                        continue;
                }
@@ -264,13 +307,24 @@ BOOL create_subnets(void)
 
         /* We must have at least one subnet. */
        if (subnetlist == NULL) {
-               DEBUG(0,("create_subnets: unable to create any subnet from "
-                               "given interfaces. nmbd is terminating\n"));
-               return False;
+               void (*saved_handler)(int);
+
+               DEBUG(0,("create_subnets: Unable to create any subnet from "
+                               "given interfaces. Is your interface line in "
+                               "smb.conf correct ?\n"));
+
+               saved_handler = CatchSignal(SIGTERM, SIG_DFL);
+
+               sleep(5);
+               load_interfaces();
+
+               CatchSignal(SIGTERM, saved_handler);
+               goto try_interfaces_again;
        }
 
        if (lp_we_are_a_wins_server()) {
-               /* Pick the first interface IPv4 address as the WINS server ip. */
+               /* Pick the first interface IPv4 address as the WINS server
+                * ip. */
                const struct in_addr *nip = first_ipv4_iface();
 
                if (!nip) {
@@ -323,7 +377,7 @@ BOOL create_subnets(void)
 Function to tell us if we can use the unicast subnet.
 ******************************************************************/
 
-BOOL we_are_a_wins_client(void)
+bool we_are_a_wins_client(void)
 {
        if (wins_srv_count() > 0) {
                return True;