r5454: moved the WINS server code into its own directory
[samba.git] / source / nbt_server / register.c
index c655de0515764dee6d8c04d3a6ba837de2edc6b5..bec316cdea3b8d813492b9882e732cef9c79a1cb 100644 (file)
 #include "libcli/composite/composite.h"
 
 
-static void nbtd_start_refresh_timer(struct nbt_iface_name *iname);
+static void nbtd_start_refresh_timer(struct nbtd_iface_name *iname);
 
 /*
   a name refresh request has completed
 */
 static void refresh_completion_handler(struct nbt_name_request *req)
 {
-       struct nbt_iface_name *iname = talloc_get_type(req->async.private, struct nbt_iface_name);
+       struct nbtd_iface_name *iname = talloc_get_type(req->async.private, 
+                                                       struct nbtd_iface_name);
        NTSTATUS status;
        struct nbt_name_refresh io;
        TALLOC_CTX *tmp_ctx = talloc_new(iname);
 
        status = nbt_name_refresh_recv(req, tmp_ctx, &io);
        if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
-               DEBUG(4,("Refreshed name %s<%02x> on %s\n", 
-                        iname->name.name, iname->name.type, iname->iface->ip_address));
+               DEBUG(4,("Refreshed name %s on %s\n", 
+                        nbt_name_string(tmp_ctx, &iname->name), 
+                        iname->iface->ip_address));
                iname->registration_time = timeval_current();
                nbtd_start_refresh_timer(iname);
                talloc_free(tmp_ctx);
@@ -55,12 +57,14 @@ static void refresh_completion_handler(struct nbt_name_request *req)
        iname->nb_flags &= ~NBT_NM_ACTIVE;
 
        if (NT_STATUS_IS_OK(status)) {
-               DEBUG(1,("Name conflict from %s refreshing name %s<%02x> on %s - rcode %d\n", 
-                        io.out.reply_addr, iname->name.name, iname->name.type, 
-                        iname->iface->ip_address, io.out.rcode));
+               DEBUG(1,("Name conflict from %s refreshing name %s on %s - %s\n", 
+                        io.out.reply_addr, nbt_name_string(tmp_ctx, &iname->name),
+                        iname->iface->ip_address, 
+                        nt_errstr(nbt_rcode_to_ntstatus(io.out.rcode))));
        } else {
-               DEBUG(1,("Error refreshing name %s<%02x> on %s - %s\n", 
-                        iname->name.name, iname->name.type, iname->iface->ip_address,
+               DEBUG(1,("Error refreshing name %s on %s - %s\n", 
+                        nbt_name_string(tmp_ctx, &iname->name), 
+                        iname->iface->ip_address,
                         nt_errstr(status)));
        }
 
@@ -74,8 +78,8 @@ static void refresh_completion_handler(struct nbt_name_request *req)
 static void name_refresh_handler(struct event_context *ev, struct timed_event *te, 
                                 struct timeval t, void *private)
 {
-       struct nbt_iface_name *iname = talloc_get_type(private, struct nbt_iface_name);
-       struct nbt_interface *iface = iname->iface;
+       struct nbtd_iface_name *iname = talloc_get_type(private, struct nbtd_iface_name);
+       struct nbtd_interface *iface = iname->iface;
        struct nbt_name_register io;
        struct nbt_name_request *req;
 
@@ -91,7 +95,9 @@ static void name_refresh_handler(struct event_context *ev, struct timed_event *t
        io.in.ttl             = iname->ttl;
        io.in.register_demand = False;
        io.in.broadcast       = True;
+       io.in.multi_homed     = False;
        io.in.timeout         = 3;
+       io.in.retries         = 0;
 
        req = nbt_name_register_send(iface->nbtsock, &io);
        if (req == NULL) return;
@@ -104,7 +110,7 @@ static void name_refresh_handler(struct event_context *ev, struct timed_event *t
 /*
   start a timer to refresh this name
 */
-static void nbtd_start_refresh_timer(struct nbt_iface_name *iname)
+static void nbtd_start_refresh_timer(struct nbtd_iface_name *iname)
 {
        uint32_t refresh_time;
        uint32_t max_refresh_time = lp_parm_int(-1, "nbtd", "max_refresh_time", 7200);
@@ -123,17 +129,20 @@ static void nbtd_start_refresh_timer(struct nbt_iface_name *iname)
 */
 static void nbtd_register_handler(struct composite_context *req)
 {
-       struct nbt_iface_name *iname = talloc_get_type(req->async.private, 
-                                                      struct nbt_iface_name);
+       struct nbtd_iface_name *iname = talloc_get_type(req->async.private, 
+                                                       struct nbtd_iface_name);
        NTSTATUS status;
+       TALLOC_CTX *tmp_ctx = talloc_new(iname);
 
        status = nbt_name_register_bcast_recv(req);
        if (NT_STATUS_IS_OK(status)) {
                /* good - nobody complained about our registration */
                iname->nb_flags |= NBT_NM_ACTIVE;
-               DEBUG(3,("Registered %s<%02x> on interface %s\n",
-                        iname->name.name, iname->name.type, iname->iface->bcast_address));
+               DEBUG(3,("Registered %s on interface %s\n",
+                        nbt_name_string(tmp_ctx, &iname->name), 
+                        iname->iface->bcast_address));
                iname->registration_time = timeval_current();
+               talloc_free(tmp_ctx);
                nbtd_start_refresh_timer(iname);
                return;
        }
@@ -141,40 +150,42 @@ static void nbtd_register_handler(struct composite_context *req)
        /* someone must have replied with an objection! */
        iname->nb_flags |= NBT_NM_CONFLICT;
 
-       DEBUG(1,("Error registering %s<%02x> on interface %s - %s\n",
-                iname->name.name, iname->name.type, iname->iface->bcast_address,
+       DEBUG(1,("Error registering %s on interface %s - %s\n",
+                nbt_name_string(tmp_ctx, &iname->name), iname->iface->bcast_address,
                 nt_errstr(status)));
+       talloc_free(tmp_ctx);
 }
 
 
 /*
   register a name on a network interface
 */
-static void nbtd_register_name_iface(struct nbt_interface *iface,
+static void nbtd_register_name_iface(struct nbtd_interface *iface,
                                     const char *name, enum nbt_name_type type,
                                     uint16_t nb_flags)
 {
-       struct nbt_iface_name *iname;
+       struct nbtd_iface_name *iname;
        const char *scope = lp_netbios_scope();
        struct nbt_name_register_bcast io;
        struct composite_context *req;
 
-       iname = talloc(iface, struct nbt_iface_name);
+       iname = talloc(iface, struct nbtd_iface_name);
        if (!iname) return;
 
        iname->iface     = iface;
        iname->name.name = strupper_talloc(iname, name);
        iname->name.type = type;
        if (scope && *scope) {
-               iname->name.scope = talloc_strdup(iname, scope);
+               iname->name.scope = strupper_talloc(iname, scope);
        } else {
                iname->name.scope = NULL;
        }
        iname->nb_flags          = nb_flags;
        iname->ttl               = lp_parm_int(-1, "nbtd", "bcast_ttl", 300000);
        iname->registration_time = timeval_zero();
+       iname->wins_server       = NULL;
 
-       DLIST_ADD_END(iface->names, iname, struct nbt_iface_name *);
+       DLIST_ADD_END(iface->names, iname, struct nbtd_iface_name *);
 
        if (nb_flags & NBT_NM_PERMANENT) {
                /* permanent names are not announced and are immediately active */
@@ -183,6 +194,13 @@ static void nbtd_register_name_iface(struct nbt_interface *iface,
                return;
        }
 
+       /* if this is the wins interface, then we need to do a special
+          wins name registration */
+       if (iface == iface->nbtsrv->wins_interface) {
+               nbtd_winsclient_register(iname);
+               return;
+       }
+
        /* setup a broadcast name registration request */
        io.in.name            = iname->name;
        io.in.dest_addr       = iface->bcast_address;
@@ -201,11 +219,11 @@ static void nbtd_register_name_iface(struct nbt_interface *iface,
 /*
   register one name on all our interfaces
 */
-static void nbtd_register_name(struct nbt_server *nbtsrv, 
+static void nbtd_register_name(struct nbtd_server *nbtsrv, 
                               const char *name, enum nbt_name_type type,
                               uint16_t nb_flags)
 {
-       struct nbt_interface *iface;
+       struct nbtd_interface *iface;
        
        /* register with all the local interfaces */
        for (iface=nbtsrv->interfaces;iface;iface=iface->next) {
@@ -218,14 +236,17 @@ static void nbtd_register_name(struct nbt_server *nbtsrv,
                                         nb_flags | NBT_NM_PERMANENT);
        }
 
-       /* TODO: register with our WINS servers */
+       /* register with our WINS servers */
+       if (nbtsrv->wins_interface) {
+               nbtd_register_name_iface(nbtsrv->wins_interface, name, type, nb_flags);
+       }
 }
 
 
 /*
   register our names on all interfaces
 */
-void nbtd_register_names(struct nbt_server *nbtsrv)
+void nbtd_register_names(struct nbtd_server *nbtsrv)
 {
        uint16_t nb_flags = NBT_NODE_M;
        const char **aliases;
@@ -238,6 +259,7 @@ void nbtd_register_names(struct nbt_server *nbtsrv)
 
        aliases = lp_netbios_aliases();
        while (aliases && aliases[0]) {
+               nbtd_register_name(nbtsrv, aliases[0], NBT_NAME_CLIENT, nb_flags);
                nbtd_register_name(nbtsrv, aliases[0], NBT_NAME_SERVER, nb_flags);
                aliases++;
        }