root/source4/nbt_server/nodestatus.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nbtd_node_status_reply
  2. nbtd_query_status

   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 /*
  30   send a name status reply
  31 */
  32 static void nbtd_node_status_reply(struct nbt_name_socket *nbtsock, 
     /* [<][>][^][v][top][bottom][index][help] */
  33                                    struct nbt_name_packet *request_packet, 
  34                                    struct socket_address *src,
  35                                    struct nbt_name *name, 
  36                                    struct nbtd_interface *iface)
  37 {
  38         struct nbt_name_packet *packet;
  39         uint32_t name_count;
  40         struct nbtd_iface_name *iname;
  41         struct nbtd_server *nbtsrv = iface->nbtsrv;
  42         
  43         /* work out how many names to send */
  44         name_count = 0;
  45         for (iname=iface->names;iname;iname=iname->next) {
  46                 if ((iname->nb_flags & NBT_NM_ACTIVE) && 
  47                     strcmp(iname->name.name, "*") != 0) {
  48                         name_count++;
  49                 }
  50         }
  51 
  52         packet = talloc_zero(nbtsock, struct nbt_name_packet);
  53         if (packet == NULL) return;
  54 
  55         packet->name_trn_id = request_packet->name_trn_id;
  56         packet->ancount = 1;
  57         packet->operation = NBT_OPCODE_QUERY | NBT_FLAG_REPLY | NBT_FLAG_AUTHORITIVE;
  58 
  59         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
  60         if (packet->answers == NULL) goto failed;
  61 
  62         packet->answers[0].name     = *name;
  63         packet->answers[0].rr_type  = NBT_QTYPE_STATUS;
  64         packet->answers[0].rr_class = NBT_QCLASS_IP;
  65         packet->answers[0].ttl      = 0;
  66         packet->answers[0].rdata.status.num_names = name_count;
  67         packet->answers[0].rdata.status.names = talloc_array(packet->answers,
  68                                                              struct nbt_status_name, name_count);
  69         if (packet->answers[0].rdata.status.names == NULL) goto failed;
  70 
  71         name_count = 0;
  72         for (iname=iface->names;iname;iname=iname->next) {
  73                 if ((iname->nb_flags & NBT_NM_ACTIVE) && 
  74                     strcmp(iname->name.name, "*") != 0) {
  75                         struct nbt_status_name *n = &packet->answers[0].rdata.status.names[name_count];
  76                         n->name = talloc_asprintf(packet->answers, "%-15s", iname->name.name);
  77                         if (n->name == NULL) goto failed;
  78                         n->type     = iname->name.type;
  79                         n->nb_flags = iname->nb_flags;
  80                         name_count++;
  81                 }
  82         }
  83         /* we deliberately don't fill in the statistics structure as
  84            it could lead to giving attackers too much information */
  85         ZERO_STRUCT(packet->answers[0].rdata.status.statistics);
  86 
  87         DEBUG(7,("Sending node status reply for %s to %s:%d\n", 
  88                  nbt_name_string(packet, name), src->addr, src->port));
  89         
  90         nbtsrv->stats.total_sent++;
  91         nbt_name_reply_send(nbtsock, src, packet);
  92 
  93 failed:
  94         talloc_free(packet);
  95 }
  96 
  97 
  98 /*
  99   answer a node status query
 100 */
 101 void nbtd_query_status(struct nbt_name_socket *nbtsock, 
     /* [<][>][^][v][top][bottom][index][help] */
 102                        struct nbt_name_packet *packet, 
 103                        struct socket_address *src)
 104 {
 105         struct nbt_name *name;
 106         struct nbtd_iface_name *iname;
 107         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
 108                                                        struct nbtd_interface);
 109 
 110         NBTD_ASSERT_PACKET(packet, src, packet->qdcount == 1);
 111         NBTD_ASSERT_PACKET(packet, src, packet->questions[0].question_type == NBT_QTYPE_STATUS);
 112         NBTD_ASSERT_PACKET(packet, src, packet->questions[0].question_class == NBT_QCLASS_IP);
 113 
 114         /* see if we have the requested name on this interface */
 115         name = &packet->questions[0].name;
 116 
 117         iname = nbtd_find_iname(iface, name, NBT_NM_ACTIVE);
 118         if (iname == NULL) {
 119                 DEBUG(7,("Node status query for %s from %s - not found on %s\n",
 120                          nbt_name_string(packet, name), src->addr, iface->ip_address));
 121                 return;
 122         }
 123 
 124         nbtd_node_status_reply(nbtsock, packet, src, 
 125                                &iname->name, iface);
 126 }

/* [<][>][^][v][top][bottom][index][help] */