From 414f6c80b22b128c25d947d62f6b5d1ec13091b6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 31 Jan 2005 01:57:58 +0000 Subject: r5114: the nbtd task can now act as a basic B-node server. It registers its names on the network and answers name queries. Lots of details are still missing, but at least this now means you don't need a Samba3 nmbd to use Samba4. missing pieces include: - name registrations should be "shout 3 times, then demand" - no WINS server yet - no master browser code (This used to be commit d7d31fdc6670f026f96b50e51a4de19f0b920e5b) --- source4/nbt_server/register.c | 161 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 source4/nbt_server/register.c (limited to 'source4/nbt_server/register.c') diff --git a/source4/nbt_server/register.c b/source4/nbt_server/register.c new file mode 100644 index 0000000000..9a416e37aa --- /dev/null +++ b/source4/nbt_server/register.c @@ -0,0 +1,161 @@ +/* + Unix SMB/CIFS implementation. + + register our names + + 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 02139, USA. +*/ + +#include "includes.h" +#include "dlinklist.h" +#include "nbt_server/nbt_server.h" + +/* + start a timer to refresh this name +*/ +static void nbt_start_refresh_timer(struct nbt_iface_name *iname) +{ +} + + +/* + a name registration has completed +*/ +static void nbt_register_handler(struct nbt_name_request *req) +{ + struct nbt_iface_name *iname = talloc_get_type(req->async.private, struct nbt_iface_name); + NTSTATUS status; + struct nbt_name_register io; + + status = nbt_name_register_recv(req, iname, &io); + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + /* 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)); + nbt_start_refresh_timer(iname); + return; + } + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1,("Error registering %s<%02x> on interface %s - %s\n", + iname->name.name, iname->name.type, iname->iface->bcast_address, + nt_errstr(status))); + return; + } + + /* someone must have replied with an objection! */ + iname->nb_flags |= NBT_NM_CONFLICT; + + DEBUG(1,("Name conflict registering %s<%02x> on interface %s - rcode %d from %s for %s\n", + iname->name.name, iname->name.type, iname->iface->bcast_address, + io.out.rcode, io.out.reply_from, io.out.reply_addr)); +} + + +/* + register a name on a network interface +*/ +static void nbt_register_name_iface(struct nbt_interface *iface, + const char *name, enum nbt_name_type type, + uint16_t nb_flags) +{ + struct nbt_iface_name *iname; + const char *scope = lp_netbios_scope(); + struct nbt_name_register io; + struct nbt_name_request *req; + + iname = talloc(iface, struct nbt_iface_name); + if (!iname) return; + + iname->iface = iface; + iname->name.name = talloc_strdup(iname, name); + iname->name.type = type; + if (scope && *scope) { + iname->name.scope = talloc_strdup(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(); + + DLIST_ADD(iface->names, iname); + + if (nb_flags & NBT_NM_PERMANENT) { + /* permanent names are not announced and are immediately active */ + iname->nb_flags |= NBT_NM_ACTIVE; + iname->ttl = 0; + return; + } + + /* setup a broadcast name registration request */ + io.in.name = iname->name; + io.in.dest_addr = iface->bcast_address; + io.in.address = iface->ip_address; + io.in.nb_flags = nb_flags; + io.in.register_demand = False; + io.in.broadcast = True; + io.in.ttl = iname->ttl; + io.in.timeout = 1; + + req = nbt_name_register_send(iface->nbtsock, &io); + if (req == NULL) return; + + req->async.fn = nbt_register_handler; + req->async.private = iname; +} + + +/* + register one name on all our interfaces +*/ +static void nbt_register_name(struct nbt_server *nbtsrv, + const char *name, enum nbt_name_type type, + uint16_t nb_flags) +{ + struct nbt_interface *iface; + + /* register with all the local interfaces */ + for (iface=nbtsrv->interfaces;iface;iface=iface->next) { + nbt_register_name_iface(iface, name, type, nb_flags); + } + + /* register on our general broadcast interface as a permanent name */ + nbt_register_name_iface(nbtsrv->bcast_interface, name, type, nb_flags | NBT_NM_PERMANENT); + + /* TODO: register with our WINS servers */ +} + + +/* + register our names on all interfaces +*/ +void nbt_register_names(struct nbt_server *nbtsrv) +{ + uint16_t nb_flags = NBT_NODE_M; + + /* note that we don't initially mark the names "ACTIVE". They are + marked active once registration is successful */ + nbt_register_name(nbtsrv, lp_netbios_name(), NBT_NAME_CLIENT, nb_flags); + nbt_register_name(nbtsrv, lp_netbios_name(), NBT_NAME_USER, nb_flags); + nbt_register_name(nbtsrv, lp_netbios_name(), NBT_NAME_SERVER, nb_flags); + nbt_register_name(nbtsrv, lp_workgroup(), NBT_NAME_CLIENT, nb_flags | NBT_NM_GROUP); + nbt_register_name(nbtsrv, lp_workgroup(), NBT_NAME_SERVER, nb_flags | NBT_NM_GROUP); + nbt_register_name(nbtsrv, "__SAMBA__", NBT_NAME_CLIENT, nb_flags | NBT_NM_PERMANENT); + nbt_register_name(nbtsrv, "__SAMBA__", NBT_NAME_SERVER, nb_flags | NBT_NM_PERMANENT); +} -- cgit