LCOV - code coverage report
Current view: top level - source4/nbt_server - nodestatus.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 55 77 71.4 %
Date: 2024-04-21 15:09:00 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    answer node status queries
       5             : 
       6             :    Copyright (C) Andrew Tridgell        2005
       7             :    
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             :    
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             :    
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "../lib/util/dlinklist.h"
      24             : #include "system/network.h"
      25             : #include "nbt_server/nbt_server.h"
      26             : #include "lib/socket/socket.h"
      27             : #include "librpc/gen_ndr/ndr_nbt.h"
      28             : 
      29          19 : struct nbt_name_packet *nbtd_node_status_reply_packet(
      30             :         TALLOC_CTX *mem_ctx,
      31             :         uint16_t trn_id,
      32             :         const struct nbt_name *name,
      33             :         struct nbtd_interface *iface)
      34             : {
      35           0 :         struct nbtd_iface_name *iname;
      36           0 :         struct nbt_name_packet *packet;
      37           0 :         struct nbt_res_rec *answer;
      38           0 :         struct nbt_rdata_status *stat;
      39           0 :         uint32_t num_names;
      40           0 :         NTSTATUS status;
      41             : 
      42          19 :         num_names = 0;
      43         186 :         for (iname = iface->names; iname != NULL; iname = iname->next) {
      44         167 :                 if ((iname->nb_flags & NBT_NM_ACTIVE) == 0) {
      45           0 :                         continue;
      46             :                 }
      47         167 :                 if (strcmp(iname->name.name, "*") == 0) {
      48          19 :                         continue;
      49             :                 }
      50         148 :                 num_names += 1;
      51             :         }
      52             : 
      53          19 :         packet = talloc_zero(mem_ctx, struct nbt_name_packet);
      54          19 :         if (packet == NULL) {
      55           0 :                 return NULL;
      56             :         }
      57             : 
      58          19 :         packet->name_trn_id = trn_id;
      59          19 :         packet->ancount = 1;
      60          19 :         packet->operation =
      61             :                 NBT_OPCODE_QUERY |
      62             :                 NBT_FLAG_REPLY |
      63             :                 NBT_FLAG_AUTHORITATIVE;
      64             : 
      65          19 :         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
      66          19 :         if (packet->answers == NULL) {
      67           0 :                 goto failed;
      68             :         }
      69             : 
      70          19 :         answer = &packet->answers[0];
      71             : 
      72          19 :         status = nbt_name_dup(packet->answers, name, &answer->name);
      73          19 :         if (!NT_STATUS_IS_OK(status)) {
      74           0 :                 goto failed;
      75             :         }
      76             : 
      77          19 :         answer->rr_type  = NBT_QTYPE_STATUS;
      78          19 :         answer->rr_class = NBT_QCLASS_IP;
      79          19 :         answer->ttl      = 0;
      80             : 
      81          19 :         stat = &packet->answers[0].rdata.status;
      82             : 
      83          19 :         stat->num_names = num_names;
      84          19 :         stat->names = talloc_zero_array(
      85             :                 packet->answers,
      86             :                 struct nbt_status_name,
      87             :                 num_names);
      88          19 :         if (stat->names == NULL) {
      89           0 :                 goto failed;
      90             :         }
      91             : 
      92          19 :         num_names = 0;
      93         186 :         for (iname = iface->names; iname != NULL; iname = iname->next) {
      94         167 :                 struct nbt_status_name *n = &stat->names[num_names];
      95             : 
      96         167 :                 if ((iname->nb_flags & NBT_NM_ACTIVE) == 0) {
      97           0 :                         continue;
      98             :                 }
      99         167 :                 if (strcmp(iname->name.name, "*") == 0) {
     100          19 :                         continue;
     101             :                 }
     102             : 
     103         296 :                 n->name = talloc_asprintf(
     104         148 :                         stat->names,
     105             :                         "%-15s",
     106             :                         iname->name.name);
     107         148 :                 if (n->name == NULL) {
     108           0 :                         goto failed;
     109             :                 }
     110         148 :                 n->type = iname->name.type;
     111         148 :                 n->nb_flags = iname->nb_flags;
     112             : 
     113         148 :                 num_names += 1;
     114             :         }
     115             : 
     116          19 :         return packet;
     117             : 
     118           0 : failed:
     119           0 :         TALLOC_FREE(packet);
     120           0 :         return NULL;
     121             : }
     122             : 
     123             : /*
     124             :   send a name status reply
     125             : */
     126          19 : static void nbtd_node_status_reply(struct nbt_name_socket *nbtsock, 
     127             :                                    struct nbt_name_packet *request_packet, 
     128             :                                    struct socket_address *src,
     129             :                                    struct nbt_name *name, 
     130             :                                    struct nbtd_interface *iface)
     131             : {
     132           0 :         struct nbt_name_packet *packet;
     133          19 :         struct nbtd_server *nbtsrv = iface->nbtsrv;
     134             : 
     135          19 :         packet = nbtd_node_status_reply_packet(
     136             :                 nbtsock,
     137          19 :                 request_packet->name_trn_id,
     138             :                 name,
     139             :                 iface);
     140          19 :         if (packet == NULL) {
     141           0 :                 return;
     142             :         }
     143             : 
     144          19 :         DEBUG(7,("Sending node status reply for %s to %s:%d\n", 
     145             :                  nbt_name_string(packet, name), src->addr, src->port));
     146             :         
     147          19 :         nbtsrv->stats.total_sent++;
     148          19 :         nbt_name_reply_send(nbtsock, src, packet);
     149             : 
     150          19 :         talloc_free(packet);
     151             : }
     152             : 
     153             : 
     154             : /*
     155             :   answer a node status query
     156             : */
     157          19 : void nbtd_query_status(struct nbt_name_socket *nbtsock, 
     158             :                        struct nbt_name_packet *packet, 
     159             :                        struct socket_address *src)
     160             : {
     161           0 :         struct nbt_name *name;
     162           0 :         struct nbtd_iface_name *iname;
     163          19 :         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
     164             :                                                        struct nbtd_interface);
     165             : 
     166          19 :         NBTD_ASSERT_PACKET(packet, src, packet->qdcount == 1);
     167          19 :         NBTD_ASSERT_PACKET(packet, src, packet->questions[0].question_type == NBT_QTYPE_STATUS);
     168          19 :         NBTD_ASSERT_PACKET(packet, src, packet->questions[0].question_class == NBT_QCLASS_IP);
     169             : 
     170             :         /* see if we have the requested name on this interface */
     171          19 :         name = &packet->questions[0].name;
     172             : 
     173          19 :         iname = nbtd_find_iname(iface, name, NBT_NM_ACTIVE);
     174          19 :         if (iname == NULL) {
     175           0 :                 DEBUG(7,("Node status query for %s from %s - not found on %s\n",
     176             :                          nbt_name_string(packet, name), src->addr, iface->ip_address));
     177           0 :                 return;
     178             :         }
     179             : 
     180          19 :         nbtd_node_status_reply(nbtsock, packet, src, 
     181             :                                &iname->name, iface);
     182             : }

Generated by: LCOV version 1.14