/* register a name with our WINS servers */ void nbtd_winsclient_register(struct nbtd_iface_name *iname) { struct nbtd_interface *iface = iname->iface; struct nbt_name_register_wins io; struct composite_context *c; /* setup a wins name register request */ io.in.name = iname->name; io.in.wins_port = lp_nbt_port(iname->iface->nbtsrv->task->lp_ctx); io.in.wins_servers = lp_wins_server_list(iname->iface->nbtsrv->task->lp_ctx); io.in.addresses = nbtd_address_list(iface, iname); io.in.nb_flags = iname->nb_flags; io.in.ttl = iname->ttl; if (!io.in.addresses) { return; } c = nbt_name_register_wins_send(wins_socket(iface), &io); if (c == NULL) { talloc_free(io.in.addresses); return; } talloc_steal(c, io.in.addresses); c->async.fn = nbtd_wins_register_handler; c->async.private_data = iname; }
/* refresh a WINS name registration */ static void nbtd_wins_refresh(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *private_data) { struct nbtd_iface_name *iname = talloc_get_type(private_data, struct nbtd_iface_name); struct nbtd_interface *iface = iname->iface; struct nbt_name_refresh_wins io; struct composite_context *c; TALLOC_CTX *tmp_ctx = talloc_new(iname); /* setup a wins name refresh request */ io.in.name = iname->name; io.in.wins_servers = (const char **)str_list_make_single(tmp_ctx, iname->wins_server); io.in.wins_port = lp_nbt_port(iface->nbtsrv->task->lp_ctx); io.in.addresses = nbtd_address_list(iface, tmp_ctx); io.in.nb_flags = iname->nb_flags; io.in.ttl = iname->ttl; if (!io.in.addresses) { talloc_free(tmp_ctx); return; } c = nbt_name_refresh_wins_send(wins_socket(iface), &io); if (c == NULL) { talloc_free(tmp_ctx); return; } talloc_steal(c, io.in.addresses); c->async.fn = nbtd_wins_refresh_handler; c->async.private_data = iname; talloc_free(tmp_ctx); }
/* answer a name query */ void nbtd_request_query(struct nbt_name_socket *nbtsock, struct nbt_name_packet *packet, struct socket_address *src) { struct nbtd_iface_name *iname; struct nbt_name *name; struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data, struct nbtd_interface); /* see if its a node status query */ if (packet->qdcount == 1 && packet->questions[0].question_type == NBT_QTYPE_STATUS) { nbtd_query_status(nbtsock, packet, src); return; } NBTD_ASSERT_PACKET(packet, src, packet->qdcount == 1); NBTD_ASSERT_PACKET(packet, src, packet->questions[0].question_type == NBT_QTYPE_NETBIOS); NBTD_ASSERT_PACKET(packet, src, packet->questions[0].question_class == NBT_QCLASS_IP); /* see if we have the requested name on this interface */ name = &packet->questions[0].name; iname = nbtd_find_iname(iface, name, 0); if (iname == NULL) { /* don't send negative replies to broadcast queries */ if (packet->operation & NBT_FLAG_BROADCAST) { return; } if (packet->operation & NBT_FLAG_RECURSION_DESIRED) { nbtd_winsserver_request(nbtsock, packet, src); return; } /* otherwise send a negative reply */ nbtd_negative_name_query_reply(nbtsock, packet, src); return; } /* * normally we should forward all queries with the * recursion desired flag to the wins server, but this * breaks are winsclient code, when doing mhomed registrations */ if (!(packet->operation & NBT_FLAG_BROADCAST) && (packet->operation & NBT_FLAG_RECURSION_DESIRED) && (iname->nb_flags & NBT_NM_GROUP) && lpcfg_wins_support(iface->nbtsrv->task->lp_ctx)) { nbtd_winsserver_request(nbtsock, packet, src); return; } /* if the name is not yet active and its a broadcast query then ignore it for now */ if (!(iname->nb_flags & NBT_NM_ACTIVE) && (packet->operation & NBT_FLAG_BROADCAST)) { DEBUG(7,("Query for %s from %s - name not active yet on %s\n", nbt_name_string(packet, name), src->addr, iface->ip_address)); return; } nbtd_name_query_reply(nbtsock, packet, src, &iname->name, iname->ttl, iname->nb_flags, nbtd_address_list(iface, packet)); }