summaryrefslogtreecommitdiff
path: root/source4/nbt_server
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2018-02-02 15:03:16 +0100
committerVolker Lendecke <vl@samba.org>2018-04-17 21:27:23 +0200
commita7d5250597f5ae7a2b4555d12e0f12212e27fb3d (patch)
treec1ed5f8b027621870c793304e42411cdbe381bc9 /source4/nbt_server
parente6df6f206d568e313e9da99461ae5502d06d7eb1 (diff)
downloadsamba-a7d5250597f5ae7a2b4555d12e0f12212e27fb3d.tar.gz
nbt_server: Factor out nbtd_node_status_reply_packet
Separate packet creation from sending out the packet. This way packet creation can be used elsewhere in the future. Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'source4/nbt_server')
-rw-r--r--source4/nbt_server/nodestatus.c146
1 files changed, 101 insertions, 45 deletions
diff --git a/source4/nbt_server/nodestatus.c b/source4/nbt_server/nodestatus.c
index f71746ab300..e26cda7c5dd 100644
--- a/source4/nbt_server/nodestatus.c
+++ b/source4/nbt_server/nodestatus.c
@@ -26,6 +26,100 @@
#include "lib/socket/socket.h"
#include "librpc/gen_ndr/ndr_nbt.h"
+struct nbt_name_packet *nbtd_node_status_reply_packet(
+ TALLOC_CTX *mem_ctx,
+ uint16_t trn_id,
+ const struct nbt_name *name,
+ struct nbtd_interface *iface)
+{
+ struct nbtd_iface_name *iname;
+ struct nbt_name_packet *packet;
+ struct nbt_res_rec *answer;
+ struct nbt_rdata_status *stat;
+ uint32_t num_names;
+ NTSTATUS status;
+
+ num_names = 0;
+ for (iname = iface->names; iname != NULL; iname = iname->next) {
+ if ((iname->nb_flags & NBT_NM_ACTIVE) == 0) {
+ continue;
+ }
+ if (strcmp(iname->name.name, "*") == 0) {
+ continue;
+ }
+ num_names += 1;
+ }
+
+ packet = talloc_zero(mem_ctx, struct nbt_name_packet);
+ if (packet == NULL) {
+ return NULL;
+ }
+
+ packet->name_trn_id = trn_id;
+ packet->ancount = 1;
+ packet->operation =
+ NBT_OPCODE_QUERY |
+ NBT_FLAG_REPLY |
+ NBT_FLAG_AUTHORITATIVE;
+
+ packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
+ if (packet->answers == NULL) {
+ goto failed;
+ }
+
+ answer = &packet->answers[0];
+
+ status = nbt_name_dup(packet->answers, name, &answer->name);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto failed;
+ }
+
+ answer->rr_type = NBT_QTYPE_STATUS;
+ answer->rr_class = NBT_QCLASS_IP;
+ answer->ttl = 0;
+
+ stat = &packet->answers[0].rdata.status;
+
+ stat->num_names = num_names;
+ stat->names = talloc_zero_array(
+ packet->answers,
+ struct nbt_status_name,
+ num_names);
+ if (stat->names == NULL) {
+ goto failed;
+ }
+
+ num_names = 0;
+ for (iname = iface->names; iname != NULL; iname = iname->next) {
+ struct nbt_status_name *n = &stat->names[num_names];
+
+ if ((iname->nb_flags & NBT_NM_ACTIVE) == 0) {
+ continue;
+ }
+ if (strcmp(iname->name.name, "*") == 0) {
+ continue;
+ }
+
+ n->name = talloc_asprintf(
+ stat->names,
+ "%-15s",
+ iname->name.name);
+ if (n->name == NULL) {
+ goto failed;
+ }
+ n->type = iname->name.type;
+ n->nb_flags = iname->nb_flags;
+
+ num_names += 1;
+ }
+
+ return packet;
+
+failed:
+ TALLOC_FREE(packet);
+ return NULL;
+}
+
/*
send a name status reply
*/
@@ -36,53 +130,16 @@ static void nbtd_node_status_reply(struct nbt_name_socket *nbtsock,
struct nbtd_interface *iface)
{
struct nbt_name_packet *packet;
- uint32_t name_count;
- struct nbtd_iface_name *iname;
struct nbtd_server *nbtsrv = iface->nbtsrv;
-
- /* work out how many names to send */
- name_count = 0;
- for (iname=iface->names;iname;iname=iname->next) {
- if ((iname->nb_flags & NBT_NM_ACTIVE) &&
- strcmp(iname->name.name, "*") != 0) {
- name_count++;
- }
- }
-
- 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_OPCODE_QUERY | NBT_FLAG_REPLY | NBT_FLAG_AUTHORITATIVE;
-
- 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_STATUS;
- packet->answers[0].rr_class = NBT_QCLASS_IP;
- packet->answers[0].ttl = 0;
- packet->answers[0].rdata.status.num_names = name_count;
- packet->answers[0].rdata.status.names = talloc_array(packet->answers,
- struct nbt_status_name, name_count);
- if (packet->answers[0].rdata.status.names == NULL) goto failed;
-
- name_count = 0;
- for (iname=iface->names;iname;iname=iname->next) {
- if ((iname->nb_flags & NBT_NM_ACTIVE) &&
- strcmp(iname->name.name, "*") != 0) {
- struct nbt_status_name *n = &packet->answers[0].rdata.status.names[name_count];
- n->name = talloc_asprintf(packet->answers, "%-15s", iname->name.name);
- if (n->name == NULL) goto failed;
- n->type = iname->name.type;
- n->nb_flags = iname->nb_flags;
- name_count++;
- }
+ packet = nbtd_node_status_reply_packet(
+ nbtsock,
+ request_packet->name_trn_id,
+ name,
+ iface);
+ if (packet == NULL) {
+ return;
}
- /* we deliberately don't fill in the statistics structure as
- it could lead to giving attackers too much information */
- ZERO_STRUCT(packet->answers[0].rdata.status.statistics);
DEBUG(7,("Sending node status reply for %s to %s:%d\n",
nbt_name_string(packet, name), src->addr, src->port));
@@ -90,7 +147,6 @@ static void nbtd_node_status_reply(struct nbt_name_socket *nbtsock,
nbtsrv->stats.total_sent++;
nbt_name_reply_send(nbtsock, src, packet);
-failed:
talloc_free(packet);
}