static bool process_one(struct loadparm_context *lp_ctx, struct tevent_context *ev, struct interface *ifaces, const char *name, int nbt_port) { TALLOC_CTX *tmp_ctx = talloc_new(NULL); enum nbt_name_type node_type = NBT_NAME_CLIENT; char *node_name, *p; struct socket_address *all_zero_addr; struct nbt_name_socket *nbtsock; NTSTATUS status = NT_STATUS_OK; bool ret = true; if (!options.case_sensitive) { name = strupper_talloc(tmp_ctx, name); } if (options.find_master) { node_type = NBT_NAME_MASTER; if (*name == '-' || *name == '_') { name = "\01\02__MSBROWSE__\02"; node_type = NBT_NAME_MS; } } p = strchr(name, '#'); if (p) { node_name = talloc_strndup(tmp_ctx, name, PTR_DIFF(p,name)); node_type = (enum nbt_name_type)strtol(p+1, NULL, 16); } else { node_name = talloc_strdup(tmp_ctx, name); } nbtsock = nbt_name_socket_init(tmp_ctx, ev); if (options.root_port) { all_zero_addr = socket_address_from_strings(tmp_ctx, nbtsock->sock->backend_name, "0.0.0.0", NBT_NAME_SERVICE_PORT); if (!all_zero_addr) { talloc_free(tmp_ctx); return false; } status = socket_listen(nbtsock->sock, all_zero_addr, 0, 0); if (!NT_STATUS_IS_OK(status)) { printf("Failed to bind to local port 137 - %s\n", nt_errstr(status)); talloc_free(tmp_ctx); return false; } } if (options.lookup_by_ip) { ret = do_node_status(nbtsock, name, nbt_port); talloc_free(tmp_ctx); return ret; } if (options.broadcast_address) { status = do_node_query(nbtsock, options.broadcast_address, nbt_port, node_name, node_type, true); } else if (options.unicast_address) { status = do_node_query(nbtsock, options.unicast_address, nbt_port, node_name, node_type, false); } else { int i, num_interfaces; num_interfaces = iface_list_count(ifaces); for (i=0;i<num_interfaces;i++) { const char *bcast = iface_list_n_bcast(ifaces, i); if (bcast == NULL) continue; status = do_node_query(nbtsock, bcast, nbt_port, node_name, node_type, true); if (NT_STATUS_IS_OK(status)) break; } } if (!NT_STATUS_IS_OK(status)) { printf("Lookup failed - %s\n", nt_errstr(status)); ret = false; } talloc_free(tmp_ctx); return ret; }
/* setup our listening sockets on the configured network interfaces */ NTSTATUS nbtd_startup_interfaces(struct nbtd_server *nbtsrv, struct loadparm_context *lp_ctx, struct interface *ifaces) { int num_interfaces = iface_list_count(ifaces); int i; TALLOC_CTX *tmp_ctx = talloc_new(nbtsrv); NTSTATUS status; /* if we are allowing incoming packets from any address, then we also need to bind to the wildcard address */ if (!lpcfg_bind_interfaces_only(lp_ctx)) { const char *primary_address; primary_address = iface_list_first_v4(ifaces); /* the primary address is the address we will return for non-WINS queries not made on a specific interface */ if (primary_address == NULL) { primary_address = inet_ntoa(interpret_addr2( lpcfg_netbios_name(lp_ctx))); } primary_address = talloc_strdup(tmp_ctx, primary_address); NT_STATUS_HAVE_NO_MEMORY(primary_address); status = nbtd_add_socket(nbtsrv, lp_ctx, "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); } for (i=0; i<num_interfaces; i++) { const char *bcast; const char *address, *netmask; if (!iface_list_n_is_v4(ifaces, i)) { /* v4 only for NBT protocol */ continue; } bcast = iface_list_n_bcast(ifaces, i); /* we can't assume every interface is broadcast capable */ if (bcast == NULL) continue; address = talloc_strdup(tmp_ctx, iface_list_n_ip(ifaces, i)); bcast = talloc_strdup(tmp_ctx, bcast); netmask = talloc_strdup(tmp_ctx, iface_list_n_netmask(ifaces, i)); status = nbtd_add_socket(nbtsrv, lp_ctx, address, address, bcast, netmask); NT_STATUS_NOT_OK_RETURN(status); } if (lpcfg_wins_server_list(lp_ctx)) { status = nbtd_add_wins_socket(nbtsrv); NT_STATUS_NOT_OK_RETURN(status); } talloc_free(tmp_ctx); return NT_STATUS_OK; }