summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/nbt_server/interfaces.c125
-rw-r--r--source4/nbt_server/nbt_server.c23
-rw-r--r--source4/nbt_server/nodestatus.c6
-rw-r--r--source4/nbt_server/query.c6
-rw-r--r--source4/nbt_server/register.c5
5 files changed, 76 insertions, 89 deletions
diff --git a/source4/nbt_server/interfaces.c b/source4/nbt_server/interfaces.c
index 303802e2cd..8c5566c819 100644
--- a/source4/nbt_server/interfaces.c
+++ b/source4/nbt_server/interfaces.c
@@ -25,6 +25,23 @@
#include "nbt_server/nbt_server.h"
#include "smbd/service_task.h"
+
+/*
+ receive an incoming request and dispatch it to the right place
+*/
+static void nbt_request_handler(struct nbt_name_socket *nbtsock,
+ struct nbt_name_packet *packet,
+ const char *src_address, int src_port)
+{
+ switch (packet->operation & NBT_OPCODE) {
+ case NBT_OPCODE_QUERY:
+ nbt_request_query(nbtsock, packet, src_address, src_port);
+ break;
+ }
+}
+
+
+
/*
find a registered name on an interface
*/
@@ -43,56 +60,24 @@ struct nbt_iface_name *nbt_find_iname(struct nbt_interface *iface, struct nbt_na
}
/*
- see if a src address matches an interface
-*/
-static BOOL nbt_iface_match(struct nbt_interface *iface, const char *src_address)
-{
- struct ipv4_addr ip1, ip2, mask;
- ip1 = interpret_addr2(iface->ip_address);
- ip2 = interpret_addr2(src_address);
- mask = interpret_addr2(iface->netmask);
- return same_net(ip1, ip2, mask);
-}
-
-
-/*
- find the appropriate interface for a incoming packet. If a local interface isn't
- found then the general broadcast interface is used
-*/
-struct nbt_interface *nbt_iface_find(struct nbt_name_socket *nbtsock, const char *src_address)
-{
- struct nbt_interface *iface = talloc_get_type(nbtsock->incoming.private, struct nbt_interface);
- struct nbt_server *nbtsrv = iface->nbtsrv;
-
- /* it might have been received by one of our specific bound
- addresses */
- if (iface != nbtsrv->bcast_interface) {
- return iface;
- }
-
- /* it came in on our broadcast interface - try to find a match */
- for (iface=nbtsrv->interfaces;iface;iface=iface->next) {
- if (nbt_iface_match(iface, src_address)) {
- return iface;
- }
- }
-
- /* it didn't match any specific interface - use our general broadcast interface */
- return nbtsrv->bcast_interface;
-}
-
-
-/*
start listening on the given address
*/
static NTSTATUS nbt_add_socket(struct nbt_server *nbtsrv,
- const char *bind_address,
const char *address,
const char *bcast,
const char *netmask)
{
struct nbt_interface *iface;
NTSTATUS status;
+ struct nbt_name_socket *bcast_nbtsock;
+
+ /*
+ we actually create two sockets. One listens on the broadcast address
+ for the interface, and the other listens on our specific address. This
+ allows us to run with "bind interfaces only" while still receiving
+ broadcast addresses, and also simplifies matching incoming requests
+ to interfaces
+ */
iface = talloc(nbtsrv, struct nbt_interface);
NT_STATUS_HAVE_NO_MEMORY(iface);
@@ -103,10 +88,25 @@ static NTSTATUS nbt_add_socket(struct nbt_server *nbtsrv,
iface->netmask = talloc_steal(iface, netmask);
iface->names = NULL;
+ if (strcmp(netmask, "0.0.0.0") != 0) {
+ bcast_nbtsock = nbt_name_socket_init(iface, nbtsrv->task->event_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(iface->ip_address);
+
+ status = socket_listen(bcast_nbtsock->sock, bcast, lp_nbt_port(), 0, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Failed to bind to %s:%d - %s\n",
+ bcast, lp_nbt_port(), nt_errstr(status)));
+ talloc_free(iface);
+ return status;
+ }
+
+ nbt_set_incoming_handler(bcast_nbtsock, nbt_request_handler, iface);
+ }
+
iface->nbtsock = nbt_name_socket_init(iface, nbtsrv->task->event_ctx);
NT_STATUS_HAVE_NO_MEMORY(iface->ip_address);
- status = socket_listen(iface->nbtsock->sock, bind_address, lp_nbt_port(), 0, 0);
+ status = socket_listen(iface->nbtsock->sock, address, lp_nbt_port(), 0, 0);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to bind to %s:%d - %s\n",
address, lp_nbt_port(), nt_errstr(status)));
@@ -114,8 +114,11 @@ static NTSTATUS nbt_add_socket(struct nbt_server *nbtsrv,
return status;
}
+ /* we need to be able to send broadcasts out */
socket_set_option(iface->nbtsock->sock, "SO_BROADCAST", "1");
+ nbt_set_incoming_handler(iface->nbtsock, nbt_request_handler, iface);
+
if (strcmp(netmask, "0.0.0.0") == 0) {
DLIST_ADD(nbtsrv->bcast_interface, iface);
} else {
@@ -135,29 +138,37 @@ NTSTATUS nbt_startup_interfaces(struct nbt_server *nbtsrv)
int i;
TALLOC_CTX *tmp_ctx = talloc_new(nbtsrv);
NTSTATUS status;
- const char *primary_address;
- /* the primary address is the address we will return for non-WINS queries
- not made on a specific interface */
- if (num_interfaces > 0) {
- primary_address = talloc_strdup(tmp_ctx, sys_inet_ntoa(*iface_n_ip(0)));
- } else {
- primary_address = sys_inet_ntoa(interpret_addr2(lp_netbios_name()));
- }
+ /* if we are allowing incoming packets from any address, then
+ we also need to bind to the wildcard address */
+ if (!lp_bind_interfaces_only()) {
+ const char *primary_address;
+
+ /* the primary address is the address we will return
+ for non-WINS queries not made on a specific
+ interface */
+ if (num_interfaces > 0) {
+ primary_address = sys_inet_ntoa(*iface_n_ip(0));
+ } else {
+ primary_address = sys_inet_ntoa(interpret_addr2(
+ lp_netbios_name()));
+ }
+ primary_address = talloc_strdup(tmp_ctx, primary_address);
+ NT_STATUS_HAVE_NO_MEMORY(primary_address);
- status = nbt_add_socket(nbtsrv,
- "0.0.0.0",
- primary_address,
- talloc_strdup(tmp_ctx, "255.255.255.255"),
- talloc_strdup(tmp_ctx, "0.0.0.0"));
- NT_STATUS_NOT_OK_RETURN(status);
+ status = nbt_add_socket(nbtsrv,
+ primary_address,
+ talloc_strdup(tmp_ctx, "255.255.255.255"),
+ talloc_strdup(tmp_ctx, "0.0.0.0"));
+ NT_STATUS_NOT_OK_RETURN(status);
+ }
for (i=0; i<num_interfaces; i++) {
const char *address = talloc_strdup(tmp_ctx, sys_inet_ntoa(*iface_n_ip(i)));
const char *bcast = talloc_strdup(tmp_ctx, sys_inet_ntoa(*iface_n_bcast(i)));
const char *netmask = talloc_strdup(tmp_ctx, sys_inet_ntoa(*iface_n_netmask(i)));
- status = nbt_add_socket(nbtsrv, address, address, bcast, netmask);
+ status = nbt_add_socket(nbtsrv, address, bcast, netmask);
NT_STATUS_NOT_OK_RETURN(status);
}
diff --git a/source4/nbt_server/nbt_server.c b/source4/nbt_server/nbt_server.c
index 6e4acba115..4884398d78 100644
--- a/source4/nbt_server/nbt_server.c
+++ b/source4/nbt_server/nbt_server.c
@@ -27,27 +27,11 @@
/*
- receive an incoming request
-*/
-static void nbt_request_handler(struct nbt_name_socket *nbtsock,
- struct nbt_name_packet *packet,
- const char *src_address, int src_port)
-{
- switch (packet->operation & NBT_OPCODE) {
- case NBT_OPCODE_QUERY:
- nbt_request_query(nbtsock, packet, src_address, src_port);
- break;
- }
-}
-
-
-/*
startup the nbtd task
*/
static void nbtd_task_init(struct task_server *task)
{
struct nbt_server *nbtsrv;
- struct nbt_interface *iface;
NTSTATUS status;
nbtsrv = talloc(task, struct nbt_server);
@@ -67,13 +51,6 @@ static void nbtd_task_init(struct task_server *task)
return;
}
- /* setup the incoming request handler for all our interfaces */
- for (iface=nbtsrv->interfaces;iface;iface=iface->next) {
- nbt_set_incoming_handler(iface->nbtsock, nbt_request_handler, iface);
- }
- nbt_set_incoming_handler(nbtsrv->bcast_interface->nbtsock, nbt_request_handler,
- nbtsrv->bcast_interface);
-
/* start the process of registering our names on all interfaces */
nbt_register_names(nbtsrv);
}
diff --git a/source4/nbt_server/nodestatus.c b/source4/nbt_server/nodestatus.c
index f57c86d10f..36c3707374 100644
--- a/source4/nbt_server/nodestatus.c
+++ b/source4/nbt_server/nodestatus.c
@@ -99,12 +99,10 @@ void nbt_query_status(struct nbt_name_socket *nbtsock,
struct nbt_name_packet *packet,
const char *src_address, int src_port)
{
- struct nbt_interface *iface;
struct nbt_name *name;
struct nbt_iface_name *iname;
-
- /* find the interface for this query */
- iface = nbt_iface_find(nbtsock, src_address);
+ struct nbt_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbt_interface);
NBT_ASSERT_PACKET(packet, src_address, packet->qdcount == 1);
NBT_ASSERT_PACKET(packet, src_address, packet->questions[0].question_type == NBT_QTYPE_STATUS);
diff --git a/source4/nbt_server/query.c b/source4/nbt_server/query.c
index 2d2e75d51e..6dab18cfbe 100644
--- a/source4/nbt_server/query.c
+++ b/source4/nbt_server/query.c
@@ -81,9 +81,10 @@ void nbt_request_query(struct nbt_name_socket *nbtsock,
struct nbt_name_packet *packet,
const char *src_address, int src_port)
{
- struct nbt_interface *iface;
struct nbt_iface_name *iname;
struct nbt_name *name;
+ struct nbt_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbt_interface);
/* see if its a node status query */
if (packet->qdcount == 1 &&
@@ -99,9 +100,6 @@ void nbt_request_query(struct nbt_name_socket *nbtsock,
return;
}
- /* find the interface for this query */
- iface = nbt_iface_find(nbtsock, src_address);
-
NBT_ASSERT_PACKET(packet, src_address, packet->qdcount == 1);
NBT_ASSERT_PACKET(packet, src_address, packet->questions[0].question_type == NBT_QTYPE_NETBIOS);
NBT_ASSERT_PACKET(packet, src_address, packet->questions[0].question_class == NBT_QCLASS_IP);
diff --git a/source4/nbt_server/register.c b/source4/nbt_server/register.c
index 4f954c189a..6b75c992a9 100644
--- a/source4/nbt_server/register.c
+++ b/source4/nbt_server/register.c
@@ -209,7 +209,10 @@ static void nbt_register_name(struct nbt_server *nbtsrv,
}
/* register on our general broadcast interface as a permanent name */
- nbt_register_name_iface(nbtsrv->bcast_interface, name, type, nb_flags | NBT_NM_PERMANENT);
+ if (nbtsrv->bcast_interface) {
+ nbt_register_name_iface(nbtsrv->bcast_interface, name, type,
+ nb_flags | NBT_NM_PERMANENT);
+ }
/* TODO: register with our WINS servers */
}