diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/nbt_server/interfaces.c | 125 | ||||
-rw-r--r-- | source4/nbt_server/nbt_server.c | 23 | ||||
-rw-r--r-- | source4/nbt_server/nodestatus.c | 6 | ||||
-rw-r--r-- | source4/nbt_server/query.c | 6 | ||||
-rw-r--r-- | source4/nbt_server/register.c | 5 |
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 */ } |