Esempio n. 1
0
/*
  find the interface to use for sending a outgoing request
*/
struct nbtd_interface *nbtd_find_request_iface(struct nbtd_server *nbtd_server,
					       const char *address, bool allow_bcast_iface)
{
	struct nbtd_interface *cur;

	/* 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) {
		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 */
	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;
}
Esempio n. 2
0
static void nbtd_wins_randomize1Clist(struct loadparm_context *lp_ctx,
				      const char **addresses, struct socket_address *src)
{
	const char *mask;
	const char *tmp;
	uint32_t num_addrs;
	uint32_t idx, sidx;
	int r;

	for (num_addrs=0; addresses[num_addrs]; num_addrs++) { /* noop */ }

	if (num_addrs <= 1) return; /* nothing to do */

	/* first sort the addresses depending on the matching to the client */
	ldb_qsort(addresses, num_addrs , sizeof(addresses[0]),
		  src, (ldb_qsort_cmp_fn_t)nbtd_wins_randomize1Clist_sort);

	mask = lp_parm_string(lp_ctx, NULL, "nbtd", "wins_randomize1Clist_mask");
	if (!mask) {
		mask = "255.255.255.0";
	}

	/* 
	 * choose a random address to be the first in the response to the client,
	 * preferr the addresses inside the nbtd:wins_randomize1Clist_mask netmask
	 */
	r = random();
	idx = sidx = r % num_addrs;

	while (1) {
		bool same;

		/* if the current one is in the same subnet, use it */
		same = iface_same_net(addresses[idx], src->addr, mask);
		if (same) {
			sidx = idx;
			break;
		}

		/* we need to check for idx == 0, after checking for the same net */
		if (idx == 0) break;
		/* 
		 * if we haven't found an address in the same subnet, search in ones
		 * which match the client more
		 *
		 * some notes:
		 *
		 * it's not "idx = idx % r" but "idx = r % idx"
		 * because in "a % b" b is the allowed range
		 * and b-1 is the maximum possible result, so it must be decreasing
		 * and the above idx == 0 check breaks the while(1) loop.
		 */
		idx = r % idx;
	}

	/* note sidx == 0 is also valid here ... */
	tmp		= addresses[0];
	addresses[0]	= addresses[sidx];
	addresses[sidx]	= tmp;
}