From 0487eee93a06c8d4d1925660d6d14374c4039d86 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Feb 2005 23:54:37 +0000 Subject: r5346: - a bit more preparation for the WINS server going in - more NBT packet asserts, to ensure that incoming requests have all the elements we depend on - open the WINS database at startup if we are configured as a WINS server - split out the nbtd server reply packet generation code so it can be shared by the WINS server - re-did the logic of what is answered by the WINS server and what by the B node server. It now always tries to answer by the B node, and only "recurses" to the WINS server for names that are not found. (This used to be commit 5613e6b8ad9b32639caf5055f793dbc4d0a2fc19) --- source4/nbt_server/packet.c | 142 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) (limited to 'source4/nbt_server/packet.c') diff --git a/source4/nbt_server/packet.c b/source4/nbt_server/packet.c index a6df618a3f..edca4ecb00 100644 --- a/source4/nbt_server/packet.c +++ b/source4/nbt_server/packet.c @@ -76,3 +76,145 @@ BOOL nbtd_self_packet(struct nbt_name_socket *nbtsock, return False; } + + +/* + send a name query reply +*/ +void nbtd_name_query_reply(struct nbt_name_socket *nbtsock, + struct nbt_name_packet *request_packet, + const char *src_address, int src_port, + struct nbt_name *name, uint32_t ttl, + uint16_t nb_flags, const char **addresses) +{ + struct nbt_name_packet *packet; + size_t num_addresses = str_list_length(addresses); + int i; + + if (num_addresses == 0) { + DEBUG(3,("No addresses in name query reply - failing\n")); + return; + } + + packet = talloc_zero(nbtsock, struct nbt_name_packet); + if (packet == NULL) return; + + packet->name_trn_id = request_packet->name_trn_id; + packet->ancount = 1; + packet->operation = + NBT_FLAG_REPLY | + NBT_OPCODE_QUERY | + NBT_FLAG_AUTHORITIVE | + NBT_FLAG_RECURSION_DESIRED | + NBT_FLAG_RECURSION_AVAIL; + + packet->answers = talloc_array(packet, struct nbt_res_rec, 1); + if (packet->answers == NULL) goto failed; + + packet->answers[0].name = *name; + packet->answers[0].rr_type = NBT_QTYPE_NETBIOS; + packet->answers[0].rr_class = NBT_QCLASS_IP; + packet->answers[0].ttl = ttl; + packet->answers[0].rdata.netbios.length = num_addresses*6; + packet->answers[0].rdata.netbios.addresses = + talloc_array(packet->answers, struct nbt_rdata_address, num_addresses); + if (packet->answers[0].rdata.netbios.addresses == NULL) goto failed; + + for (i=0;ianswers[0].rdata.netbios.addresses[i]; + addr->nb_flags = nb_flags; + addr->ipaddr = talloc_strdup(packet->answers, addresses[i]); + if (addr->ipaddr == NULL) goto failed; + } + + DEBUG(7,("Sending name query reply for %s<%02x> at %s to %s:%d\n", + name->name, name->type, addresses[0], src_address, src_port)); + + nbt_name_reply_send(nbtsock, src_address, src_port, packet); + +failed: + talloc_free(packet); +} + + +/* + send a negative name query reply +*/ +void nbtd_negative_name_query_reply(struct nbt_name_socket *nbtsock, + struct nbt_name_packet *request_packet, + const char *src_address, int src_port) +{ + struct nbt_name_packet *packet; + struct nbt_name *name = &request_packet->questions[0].name; + + packet = talloc_zero(nbtsock, struct nbt_name_packet); + if (packet == NULL) return; + + packet->name_trn_id = request_packet->name_trn_id; + packet->ancount = 1; + packet->operation = + NBT_FLAG_REPLY | + NBT_OPCODE_QUERY | + NBT_FLAG_AUTHORITIVE | + NBT_RCODE_NAM; + + packet->answers = talloc_array(packet, struct nbt_res_rec, 1); + if (packet->answers == NULL) goto failed; + + packet->answers[0].name = *name; + packet->answers[0].rr_type = NBT_QTYPE_NULL; + packet->answers[0].rr_class = NBT_QCLASS_IP; + packet->answers[0].ttl = 0; + ZERO_STRUCT(packet->answers[0].rdata); + + DEBUG(7,("Sending negative name query reply for %s<%02x> to %s:%d\n", + name->name, name->type, src_address, src_port)); + + nbt_name_reply_send(nbtsock, src_address, src_port, packet); + +failed: + talloc_free(packet); +} + +/* + send a name defense reply +*/ +void nbtd_negative_name_registration_reply(struct nbt_name_socket *nbtsock, + struct nbt_name_packet *request_packet, + const char *src_address, int src_port) +{ + struct nbt_name_packet *packet; + struct nbt_name *name = &request_packet->questions[0].name; + + packet = talloc_zero(nbtsock, struct nbt_name_packet); + if (packet == NULL) return; + + packet->name_trn_id = request_packet->name_trn_id; + packet->ancount = 1; + packet->operation = + NBT_FLAG_REPLY | + NBT_OPCODE_REGISTER | + NBT_FLAG_AUTHORITIVE | + NBT_FLAG_RECURSION_DESIRED | + NBT_FLAG_RECURSION_AVAIL | + NBT_RCODE_ACT; + + packet->answers = talloc_array(packet, struct nbt_res_rec, 1); + if (packet->answers == NULL) goto failed; + + packet->answers[0].name = *name; + packet->answers[0].rr_type = NBT_QTYPE_NETBIOS; + packet->answers[0].rr_class = NBT_QCLASS_IP; + packet->answers[0].ttl = 0; + packet->answers[0].rdata = request_packet->additional[0].rdata; + + DEBUG(7,("Sending negative name registration reply for %s<%02x> to %s:%d\n", + name->name, name->type, src_address, src_port)); + + nbt_name_reply_send(nbtsock, src_address, src_port, packet); + +failed: + talloc_free(packet); +} + -- cgit