/* 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_list_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; }
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_TYPESAFE_QSORT(addresses, num_addrs, src, nbtd_wins_randomize1Clist_sort); mask = lpcfg_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, * prefer 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_list_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; }
/* return the list of interface IPs we have configured takes an loadparm context, returns a list of IPs in string form Does not return addresses on 127.0.0.0/8 */ static PyObject *py_interface_ips(PyObject *self, PyObject *args) { PyObject *pylist; int count; TALLOC_CTX *tmp_ctx; PyObject *py_lp_ctx; struct loadparm_context *lp_ctx; struct interface *ifaces; int i, ifcount; int all_interfaces = 1; if (!PyArg_ParseTuple(args, "O|i", &py_lp_ctx, &all_interfaces)) return NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { PyErr_NoMemory(); return NULL; } lp_ctx = lpcfg_from_py_object(tmp_ctx, py_lp_ctx); if (lp_ctx == NULL) { talloc_free(tmp_ctx); return NULL; } load_interface_list(tmp_ctx, lp_ctx, &ifaces); count = iface_list_count(ifaces); /* first count how many are not loopback addresses */ for (ifcount = i = 0; i<count; i++) { const char *ip = iface_list_n_ip(ifaces, i); if (all_interfaces) { ifcount++; continue; } if (iface_list_same_net(ip, "127.0.0.1", "255.0.0.0")) { continue; } if (iface_list_same_net(ip, "169.254.0.0", "255.255.0.0")) { continue; } if (iface_list_same_net(ip, "::1", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")) { continue; } if (iface_list_same_net(ip, "fe80::", "ffff:ffff:ffff:ffff::")) { continue; } ifcount++; } pylist = PyList_New(ifcount); for (ifcount = i = 0; i<count; i++) { const char *ip = iface_list_n_ip(ifaces, i); if (all_interfaces) { PyList_SetItem(pylist, ifcount, PyString_FromString(ip)); ifcount++; continue; } if (iface_list_same_net(ip, "127.0.0.1", "255.0.0.0")) { continue; } if (iface_list_same_net(ip, "169.254.0.0", "255.255.0.0")) { continue; } if (iface_list_same_net(ip, "::1", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")) { continue; } if (iface_list_same_net(ip, "fe80::", "ffff:ffff:ffff:ffff::")) { continue; } PyList_SetItem(pylist, ifcount, PyString_FromString(ip)); ifcount++; } talloc_free(tmp_ctx); return pylist; }