*/
#include "includes.h"
-#include "lib/util/dlinklist.h"
+#include "../lib/util/dlinklist.h"
#include "nbt_server/nbt_server.h"
#include "smbd/service_task.h"
#include "lib/socket/socket.h"
#include "system/network.h"
#include "lib/socket/netif.h"
#include "param/param.h"
+#include "lib/util/util_net.h"
/*
struct nbt_name_packet *packet,
struct socket_address *src)
{
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
struct nbtd_server *nbtsrv = iface->nbtsrv;
}
}
+static void nbtd_unexpected_handler(struct nbt_name_socket *nbtsock,
+ struct nbt_name_packet *packet,
+ struct socket_address *src)
+{
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
+ struct nbtd_interface);
+ struct nbtd_server *nbtsrv = iface->nbtsrv;
+ struct nbtd_interface *i;
+ struct nbt_name_request *req = NULL;
+
+ nbtsrv->stats.total_received++;
+
+ DEBUG(10,("unexpected from src[%s] on interface[%p] %s/%s\n",
+ src->addr, iface, iface->ip_address, iface->netmask));
+
+ /* try the broadcast interface */
+ if (nbtsrv->bcast_interface) {
+ i = nbtsrv->bcast_interface;
+ req = idr_find(i->nbtsock->idr, packet->name_trn_id);
+ }
+
+ /* try the wins server client interface */
+ if (!req && nbtsrv->wins_interface && nbtsrv->wins_interface->nbtsock) {
+ i = nbtsrv->wins_interface;
+ req = idr_find(i->nbtsock->idr, packet->name_trn_id);
+ }
+
+ /* try all other interfaces... */
+ if (!req) {
+ for (i = nbtsrv->interfaces; i; i = i->next) {
+ if (i == iface) {
+ continue;
+ }
+ req = idr_find(i->nbtsock->idr, packet->name_trn_id);
+ if (req) break;
+ }
+ }
+
+ if (!req) {
+ DEBUG(10,("unexpected from src[%s] unable to redirected\n", src->addr));
+ return;
+ }
+
+ DEBUG(10,("unexpected from src[%s] redirected to interface[%p] %s/%s\n",
+ src->addr, i, i->ip_address, i->netmask));
+
+ /*
+ * redirect the incoming response to the socket
+ * we sent the matching request
+ */
+ nbt_name_socket_handle_response_packet(req, packet, src);
+}
/*
find a registered name on an interface
struct socket_address *bcast_address;
struct socket_address *unicast_address;
+ DEBUG(6,("nbtd_add_socket(%s, %s, %s, %s)\n", bind_address, address, bcast, netmask));
+
/*
we actually create two sockets. One listens on the broadcast address
for the interface, and the other listens on our specific address. This
iface->ip_address = talloc_steal(iface, address);
iface->netmask = talloc_steal(iface, netmask);
iface->names = NULL;
+ iface->wack_queue = NULL;
if (strcmp(netmask, "0.0.0.0") != 0) {
struct nbt_name_socket *bcast_nbtsock;
talloc_free(unicast_address);
nbt_set_incoming_handler(iface->nbtsock, nbtd_request_handler, iface);
+ nbt_set_unexpected_handler(iface->nbtsock, nbtd_unexpected_handler, iface);
/* also setup the datagram listeners */
status = nbtd_dgram_setup(iface, bind_address);
/*
setup our listening sockets on the configured network interfaces
*/
-NTSTATUS nbtd_startup_interfaces(struct nbtd_server *nbtsrv, struct loadparm_context *lp_ctx)
+NTSTATUS nbtd_startup_interfaces(struct nbtd_server *nbtsrv, struct loadparm_context *lp_ctx,
+ struct interface *ifaces)
{
- int num_interfaces = iface_count();
+ int num_interfaces = iface_count(ifaces);
int i;
TALLOC_CTX *tmp_ctx = talloc_new(nbtsrv);
NTSTATUS status;
for non-WINS queries not made on a specific
interface */
if (num_interfaces > 0) {
- primary_address = iface_n_ip(0);
+ primary_address = iface_n_ip(ifaces, 0);
} else {
primary_address = inet_ntoa(interpret_addr2(
lp_netbios_name(lp_ctx)));
}
for (i=0; i<num_interfaces; i++) {
- const char *bcast = iface_n_bcast(i);
+ const char *bcast = iface_n_bcast(ifaces, i);
const char *address, *netmask;
/* we can't assume every interface is broadcast capable */
if (bcast == NULL) continue;
- address = talloc_strdup(tmp_ctx, iface_n_ip(i));
+ address = talloc_strdup(tmp_ctx, iface_n_ip(ifaces, i));
bcast = talloc_strdup(tmp_ctx, bcast);
- netmask = talloc_strdup(tmp_ctx, iface_n_netmask(i));
+ netmask = talloc_strdup(tmp_ctx, iface_n_netmask(ifaces, i));
status = nbtd_add_socket(nbtsrv, lp_ctx,
address, address, bcast, netmask);
/* try to find a exact match */
for (cur=nbtd_server->interfaces;cur;cur=cur->next) {
if (iface_same_net(address, cur->ip_address, cur->netmask)) {
+ DEBUG(10,("find interface for dst[%s] ip: %s/%s (iface[%p])\n",
+ address, cur->ip_address, cur->netmask, cur));
return cur;
}
}
/* no exact match, if we have the broadcast interface, use that */
if (allow_bcast_iface && nbtd_server->bcast_interface) {
- return nbtd_server->bcast_interface;
+ cur = nbtd_server->bcast_interface;
+ DEBUG(10,("find interface for dst[%s] ip: %s/%s (bcast iface[%p])\n",
+ address, cur->ip_address, cur->netmask, cur));
+ return cur;
}
/* fallback to first interface */
- return nbtd_server->interfaces;
+ cur = nbtd_server->interfaces;
+ DEBUG(10,("find interface for dst[%s] ip: %s/%s (default iface[%p])\n",
+ address, cur->ip_address, cur->netmask, cur));
+ return cur;
}
/*