nmbd: xfile->stdio
[samba.git] / source3 / nmbd / nmbd_subnetdb.c
index 61af0bb4a4d57d7b9c71251089b52fec740b9b18..5c9e4c7eb26524541b84fba2193112a1e2fc7589 100644 (file)
@@ -23,6 +23,7 @@
 */
 
 #include "includes.h"
+#include "nmbd/nmbd.h"
 
 extern int global_nmb_port;
 
@@ -36,7 +37,7 @@ struct subnet_record *unicast_subnet = NULL;
 struct subnet_record *remote_broadcast_subnet = NULL;
 struct subnet_record *wins_server_subnet = NULL;
 
-extern uint16 samba_nb_type; /* Samba's NetBIOS name type. */
+extern uint16_t samba_nb_type; /* Samba's NetBIOS name type. */
 
 /****************************************************************************
   Add a subnet into the list.
@@ -55,13 +56,21 @@ yet and it may be in use by a response record
 
 void close_subnet(struct subnet_record *subrec)
 {
+       if (subrec->nmb_sock != -1) {
+               close(subrec->nmb_sock);
+               subrec->nmb_sock = -1;
+       }
+       if (subrec->nmb_bcast != -1) {
+               close(subrec->nmb_bcast);
+               subrec->nmb_bcast = -1;
+       }
        if (subrec->dgram_sock != -1) {
                close(subrec->dgram_sock);
                subrec->dgram_sock = -1;
        }
-       if (subrec->nmb_sock != -1) {
-               close(subrec->nmb_sock);
-               subrec->nmb_sock = -1;
+       if (subrec->dgram_bcast != -1) {
+               close(subrec->dgram_bcast);
+               subrec->dgram_bcast = -1;
        }
 
        DLIST_REMOVE(subnetlist, subrec);
@@ -76,18 +85,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_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
@@ -95,60 +107,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 +189,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;
 }
 
 /****************************************************************************
@@ -203,8 +247,11 @@ bool create_subnets(void)
 
        /* 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"));
+               daemon_status("nmbd",
+                             "No local IPv4 non-loopback interfaces "
+                             "available, waiting for interface ...");
+               DEBUG(0,("NOTE: NetBIOS name resolution is not supported for "
+                        "Internet Protocol Version 6 (IPv6).\n"));
        }
 
        /* We only count IPv4, non-loopback interfaces here. */
@@ -216,7 +263,7 @@ bool create_subnets(void)
                 * cause us to exit.
                 */
 
-               saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );
+               saved_handler = CatchSignal(SIGTERM, SIG_DFL);
 
                sleep(5);
                load_interfaces();
@@ -225,7 +272,7 @@ bool create_subnets(void)
                 * We got an interface, restore our normal term handler.
                 */
 
-               CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
+               CatchSignal(SIGTERM, saved_handler);
        }
 
        /*
@@ -260,7 +307,7 @@ bool create_subnets(void)
                 * ignore it here. JRA.
                 */
 
-               if (is_loopback_addr((struct sockaddr *)&iface->ip)) {
+               if (is_loopback_addr((const struct sockaddr *)&iface->ip)) {
                        DEBUG(2,("create_subnets: Ignoring loopback interface.\n" ));
                        continue;
                }
@@ -277,17 +324,18 @@ bool create_subnets(void)
                                "given interfaces. Is your interface line in "
                                "smb.conf correct ?\n"));
 
-               saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );
+               saved_handler = CatchSignal(SIGTERM, SIG_DFL);
 
                sleep(5);
                load_interfaces();
 
-               CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
+               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) {